deviceTheme.js 5.7 KB

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