css.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Require-CSS RequireJS css! loader plugin
  3. * 0.1.2
  4. * Guy Bedford 2013
  5. * MIT
  6. */
  7. /*
  8. *
  9. * Usage:
  10. * require(['css!./mycssFile']);
  11. *
  12. * Tested and working in (up to latest versions as of March 2013):
  13. * Android
  14. * iOS 6
  15. * IE 6 - 10
  16. * Chome 3 - 26
  17. * Firefox 3.5 - 19
  18. * Opera 10 - 12
  19. *
  20. * browserling.com used for virtual testing environment
  21. *
  22. * Credit to B Cavalier & J Hann for the IE 6 - 9 method,
  23. * refined with help from Martin Cermak
  24. *
  25. * Sources that helped along the way:
  26. * - https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent
  27. * - http://www.phpied.com/when-is-a-stylesheet-really-loaded/
  28. * - https://github.com/cujojs/curl/blob/master/src/curl/plugin/css.js
  29. *
  30. */
  31. define(function() {
  32. //>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
  33. if (typeof window == 'undefined')
  34. return { load: function(n, r, load){ load() } };
  35. var head = document.getElementsByTagName('head')[0];
  36. var engine = window.navigator.userAgent.match(/Trident\/([^ ;]*)|AppleWebKit\/([^ ;]*)|Opera\/([^ ;]*)|rv\:([^ ;]*)(.*?)Gecko\/([^ ;]*)|MSIE\s([^ ;]*)|AndroidWebKit\/([^ ;]*)/) || 0;
  37. // use <style> @import load method (IE < 9, Firefox < 18)
  38. var useImportLoad = false;
  39. // set to false for explicit <link> load checking when onload doesn't work perfectly (webkit)
  40. var useOnload = true;
  41. // trident / msie
  42. if (engine[1] || engine[7])
  43. useImportLoad = parseInt(engine[1]) < 6 || parseInt(engine[7]) <= 9;
  44. // webkit
  45. else if (engine[2] || engine[8])
  46. useOnload = false;
  47. // gecko
  48. else if (engine[4])
  49. useImportLoad = parseInt(engine[4]) < 18;
  50. //>>excludeEnd('excludeRequireCss')
  51. //main api object
  52. var cssAPI = {};
  53. //>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
  54. cssAPI.pluginBuilder = './css-builder';
  55. // <style> @import load method
  56. var curStyle, curSheet;
  57. var createStyle = function () {
  58. curStyle = document.createElement('style');
  59. head.appendChild(curStyle);
  60. curSheet = curStyle.styleSheet || curStyle.sheet;
  61. }
  62. var ieCnt = 0;
  63. var ieLoads = [];
  64. var ieCurCallback;
  65. var createIeLoad = function(url) {
  66. ieCnt++;
  67. if (ieCnt == 32) {
  68. createStyle();
  69. ieCnt = 0;
  70. }
  71. curSheet.addImport(url);
  72. curStyle.onload = function(){ processIeLoad() };
  73. }
  74. var processIeLoad = function() {
  75. ieCurCallback();
  76. var nextLoad = ieLoads.shift();
  77. if (!nextLoad) {
  78. ieCurCallback = null;
  79. return;
  80. }
  81. ieCurCallback = nextLoad[1];
  82. createIeLoad(nextLoad[0]);
  83. }
  84. var importLoad = function(url, callback) {
  85. if (!curSheet || !curSheet.addImport)
  86. createStyle();
  87. if (curSheet && curSheet.addImport) {
  88. // old IE
  89. if (ieCurCallback) {
  90. ieLoads.push([url, callback]);
  91. }
  92. else {
  93. createIeLoad(url);
  94. ieCurCallback = callback;
  95. }
  96. }
  97. else {
  98. // old Firefox
  99. curStyle.textContent = '@import "' + url + '";';
  100. var loadInterval = setInterval(function() {
  101. try {
  102. curStyle.sheet.cssRules;
  103. clearInterval(loadInterval);
  104. callback();
  105. } catch(e) {}
  106. }, 10);
  107. }
  108. }
  109. // <link> load method
  110. var linkLoad = function(url, callback) {
  111. var link = document.createElement('link');
  112. link.type = 'text/css';
  113. link.rel = 'stylesheet';
  114. if (useOnload)
  115. link.onload = function() {
  116. link.onload = function() {};
  117. // for style dimensions queries, a short delay can still be necessary
  118. setTimeout(callback, 7);
  119. }
  120. else
  121. var loadInterval = setInterval(function() {
  122. for (var i = 0; i < document.styleSheets.length; i++) {
  123. var sheet = document.styleSheets[i];
  124. if (sheet.href == link.href) {
  125. clearInterval(loadInterval);
  126. return callback();
  127. }
  128. }
  129. }, 10);
  130. link.href = url;
  131. head.appendChild(link);
  132. }
  133. //>>excludeEnd('excludeRequireCss')
  134. cssAPI.normalize = function(name, normalize) {
  135. if (name.substr(name.length - 4, 4) == '.css')
  136. name = name.substr(0, name.length - 4);
  137. return normalize(name);
  138. }
  139. //>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
  140. cssAPI.load = function(cssId, req, load, config) {
  141. (useImportLoad ? importLoad : linkLoad)(req.toUrl(cssId + '.css'), load);
  142. }
  143. //>>excludeEnd('excludeRequireCss')
  144. return cssAPI;
  145. });