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 | }; |
---|