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