1 | define(["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(!has("dojo-has-api")){ |
---|
19 | // notice the condition is written so that if has("dojo-has-api") 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 cache[name] = typeof cache[name] == "function" ? 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 | has.add("host-browser", isBrowser); |
---|
100 | has.add("dom", isBrowser); |
---|
101 | has.add("dojo-dom-ready-api", 1); |
---|
102 | has.add("dojo-sniff", 1); |
---|
103 | } |
---|
104 | |
---|
105 | if(has("host-browser")){ |
---|
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 | }); |
---|