source: Dev/trunk/src/client/dojox/lang/docs.js @ 529

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

Added Dojo 1.9.3 release.

File size: 5.6 KB
Line 
1dojo.provide("dojox.lang.docs");
2
3// Extracts information from the API docs to apply a schema representation to dojo classes.
4// This can be utilized for runtime metadata retrieval and type checking
5(function(){
6        function error(error){
7                console.log("Warning, the API docs must be available at ../util/docscripts/api.json "+
8                "or ../util/docscripts/api/*.json "+
9                "in order for dojox.lang.docs to supply schema information, but it could not be loaded: " + error);
10        }
11
12        var declaredClasses = {};
13        var requiredModules = [];
14        var _docs = dojox.lang.docs._loadedDocs = {};
15
16        var schemifyClass = function(clazz, name){
17                // initial implementation records classes until they are ready
18                declaredClasses[name] = clazz;
19        };
20        var getType = function(typeDef){
21                var type = typeDef.type || '';
22                var typeObj, optional = false, array = false, dontModify;
23                type = type.replace(/\?/, function(){
24                        optional = true;
25                        return '';
26                });
27                type = type.replace(/\[\]/, function(){
28                        array = true;
29                        return '';
30                });
31                if(type.match(/HTML/)){
32                        // HTML String and other "types" of strings are really just strings
33                        type = "string";
34                }else if(type == 'String' || type == 'Number' ||
35                                type == 'Boolean' || type == 'Object' ||
36                                type == 'Array' || type == 'Integer' || type == "Function"){
37                        type = type.toLowerCase();
38                }else if(type == "bool"){
39                        type = "boolean";
40                }else if(type){
41                        typeObj = dojo.getObject(type) || {};
42                        dontModify = true;
43                }else{
44                        typeObj = {};
45                }
46                typeObj = typeObj || {type:type};
47                if(array){
48                        typeObj = {items:typeObj, type:"array"};
49                        dontModify = false;
50                }
51                if(!dontModify){
52                        if(optional){
53                                typeObj.optional = true;
54                        }
55                        if(/const/.test(typeDef.tags)){
56                                typeObj.readonly = true;
57                        }
58                }
59                return typeObj;
60        };
61        var actualSchemifyClass = function(clazz, name){
62                var docForClass = _docs[name];
63                if(docForClass){
64                        clazz.description = docForClass.description;
65                        clazz.properties = {};
66                        clazz.methods = {};
67
68                        if(docForClass.properties){
69                                var props = docForClass.properties;
70                                for(var i=0, l=props.length; i<l; i++){
71                                        if(props[i].scope == "prototype"){
72                                                var propDef = clazz.properties[props[i].name] = getType(props[i]);
73                                                propDef.description = props[i].summary;
74                                        }
75                                }
76                        }
77
78                        // translate the methods to JSON Schema
79                        if(docForClass.methods){
80                                var methods = docForClass.methods;
81                                for(i=0, l=methods.length; i<l; i++){
82                                        name = methods[i].name;
83                                        if(name && methods[i].scope == "prototype"){
84                                                var methodDef = clazz.methods[name] = {};
85                                                methodDef.description = methods[i].summary;
86                                                var parameters = methods[i].parameters;
87                                                if(parameters){
88                                                        methodDef.parameters = [];
89                                                        for(var j=0, k=parameters.length; j<k; j++){
90                                                                var param = parameters[j];
91                                                                var paramDef = methodDef.parameters[j] = getType(param);
92                                                                paramDef.name = param.name;
93                                                                paramDef.optional = "optional" == param.usage;
94                                                        }
95                                                }
96                                                var ret = methods[i]['return-types'];
97                                                if(ret && ret[0]){
98                                                        var returns = getType(ret[0]);
99                                                        if(returns.type){
100                                                                methodDef.returns = returns;
101                                                        }
102                                                }
103                                        }
104                                }
105                        }
106
107                        var superclass = docForClass.superclass;
108                        if(superclass){
109                                clazz["extends"] = dojo.getObject(superclass);
110                        }
111                }
112        };
113        var requireDocs = function(moduleName){
114                requiredModules.push(moduleName);
115        };
116
117        // hook into all declared classes
118        var defaultDeclare = dojo.declare;
119        dojo.declare = function(name){
120                var clazz = defaultDeclare.apply(this, arguments);
121                schemifyClass(clazz, name);
122                return clazz;
123        };
124        dojo.mixin(dojo.declare, defaultDeclare);
125        var initialized;
126
127        // hook into dojo.require
128        var defaultRequire = dojo.require;
129        dojo.require = function(moduleName){
130                requireDocs(moduleName);
131                var module = defaultRequire.apply(this, arguments);
132                return module;
133        };
134
135        dojox.lang.docs.init = function(/*Boolean*/async){
136                // summary:
137                //              Loads the documentation and applies it to the previously defined classes
138                //              and any future defined classes
139                // async:
140                //               If true, the documentation will be loaded asynchronously
141                function loadFullDocs(){
142                        dojo.require = defaultRequire;
143                        requiredModules = null;
144                        try{
145                                dojo.xhrGet({
146                                        sync:!async,
147                                        url: dojo.baseUrl + '../util/docscripts/api.json',
148                                        handleAs: 'text'
149                                }).addCallbacks(function(obj){
150                                        _docs = (new Function("return " + obj))();
151                                        obj = null;
152                                        schemifyClass = actualSchemifyClass;
153
154                                        for(var i in declaredClasses){
155                                                schemifyClass(declaredClasses[i], i);
156                                        }
157                                        declaredClasses = null;
158                                }, error);
159                        }catch(e){
160                                error(e);
161                        }
162                }
163               
164                if(initialized){
165                        return null;
166                }
167                initialized = true;
168
169                var getSplitDocs = function(moduleName, sync){
170                        return dojo.xhrGet({
171                                sync: sync||!async,
172                                url: dojo.baseUrl + '../util/docscripts/api/' + moduleName + '.json',
173                                handleAs: 'text'
174                        }).addCallback(function(obj){
175                                obj = (new Function("return " + obj))();
176                                for(var clazz in obj){
177                                        if(!_docs[clazz]){
178                                                _docs[clazz] = obj[clazz];
179                                        }
180                                }
181                        });
182                };
183                try{
184                        var firstMod = requiredModules.shift();
185                        getSplitDocs(firstMod, true).addCallbacks(function(){
186                                requireDocs = function(moduleName){
187                                        if(!_docs[moduleName]){
188                                                try{
189                                                        getSplitDocs(moduleName);
190                                                }catch(e){
191                                                        _docs[moduleName] = {};
192                                                }
193                                        }
194                                };
195                                //console.log(requiredModules);
196                                dojo.forEach(requiredModules, function(mod){
197                                        requireDocs(mod);
198                                });
199                                requiredModules = null;
200
201                                schemifyClass = actualSchemifyClass;
202
203                                for(i in declaredClasses){
204                                        schemifyClass(declaredClasses[i], i);
205                                }
206                                declaredClasses = null;
207                        },loadFullDocs);
208                }catch(e){
209                        loadFullDocs();
210                }
211                return null;
212        }
213})();
Note: See TracBrowser for help on using the repository browser.