clear
This commit is contained in:
193
node_modules/clean-css/lib/tokenizer/extract-properties.js
generated
vendored
Normal file
193
node_modules/clean-css/lib/tokenizer/extract-properties.js
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
var split = require('../utils/split');
|
||||
|
||||
var COMMA = ',';
|
||||
var FORWARD_SLASH = '/';
|
||||
|
||||
var AT_RULE = 'at-rule';
|
||||
|
||||
var IMPORTANT_WORD = 'important';
|
||||
var IMPORTANT_TOKEN = '!'+IMPORTANT_WORD;
|
||||
var IMPORTANT_WORD_MATCH = new RegExp('^'+IMPORTANT_WORD+'$', 'i');
|
||||
var IMPORTANT_TOKEN_MATCH = new RegExp('^'+IMPORTANT_TOKEN+'$', 'i');
|
||||
|
||||
function selectorName(value) {
|
||||
return value[0];
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
|
||||
function withoutComments(string, into, heading, context) {
|
||||
var matcher = heading ? /^__ESCAPED_COMMENT_/ : /__ESCAPED_COMMENT_/;
|
||||
var track = heading ? context.track : noop; // don't track when comment not in a heading as we do it later in `trackComments`
|
||||
|
||||
while (matcher.test(string)) {
|
||||
var startOfComment = string.indexOf('__');
|
||||
var endOfComment = string.indexOf('__', startOfComment + 1) + 2;
|
||||
var comment = string.substring(startOfComment, endOfComment);
|
||||
string = string.substring(0, startOfComment) + string.substring(endOfComment);
|
||||
|
||||
track(comment);
|
||||
into.push(comment);
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
function withoutHeadingComments(string, into, context) {
|
||||
return withoutComments(string, into, true, context);
|
||||
}
|
||||
|
||||
function withoutInnerComments(string, into, context) {
|
||||
return withoutComments(string, into, false, context);
|
||||
}
|
||||
|
||||
function trackComments(comments, into, context) {
|
||||
for (var i = 0, l = comments.length; i < l; i++) {
|
||||
context.track(comments[i]);
|
||||
into.push(comments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function extractProperties(string, selectors, context) {
|
||||
var list = [];
|
||||
var innerComments = [];
|
||||
var valueSeparator = /[\s,\/]/;
|
||||
|
||||
if (typeof string != 'string')
|
||||
return [];
|
||||
|
||||
if (string.indexOf(')') > -1)
|
||||
string = string.replace(/\)([^\s_;:,\)])/g, context.sourceMap ? ') __ESCAPED_COMMENT_CLEAN_CSS(0,-1)__ $1' : ') $1');
|
||||
|
||||
if (string.indexOf('ESCAPED_URL_CLEAN_CSS') > -1)
|
||||
string = string.replace(/(ESCAPED_URL_CLEAN_CSS[^_]+?__)/g, context.sourceMap ? '$1 __ESCAPED_COMMENT_CLEAN_CSS(0,-1)__ ' : '$1 ');
|
||||
|
||||
var candidates = split(string, ';', false, '{', '}');
|
||||
|
||||
for (var i = 0, l = candidates.length; i < l; i++) {
|
||||
var candidate = candidates[i];
|
||||
var firstColonAt = candidate.indexOf(':');
|
||||
|
||||
var atRule = candidate.trim()[0] == '@';
|
||||
if (atRule) {
|
||||
context.track(candidate);
|
||||
list.push([AT_RULE, candidate.trim()]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (firstColonAt == -1) {
|
||||
context.track(candidate);
|
||||
if (candidate.indexOf('__ESCAPED_COMMENT_SPECIAL') > -1)
|
||||
list.push(candidate.trim());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (candidate.indexOf('{') > 0 && candidate.indexOf('{') < firstColonAt) {
|
||||
context.track(candidate);
|
||||
continue;
|
||||
}
|
||||
|
||||
var body = [];
|
||||
var name = candidate.substring(0, firstColonAt);
|
||||
|
||||
innerComments = [];
|
||||
|
||||
if (name.indexOf('__ESCAPED_COMMENT') > -1)
|
||||
name = withoutHeadingComments(name, list, context);
|
||||
|
||||
if (name.indexOf('__ESCAPED_COMMENT') > -1)
|
||||
name = withoutInnerComments(name, innerComments, context);
|
||||
|
||||
body.push([name.trim()].concat(context.track(name, true)));
|
||||
context.track(':');
|
||||
|
||||
trackComments(innerComments, list, context);
|
||||
|
||||
var firstBraceAt = candidate.indexOf('{');
|
||||
var isVariable = name.trim().indexOf('--') === 0;
|
||||
if (isVariable && firstBraceAt > 0) {
|
||||
var blockPrefix = candidate.substring(firstColonAt + 1, firstBraceAt + 1);
|
||||
var blockSuffix = candidate.substring(candidate.indexOf('}'));
|
||||
var blockContent = candidate.substring(firstBraceAt + 1, candidate.length - blockSuffix.length);
|
||||
|
||||
context.track(blockPrefix);
|
||||
body.push(extractProperties(blockContent, selectors, context));
|
||||
list.push(body);
|
||||
context.track(blockSuffix);
|
||||
context.track(i < l - 1 ? ';' : '');
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
var values = split(candidate.substring(firstColonAt + 1), valueSeparator, true);
|
||||
|
||||
if (values.length == 1 && values[0] === '') {
|
||||
context.warnings.push('Empty property \'' + name + '\' inside \'' + selectors.filter(selectorName).join(',') + '\' selector. Ignoring.');
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var j = 0, m = values.length; j < m; j++) {
|
||||
var value = values[j];
|
||||
var trimmed = value.trim();
|
||||
|
||||
if (trimmed.length === 0)
|
||||
continue;
|
||||
|
||||
var lastCharacter = trimmed[trimmed.length - 1];
|
||||
var endsWithNonSpaceSeparator = trimmed.length > 1 && (lastCharacter == COMMA || lastCharacter == FORWARD_SLASH);
|
||||
|
||||
if (endsWithNonSpaceSeparator)
|
||||
trimmed = trimmed.substring(0, trimmed.length - 1);
|
||||
|
||||
if (trimmed.indexOf('__ESCAPED_COMMENT_CLEAN_CSS(0,-') > -1) {
|
||||
context.track(trimmed);
|
||||
continue;
|
||||
}
|
||||
|
||||
innerComments = [];
|
||||
|
||||
if (trimmed.indexOf('__ESCAPED_COMMENT') > -1)
|
||||
trimmed = withoutHeadingComments(trimmed, list, context);
|
||||
|
||||
if (trimmed.indexOf('__ESCAPED_COMMENT') > -1)
|
||||
trimmed = withoutInnerComments(trimmed, innerComments, context);
|
||||
|
||||
if (trimmed.length === 0) {
|
||||
trackComments(innerComments, list, context);
|
||||
continue;
|
||||
}
|
||||
|
||||
var pos = body.length - 1;
|
||||
if (IMPORTANT_WORD_MATCH.test(trimmed) && body[pos][0] == '!') {
|
||||
context.track(trimmed);
|
||||
body[pos - 1][0] += IMPORTANT_TOKEN;
|
||||
body.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IMPORTANT_TOKEN_MATCH.test(trimmed) || (IMPORTANT_WORD_MATCH.test(trimmed) && body[pos][0][body[pos][0].length - 1] == '!')) {
|
||||
context.track(trimmed);
|
||||
body[pos][0] += trimmed;
|
||||
continue;
|
||||
}
|
||||
|
||||
body.push([trimmed].concat(context.track(value, true)));
|
||||
|
||||
trackComments(innerComments, list, context);
|
||||
|
||||
if (endsWithNonSpaceSeparator) {
|
||||
body.push([lastCharacter]);
|
||||
context.track(lastCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
if (i < l - 1)
|
||||
context.track(';');
|
||||
|
||||
list.push(body);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
module.exports = extractProperties;
|
||||
17
node_modules/clean-css/lib/tokenizer/extract-selectors.js
generated
vendored
Normal file
17
node_modules/clean-css/lib/tokenizer/extract-selectors.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
var split = require('../utils/split');
|
||||
|
||||
function extractSelectors(string, context) {
|
||||
var list = [];
|
||||
var metadata;
|
||||
var selectors = split(string, ',');
|
||||
|
||||
for (var i = 0, l = selectors.length; i < l; i++) {
|
||||
metadata = context.track(selectors[i], true, i);
|
||||
context.track(',');
|
||||
list.push([selectors[i].trim()].concat(metadata));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
module.exports = extractSelectors;
|
||||
268
node_modules/clean-css/lib/tokenizer/tokenize.js
generated
vendored
Normal file
268
node_modules/clean-css/lib/tokenizer/tokenize.js
generated
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
var extractProperties = require('./extract-properties');
|
||||
var extractSelectors = require('./extract-selectors');
|
||||
var track = require('../source-maps/track');
|
||||
var split = require('../utils/split');
|
||||
|
||||
var path = require('path');
|
||||
|
||||
var flatBlock = /(@(font\-face|page|\-ms\-viewport|\-o\-viewport|viewport|counter\-style)|\\@.+?)/;
|
||||
|
||||
function tokenize(data, outerContext) {
|
||||
var chunks = split(normalize(data), '}', true, '{', '}');
|
||||
if (chunks.length === 0)
|
||||
return [];
|
||||
|
||||
var context = {
|
||||
chunk: chunks.shift(),
|
||||
chunks: chunks,
|
||||
column: 0,
|
||||
cursor: 0,
|
||||
line: 1,
|
||||
mode: 'top',
|
||||
resolvePath: outerContext.options.explicitTarget ?
|
||||
relativePathResolver(outerContext.options.root, outerContext.options.target) :
|
||||
null,
|
||||
source: undefined,
|
||||
sourceMap: outerContext.options.sourceMap,
|
||||
sourceMapInlineSources: outerContext.options.sourceMapInlineSources,
|
||||
sourceMapTracker: outerContext.inputSourceMapTracker,
|
||||
sourceReader: outerContext.sourceReader,
|
||||
sourceTracker: outerContext.sourceTracker,
|
||||
state: [],
|
||||
track: outerContext.options.sourceMap ?
|
||||
function (data, snapshotMetadata, fallbacks) { return [[track(data, context, snapshotMetadata, fallbacks)]]; } :
|
||||
function () { return []; },
|
||||
warnings: outerContext.warnings
|
||||
};
|
||||
|
||||
return intoTokens(context);
|
||||
}
|
||||
|
||||
function normalize(data) {
|
||||
return data.replace(/\r\n/g, '\n');
|
||||
}
|
||||
|
||||
function relativePathResolver(root, target) {
|
||||
var rebaseTo = path.relative(root, target);
|
||||
|
||||
return function (relativeTo, sourcePath) {
|
||||
return relativeTo != sourcePath ?
|
||||
path.normalize(path.join(path.relative(rebaseTo, path.dirname(relativeTo)), sourcePath)) :
|
||||
sourcePath;
|
||||
};
|
||||
}
|
||||
|
||||
function whatsNext(context) {
|
||||
var mode = context.mode;
|
||||
var chunk = context.chunk;
|
||||
var closest;
|
||||
|
||||
if (chunk.length == context.cursor) {
|
||||
if (context.chunks.length === 0)
|
||||
return null;
|
||||
|
||||
context.chunk = chunk = context.chunks.shift();
|
||||
context.cursor = 0;
|
||||
}
|
||||
|
||||
if (mode == 'body') {
|
||||
if (chunk[context.cursor] == '}')
|
||||
return [context.cursor, 'bodyEnd'];
|
||||
|
||||
if (chunk.indexOf('}', context.cursor) == -1)
|
||||
return null;
|
||||
|
||||
closest = context.cursor + split(chunk.substring(context.cursor - 1), '}', true, '{', '}')[0].length - 2;
|
||||
return [closest, 'bodyEnd'];
|
||||
}
|
||||
|
||||
var nextSpecial = chunk.indexOf('@', context.cursor);
|
||||
var nextEscape = chunk.indexOf('__ESCAPED_', context.cursor);
|
||||
var nextBodyStart = chunk.indexOf('{', context.cursor);
|
||||
var nextBodyEnd = chunk.indexOf('}', context.cursor);
|
||||
|
||||
if (nextSpecial > -1 && context.cursor > 0 && !/\s|\{|\}|\/|_|,|;/.test(chunk.substring(nextSpecial - 1, nextSpecial))) {
|
||||
nextSpecial = -1;
|
||||
}
|
||||
|
||||
if (nextEscape > -1 && /\S/.test(chunk.substring(context.cursor, nextEscape)))
|
||||
nextEscape = -1;
|
||||
|
||||
closest = nextSpecial;
|
||||
if (closest == -1 || (nextEscape > -1 && nextEscape < closest))
|
||||
closest = nextEscape;
|
||||
if (closest == -1 || (nextBodyStart > -1 && nextBodyStart < closest))
|
||||
closest = nextBodyStart;
|
||||
if (closest == -1 || (nextBodyEnd > -1 && nextBodyEnd < closest))
|
||||
closest = nextBodyEnd;
|
||||
|
||||
if (closest == -1)
|
||||
return;
|
||||
if (nextEscape === closest)
|
||||
return [closest, 'escape'];
|
||||
if (nextBodyStart === closest)
|
||||
return [closest, 'bodyStart'];
|
||||
if (nextBodyEnd === closest)
|
||||
return [closest, 'bodyEnd'];
|
||||
if (nextSpecial === closest)
|
||||
return [closest, 'special'];
|
||||
}
|
||||
|
||||
function intoTokens(context) {
|
||||
var chunk = context.chunk;
|
||||
var tokenized = [];
|
||||
var newToken;
|
||||
var value;
|
||||
|
||||
while (true) {
|
||||
var next = whatsNext(context);
|
||||
if (!next) {
|
||||
var whatsLeft = context.chunk.substring(context.cursor);
|
||||
if (whatsLeft.trim().length > 0) {
|
||||
if (context.mode == 'body') {
|
||||
context.warnings.push('Missing \'}\' after \'' + whatsLeft + '\'. Ignoring.');
|
||||
} else {
|
||||
tokenized.push(['text', [whatsLeft]]);
|
||||
}
|
||||
context.cursor += whatsLeft.length;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var nextSpecial = next[0];
|
||||
var what = next[1];
|
||||
var nextEnd;
|
||||
var oldMode;
|
||||
|
||||
chunk = context.chunk;
|
||||
|
||||
if (context.cursor != nextSpecial && what != 'bodyEnd') {
|
||||
var spacing = chunk.substring(context.cursor, nextSpecial);
|
||||
var leadingWhitespace = /^\s+/.exec(spacing);
|
||||
|
||||
if (leadingWhitespace) {
|
||||
context.cursor += leadingWhitespace[0].length;
|
||||
context.track(leadingWhitespace[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (what == 'special') {
|
||||
var firstOpenBraceAt = chunk.indexOf('{', nextSpecial);
|
||||
var firstSemicolonAt = chunk.indexOf(';', nextSpecial);
|
||||
var isSingle = firstSemicolonAt > -1 && (firstOpenBraceAt == -1 || firstSemicolonAt < firstOpenBraceAt);
|
||||
var isBroken = firstOpenBraceAt == -1 && firstSemicolonAt == -1;
|
||||
if (isBroken) {
|
||||
context.warnings.push('Broken declaration: \'' + chunk.substring(context.cursor) + '\'.');
|
||||
context.cursor = chunk.length;
|
||||
} else if (isSingle) {
|
||||
nextEnd = chunk.indexOf(';', nextSpecial + 1);
|
||||
value = chunk.substring(context.cursor, nextEnd + 1);
|
||||
|
||||
tokenized.push([
|
||||
'at-rule',
|
||||
[value].concat(context.track(value, true))
|
||||
]);
|
||||
|
||||
context.track(';');
|
||||
context.cursor = nextEnd + 1;
|
||||
} else {
|
||||
nextEnd = chunk.indexOf('{', nextSpecial + 1);
|
||||
value = chunk.substring(context.cursor, nextEnd);
|
||||
|
||||
var trimmedValue = value.trim();
|
||||
var isFlat = flatBlock.test(trimmedValue);
|
||||
oldMode = context.mode;
|
||||
context.cursor = nextEnd + 1;
|
||||
context.mode = isFlat ? 'body' : 'block';
|
||||
|
||||
newToken = [
|
||||
isFlat ? 'flat-block' : 'block'
|
||||
];
|
||||
|
||||
newToken.push([trimmedValue].concat(context.track(value, true)));
|
||||
context.track('{');
|
||||
newToken.push(intoTokens(context));
|
||||
|
||||
if (typeof newToken[2] == 'string')
|
||||
newToken[2] = extractProperties(newToken[2], [[trimmedValue]], context);
|
||||
|
||||
context.mode = oldMode;
|
||||
context.track('}');
|
||||
|
||||
tokenized.push(newToken);
|
||||
}
|
||||
} else if (what == 'escape') {
|
||||
nextEnd = chunk.indexOf('__', nextSpecial + 1);
|
||||
var escaped = chunk.substring(context.cursor, nextEnd + 2);
|
||||
var isStartSourceMarker = !!context.sourceTracker.nextStart(escaped);
|
||||
var isEndSourceMarker = !!context.sourceTracker.nextEnd(escaped);
|
||||
|
||||
if (isStartSourceMarker) {
|
||||
context.track(escaped);
|
||||
context.state.push({
|
||||
source: context.source,
|
||||
line: context.line,
|
||||
column: context.column
|
||||
});
|
||||
context.source = context.sourceTracker.nextStart(escaped).filename;
|
||||
context.line = 1;
|
||||
context.column = 0;
|
||||
} else if (isEndSourceMarker) {
|
||||
var oldState = context.state.pop();
|
||||
context.source = oldState.source;
|
||||
context.line = oldState.line;
|
||||
context.column = oldState.column;
|
||||
context.track(escaped);
|
||||
} else {
|
||||
if (escaped.indexOf('__ESCAPED_COMMENT_SPECIAL') === 0)
|
||||
tokenized.push(['text', [escaped]]);
|
||||
|
||||
context.track(escaped);
|
||||
}
|
||||
|
||||
context.cursor = nextEnd + 2;
|
||||
} else if (what == 'bodyStart') {
|
||||
var selectors = extractSelectors(chunk.substring(context.cursor, nextSpecial), context);
|
||||
|
||||
oldMode = context.mode;
|
||||
context.cursor = nextSpecial + 1;
|
||||
context.mode = 'body';
|
||||
|
||||
var body = extractProperties(intoTokens(context), selectors, context);
|
||||
|
||||
context.track('{');
|
||||
context.mode = oldMode;
|
||||
|
||||
tokenized.push([
|
||||
'selector',
|
||||
selectors,
|
||||
body
|
||||
]);
|
||||
} else if (what == 'bodyEnd') {
|
||||
// extra closing brace at the top level can be safely ignored
|
||||
if (context.mode == 'top') {
|
||||
var at = context.cursor;
|
||||
var warning = chunk[context.cursor] == '}' ?
|
||||
'Unexpected \'}\' in \'' + chunk.substring(at - 20, at + 20) + '\'. Ignoring.' :
|
||||
'Unexpected content: \'' + chunk.substring(at, nextSpecial + 1) + '\'. Ignoring.';
|
||||
|
||||
context.warnings.push(warning);
|
||||
context.cursor = nextSpecial + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (context.mode == 'block')
|
||||
context.track(chunk.substring(context.cursor, nextSpecial));
|
||||
if (context.mode != 'block')
|
||||
tokenized = chunk.substring(context.cursor, nextSpecial);
|
||||
|
||||
context.cursor = nextSpecial + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return tokenized;
|
||||
}
|
||||
|
||||
module.exports = tokenize;
|
||||
Reference in New Issue
Block a user