Spaces:
Configuration error
Configuration error
; | |
const types = require('../tokenizer/types.cjs'); | |
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+) | |
const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-) | |
const code = (type, value) => { | |
if (type === types.Delim) { | |
type = value; | |
} | |
if (typeof type === 'string') { | |
const charCode = type.charCodeAt(0); | |
return charCode > 0x7F ? 0x8000 : charCode << 8; | |
} | |
return type; | |
}; | |
// https://www.w3.org/TR/css-syntax-3/#serialization | |
// The only requirement for serialization is that it must "round-trip" with parsing, | |
// that is, parsing the stylesheet must produce the same data structures as parsing, | |
// serializing, and parsing again, except for consecutive <whitespace-token>s, | |
// which may be collapsed into a single token. | |
const specPairs = [ | |
[types.Ident, types.Ident], | |
[types.Ident, types.Function], | |
[types.Ident, types.Url], | |
[types.Ident, types.BadUrl], | |
[types.Ident, '-'], | |
[types.Ident, types.Number], | |
[types.Ident, types.Percentage], | |
[types.Ident, types.Dimension], | |
[types.Ident, types.CDC], | |
[types.Ident, types.LeftParenthesis], | |
[types.AtKeyword, types.Ident], | |
[types.AtKeyword, types.Function], | |
[types.AtKeyword, types.Url], | |
[types.AtKeyword, types.BadUrl], | |
[types.AtKeyword, '-'], | |
[types.AtKeyword, types.Number], | |
[types.AtKeyword, types.Percentage], | |
[types.AtKeyword, types.Dimension], | |
[types.AtKeyword, types.CDC], | |
[types.Hash, types.Ident], | |
[types.Hash, types.Function], | |
[types.Hash, types.Url], | |
[types.Hash, types.BadUrl], | |
[types.Hash, '-'], | |
[types.Hash, types.Number], | |
[types.Hash, types.Percentage], | |
[types.Hash, types.Dimension], | |
[types.Hash, types.CDC], | |
[types.Dimension, types.Ident], | |
[types.Dimension, types.Function], | |
[types.Dimension, types.Url], | |
[types.Dimension, types.BadUrl], | |
[types.Dimension, '-'], | |
[types.Dimension, types.Number], | |
[types.Dimension, types.Percentage], | |
[types.Dimension, types.Dimension], | |
[types.Dimension, types.CDC], | |
['#', types.Ident], | |
['#', types.Function], | |
['#', types.Url], | |
['#', types.BadUrl], | |
['#', '-'], | |
['#', types.Number], | |
['#', types.Percentage], | |
['#', types.Dimension], | |
['#', types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 | |
['-', types.Ident], | |
['-', types.Function], | |
['-', types.Url], | |
['-', types.BadUrl], | |
['-', '-'], | |
['-', types.Number], | |
['-', types.Percentage], | |
['-', types.Dimension], | |
['-', types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 | |
[types.Number, types.Ident], | |
[types.Number, types.Function], | |
[types.Number, types.Url], | |
[types.Number, types.BadUrl], | |
[types.Number, types.Number], | |
[types.Number, types.Percentage], | |
[types.Number, types.Dimension], | |
[types.Number, '%'], | |
[types.Number, types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 | |
['@', types.Ident], | |
['@', types.Function], | |
['@', types.Url], | |
['@', types.BadUrl], | |
['@', '-'], | |
['@', types.CDC], // https://github.com/w3c/csswg-drafts/pull/6874 | |
['.', types.Number], | |
['.', types.Percentage], | |
['.', types.Dimension], | |
['+', types.Number], | |
['+', types.Percentage], | |
['+', types.Dimension], | |
['/', '*'] | |
]; | |
// validate with scripts/generate-safe | |
const safePairs = specPairs.concat([ | |
[types.Ident, types.Hash], | |
[types.Dimension, types.Hash], | |
[types.Hash, types.Hash], | |
[types.AtKeyword, types.LeftParenthesis], | |
[types.AtKeyword, types.String], | |
[types.AtKeyword, types.Colon], | |
[types.Percentage, types.Percentage], | |
[types.Percentage, types.Dimension], | |
[types.Percentage, types.Function], | |
[types.Percentage, '-'], | |
[types.RightParenthesis, types.Ident], | |
[types.RightParenthesis, types.Function], | |
[types.RightParenthesis, types.Percentage], | |
[types.RightParenthesis, types.Dimension], | |
[types.RightParenthesis, types.Hash], | |
[types.RightParenthesis, '-'] | |
]); | |
function createMap(pairs) { | |
const isWhiteSpaceRequired = new Set( | |
pairs.map(([prev, next]) => (code(prev) << 16 | code(next))) | |
); | |
return function(prevCode, type, value) { | |
const nextCode = code(type, value); | |
const nextCharCode = value.charCodeAt(0); | |
const emitWs = | |
(nextCharCode === HYPHENMINUS && | |
type !== types.Ident && | |
type !== types.Function && | |
type !== types.CDC) || | |
(nextCharCode === PLUSSIGN) | |
? isWhiteSpaceRequired.has(prevCode << 16 | nextCharCode << 8) | |
: isWhiteSpaceRequired.has(prevCode << 16 | nextCode); | |
if (emitWs) { | |
this.emit(' ', types.WhiteSpace, true); | |
} | |
return nextCode; | |
}; | |
} | |
const spec = createMap(specPairs); | |
const safe = createMap(safePairs); | |
exports.safe = safe; | |
exports.spec = spec; | |