Bug 1544223 - Don't advance to the next property or value when parsing ; or : inside a CSS block; r=gl
Differential Revision: https://phabricator.services.mozilla.com/D31973
This commit is contained in:
@@ -20,6 +20,7 @@ loader.lazyRequireGetter(this, "CSS_ANGLEUNIT", "devtools/shared/css/constants",
|
||||
const SELECTOR_ATTRIBUTE = exports.SELECTOR_ATTRIBUTE = 1;
|
||||
const SELECTOR_ELEMENT = exports.SELECTOR_ELEMENT = 2;
|
||||
const SELECTOR_PSEUDO_CLASS = exports.SELECTOR_PSEUDO_CLASS = 3;
|
||||
const CSS_BLOCKS = { "(": ")", "[": "]", "{": "}" };
|
||||
|
||||
// When commenting out a declaration, we put this character into the
|
||||
// comment opener so that future parses of the commented text know to
|
||||
@@ -278,6 +279,12 @@ function parseDeclarationsInternal(isCssPropertyKnown, inputString,
|
||||
let declarations = [getEmptyDeclaration()];
|
||||
let lastProp = declarations[0];
|
||||
|
||||
// This tracks the various CSS blocks the current token is in currently.
|
||||
// This is a stack we push to when a block is opened, and we pop from when a block is
|
||||
// closed. Within a block, colons and semicolons don't advance the way they do outside
|
||||
// of blocks.
|
||||
let currentBlocks = [];
|
||||
|
||||
// This tracks the "!important" parsing state. The states are:
|
||||
// 0 - haven't seen anything
|
||||
// 1 - have seen "!", looking for "important" next (possibly after
|
||||
@@ -309,7 +316,20 @@ function parseDeclarationsInternal(isCssPropertyKnown, inputString,
|
||||
importantWS = true;
|
||||
}
|
||||
|
||||
if (token.tokenType === "symbol" && token.text === ":") {
|
||||
if (token.tokenType === "symbol" &&
|
||||
currentBlocks[currentBlocks.length - 1] === token.text) {
|
||||
// Closing the last block that was opened.
|
||||
currentBlocks.pop();
|
||||
current += token.text;
|
||||
} else if (token.tokenType === "symbol" && CSS_BLOCKS[token.text]) {
|
||||
// Opening a new block.
|
||||
currentBlocks.push(CSS_BLOCKS[token.text]);
|
||||
current += token.text;
|
||||
} else if (token.tokenType === "function") {
|
||||
// Opening a function is like opening a new block, so push one to the stack.
|
||||
currentBlocks.push(CSS_BLOCKS["("]);
|
||||
current += token.text + "(";
|
||||
} else if (token.tokenType === "symbol" && token.text === ":") {
|
||||
// Either way, a "!important" we've seen is no longer valid now.
|
||||
importantState = 0;
|
||||
importantWS = false;
|
||||
@@ -318,6 +338,7 @@ function parseDeclarationsInternal(isCssPropertyKnown, inputString,
|
||||
lastProp.name = cssTrim(current);
|
||||
lastProp.colonOffsets = [token.startOffset, token.endOffset];
|
||||
current = "";
|
||||
currentBlocks = [];
|
||||
|
||||
// When parsing a comment body, if the left-hand-side is not a
|
||||
// valid property name, then drop it and stop parsing.
|
||||
@@ -331,13 +352,15 @@ function parseDeclarationsInternal(isCssPropertyKnown, inputString,
|
||||
// with colons)
|
||||
current += ":";
|
||||
}
|
||||
} else if (token.tokenType === "symbol" && token.text === ";") {
|
||||
} else if (token.tokenType === "symbol" && token.text === ";" &&
|
||||
!currentBlocks.length) {
|
||||
lastProp.terminator = "";
|
||||
// When parsing a comment, if the name hasn't been set, then we
|
||||
// have probably just seen an ordinary semicolon used in text,
|
||||
// so drop this and stop parsing.
|
||||
if (inComment && !lastProp.name) {
|
||||
current = "";
|
||||
currentBlocks = [];
|
||||
break;
|
||||
}
|
||||
if (importantState === 2) {
|
||||
@@ -350,6 +373,7 @@ function parseDeclarationsInternal(isCssPropertyKnown, inputString,
|
||||
}
|
||||
lastProp.value = cssTrim(current);
|
||||
current = "";
|
||||
currentBlocks = [];
|
||||
importantState = 0;
|
||||
importantWS = false;
|
||||
declarations.push(getEmptyDeclaration());
|
||||
|
||||
Reference in New Issue
Block a user