fix: more bugs

This commit is contained in:
alexander.akait 2023-04-13 02:27:04 +03:00
parent cb77a36b2a
commit 7ee28a7cc8
2 changed files with 48 additions and 17 deletions

View File

@ -23,19 +23,24 @@ const CC_COLON = ":".charCodeAt(0);
const CC_SLASH = "/".charCodeAt(0);
const CC_SEMICOLON = ";".charCodeAt(0);
const normalizeUrl = str => {
const STRING_MULTILINE = /\\(\n|\r\n|\r|\f)/g;
const TRIM_WHITE_SPACES = /(^( |\t\n|\r\n|\r|\f)*|( |\t\n|\r\n|\r|\f)*$)/g;
const UNESCAPE = /\\([0-9a-fA-F]{1,6}[ \t\n\r\f]?|[\s\S])/g;
const normalizeUrl = (str, isString) => {
// Handle spaces and newlines:
// `url("im\
// g.png")`
if (isString) {
str = str.replace(STRING_MULTILINE, "");
}
return (
str
// Remove unnecessary spaces from:
//
// 1. `url(" img.png ")`
//
// 2. `url("im\
// g.png")`
//
.replace(/ |\t\n|\r\n|\r|\f/g, "")
// Remove unnecessary spaces from `url(" img.png ")`
.replace(TRIM_WHITE_SPACES, "")
// Unescape
.replace(/\\([0-9a-fA-F]{1,6}[ \t\n\r\f]?|[\s\S])/g, match => {
.replace(UNESCAPE, match => {
if (match.length > 2) {
return String.fromCharCode(parseInt(match.slice(1).trim(), 16));
} else {
@ -315,8 +320,11 @@ class CssParser extends Parser {
isSelector: () => {
return mode !== CSS_MODE_IN_RULE && mode !== CSS_MODE_IN_LOCAL_RULE;
},
url: (input, start, end, contentStart, contentEnd) => {
let value = normalizeUrl(input.slice(contentStart, contentEnd));
url: (input, start, end, contentStart, contentEnd, isString) => {
let value = normalizeUrl(
input.slice(contentStart, contentEnd),
isString
);
switch (mode) {
case CSS_MODE_AT_IMPORT_EXPECT_URL: {
modeData.url = value;
@ -355,7 +363,7 @@ class CssParser extends Parser {
string: (input, start, end) => {
switch (mode) {
case CSS_MODE_AT_IMPORT_EXPECT_URL: {
modeData.url = normalizeUrl(input.slice(start + 1, end - 1));
modeData.url = normalizeUrl(input.slice(start + 1, end - 1), true);
mode = CSS_MODE_AT_IMPORT_EXPECT_SUPPORTS;
break;
}

View File

@ -8,7 +8,7 @@
/**
* @typedef {Object} CssTokenCallbacks
* @property {function(string, number): boolean} isSelector
* @property {function(string, number, number, number, number): number=} url
* @property {function(string, number, number, number, number, boolean): number=} url
* @property {function(string, number, number): number=} string
* @property {function(string, number, number): number=} leftParenthesis
* @property {function(string, number, number): number=} rightParenthesis
@ -300,8 +300,10 @@ const consumePotentialUrl = (input, pos, callbacks) => {
if (pos === input.length) return pos;
cc = input.charCodeAt(pos);
}
let isString = false;
if (cc === CC_QUOTATION_MARK || cc === CC_APOSTROPHE) {
pos++;
isString = true;
const contentStart = pos;
pos = _consumeString(input, pos, cc);
const contentEnd = pos - 1;
@ -314,7 +316,14 @@ const consumePotentialUrl = (input, pos, callbacks) => {
if (cc !== CC_RIGHT_PARENTHESIS) return pos;
pos++;
if (callbacks.url !== undefined)
return callbacks.url(input, start, pos, contentStart, contentEnd);
return callbacks.url(
input,
start,
pos,
contentStart,
contentEnd,
isString
);
return pos;
} else {
const contentStart = pos;
@ -334,14 +343,28 @@ const consumePotentialUrl = (input, pos, callbacks) => {
if (cc !== CC_RIGHT_PARENTHESIS) return pos;
pos++;
if (callbacks.url !== undefined) {
return callbacks.url(input, start, pos, contentStart, contentEnd);
return callbacks.url(
input,
start,
pos,
contentStart,
contentEnd,
isString
);
}
return pos;
} else if (cc === CC_RIGHT_PARENTHESIS) {
contentEnd = pos;
pos++;
if (callbacks.url !== undefined) {
return callbacks.url(input, start, pos, contentStart, contentEnd);
return callbacks.url(
input,
start,
pos,
contentStart,
contentEnd,
isString
);
}
return pos;
} else if (cc === CC_LEFT_PARENTHESIS) {