has.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. define("dojo/has", ["require"], function(require) {
  2. // module:
  3. // dojo/has
  4. // summary:
  5. // Defines the has.js API and several feature tests used by dojo.
  6. // description:
  7. // This module defines the has API as described by the project has.js with the following additional features:
  8. //
  9. // * the has test cache is exposed at has.cache.
  10. // * the method has.add includes a forth parameter that controls whether or not existing tests are replaced
  11. // * the loader's has cache may be optionally copied into this module's has cahce.
  12. //
  13. // This module adopted from https://github.com/phiggins42/has.js; thanks has.js team!
  14. // try to pull the has implementation from the loader; both the dojo loader and bdLoad provide one
  15. // WARNING: if a foreign loader defines require.has to be something other than the has.js API, then this implementation fail
  16. var has = require.has || function(){};
  17. if(!1){
  18. // notice the condition is written so that if 1 is transformed to 1 during a build
  19. // the conditional will be (!1 && typeof has=="function") which is statically false and the closure
  20. // compiler will discard the block.
  21. var
  22. isBrowser =
  23. // the most fundamental decision: are we in the browser?
  24. typeof window != "undefined" &&
  25. typeof location != "undefined" &&
  26. typeof document != "undefined" &&
  27. window.location == location && window.document == document,
  28. // has API variables
  29. global = (function () { return this; })(),
  30. doc = isBrowser && document,
  31. element = doc && doc.createElement("DiV"),
  32. cache = {};
  33. has = /*===== dojo.has= =====*/ function(name){
  34. // summary:
  35. // Return the current value of the named feature.
  36. //
  37. // name: String|Integer
  38. // The name (if a string) or identifier (if an integer) of the feature to test.
  39. //
  40. // description:
  41. // Returns the value of the feature named by name. The feature must have been
  42. // previously added to the cache by has.add.
  43. return typeof cache[name] == "function" ? (cache[name] = cache[name](global, doc, element)) : cache[name]; // Boolean
  44. };
  45. has.cache = cache;
  46. has.add = /*====== dojo.has.add= ======*/ function(name, test, now, force){
  47. // summary:
  48. // Register a new feature test for some named feature.
  49. //
  50. // name: String|Integer
  51. // The name (if a string) or identifier (if an integer) of the feature to test.
  52. //
  53. // test: Function
  54. // A test function to register. If a function, queued for testing until actually
  55. // needed. The test function should return a boolean indicating
  56. // the presence of a feature or bug.
  57. //
  58. // now: Boolean?
  59. // Optional. Omit if `test` is not a function. Provides a way to immediately
  60. // run the test and cache the result.
  61. //
  62. // force: Boolean?
  63. // Optional. If the test already exists and force is truthy, then the existing
  64. // test will be replaced; otherwise, add does not replace an existing test (that
  65. // is, by default, the first test advice wins).
  66. //
  67. // example:
  68. // A redundant test, testFn with immediate execution:
  69. // | has.add("javascript", function(){ return true; }, true);
  70. //
  71. // example:
  72. // Again with the redundantness. You can do this in your tests, but we should
  73. // not be doing this in any internal has.js tests
  74. // | has.add("javascript", true);
  75. //
  76. // example:
  77. // Three things are passed to the testFunction. `global`, `document`, and a generic element
  78. // from which to work your test should the need arise.
  79. // | has.add("bug-byid", function(g, d, el){
  80. // | // g == global, typically window, yadda yadda
  81. // | // d == document object
  82. // | // el == the generic element. a `has` element.
  83. // | return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer
  84. // | });
  85. (typeof cache[name]=="undefined" || force) && (cache[name]= test);
  86. return now && has(name);
  87. };
  88. // since we're operating under a loader that doesn't provide a has API, we must explicitly initialize
  89. // has as it would have otherwise been initialized by the dojo loader; use has.add to the builder
  90. // can optimize these away iff desired
  91. true || has.add("host-browser", isBrowser);
  92. false && has.add("host-node", (typeof process == "object" && process.versions && process.versions.node && process.versions.v8));
  93. false && has.add("host-rhino", (typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object")));
  94. true || has.add("dom", isBrowser);
  95. true || has.add("dojo-dom-ready-api", 1);
  96. true || has.add("dojo-sniff", 1);
  97. }
  98. if(1){
  99. var agent = navigator.userAgent;
  100. // Common application level tests
  101. has.add("dom-addeventlistener", !!document.addEventListener);
  102. has.add("touch", "ontouchstart" in document);
  103. // I don't know if any of these tests are really correct, just a rough guess
  104. has.add("device-width", screen.availWidth || innerWidth);
  105. has.add("agent-ios", !!agent.match(/iPhone|iP[ao]d/));
  106. has.add("agent-android", agent.indexOf("android") > 1);
  107. }
  108. has.clearElement = /*===== dojo.has.clearElement= ======*/ function(element) {
  109. // summary:
  110. // Deletes the contents of the element passed to test functions.
  111. element.innerHTML= "";
  112. return element;
  113. };
  114. has.normalize = /*===== dojo.has.normalize= ======*/ function(id, toAbsMid){
  115. // summary:
  116. // Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s).
  117. //
  118. // toAbsMid: Function
  119. // Resolves a relative module id into an absolute module id
  120. var
  121. tokens = id.match(/[\?:]|[^:\?]*/g), i = 0,
  122. get = function(skip){
  123. var term = tokens[i++];
  124. if(term == ":"){
  125. // empty string module name, resolves to 0
  126. return 0;
  127. }else{
  128. // postfixed with a ? means it is a feature to branch on, the term is the name of the feature
  129. if(tokens[i++] == "?"){
  130. if(!skip && has(term)){
  131. // matched the feature, get the first value from the options
  132. return get();
  133. }else{
  134. // did not match, get the second value, passing over the first
  135. get(true);
  136. return get(skip);
  137. }
  138. }
  139. // a module
  140. return term || 0;
  141. }
  142. };
  143. id = get();
  144. return id && toAbsMid(id);
  145. };
  146. has.load = /*===== dojo.has.load= ======*/ function(id, parentRequire, loaded){
  147. // summary:
  148. // Conditional loading of AMD modules based on a has feature test value.
  149. //
  150. // id: String
  151. // Gives the resolved module id to load.
  152. //
  153. // parentRequire: Function
  154. // The loader require function with respect to the module that contained the plugin resource in it's
  155. // dependency list.
  156. //
  157. // loaded: Function
  158. // Callback to loader that consumes result of plugin demand.
  159. if(id){
  160. parentRequire([id], loaded);
  161. }else{
  162. loaded();
  163. }
  164. };
  165. return has;
  166. });