source: Dev/trunk/src/client/dojox/help/_base.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 12.5 KB
Line 
1dojo.provide("dojox.help._base");
2dojo.require("dojox.rpc.Service");
3dojo.require("dojo.io.script");
4
5dojo.experimental("dojox.help");
6console.warn("Script causes side effects (on numbers, strings, and booleans). Call dojox.help.noConflict() if you plan on executing code.");
7
8dojox.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};
Note: See TracBrowser for help on using the repository browser.