1 | define([ |
---|
2 | "dojo/_base/array", |
---|
3 | "dojo/_base/config", |
---|
4 | "dojo/_base/lang", |
---|
5 | "dojo/_base/window", |
---|
6 | "dojo/dom-class", |
---|
7 | "dojo/dom-construct", |
---|
8 | "require" |
---|
9 | ], function(array, config, lang, win, domClass, domConstruct, require){ |
---|
10 | |
---|
11 | var dm = lang.getObject("dojox.mobile", true); |
---|
12 | /*===== |
---|
13 | var dm = dojox.mobile |
---|
14 | =====*/ |
---|
15 | |
---|
16 | // module: |
---|
17 | // dojox/mobile/deviceTheme |
---|
18 | // summary: |
---|
19 | // Automatic Theme Loader |
---|
20 | // description: |
---|
21 | // Detects the User Agent of the browser and loads appropriate theme files. |
---|
22 | // Simply dojo.require this module to enable the automatic theme loading. |
---|
23 | // For simulations, the user agent may be overridden by setting djConfig.mblUserAgent. |
---|
24 | // |
---|
25 | // By default, an all-in-one theme file (e.g. themes/iphone/iphone.css) is |
---|
26 | // loaded. The all-in-one theme files contain style sheets for all the |
---|
27 | // dojox.mobile widgets regardless of whether they are used in your |
---|
28 | // application or not. |
---|
29 | // If you want to choose what theme files to load, you can specify them |
---|
30 | // via djConfig as shown in the following example: |
---|
31 | // |
---|
32 | // | djConfig="parseOnLoad:true, mblThemeFiles:['base','Button']" |
---|
33 | // |
---|
34 | // Or you may want to use dojox.mobile.themeFiles as follows to get the |
---|
35 | // same result. Note that the assignment has to be done before loading |
---|
36 | // deviceTheme.js. |
---|
37 | // |
---|
38 | // | dojo.require("dojox.mobile"); |
---|
39 | // | dojox.mobile.themeFiles = ['base','Button']; |
---|
40 | // | dojo.require("dojox.mobile.deviceTheme"); |
---|
41 | // |
---|
42 | // In the case of this example, if iphone is detected, for example, the |
---|
43 | // following files will be loaded: |
---|
44 | // |
---|
45 | // | dojox/mobile/themes/iphone/base.css |
---|
46 | // | dojox/mobile/themes/iphone/Button.css |
---|
47 | // |
---|
48 | // If you want to load style sheets for your own custom widgets, you can |
---|
49 | // specify a package name along with a theme file name in an array. |
---|
50 | // |
---|
51 | // | ['base',['com.acme','MyWidget']] |
---|
52 | // |
---|
53 | // In this case, the following files will be loaded. |
---|
54 | // |
---|
55 | // | dojox/mobile/themes/iphone/base.css |
---|
56 | // | com/acme/themes/iphone/MyWidget.css |
---|
57 | // |
---|
58 | // If you specify '@theme' as a theme file name, it will be replaced with |
---|
59 | // the theme folder name (e.g. 'iphone'). For example, |
---|
60 | // |
---|
61 | // | ['@theme',['com.acme','MyWidget']] |
---|
62 | // |
---|
63 | // will load the following files. |
---|
64 | // |
---|
65 | // | dojox/mobile/themes/iphone/iphone.css |
---|
66 | // | com/acme/themes/iphone/MyWidget.css |
---|
67 | // |
---|
68 | // Note that the load of the theme files is performed asynchronously by |
---|
69 | // the browser, and thus you cannot assume the load has been completed |
---|
70 | // when your appliation is initialized. For example, if some widget in |
---|
71 | // your application uses node dimensions that cannot be determined |
---|
72 | // without CSS styles being applied to them to calculate its layout at |
---|
73 | // initialization, the layout calculation may fail. |
---|
74 | // Possible workaround for this problem is to use dojo.require to load |
---|
75 | // deviceTheme.js and place it in a separate <script> block immediately |
---|
76 | // below a script tag that loads dojo.js as below. This may (or may |
---|
77 | // not) solve the problem. |
---|
78 | // |
---|
79 | // | <script src="dojo.js"></script> |
---|
80 | // | <script> |
---|
81 | // | dojo.require("dojox.mobile.deviceTheme"); |
---|
82 | // | </script> |
---|
83 | // | <script> |
---|
84 | // | dojo.require("dojox.mobile"); |
---|
85 | // | .... |
---|
86 | // |
---|
87 | // A better solution would be to not use deviceTheme and use <link> |
---|
88 | // or @import instead to load the theme files. |
---|
89 | |
---|
90 | |
---|
91 | dm.loadCssFile = function(/*String*/file){ |
---|
92 | // summary: |
---|
93 | // Loads the given CSS file programmatically. |
---|
94 | dm.loadedCssFiles.push(domConstruct.create("LINK", { |
---|
95 | href: file, |
---|
96 | type: "text/css", |
---|
97 | rel: "stylesheet" |
---|
98 | }, win.doc.getElementsByTagName('head')[0])); |
---|
99 | }; |
---|
100 | |
---|
101 | dm.themeMap = dm.themeMap || [ |
---|
102 | // summary: |
---|
103 | // A map of user-agents to theme files. |
---|
104 | // description: |
---|
105 | // The first array element is a regexp pattern that matches the |
---|
106 | // userAgent string. |
---|
107 | // |
---|
108 | // The second array element is a theme folder name. |
---|
109 | // |
---|
110 | // The third array element is an array of css file paths to load. |
---|
111 | // |
---|
112 | // The matching is performed in the array order, and stops after the |
---|
113 | // first match. |
---|
114 | [ |
---|
115 | "Android", |
---|
116 | "android", |
---|
117 | [] |
---|
118 | ], |
---|
119 | [ |
---|
120 | "BlackBerry", |
---|
121 | "blackberry", |
---|
122 | [] |
---|
123 | ], |
---|
124 | [ |
---|
125 | "iPad", |
---|
126 | "iphone", |
---|
127 | [require.toUrl("dojox/mobile/themes/iphone/ipad.css")] |
---|
128 | ], |
---|
129 | [ |
---|
130 | "Custom", |
---|
131 | "custom", |
---|
132 | [] |
---|
133 | ], |
---|
134 | [ |
---|
135 | ".*", |
---|
136 | "iphone", |
---|
137 | [] |
---|
138 | ] |
---|
139 | ]; |
---|
140 | |
---|
141 | dm.loadDeviceTheme = function(/*String?*/userAgent){ |
---|
142 | // summary: |
---|
143 | // Loads a device-specific theme according to the user-agent |
---|
144 | // string. |
---|
145 | // description: |
---|
146 | // This function is automatically called when this module is |
---|
147 | // evaluated. |
---|
148 | var t = config["mblThemeFiles"] || dm.themeFiles || ["@theme"]; |
---|
149 | if(!lang.isArray(t)){ console.log("loadDeviceTheme: array is expected but found: "+t); } |
---|
150 | var i, j; |
---|
151 | var m = dm.themeMap; |
---|
152 | var ua = userAgent || config["mblUserAgent"] || (location.search.match(/theme=(\w+)/) ? RegExp.$1 : navigator.userAgent); |
---|
153 | for(i = 0; i < m.length; i++){ |
---|
154 | if(ua.match(new RegExp(m[i][0]))){ |
---|
155 | var theme = m[i][1]; |
---|
156 | domClass.replace(win.doc.documentElement, theme + "_theme", dm.currentTheme ? dm.currentTheme + "_theme" : ""); |
---|
157 | dm.currentTheme = theme; |
---|
158 | var files = [].concat(m[i][2]); |
---|
159 | for(j = t.length - 1; j >= 0; j--){ |
---|
160 | var pkg = lang.isArray(t[j]) ? (t[j][0]||"").replace(/\./g, '/') : "dojox/mobile"; |
---|
161 | var name = lang.isArray(t[j]) ? t[j][1] : t[j]; |
---|
162 | var f = "themes/" + theme + "/" + |
---|
163 | (name === "@theme" ? theme : name) + ".css"; |
---|
164 | files.unshift(require.toUrl(pkg+"/"+f)); |
---|
165 | } |
---|
166 | //remove old css files |
---|
167 | array.forEach(dm.loadedCssFiles, function(n){ |
---|
168 | n.parentNode.removeChild(n); |
---|
169 | }); |
---|
170 | dm.loadedCssFiles = []; |
---|
171 | for(j = 0; j < files.length; j++){ |
---|
172 | dm.loadCssFile(files[j].toString()); |
---|
173 | } |
---|
174 | if(userAgent && dm.loadCompatCssFiles){ // we will assume compat is loaded and ready.. |
---|
175 | dm.loadCompatCssFiles(); |
---|
176 | } |
---|
177 | break; |
---|
178 | } |
---|
179 | } |
---|
180 | }; |
---|
181 | |
---|
182 | if(dm.configDeviceTheme){ |
---|
183 | dm.configDeviceTheme(); |
---|
184 | } |
---|
185 | dm.loadDeviceTheme(); |
---|
186 | |
---|
187 | return dm; |
---|
188 | }); |
---|