[483] | 1 | define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/query", |
---|
| 2 | "dojo/dom-construct","dojo/io/script"], |
---|
| 3 | function(kernel, lang, declare, domQuery, domConstruct, scriptIO) { |
---|
| 4 | |
---|
| 5 | kernel.experimental("dojox.data.GoogleSearchStore"); |
---|
| 6 | |
---|
| 7 | var SearchStore = declare("dojox.data.GoogleSearchStore",null,{ |
---|
| 8 | // summary: |
---|
| 9 | // A data store for retrieving search results from Google. |
---|
| 10 | // This data store acts as a base class for Google searches, |
---|
| 11 | // and has a number of child data stores that implement different |
---|
| 12 | // searches. This store defaults to searching the web, and is functionally |
---|
| 13 | // identical to the dojox.data.GoogleWebSearchStore object. |
---|
| 14 | // The following attributes are supported on each item: |
---|
| 15 | // |
---|
| 16 | // - url - The URL for the item |
---|
| 17 | // - unescapedUrl - The URL for the item, with URL escaping. This is often more readable |
---|
| 18 | // - visibleUrl - The URL with no protocol specified. |
---|
| 19 | // - cacheUrl - The URL to the copy of the document cached by Google |
---|
| 20 | // - title - The page title in HTML format. |
---|
| 21 | // - titleNoFormatting - The page title in plain text |
---|
| 22 | // - content - A snippet of information about the page |
---|
| 23 | // |
---|
| 24 | // The query accepts one parameter: text - The string to search for |
---|
| 25 | constructor: function(/*Object*/args){ |
---|
| 26 | // summary: |
---|
| 27 | // Initializer for the GoogleSearchStore store. |
---|
| 28 | // description: |
---|
| 29 | // The GoogleSearchStore is a Datastore interface to |
---|
| 30 | // the Google search service. The constructor accepts the following arguments: |
---|
| 31 | // |
---|
| 32 | // - label - the label attribute to use. Defaults to titleNoFormatting |
---|
| 33 | // - key - The API key to use. This is optional |
---|
| 34 | // - lang - The language locale to use. Defaults to the browser locale |
---|
| 35 | |
---|
| 36 | if(args){ |
---|
| 37 | if(args.label){ |
---|
| 38 | this.label = args.label; |
---|
| 39 | } |
---|
| 40 | if(args.key){ |
---|
| 41 | this._key = args.key; |
---|
| 42 | } |
---|
| 43 | if(args.lang){ |
---|
| 44 | this._lang = args.lang; |
---|
| 45 | } |
---|
| 46 | if("urlPreventCache" in args){ |
---|
| 47 | this.urlPreventCache = args.urlPreventCache?true:false; |
---|
| 48 | } |
---|
| 49 | } |
---|
| 50 | this._id = dojox.data.GoogleSearchStore.prototype._id++; |
---|
| 51 | }, |
---|
| 52 | |
---|
| 53 | // _id: Integer |
---|
| 54 | // A unique identifier for this store. |
---|
| 55 | _id: 0, |
---|
| 56 | |
---|
| 57 | // _requestCount: Integer |
---|
| 58 | // A counter for the number of requests made. This is used to define |
---|
| 59 | // the callback function that GoogleSearchStore will use. |
---|
| 60 | _requestCount: 0, |
---|
| 61 | |
---|
| 62 | // _googleUrl: String |
---|
| 63 | // The URL to Googles search web service. |
---|
| 64 | _googleUrl: "http://ajax.googleapis.com/ajax/services/search/", |
---|
| 65 | |
---|
| 66 | // _storeRef: String |
---|
| 67 | // The internal reference added to each item pointing at the store which owns it. |
---|
| 68 | _storeRef: "_S", |
---|
| 69 | |
---|
| 70 | // _attributes: Array |
---|
| 71 | // The list of attributes that this store supports |
---|
| 72 | _attributes: [ "unescapedUrl", "url", "visibleUrl", "cacheUrl", "title", |
---|
| 73 | "titleNoFormatting", "content", "estimatedResultCount"], |
---|
| 74 | |
---|
| 75 | // _aggregtedAttributes: Hash |
---|
| 76 | // Maps per-query aggregated attributes that this store supports to the result keys that they come from. |
---|
| 77 | _aggregatedAttributes: { |
---|
| 78 | estimatedResultCount: "cursor.estimatedResultCount" |
---|
| 79 | }, |
---|
| 80 | |
---|
| 81 | // label: String |
---|
| 82 | // The default attribute which acts as a label for each item. |
---|
| 83 | label: "titleNoFormatting", |
---|
| 84 | |
---|
| 85 | // type: String |
---|
| 86 | // The type of search. Valid values are "web", "local", "video", "blogs", "news", "books", "images". |
---|
| 87 | // This should not be set directly. Instead use one of the child classes. |
---|
| 88 | _type: "web", |
---|
| 89 | |
---|
| 90 | // urlPreventCache: boolean |
---|
| 91 | // Sets whether or not to pass preventCache to dojo.io.script. |
---|
| 92 | urlPreventCache: true, |
---|
| 93 | |
---|
| 94 | |
---|
| 95 | // _queryAttrs: Hash |
---|
| 96 | // Maps query hash keys to Google query parameters. |
---|
| 97 | _queryAttrs: { |
---|
| 98 | text: 'q' |
---|
| 99 | }, |
---|
| 100 | |
---|
| 101 | _assertIsItem: function(/* item */ item){ |
---|
| 102 | // summary: |
---|
| 103 | // This function tests whether the item passed in is indeed an item in the store. |
---|
| 104 | // item: |
---|
| 105 | // The item to test for being contained by the store. |
---|
| 106 | if(!this.isItem(item)){ |
---|
| 107 | throw new Error("dojox.data.GoogleSearchStore: a function was passed an item argument that was not an item"); |
---|
| 108 | } |
---|
| 109 | }, |
---|
| 110 | |
---|
| 111 | _assertIsAttribute: function(/* attribute-name-string */ attribute){ |
---|
| 112 | // summary: |
---|
| 113 | // This function tests whether the item passed in is indeed a valid 'attribute' like type for the store. |
---|
| 114 | // attribute: |
---|
| 115 | // The attribute to test for being contained by the store. |
---|
| 116 | if(typeof attribute !== "string"){ |
---|
| 117 | throw new Error("dojox.data.GoogleSearchStore: a function was passed an attribute argument that was not an attribute name string"); |
---|
| 118 | } |
---|
| 119 | }, |
---|
| 120 | |
---|
| 121 | getFeatures: function(){ |
---|
| 122 | // summary: |
---|
| 123 | // See dojo/data/api/Read.getFeatures() |
---|
| 124 | return { |
---|
| 125 | 'dojo.data.api.Read': true |
---|
| 126 | }; |
---|
| 127 | }, |
---|
| 128 | |
---|
| 129 | getValue: function(item, attribute, defaultValue){ |
---|
| 130 | // summary: |
---|
| 131 | // See dojo/data/api/Read.getValue() |
---|
| 132 | var values = this.getValues(item, attribute); |
---|
| 133 | if(values && values.length > 0){ |
---|
| 134 | return values[0]; |
---|
| 135 | } |
---|
| 136 | return defaultValue; |
---|
| 137 | }, |
---|
| 138 | |
---|
| 139 | getAttributes: function(item){ |
---|
| 140 | // summary: |
---|
| 141 | // See dojo/data/api/Read.getAttributes() |
---|
| 142 | return this._attributes; |
---|
| 143 | }, |
---|
| 144 | |
---|
| 145 | hasAttribute: function(item, attribute){ |
---|
| 146 | // summary: |
---|
| 147 | // See dojo/data/api/Read.hasAttributes() |
---|
| 148 | if(this.getValue(item,attribute)){ |
---|
| 149 | return true; |
---|
| 150 | } |
---|
| 151 | return false; |
---|
| 152 | }, |
---|
| 153 | |
---|
| 154 | isItemLoaded: function(item){ |
---|
| 155 | // summary: |
---|
| 156 | // See dojo/data/api/Read.isItemLoaded() |
---|
| 157 | return this.isItem(item); |
---|
| 158 | }, |
---|
| 159 | |
---|
| 160 | loadItem: function(keywordArgs){ |
---|
| 161 | // summary: |
---|
| 162 | // See dojo/data/api/Read.loadItem() |
---|
| 163 | }, |
---|
| 164 | |
---|
| 165 | getLabel: function(item){ |
---|
| 166 | // summary: |
---|
| 167 | // See dojo/data/api/Read.getLabel() |
---|
| 168 | return this.getValue(item,this.label); |
---|
| 169 | }, |
---|
| 170 | |
---|
| 171 | getLabelAttributes: function(item){ |
---|
| 172 | // summary: |
---|
| 173 | // See dojo/data/api/Read.getLabelAttributes() |
---|
| 174 | return [this.label]; |
---|
| 175 | }, |
---|
| 176 | |
---|
| 177 | containsValue: function(item, attribute, value){ |
---|
| 178 | // summary: |
---|
| 179 | // See dojo/data/api/Read.containsValue() |
---|
| 180 | var values = this.getValues(item,attribute); |
---|
| 181 | for(var i = 0; i < values.length; i++){ |
---|
| 182 | if(values[i] === value){ |
---|
| 183 | return true; |
---|
| 184 | } |
---|
| 185 | } |
---|
| 186 | return false; |
---|
| 187 | }, |
---|
| 188 | |
---|
| 189 | getValues: function(item, attribute){ |
---|
| 190 | // summary: |
---|
| 191 | // See dojo/data/api/Read.getValue() |
---|
| 192 | this._assertIsItem(item); |
---|
| 193 | this._assertIsAttribute(attribute); |
---|
| 194 | var val = item[attribute]; |
---|
| 195 | if(lang.isArray(val)) { |
---|
| 196 | return val; |
---|
| 197 | }else if(val !== undefined){ |
---|
| 198 | return [val]; |
---|
| 199 | }else{ |
---|
| 200 | return []; |
---|
| 201 | } |
---|
| 202 | }, |
---|
| 203 | |
---|
| 204 | isItem: function(item){ |
---|
| 205 | // summary: |
---|
| 206 | // See dojo/data/api/Read.isItem() |
---|
| 207 | if(item && item[this._storeRef] === this){ |
---|
| 208 | return true; |
---|
| 209 | } |
---|
| 210 | return false; |
---|
| 211 | }, |
---|
| 212 | |
---|
| 213 | close: function(request){ |
---|
| 214 | // summary: |
---|
| 215 | // See dojo/data/api/Read.close() |
---|
| 216 | }, |
---|
| 217 | |
---|
| 218 | _format: function(item, name){ |
---|
| 219 | return item;//base implementation does not format any items |
---|
| 220 | }, |
---|
| 221 | |
---|
| 222 | fetch: function(request){ |
---|
| 223 | // summary: |
---|
| 224 | // Fetch Google search items that match to a query |
---|
| 225 | // request: |
---|
| 226 | // A request object |
---|
| 227 | // fetchHandler: |
---|
| 228 | // A function to call for fetched items |
---|
| 229 | // errorHandler: |
---|
| 230 | // A function to call on error |
---|
| 231 | request = request || {}; |
---|
| 232 | |
---|
| 233 | var scope = request.scope || kernel.global; |
---|
| 234 | |
---|
| 235 | if(!request.query){ |
---|
| 236 | if(request.onError){ |
---|
| 237 | request.onError.call(scope, new Error(this.declaredClass + |
---|
| 238 | ": A query must be specified.")); |
---|
| 239 | return; |
---|
| 240 | } |
---|
| 241 | } |
---|
| 242 | //Make a copy of the request object, in case it is |
---|
| 243 | //modified outside the store in the middle of a request |
---|
| 244 | var query = {}; |
---|
| 245 | for(var attr in this._queryAttrs) { |
---|
| 246 | query[attr] = request.query[attr]; |
---|
| 247 | } |
---|
| 248 | request = { |
---|
| 249 | query: query, |
---|
| 250 | onComplete: request.onComplete, |
---|
| 251 | onError: request.onError, |
---|
| 252 | onItem: request.onItem, |
---|
| 253 | onBegin: request.onBegin, |
---|
| 254 | start: request.start, |
---|
| 255 | count: request.count |
---|
| 256 | }; |
---|
| 257 | |
---|
| 258 | //Google's web api will only return a max of 8 results per page. |
---|
| 259 | var pageSize = 8; |
---|
| 260 | |
---|
| 261 | //Generate a unique function to be called back |
---|
| 262 | var callbackFn = "GoogleSearchStoreCallback_" + this._id + "_" + (++this._requestCount); |
---|
| 263 | |
---|
| 264 | //Build up the content to send the request for. |
---|
| 265 | //rsz is the result size, "large" gives 8 results each time |
---|
| 266 | var content = this._createContent(query, callbackFn, request); |
---|
| 267 | |
---|
| 268 | var firstRequest; |
---|
| 269 | |
---|
| 270 | if(typeof(request.start) === "undefined" || request.start === null){ |
---|
| 271 | request.start = 0; |
---|
| 272 | } |
---|
| 273 | |
---|
| 274 | if(!request.count){ |
---|
| 275 | request.count = pageSize; |
---|
| 276 | } |
---|
| 277 | firstRequest = {start: request.start - request.start % pageSize}; |
---|
| 278 | |
---|
| 279 | var _this = this; |
---|
| 280 | var searchUrl = this._googleUrl + this._type; |
---|
| 281 | |
---|
| 282 | var getArgs = { |
---|
| 283 | url: searchUrl, |
---|
| 284 | preventCache: this.urlPreventCache, |
---|
| 285 | content: content |
---|
| 286 | }; |
---|
| 287 | |
---|
| 288 | var items = []; |
---|
| 289 | var successfulReq = 0; |
---|
| 290 | var finished = false; |
---|
| 291 | var lastOnItem = request.start -1; |
---|
| 292 | var numRequests = 0; |
---|
| 293 | var scriptIds = []; |
---|
| 294 | |
---|
| 295 | // Performs the remote request. |
---|
| 296 | function doRequest(req){ |
---|
| 297 | //Record how many requests have been made. |
---|
| 298 | numRequests ++; |
---|
| 299 | getArgs.content.context = getArgs.content.start = req.start; |
---|
| 300 | |
---|
| 301 | var deferred = scriptIO.get(getArgs); |
---|
| 302 | scriptIds.push(deferred.ioArgs.id); |
---|
| 303 | |
---|
| 304 | //We only set up the errback, because the callback isn't ever really used because we have |
---|
| 305 | //to link to the jsonp callback function.... |
---|
| 306 | deferred.addErrback(function(error){ |
---|
| 307 | if(request.onError){ |
---|
| 308 | request.onError.call(scope, error, request); |
---|
| 309 | } |
---|
| 310 | }); |
---|
| 311 | } |
---|
| 312 | |
---|
| 313 | // Function to handle returned data. |
---|
| 314 | var myHandler = function(start, data){ |
---|
| 315 | if (scriptIds.length > 0) { |
---|
| 316 | // Delete the script node that was created. |
---|
| 317 | domQuery("#" + scriptIds.splice(0,1)).forEach(domConstruct.destroy); |
---|
| 318 | } |
---|
| 319 | if(finished){return;} |
---|
| 320 | |
---|
| 321 | var results = _this._getItems(data); |
---|
| 322 | var cursor = data ? data['cursor']: null; |
---|
| 323 | |
---|
| 324 | if(results){ |
---|
| 325 | //Process the results, adding the store reference to them |
---|
| 326 | for(var i = 0; i < results.length && i + start < request.count + request.start; i++) { |
---|
| 327 | _this._processItem(results[i], data); |
---|
| 328 | items[i + start] = results[i]; |
---|
| 329 | } |
---|
| 330 | successfulReq ++; |
---|
| 331 | if(successfulReq == 1){ |
---|
| 332 | // After the first request, we know how many results exist. |
---|
| 333 | // So perform any follow up requests to retrieve more data. |
---|
| 334 | var pages = cursor ? cursor.pages : null; |
---|
| 335 | var firstStart = pages ? Number(pages[pages.length - 1].start) : 0; |
---|
| 336 | |
---|
| 337 | //Call the onBegin method if it exists |
---|
| 338 | if (request.onBegin){ |
---|
| 339 | var est = cursor ? cursor.estimatedResultCount : results.length; |
---|
| 340 | var total = est ? Math.min(est, firstStart + results.length) : firstStart + results.length; |
---|
| 341 | request.onBegin.call(scope, total, request); |
---|
| 342 | } |
---|
| 343 | |
---|
| 344 | // Request the next pages. |
---|
| 345 | var nextPage = (request.start - request.start % pageSize) + pageSize; |
---|
| 346 | var page = 1; |
---|
| 347 | while(pages){ |
---|
| 348 | if(!pages[page] || Number(pages[page].start) >= request.start + request.count){ |
---|
| 349 | break; |
---|
| 350 | } |
---|
| 351 | if(Number(pages[page].start) >= nextPage) { |
---|
| 352 | doRequest({start: pages[page].start}); |
---|
| 353 | } |
---|
| 354 | page++; |
---|
| 355 | } |
---|
| 356 | } |
---|
| 357 | |
---|
| 358 | // Call the onItem function on all retrieved items. |
---|
| 359 | if(request.onItem && items[lastOnItem + 1]){ |
---|
| 360 | do{ |
---|
| 361 | lastOnItem++; |
---|
| 362 | request.onItem.call(scope, items[lastOnItem], request); |
---|
| 363 | }while(items[lastOnItem + 1] && lastOnItem < request.start + request.count); |
---|
| 364 | } |
---|
| 365 | |
---|
| 366 | //If this is the last request, call final fetch handler. |
---|
| 367 | if(successfulReq == numRequests){ |
---|
| 368 | //Process the items... |
---|
| 369 | finished = true; |
---|
| 370 | //Clean up the function, it should never be called again |
---|
| 371 | kernel.global[callbackFn] = null; |
---|
| 372 | if(request.onItem){ |
---|
| 373 | request.onComplete.call(scope, null, request); |
---|
| 374 | }else{ |
---|
| 375 | items = items.slice(request.start, request.start + request.count); |
---|
| 376 | request.onComplete.call(scope, items, request); |
---|
| 377 | } |
---|
| 378 | |
---|
| 379 | } |
---|
| 380 | } |
---|
| 381 | }; |
---|
| 382 | |
---|
| 383 | var callbacks = []; |
---|
| 384 | var lastCallback = firstRequest.start - 1; |
---|
| 385 | |
---|
| 386 | // Attach a callback function to the global namespace, where Google can call it. |
---|
| 387 | kernel.global[callbackFn] = function(start, data, responseCode, errorMsg){ |
---|
| 388 | try { |
---|
| 389 | if(responseCode != 200){ |
---|
| 390 | if(request.onError){ |
---|
| 391 | request.onError.call(scope, new Error("Response from Google was: " + responseCode), request); |
---|
| 392 | } |
---|
| 393 | kernel.global[callbackFn] = function(){};//an error occurred, do not return anything else. |
---|
| 394 | return; |
---|
| 395 | } |
---|
| 396 | |
---|
| 397 | if(start == lastCallback + 1){ |
---|
| 398 | myHandler(Number(start), data); |
---|
| 399 | lastCallback += pageSize; |
---|
| 400 | |
---|
| 401 | //make sure that the callbacks happen in the correct sequence |
---|
| 402 | if(callbacks.length > 0){ |
---|
| 403 | callbacks.sort(_this._getSort()); |
---|
| 404 | //In case the requsts do not come back in order, sort the returned results. |
---|
| 405 | while(callbacks.length > 0 && callbacks[0].start == lastCallback + 1){ |
---|
| 406 | myHandler(Number(callbacks[0].start), callbacks[0].data); |
---|
| 407 | callbacks.splice(0,1); |
---|
| 408 | lastCallback += pageSize; |
---|
| 409 | } |
---|
| 410 | } |
---|
| 411 | }else{ |
---|
| 412 | callbacks.push({start:start, data: data}); |
---|
| 413 | } |
---|
| 414 | } catch (e) { |
---|
| 415 | request.onError.call(scope, e, request); |
---|
| 416 | } |
---|
| 417 | }; |
---|
| 418 | |
---|
| 419 | // Perform the first request. When this has finished |
---|
| 420 | // we will have a list of pages, which can then be |
---|
| 421 | // gone through |
---|
| 422 | doRequest(firstRequest); |
---|
| 423 | }, |
---|
| 424 | |
---|
| 425 | _getSort: function() { |
---|
| 426 | return function(a,b){ |
---|
| 427 | if(a.start < b.start){return -1;} |
---|
| 428 | if(b.start < a.start){return 1;} |
---|
| 429 | return 0; |
---|
| 430 | }; |
---|
| 431 | }, |
---|
| 432 | |
---|
| 433 | _processItem: function(item, data) { |
---|
| 434 | item[this._storeRef] = this; |
---|
| 435 | // Copy aggregated attributes from query results to the item. |
---|
| 436 | for(var attribute in this._aggregatedAttributes) { |
---|
| 437 | item[attribute] = lang.getObject(this._aggregatedAttributes[attribute], false, data); |
---|
| 438 | } |
---|
| 439 | }, |
---|
| 440 | |
---|
| 441 | _getItems: function(data){ |
---|
| 442 | return data['results'] || data; |
---|
| 443 | }, |
---|
| 444 | |
---|
| 445 | _createContent: function(query, callback, request){ |
---|
| 446 | var content = { |
---|
| 447 | v: "1.0", |
---|
| 448 | rsz: "large", |
---|
| 449 | callback: callback, |
---|
| 450 | key: this._key, |
---|
| 451 | hl: this._lang |
---|
| 452 | }; |
---|
| 453 | for(var attr in this._queryAttrs) { |
---|
| 454 | content[this._queryAttrs[attr]] = query[attr]; |
---|
| 455 | } |
---|
| 456 | return content; |
---|
| 457 | } |
---|
| 458 | }); |
---|
| 459 | |
---|
| 460 | var WebSearchStore = declare("dojox.data.GoogleWebSearchStore", SearchStore,{ |
---|
| 461 | // summary: |
---|
| 462 | // A data store for retrieving search results from Google. |
---|
| 463 | // The following attributes are supported on each item: |
---|
| 464 | // |
---|
| 465 | // - title - The page title in HTML format. |
---|
| 466 | // - titleNoFormatting - The page title in plain text |
---|
| 467 | // - content - A snippet of information about the page |
---|
| 468 | // - url - The URL for the item |
---|
| 469 | // - unescapedUrl - The URL for the item, with URL escaping. This is often more readable |
---|
| 470 | // - visibleUrl - The URL with no protocol specified. |
---|
| 471 | // - cacheUrl - The URL to the copy of the document cached by Google |
---|
| 472 | // - estimatedResultCount - (aggregated per-query) estimated number of results |
---|
| 473 | // |
---|
| 474 | // The query accepts one parameter: text - The string to search for |
---|
| 475 | }); |
---|
| 476 | |
---|
| 477 | var BlogSearchStore = declare("dojox.data.GoogleBlogSearchStore", SearchStore,{ |
---|
| 478 | // summary: |
---|
| 479 | // A data store for retrieving search results from Google. |
---|
| 480 | // The following attributes are supported on each item: |
---|
| 481 | // |
---|
| 482 | // - title - The blog post title in HTML format. |
---|
| 483 | // - titleNoFormatting - The blog post title in plain text |
---|
| 484 | // - content - A snippet of information about the blog post |
---|
| 485 | // - blogUrl - The URL for the blog |
---|
| 486 | // - postUrl - The URL for the a single blog post |
---|
| 487 | // - visibleUrl - The URL with no protocol specified. |
---|
| 488 | // - cacheUrl - The URL to the copy of the document cached by Google |
---|
| 489 | // - author - The author of the blog post |
---|
| 490 | // - publishedDate - The published date, in RFC-822 format |
---|
| 491 | // |
---|
| 492 | // The query accepts one parameter: text - The string to search for |
---|
| 493 | _type: "blogs", |
---|
| 494 | _attributes: ["blogUrl", "postUrl", "title", "titleNoFormatting", "content", |
---|
| 495 | "author", "publishedDate"], |
---|
| 496 | _aggregatedAttributes: { } |
---|
| 497 | }); |
---|
| 498 | |
---|
| 499 | |
---|
| 500 | var LocalSearchStore = declare("dojox.data.GoogleLocalSearchStore", SearchStore,{ |
---|
| 501 | // summary: |
---|
| 502 | // A data store for retrieving search results from Google. |
---|
| 503 | // The following attributes are supported on each item: |
---|
| 504 | // |
---|
| 505 | // - title - The blog post title in HTML format. |
---|
| 506 | // - titleNoFormatting - The blog post title in plain text |
---|
| 507 | // - content - A snippet of information about the blog post |
---|
| 508 | // - url - The URL for the item |
---|
| 509 | // - lat - The latitude. |
---|
| 510 | // - lng - The longtitude. |
---|
| 511 | // - streetAddress - The street address |
---|
| 512 | // - city - The city |
---|
| 513 | // - region - The region |
---|
| 514 | // - country - The country |
---|
| 515 | // - phoneNumbers - Phone numbers associated with this address. Can be one or more. |
---|
| 516 | // - ddUrl - A URL that can be used to provide driving directions from the center of the search results to this search results |
---|
| 517 | // - ddUrlToHere - A URL that can be used to provide driving directions from this search result to a user specified location |
---|
| 518 | // - staticMapUrl - The published date, in RFC-822 format |
---|
| 519 | // - viewport - Recommended viewport for the query results (same for all results in a query) |
---|
| 520 | // - center - contains lat, lng properties |
---|
| 521 | // - span - lat, lng properties for the viewport span |
---|
| 522 | // - ne, sw - lat, lng properties for the viewport corners |
---|
| 523 | // |
---|
| 524 | // The query accepts the following parameters: |
---|
| 525 | // |
---|
| 526 | // - text - The string to search for |
---|
| 527 | // - centerLatLong - Comma-separated lat & long for the center of the search (e.g. "48.8565,2.3509") |
---|
| 528 | // - searchSpan - Comma-separated lat & long degrees indicating the size of the desired search area (e.g. "0.065165,0.194149") |
---|
| 529 | |
---|
| 530 | _type: "local", |
---|
| 531 | _attributes: ["title", "titleNoFormatting", "url", "lat", "lng", "streetAddress", |
---|
| 532 | "city", "region", "country", "phoneNumbers", "ddUrl", "ddUrlToHere", |
---|
| 533 | "ddUrlFromHere", "staticMapUrl", "viewport"], |
---|
| 534 | _aggregatedAttributes: { |
---|
| 535 | viewport: "viewport" |
---|
| 536 | }, |
---|
| 537 | _queryAttrs: { |
---|
| 538 | text: 'q', |
---|
| 539 | centerLatLong: 'sll', |
---|
| 540 | searchSpan: 'sspn' |
---|
| 541 | } |
---|
| 542 | }); |
---|
| 543 | |
---|
| 544 | var VideoSearchStore = declare("dojox.data.GoogleVideoSearchStore", SearchStore,{ |
---|
| 545 | // summary: |
---|
| 546 | // A data store for retrieving search results from Google. |
---|
| 547 | // The following attributes are supported on each item: |
---|
| 548 | // |
---|
| 549 | // - title - The blog post title in HTML format. |
---|
| 550 | // - titleNoFormatting - The blog post title in plain text |
---|
| 551 | // - content - A snippet of information about the blog post |
---|
| 552 | // - url - The URL for the item |
---|
| 553 | // - published - The published date, in RFC-822 format. |
---|
| 554 | // - publisher - The name of the publisher. |
---|
| 555 | // - duration - The approximate duration, in seconds, of the video. |
---|
| 556 | // - tbWidth - The width in pixels of the video. |
---|
| 557 | // - tbHeight - The height in pixels of the video |
---|
| 558 | // - tbUrl - The URL to a thumbnail representation of the video. |
---|
| 559 | // - playUrl - If present, supplies the url of the flash version of the video that can be played inline on your page. To play this video simply create and <embed> element on your page using this value as the src attribute and using application/x-shockwave-flash as the type attribute. If you want the video to play right away, make sure to append &autoPlay=true to the url.. |
---|
| 560 | // |
---|
| 561 | // The query accepts one parameter: text - The string to search for |
---|
| 562 | _type: "video", |
---|
| 563 | _attributes: ["title", "titleNoFormatting", "content", "url", "published", "publisher", |
---|
| 564 | "duration", "tbWidth", "tbHeight", "tbUrl", "playUrl"], |
---|
| 565 | _aggregatedAttributes: { } |
---|
| 566 | }); |
---|
| 567 | |
---|
| 568 | var NewsSearchStore = declare("dojox.data.GoogleNewsSearchStore", SearchStore,{ |
---|
| 569 | // summary: |
---|
| 570 | // A data store for retrieving search results from Google. |
---|
| 571 | // The following attributes are supported on each item: |
---|
| 572 | // |
---|
| 573 | // - title - The news story title in HTML format. |
---|
| 574 | // - titleNoFormatting - The news story title in plain text |
---|
| 575 | // - content - A snippet of information about the news story |
---|
| 576 | // - url - The URL for the item |
---|
| 577 | // - unescapedUrl - The URL for the item, with URL escaping. This is often more readable |
---|
| 578 | // - publisher - The name of the publisher |
---|
| 579 | // - clusterUrl - A URL pointing to a page listing related storied. |
---|
| 580 | // - location - The location of the news story. |
---|
| 581 | // - publishedDate - The date of publication, in RFC-822 format. |
---|
| 582 | // - relatedStories - An optional array of objects specifying related stories. |
---|
| 583 | // Each object has the following subset of properties: |
---|
| 584 | // "title", "titleNoFormatting", "url", "unescapedUrl", "publisher", "location", "publishedDate". |
---|
| 585 | // |
---|
| 586 | // The query accepts one parameter: text - The string to search for |
---|
| 587 | _type: "news", |
---|
| 588 | _attributes: ["title", "titleNoFormatting", "content", "url", "unescapedUrl", "publisher", |
---|
| 589 | "clusterUrl", "location", "publishedDate", "relatedStories" ], |
---|
| 590 | _aggregatedAttributes: { } |
---|
| 591 | }); |
---|
| 592 | |
---|
| 593 | var BookSearchStore = declare("dojox.data.GoogleBookSearchStore", SearchStore,{ |
---|
| 594 | // summary: |
---|
| 595 | // A data store for retrieving search results from Google. |
---|
| 596 | // The following attributes are supported on each item: |
---|
| 597 | // |
---|
| 598 | // - title - The book title in HTML format. |
---|
| 599 | // - titleNoFormatting - The book title in plain text |
---|
| 600 | // - authors - An array of authors |
---|
| 601 | // - url - The URL for the item |
---|
| 602 | // - unescapedUrl - The URL for the item, with URL escaping. This is often more readable |
---|
| 603 | // - bookId - An identifier for the book, usually an ISBN. |
---|
| 604 | // - pageCount - The number of pages in the book. |
---|
| 605 | // - publishedYear - The year of publication. |
---|
| 606 | // |
---|
| 607 | // The query accepts one parameter: text - The string to search for |
---|
| 608 | _type: "books", |
---|
| 609 | _attributes: ["title", "titleNoFormatting", "authors", "url", "unescapedUrl", "bookId", |
---|
| 610 | "pageCount", "publishedYear"], |
---|
| 611 | _aggregatedAttributes: { } |
---|
| 612 | }); |
---|
| 613 | |
---|
| 614 | var ImageSearchStore = declare("dojox.data.GoogleImageSearchStore", SearchStore,{ |
---|
| 615 | // summary: |
---|
| 616 | // A data store for retrieving search results from Google. |
---|
| 617 | // The following attributes are supported on each item: |
---|
| 618 | // |
---|
| 619 | // - title - The image title in HTML format. |
---|
| 620 | // - titleNoFormatting - The image title in plain text |
---|
| 621 | // - url - The URL for the image |
---|
| 622 | // - unescapedUrl - The URL for the image, with URL escaping. This is often more readable |
---|
| 623 | // - tbUrl - The URL for the image thumbnail |
---|
| 624 | // - visibleUrl - A shortened version of the URL associated with the result, stripped of a protocol and path |
---|
| 625 | // - originalContextUrl - The URL of the page containing the image. |
---|
| 626 | // - width - The width of the image in pixels. |
---|
| 627 | // - height - The height of the image in pixels. |
---|
| 628 | // - tbWidth - The width of the image thumbnail in pixels. |
---|
| 629 | // - tbHeight - The height of the image thumbnail in pixels. |
---|
| 630 | // - content - A snippet of information about the image, in HTML format |
---|
| 631 | // - contentNoFormatting - A snippet of information about the image, in plain text |
---|
| 632 | // |
---|
| 633 | // The query accepts one parameter: text - The string to search for |
---|
| 634 | _type: "images", |
---|
| 635 | _attributes: ["title", "titleNoFormatting", "visibleUrl", "url", "unescapedUrl", |
---|
| 636 | "originalContextUrl", "width", "height", "tbWidth", "tbHeight", |
---|
| 637 | "tbUrl", "content", "contentNoFormatting"], |
---|
| 638 | _aggregatedAttributes: { } |
---|
| 639 | }); |
---|
| 640 | |
---|
| 641 | return { |
---|
| 642 | Search: SearchStore, |
---|
| 643 | ImageSearch: ImageSearchStore, |
---|
| 644 | BookSearch: BookSearchStore, |
---|
| 645 | NewsSearch: NewsSearchStore, |
---|
| 646 | VideoSearch: VideoSearchStore, |
---|
| 647 | LocalSearch: LocalSearchStore, |
---|
| 648 | BlogSearch: BlogSearchStore, |
---|
| 649 | WebSearch: WebSearchStore |
---|
| 650 | } |
---|
| 651 | }); |
---|