_base.js 13 KB

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