| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 | var split = require('../utils/split');var URL_PREFIX = 'url(';var UPPERCASE_URL_PREFIX = 'URL(';var URL_SUFFIX = ')';var SINGLE_QUOTE_URL_SUFFIX = '\')';var DOUBLE_QUOTE_URL_SUFFIX = '")';var DATA_URI_PREFIX_PATTERN = /^\s*['"]?\s*data:/;var DATA_URI_TRAILER_PATTERN = /[\s\};,\/!]/;var IMPORT_URL_PREFIX = '@import';var UPPERCASE_IMPORT_URL_PREFIX = '@IMPORT';var COMMENT_END_MARKER = /\*\//;function byUrl(data, context, callback) {  var nextStart = 0;  var nextStartUpperCase = 0;  var nextEnd = 0;  var firstMatch;  var isDataURI = false;  var cursor = 0;  var tempData = [];  var hasUppercaseUrl = data.indexOf(UPPERCASE_URL_PREFIX) > -1;  for (; nextEnd < data.length;) {    nextStart = data.indexOf(URL_PREFIX, nextEnd);    nextStartUpperCase = hasUppercaseUrl ? data.indexOf(UPPERCASE_URL_PREFIX, nextEnd) : -1;    if (nextStart == -1 && nextStartUpperCase == -1)      break;    if (nextStart == -1 && nextStartUpperCase > -1)      nextStart = nextStartUpperCase;    if (data[nextStart + URL_PREFIX.length] == '"') {      nextEnd = data.indexOf(DOUBLE_QUOTE_URL_SUFFIX, nextStart);    } else if (data[nextStart + URL_PREFIX.length] == '\'') {      nextEnd = data.indexOf(SINGLE_QUOTE_URL_SUFFIX, nextStart);    } else {      isDataURI = DATA_URI_PREFIX_PATTERN.test(data.substring(nextStart + URL_PREFIX.length));      if (isDataURI) {        firstMatch = split(data.substring(nextStart), DATA_URI_TRAILER_PATTERN, false, '(', ')', true).pop();        if (firstMatch && firstMatch[firstMatch.length - 1] == URL_SUFFIX) {          nextEnd = nextStart + firstMatch.length - URL_SUFFIX.length;        } else {          nextEnd = -1;        }      } else {        nextEnd = data.indexOf(URL_SUFFIX, nextStart);      }    }    // Following lines are a safety mechanism to ensure    // incorrectly terminated urls are processed correctly.    if (nextEnd == -1) {      nextEnd = data.indexOf('}', nextStart);      if (nextEnd == -1)        nextEnd = data.length;      else        nextEnd--;      context.warnings.push('Broken URL declaration: \'' + data.substring(nextStart, nextEnd + 1) + '\'.');    } else {      if (data[nextEnd] != URL_SUFFIX)        nextEnd = data.indexOf(URL_SUFFIX, nextEnd);    }    tempData.push(data.substring(cursor, nextStart));    var url = data.substring(nextStart, nextEnd + 1);    callback(url, tempData);    cursor = nextEnd + 1;  }  return tempData.length > 0 ?    tempData.join('') + data.substring(cursor, data.length) :    data;}function byImport(data, context, callback) {  var nextImport = 0;  var nextImportUpperCase = 0;  var nextStart = 0;  var nextEnd = 0;  var cursor = 0;  var tempData = [];  var nextSingleQuote = 0;  var nextDoubleQuote = 0;  var untilNextQuote;  var withQuote;  var SINGLE_QUOTE = '\'';  var DOUBLE_QUOTE = '"';  for (; nextEnd < data.length;) {    nextImport = data.indexOf(IMPORT_URL_PREFIX, nextEnd);    nextImportUpperCase = data.indexOf(UPPERCASE_IMPORT_URL_PREFIX, nextEnd);    if (nextImport == -1 && nextImportUpperCase == -1)      break;    if (nextImport > -1 && nextImportUpperCase > -1 && nextImportUpperCase < nextImport)      nextImport = nextImportUpperCase;    nextSingleQuote = data.indexOf(SINGLE_QUOTE, nextImport);    nextDoubleQuote = data.indexOf(DOUBLE_QUOTE, nextImport);    if (nextSingleQuote > -1 && nextDoubleQuote > -1 && nextSingleQuote < nextDoubleQuote) {      nextStart = nextSingleQuote;      withQuote = SINGLE_QUOTE;    } else if (nextSingleQuote > -1 && nextDoubleQuote > -1 && nextSingleQuote > nextDoubleQuote) {      nextStart = nextDoubleQuote;      withQuote = DOUBLE_QUOTE;    } else if (nextSingleQuote > -1) {      nextStart = nextSingleQuote;      withQuote = SINGLE_QUOTE;    } else if (nextDoubleQuote > -1) {      nextStart = nextDoubleQuote;      withQuote = DOUBLE_QUOTE;    } else {      break;    }    tempData.push(data.substring(cursor, nextStart));    nextEnd = data.indexOf(withQuote, nextStart + 1);    untilNextQuote = data.substring(nextImport, nextEnd);    if (nextEnd == -1 || /^@import\s+(url\(|__ESCAPED)/i.test(untilNextQuote) || COMMENT_END_MARKER.test(untilNextQuote)) {      cursor = nextStart;      break;    }    var url = data.substring(nextStart, nextEnd + 1);    callback(url, tempData);    cursor = nextEnd + 1;  }  return tempData.length > 0 ?    tempData.join('') + data.substring(cursor, data.length) :    data;}function reduceAll(data, context, callback) {  data = byUrl(data, context, callback);  data = byImport(data, context, callback);  return data;}module.exports = reduceAll;
 |