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:
Patrick Brosset
2019-05-22 10:46:55 +00:00
parent f8b29d7f10
commit fb5091b2d5
2 changed files with 93 additions and 2 deletions

View File

@@ -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());