source: Dev/branches/rest-dojo-ui/client/dojo/has.js @ 263

Last change on this file since 263 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 6.4 KB
RevLine 
[256]1define(["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});
Note: See TracBrowser for help on using the repository browser.