[483] | 1 | dojo.provide("dojox.help._base"); |
---|
| 2 | dojo.require("dojox.rpc.Service"); |
---|
| 3 | dojo.require("dojo.io.script"); |
---|
| 4 | |
---|
| 5 | dojo.experimental("dojox.help"); |
---|
| 6 | console.warn("Script causes side effects (on numbers, strings, and booleans). Call dojox.help.noConflict() if you plan on executing code."); |
---|
| 7 | |
---|
| 8 | dojox.help = { |
---|
| 9 | // summary: |
---|
| 10 | // Adds the help function to all variables. |
---|
| 11 | locate: function(/*String*/ searchFor, /*String|Object|String[]|Object[]*/ searchIn, /*Number*/ maxResults){ |
---|
| 12 | // summary: |
---|
| 13 | // Search for dojo functionality that has something to do with the given string. |
---|
| 14 | // description: |
---|
| 15 | // Search for locally available data; variable names and any cached |
---|
| 16 | // documentation results for matches containing our search parameter |
---|
| 17 | // searchFor: |
---|
| 18 | // The string to search for. |
---|
| 19 | // searchIn: |
---|
| 20 | // The namespaces to search in. Defaults to dojox.help._namespaces |
---|
| 21 | // maxResults: |
---|
| 22 | // The maximum number of results. |
---|
| 23 | maxResults = maxResults || 20; |
---|
| 24 | var namespaces = []; |
---|
| 25 | var roots = {}; |
---|
| 26 | var root; |
---|
| 27 | if(searchIn){ |
---|
| 28 | if(!dojo.isArray(searchIn)){ |
---|
| 29 | searchIn = [searchIn]; |
---|
| 30 | } |
---|
| 31 | for(var i = 0, namespace; namespace = searchIn[i]; i++){ |
---|
| 32 | root = namespace; |
---|
| 33 | if(dojo.isString(namespace)){ |
---|
| 34 | namespace = dojo.getObject(namespace); |
---|
| 35 | if(!namespace){ |
---|
| 36 | continue; |
---|
| 37 | } |
---|
| 38 | }else if(dojo.isObject(namespace)){ |
---|
| 39 | root = namespace.__name__; |
---|
| 40 | }else{ |
---|
| 41 | continue; |
---|
| 42 | } |
---|
| 43 | // Add to a list of namespace objects (in object form) |
---|
| 44 | namespaces.push(namespace); |
---|
| 45 | if(root){ |
---|
| 46 | root = root.split(".")[0]; |
---|
| 47 | if(!roots[root] && dojo.indexOf(dojox.help._namespaces, root) == -1){ |
---|
| 48 | // Refresh anything that's not part of our global namespace list |
---|
| 49 | dojox.help.refresh(root); |
---|
| 50 | } |
---|
| 51 | roots[root] = true; |
---|
| 52 | } |
---|
| 53 | } |
---|
| 54 | } |
---|
| 55 | if(!namespaces.length){ |
---|
| 56 | namespaces.push({ __name__: "window" }); |
---|
| 57 | dojo.forEach(dojox.help._namespaces, function(item){ roots[item] = true; }); |
---|
| 58 | } |
---|
| 59 | |
---|
| 60 | var searchForLower = searchFor.toLowerCase(); |
---|
| 61 | var found = []; |
---|
| 62 | out: |
---|
| 63 | for(var i = 0, namespace; namespace = namespaces[i]; i++){ |
---|
| 64 | var name = namespace.__name__ || ""; |
---|
| 65 | var shorter = dojo.some(namespaces, function(item){ |
---|
| 66 | // Return true if we find a namespace below |
---|
| 67 | // the current namespace |
---|
| 68 | item = item.__name__ || ""; |
---|
| 69 | return (name.indexOf(item + ".") == 0); |
---|
| 70 | }); |
---|
| 71 | if(name && !shorter){ |
---|
| 72 | root = name.split(".")[0]; |
---|
| 73 | var names = []; |
---|
| 74 | if(name == "window"){ |
---|
| 75 | for(root in dojox.help._names){ |
---|
| 76 | if(dojo.isArray(dojox.help._names[root])){ |
---|
| 77 | names = names.concat(dojox.help._names[root]); |
---|
| 78 | } |
---|
| 79 | } |
---|
| 80 | }else{ |
---|
| 81 | names = dojox.help._names[root]; |
---|
| 82 | } |
---|
| 83 | for(var j = 0, variable; variable = names[j]; j++){ |
---|
| 84 | if((name == "window" || variable.indexOf(name + ".") == 0) && variable.toLowerCase().indexOf(searchForLower) != -1){ |
---|
| 85 | if(variable.slice(-10) == ".prototype"){ continue; } |
---|
| 86 | var obj = dojo.getObject(variable); |
---|
| 87 | if(obj){ |
---|
| 88 | found.push([variable, obj]); |
---|
| 89 | if(found.length == maxResults){ |
---|
| 90 | break out; |
---|
| 91 | } |
---|
| 92 | } |
---|
| 93 | } |
---|
| 94 | } |
---|
| 95 | } |
---|
| 96 | } |
---|
| 97 | |
---|
| 98 | dojox.help._displayLocated(found); |
---|
| 99 | if(!dojo.isMoz){ |
---|
| 100 | return ""; |
---|
| 101 | } |
---|
| 102 | }, |
---|
| 103 | refresh: function(/*String?*/ namespace, /*Boolean?*/ recursive){ |
---|
| 104 | // summary: |
---|
| 105 | // Useful if you reset some values, and want to restore their |
---|
| 106 | // help function |
---|
| 107 | // namespace: |
---|
| 108 | // The string-representation of a namespace. |
---|
| 109 | // recursive: |
---|
| 110 | // Whether to recurse through the namespace. |
---|
| 111 | if(arguments.length < 2){ |
---|
| 112 | recursive = true; |
---|
| 113 | } |
---|
| 114 | dojox.help._recurse(namespace, recursive); |
---|
| 115 | }, |
---|
| 116 | noConflict: function(/*Object?*/ item){ |
---|
| 117 | // summary: |
---|
| 118 | // Use this function when you want to resolve the problems |
---|
| 119 | // created by including a dojox.help package. |
---|
| 120 | // item: |
---|
| 121 | // If you pass an item, only that item will be cleaned |
---|
| 122 | if(arguments.length){ |
---|
| 123 | return dojox.help._noConflict(item); |
---|
| 124 | }else{ |
---|
| 125 | while(dojox.help._overrides.length){ |
---|
| 126 | var override = dojox.help._overrides.pop(); |
---|
| 127 | var parent = override[0]; |
---|
| 128 | var key = override[1]; |
---|
| 129 | var child = parent[key]; |
---|
| 130 | parent[key] = dojox.help._noConflict(child); |
---|
| 131 | } |
---|
| 132 | } |
---|
| 133 | }, |
---|
| 134 | init: function(/*String[]*/ namespaces, /*Boolen?*/ noConflict){ |
---|
| 135 | // summary: |
---|
| 136 | // Should be called by one of the implementations. Runs startup code |
---|
| 137 | // namespaces: |
---|
| 138 | // Any namespaces to add to the default (dojox.help._namespaces) |
---|
| 139 | // noConflict: |
---|
| 140 | // Whether to start in noConflict mode |
---|
| 141 | if(namespaces){ |
---|
| 142 | dojox.help._namespaces.concat(namespaces); |
---|
| 143 | } |
---|
| 144 | dojo.addOnLoad(function(){ |
---|
| 145 | dojo.require = (function(require){ |
---|
| 146 | return function(){ |
---|
| 147 | dojox.help.noConflict(); |
---|
| 148 | require.apply(dojo, arguments); |
---|
| 149 | if(dojox.help._timer){ |
---|
| 150 | clearTimeout(dojox.help._timer); |
---|
| 151 | } |
---|
| 152 | dojox.help._timer = setTimeout(function(){ |
---|
| 153 | dojo.addOnLoad(function(){ |
---|
| 154 | dojox.help.refresh(); |
---|
| 155 | dojox.help._timer = false; |
---|
| 156 | }); |
---|
| 157 | }, 500); |
---|
| 158 | } |
---|
| 159 | })(dojo.require); |
---|
| 160 | |
---|
| 161 | dojox.help._recurse(); |
---|
| 162 | }); |
---|
| 163 | }, |
---|
| 164 | _noConflict: function(item){ |
---|
| 165 | if(item instanceof String){ |
---|
| 166 | return item.toString(); |
---|
| 167 | }else if(item instanceof Number){ |
---|
| 168 | return +item; |
---|
| 169 | }else if(item instanceof Boolean){ |
---|
| 170 | return (item == true); |
---|
| 171 | }else if(dojo.isObject(item)){ |
---|
| 172 | delete item.__name__; |
---|
| 173 | delete item.help; |
---|
| 174 | } |
---|
| 175 | return item; |
---|
| 176 | }, |
---|
| 177 | _namespaces: ["dojo", "dojox", "dijit", "djConfig"], |
---|
| 178 | _rpc: new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.SMDLibrary", "dojo-api.smd")), |
---|
| 179 | _attributes: ["summary", "type", "returns", "parameters"], |
---|
| 180 | _clean: function(self){ |
---|
| 181 | var obj = {}; |
---|
| 182 | for(var i = 0, attribute; attribute = dojox.help._attributes[i]; i++){ |
---|
| 183 | var value = self["__" + attribute + "__"]; |
---|
| 184 | if(value){ |
---|
| 185 | obj[attribute] = value; |
---|
| 186 | } |
---|
| 187 | } |
---|
| 188 | return obj; |
---|
| 189 | }, |
---|
| 190 | _displayLocated: function(located){ |
---|
| 191 | // summary: |
---|
| 192 | // Stub function to be overridden in one of the dojox.help packages |
---|
| 193 | throw new Error("_displayLocated should be overridden in one of the dojox.help packages"); |
---|
| 194 | }, |
---|
| 195 | _displayHelp: function(loading, obj){ |
---|
| 196 | // summary: |
---|
| 197 | // Stub function to be overridden in one of the dojox.help packages |
---|
| 198 | throw new Error("_displayHelp should be overridden in one of the dojox.help packages"); |
---|
| 199 | }, |
---|
| 200 | _addVersion: function(obj){ |
---|
| 201 | if(obj.name){ |
---|
| 202 | obj.version = [dojo.version.major, dojo.version.minor, dojo.version.patch].join("."); |
---|
| 203 | var parts = obj.name.split("."); |
---|
| 204 | if(parts[0] == "dojo" || parts[0] == "dijit" || parts[0] == "dojox"){ |
---|
| 205 | obj.project = parts[0]; |
---|
| 206 | } |
---|
| 207 | } |
---|
| 208 | return obj; |
---|
| 209 | }, |
---|
| 210 | _stripPrototype: function(original){ |
---|
| 211 | var name = original.replace(/\.prototype(\.|$)/g, "."); |
---|
| 212 | var search = name; |
---|
| 213 | if(name.slice(-1) == "."){ |
---|
| 214 | search = name = name.slice(0, -1); |
---|
| 215 | }else{ |
---|
| 216 | name = original; |
---|
| 217 | } |
---|
| 218 | return [search, name]; |
---|
| 219 | }, |
---|
| 220 | _help: function(){ |
---|
| 221 | var name = this.__name__; |
---|
| 222 | var search = dojox.help._stripPrototype(name)[0]; |
---|
| 223 | var attributes = []; |
---|
| 224 | for(var i = 0, attribute; attribute = dojox.help._attributes[i]; i++){ |
---|
| 225 | if(!this["__" + attribute + "__"]){ |
---|
| 226 | attributes.push(attribute); |
---|
| 227 | } |
---|
| 228 | } |
---|
| 229 | |
---|
| 230 | dojox.help._displayHelp(true, { name: this.__name__ }); |
---|
| 231 | |
---|
| 232 | if(!attributes.length || this.__searched__){ |
---|
| 233 | dojox.help._displayHelp(false, dojox.help._clean(this)); |
---|
| 234 | }else{ |
---|
| 235 | this.__searched__ = true; |
---|
| 236 | dojox.help._rpc.get(dojox.help._addVersion({ |
---|
| 237 | name: search, |
---|
| 238 | exact: true, |
---|
| 239 | attributes: attributes |
---|
| 240 | })).addCallback(this, function(data){ |
---|
| 241 | if(this.toString === dojox.help._toString){ |
---|
| 242 | this.toString(data); |
---|
| 243 | } |
---|
| 244 | if(data && data.length){ |
---|
| 245 | data = data[0]; |
---|
| 246 | for(var i = 0, attribute; attribute = dojox.help._attributes[i]; i++){ |
---|
| 247 | if(data[attribute]){ |
---|
| 248 | this["__" + attribute + "__"] = data[attribute]; |
---|
| 249 | } |
---|
| 250 | } |
---|
| 251 | dojox.help._displayHelp(false, dojox.help._clean(this)); |
---|
| 252 | }else{ |
---|
| 253 | dojox.help._displayHelp(false, false); |
---|
| 254 | } |
---|
| 255 | }); |
---|
| 256 | } |
---|
| 257 | if(!dojo.isMoz){ |
---|
| 258 | return ""; |
---|
| 259 | } |
---|
| 260 | }, |
---|
| 261 | _parse: function(data){ |
---|
| 262 | delete this.__searching__; |
---|
| 263 | if(data && data.length){ |
---|
| 264 | var parameters = data[0].parameters; |
---|
| 265 | |
---|
| 266 | if(parameters){ |
---|
| 267 | var signature = ["function ", this.__name__, "("]; |
---|
| 268 | this.__parameters__ = parameters; |
---|
| 269 | for(var i = 0, parameter; parameter = parameters[i]; i++){ |
---|
| 270 | if(i){ |
---|
| 271 | signature.push(", "); |
---|
| 272 | } |
---|
| 273 | signature.push(parameter.name); |
---|
| 274 | if(parameter.types){ |
---|
| 275 | var types = []; |
---|
| 276 | for(var j = 0, type; type = parameter.types[j]; j++){ |
---|
| 277 | types.push(type.title); |
---|
| 278 | } |
---|
| 279 | if(types.length){ |
---|
| 280 | signature.push(": "); |
---|
| 281 | signature.push(types.join("|")); |
---|
| 282 | } |
---|
| 283 | } |
---|
| 284 | if(parameter.repeating){ |
---|
| 285 | signature.push("..."); |
---|
| 286 | } |
---|
| 287 | if(parameter.optional){ |
---|
| 288 | signature.push("?"); |
---|
| 289 | } |
---|
| 290 | } |
---|
| 291 | signature.push(")"); |
---|
| 292 | |
---|
| 293 | this.__source__ = this.__source__.replace(/function[^\(]*\([^\)]*\)/, signature.join("")); |
---|
| 294 | } |
---|
| 295 | |
---|
| 296 | if(this.__output__){ |
---|
| 297 | delete this.__output__; |
---|
| 298 | console.log(this); |
---|
| 299 | } |
---|
| 300 | }else{ |
---|
| 301 | dojox.help._displayHelp(false, false); |
---|
| 302 | } |
---|
| 303 | }, |
---|
| 304 | _toStrings: {}, |
---|
| 305 | _toString: function(data){ |
---|
| 306 | if(!this.__source__){ |
---|
| 307 | return this.__name__; |
---|
| 308 | } |
---|
| 309 | |
---|
| 310 | var first = (!this.__parameters__); |
---|
| 311 | this.__parameters__ = []; |
---|
| 312 | |
---|
| 313 | if(data){ |
---|
| 314 | dojox.help._parse.call(this, data); |
---|
| 315 | }else if(first){ |
---|
| 316 | this.__searching__ = true; |
---|
| 317 | dojox.help._toStrings[dojox.help._stripPrototype(this.__name__)[0]] = this; |
---|
| 318 | if(dojox.help._toStringTimer){ |
---|
| 319 | clearTimeout(dojox.help._toStringTimer); |
---|
| 320 | } |
---|
| 321 | dojox.help._toStringTimer = setTimeout(function(){ dojox.help.__toString(); }, 50); |
---|
| 322 | } |
---|
| 323 | |
---|
| 324 | if(!first || !this.__searching__){ |
---|
| 325 | return this.__source__; |
---|
| 326 | } |
---|
| 327 | |
---|
| 328 | var message = "function Loading info for " + this.__name__ + "... (watch console for result) {}"; |
---|
| 329 | |
---|
| 330 | if(!dojo.isMoz){ |
---|
| 331 | this.__output__ = true; |
---|
| 332 | return message; |
---|
| 333 | } |
---|
| 334 | |
---|
| 335 | return { |
---|
| 336 | toString: dojo.hitch(this, function(){ |
---|
| 337 | // Detect if this was called by Firebug |
---|
| 338 | this.__output__ = true; |
---|
| 339 | return message; |
---|
| 340 | }) |
---|
| 341 | }; |
---|
| 342 | }, |
---|
| 343 | __toString: function(){ |
---|
| 344 | if(dojox.help._toStringTimer){ |
---|
| 345 | clearTimeout(dojox.help._toStringTimer); |
---|
| 346 | } |
---|
| 347 | |
---|
| 348 | var names = []; |
---|
| 349 | dojox.help.noConflict(dojox.help._toStrings); |
---|
| 350 | for(var name in dojox.help._toStrings){ |
---|
| 351 | names.push(name); |
---|
| 352 | } |
---|
| 353 | while(names.length){ |
---|
| 354 | dojox.help._rpc.batch(dojox.help._addVersion({ |
---|
| 355 | names: names.splice(-50, 50), |
---|
| 356 | exact: true, |
---|
| 357 | attributes: ["parameters"] |
---|
| 358 | })).addCallback(this, function(datas){ |
---|
| 359 | for(var i = 0, data; data = datas[i]; i++){ |
---|
| 360 | var fn = dojox.help._toStrings[data.name]; |
---|
| 361 | if(fn){ |
---|
| 362 | dojox.help._parse.call(fn, [data]); |
---|
| 363 | delete dojox.help._toStrings[data.name]; |
---|
| 364 | } |
---|
| 365 | } |
---|
| 366 | }); |
---|
| 367 | } |
---|
| 368 | }, |
---|
| 369 | _overrides: [], |
---|
| 370 | _recursions: [], |
---|
| 371 | _names: {}, |
---|
| 372 | _recurse: function(/*String?*/ namespace, /*Boolean?*/ recursive){ |
---|
| 373 | if(arguments.length < 2){ |
---|
| 374 | recursive = true; |
---|
| 375 | } |
---|
| 376 | |
---|
| 377 | var items = []; |
---|
| 378 | |
---|
| 379 | if(namespace && dojo.isString(namespace)){ |
---|
| 380 | dojox.help.__recurse(dojo.getObject(namespace), namespace, namespace, items, recursive); |
---|
| 381 | }else{ |
---|
| 382 | for(var i = 0, ns; ns = dojox.help._namespaces[i]; i++){ |
---|
| 383 | if(window[ns]){ |
---|
| 384 | dojox.help._recursions.push([window[ns], ns, ns]); |
---|
| 385 | window[ns].__name__ = ns; |
---|
| 386 | if(!window[ns].help){ |
---|
| 387 | window[ns].help = dojox.help._help; |
---|
| 388 | } |
---|
| 389 | } |
---|
| 390 | } |
---|
| 391 | } |
---|
| 392 | |
---|
| 393 | while(dojox.help._recursions.length){ |
---|
| 394 | var recursion = dojox.help._recursions.shift(); |
---|
| 395 | dojox.help.__recurse(recursion[0], recursion[1], recursion[2], items, recursive); |
---|
| 396 | } |
---|
| 397 | |
---|
| 398 | for(var i = 0, item; item = items[i]; i++){ |
---|
| 399 | delete item.__seen__; |
---|
| 400 | } |
---|
| 401 | }, |
---|
| 402 | __recurse: function(namespace, root, name, items, recursive){ |
---|
| 403 | for(var key in namespace){ |
---|
| 404 | if(key.match(/([^\w_.$]|__[\w_.$]+__)/)){ |
---|
| 405 | continue; |
---|
| 406 | } |
---|
| 407 | |
---|
| 408 | var item = namespace[key]; |
---|
| 409 | if(typeof item == "undefined" |
---|
| 410 | || item === document |
---|
| 411 | || item === window |
---|
| 412 | || item === dojox.help._toString |
---|
| 413 | || item === dojox.help._help |
---|
| 414 | || item === null |
---|
| 415 | || (+dojo.isIE && item.tagName) |
---|
| 416 | || item.__seen__ |
---|
| 417 | ) { |
---|
| 418 | continue; |
---|
| 419 | } |
---|
| 420 | |
---|
| 421 | var isFunction = dojo.isFunction(item); |
---|
| 422 | var isObject = dojo.isObject(item) && !dojo.isArray(item) && !item.nodeType; |
---|
| 423 | |
---|
| 424 | var itemName = (name) ? (name + "." + key) : key; |
---|
| 425 | |
---|
| 426 | if(itemName == "dojo._blockAsync"){ |
---|
| 427 | continue; |
---|
| 428 | } |
---|
| 429 | |
---|
| 430 | if(!item.__name__){ |
---|
| 431 | var parent = null; |
---|
| 432 | if(dojo.isString(item)){ |
---|
| 433 | parent = String; |
---|
| 434 | }else if(typeof item == "number"){ |
---|
| 435 | parent = Number; |
---|
| 436 | }else if(typeof item == "boolean"){ |
---|
| 437 | parent = Boolean; |
---|
| 438 | } |
---|
| 439 | if(parent){ |
---|
| 440 | item = namespace[key] = new parent(item); |
---|
| 441 | } |
---|
| 442 | } |
---|
| 443 | |
---|
| 444 | item.__seen__ = true; |
---|
| 445 | item.__name__ = itemName; |
---|
| 446 | (dojox.help._names[root] = dojox.help._names[root] || []).push(itemName); |
---|
| 447 | items.push(item); |
---|
| 448 | if(!isFunction){ |
---|
| 449 | dojox.help._overrides.push([namespace, key]); |
---|
| 450 | } |
---|
| 451 | |
---|
| 452 | if((isFunction || isObject) && recursive){ |
---|
| 453 | dojox.help._recursions.push([item, root, itemName]); |
---|
| 454 | } |
---|
| 455 | |
---|
| 456 | if(isFunction){ |
---|
| 457 | if(!item.__source__){ |
---|
| 458 | item.__source__ = item.toString().replace(/^function\b ?/, "function " + itemName); |
---|
| 459 | } |
---|
| 460 | if(item.toString === Function.prototype.toString){ |
---|
| 461 | item.toString = dojox.help._toString; |
---|
| 462 | } |
---|
| 463 | } |
---|
| 464 | |
---|
| 465 | if(!item.help){ |
---|
| 466 | item.help = dojox.help._help; |
---|
| 467 | } |
---|
| 468 | } |
---|
| 469 | } |
---|
| 470 | }; |
---|