rewrite.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. var path = require('path');
  2. var url = require('url');
  3. var reduceUrls = require('./reduce');
  4. var isWindows = process.platform == 'win32';
  5. function isAbsolute(uri) {
  6. return uri[0] == '/';
  7. }
  8. function isSVGMarker(uri) {
  9. return uri[0] == '#';
  10. }
  11. function isEscaped(uri) {
  12. return uri.indexOf('__ESCAPED_URL_CLEAN_CSS__') === 0;
  13. }
  14. function isInternal(uri) {
  15. return /^\w+:\w+/.test(uri);
  16. }
  17. function isRemote(uri) {
  18. return /^[^:]+?:\/\//.test(uri) || uri.indexOf('//') === 0;
  19. }
  20. function isSameOrigin(uri1, uri2) {
  21. return url.parse(uri1).protocol == url.parse(uri2).protocol &&
  22. url.parse(uri1).host == url.parse(uri2).host;
  23. }
  24. function isImport(uri) {
  25. return uri.lastIndexOf('.css') === uri.length - 4;
  26. }
  27. function isData(uri) {
  28. return uri.indexOf('data:') === 0;
  29. }
  30. function absolute(uri, options) {
  31. return path
  32. .resolve(path.join(options.fromBase || '', uri))
  33. .replace(options.toBase, '');
  34. }
  35. function relative(uri, options) {
  36. return path.relative(options.toBase, path.join(options.fromBase || '', uri));
  37. }
  38. function normalize(uri) {
  39. return isWindows ? uri.replace(/\\/g, '/') : uri;
  40. }
  41. function rebase(uri, options) {
  42. if (isAbsolute(uri) || isSVGMarker(uri) || isEscaped(uri) || isInternal(uri))
  43. return uri;
  44. if (options.rebase === false && !isImport(uri))
  45. return uri;
  46. if (!options.imports && isImport(uri))
  47. return uri;
  48. if (isData(uri))
  49. return '\'' + uri + '\'';
  50. if (isRemote(uri) && !isRemote(options.toBase))
  51. return uri;
  52. if (isRemote(uri) && !isSameOrigin(uri, options.toBase))
  53. return uri;
  54. if (!isRemote(uri) && isRemote(options.toBase))
  55. return url.resolve(options.toBase, uri);
  56. return options.absolute ?
  57. normalize(absolute(uri, options)) :
  58. normalize(relative(uri, options));
  59. }
  60. function quoteFor(url) {
  61. if (url.indexOf('\'') > -1)
  62. return '"';
  63. else if (url.indexOf('"') > -1)
  64. return '\'';
  65. else if (/\s/.test(url) || /[\(\)]/.test(url))
  66. return '\'';
  67. else
  68. return '';
  69. }
  70. function rewriteUrls(data, options, context) {
  71. return reduceUrls(data, context, function (originUrl, tempData) {
  72. var url = originUrl.replace(/^(url\()?\s*['"]?|['"]?\s*\)?$/g, '');
  73. var match = originUrl.match(/^(url\()?\s*(['"]).*?(['"])\s*\)?$/);
  74. var quote;
  75. if (!!options.urlQuotes && match && match[2] === match[3]) {
  76. quote = match[2];
  77. } else {
  78. quote = quoteFor(url);
  79. }
  80. tempData.push('url(' + quote + rebase(url, options) + quote + ')');
  81. });
  82. }
  83. module.exports = rewriteUrls;