normalize.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. //>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
  2. /*
  3. * css.normalize.js
  4. *
  5. * CSS Normalization
  6. *
  7. * CSS paths are normalized based on an optional basePath and the RequireJS config
  8. *
  9. * Usage:
  10. * normalize(css, fromBasePath, toBasePath);
  11. *
  12. * css: the stylesheet content to normalize
  13. * fromBasePath: the absolute base path of the css relative to any root (but without ../ backtracking)
  14. * toBasePath: the absolute new base path of the css relative to the same root
  15. *
  16. * Absolute dependencies are left untouched.
  17. *
  18. * Urls in the CSS are picked up by regular expressions.
  19. * These will catch all statements of the form:
  20. *
  21. * url(*)
  22. * url('*')
  23. * url("*")
  24. *
  25. * @import '*'
  26. * @import "*"
  27. *
  28. * (and so also @import url(*) variations)
  29. *
  30. * For urls needing normalization
  31. *
  32. */
  33. define(function() {
  34. // regular expression for removing double slashes
  35. // eg http://www.example.com//my///url/here -> http://www.example.com/my/url/here
  36. var slashes = /([^:])\/+/g
  37. var removeDoubleSlashes = function(uri) {
  38. return uri.replace(slashes, '$1/');
  39. }
  40. // given a relative URI, and two absolute base URIs, convert it from one base to another
  41. var protocolRegEx = /[^\:\/]*:\/\/([^\/])*/;
  42. var absUrlRegEx = /^(\/|data:)/;
  43. function convertURIBase(uri, fromBase, toBase) {
  44. if (uri.match(absUrlRegEx) || uri.match(protocolRegEx))
  45. return uri;
  46. uri = removeDoubleSlashes(uri);
  47. // if toBase specifies a protocol path, ensure this is the same protocol as fromBase, if not
  48. // use absolute path at fromBase
  49. var toBaseProtocol = toBase.match(protocolRegEx);
  50. var fromBaseProtocol = fromBase.match(protocolRegEx);
  51. if (fromBaseProtocol && (!toBaseProtocol || toBaseProtocol[1] != fromBaseProtocol[1] || toBaseProtocol[2] != fromBaseProtocol[2]))
  52. return absoluteURI(uri, fromBase);
  53. else {
  54. return relativeURI(absoluteURI(uri, fromBase), toBase);
  55. }
  56. };
  57. // given a relative URI, calculate the absolute URI
  58. function absoluteURI(uri, base) {
  59. if (uri.substr(0, 2) == './')
  60. uri = uri.substr(2);
  61. // absolute urls are left in tact
  62. if (uri.match(absUrlRegEx) || uri.match(protocolRegEx))
  63. return uri;
  64. var baseParts = base.split('/');
  65. var uriParts = uri.split('/');
  66. baseParts.pop();
  67. while (curPart = uriParts.shift())
  68. if (curPart == '..')
  69. baseParts.pop();
  70. else
  71. baseParts.push(curPart);
  72. return baseParts.join('/');
  73. };
  74. // given an absolute URI, calculate the relative URI
  75. function relativeURI(uri, base) {
  76. // reduce base and uri strings to just their difference string
  77. var baseParts = base.split('/');
  78. baseParts.pop();
  79. base = baseParts.join('/') + '/';
  80. i = 0;
  81. while (base.substr(i, 1) == uri.substr(i, 1))
  82. i++;
  83. while (base.substr(i, 1) != '/')
  84. i--;
  85. base = base.substr(i + 1);
  86. uri = uri.substr(i + 1);
  87. // each base folder difference is thus a backtrack
  88. baseParts = base.split('/');
  89. var uriParts = uri.split('/');
  90. out = '';
  91. while (baseParts.shift())
  92. out += '../';
  93. // finally add uri parts
  94. while (curPart = uriParts.shift())
  95. out += curPart + '/';
  96. return out.substr(0, out.length - 1);
  97. };
  98. var normalizeCSS = function(source, fromBase, toBase) {
  99. fromBase = removeDoubleSlashes(fromBase);
  100. toBase = removeDoubleSlashes(toBase);
  101. var urlRegEx = /@import\s*("([^"]*)"|'([^']*)')|url\s*\((?!#)\s*(\s*"([^"]*)"|'([^']*)'|[^\)]*\s*)\s*\)/ig;
  102. var result, url, source;
  103. while (result = urlRegEx.exec(source)) {
  104. url = result[3] || result[2] || result[5] || result[6] || result[4];
  105. var newUrl;
  106. newUrl = convertURIBase(url, fromBase, toBase);
  107. var quoteLen = result[5] || result[6] ? 1 : 0;
  108. source = source.substr(0, urlRegEx.lastIndex - url.length - quoteLen - 1) + newUrl + source.substr(urlRegEx.lastIndex - quoteLen - 1);
  109. urlRegEx.lastIndex = urlRegEx.lastIndex + (newUrl.length - url.length);
  110. }
  111. return source;
  112. };
  113. normalizeCSS.convertURIBase = convertURIBase;
  114. normalizeCSS.absoluteURI = absoluteURI;
  115. normalizeCSS.relativeURI = relativeURI;
  116. return normalizeCSS;
  117. });
  118. //>>excludeEnd('excludeRequireCss')