|
@@ -332,8 +332,6 @@ const SingleFileCore = (() => {
|
|
|
// ---------
|
|
// ---------
|
|
|
// DomHelper
|
|
// DomHelper
|
|
|
// ---------
|
|
// ---------
|
|
|
- const DATA_URI_PREFIX = "data:";
|
|
|
|
|
-
|
|
|
|
|
class DomProcessorHelper {
|
|
class DomProcessorHelper {
|
|
|
static async resolveImportURLs(stylesheetContent, baseURI) {
|
|
static async resolveImportURLs(stylesheetContent, baseURI) {
|
|
|
stylesheetContent = DomUtil.removeCssComments(stylesheetContent);
|
|
stylesheetContent = DomUtil.removeCssComments(stylesheetContent);
|
|
@@ -342,7 +340,7 @@ const SingleFileCore = (() => {
|
|
|
const match = DomUtil.matchImport(cssImport);
|
|
const match = DomUtil.matchImport(cssImport);
|
|
|
if (match) {
|
|
if (match) {
|
|
|
const resourceURL = DomUtil.normalizeURL(match.resourceURL);
|
|
const resourceURL = DomUtil.normalizeURL(match.resourceURL);
|
|
|
- if (resourceURL != baseURI && !match.resourceURL.startsWith(DATA_URI_PREFIX)) {
|
|
|
|
|
|
|
+ if (resourceURL != baseURI && DomUtil.testValidPath(match.resourceURL)) {
|
|
|
let importedStylesheetContent = await Download.getContent(new URL(match.resourceURL, baseURI).href);
|
|
let importedStylesheetContent = await Download.getContent(new URL(match.resourceURL, baseURI).href);
|
|
|
importedStylesheetContent = DomUtil.wrapMediaQuery(importedStylesheetContent, match.media);
|
|
importedStylesheetContent = DomUtil.wrapMediaQuery(importedStylesheetContent, match.media);
|
|
|
if (stylesheetContent.indexOf(cssImport) != -1) {
|
|
if (stylesheetContent.indexOf(cssImport) != -1) {
|
|
@@ -364,7 +362,7 @@ const SingleFileCore = (() => {
|
|
|
urlFunctions.map(urlFunction => {
|
|
urlFunctions.map(urlFunction => {
|
|
|
let resourceURL = DomUtil.matchURL(urlFunction);
|
|
let resourceURL = DomUtil.matchURL(urlFunction);
|
|
|
resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
|
- if (resourceURL && resourceURL != baseURI && !resourceURL.startsWith(DATA_URI_PREFIX)) {
|
|
|
|
|
|
|
+ if (resourceURL && resourceURL != baseURI && DomUtil.testValidPath(resourceURL)) {
|
|
|
stylesheetContent = stylesheetContent.replace(urlFunction, urlFunction.replace(resourceURL, new URL(resourceURL, baseURI).href));
|
|
stylesheetContent = stylesheetContent.replace(urlFunction, urlFunction.replace(resourceURL, new URL(resourceURL, baseURI).href));
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
@@ -373,7 +371,7 @@ const SingleFileCore = (() => {
|
|
|
|
|
|
|
|
static async resolveLinkStylesheetURLs(resourceURL, baseURI, media) {
|
|
static async resolveLinkStylesheetURLs(resourceURL, baseURI, media) {
|
|
|
resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
|
- if (resourceURL && resourceURL != baseURI && !resourceURL.startsWith(DATA_URI_PREFIX)) {
|
|
|
|
|
|
|
+ if (resourceURL && resourceURL != baseURI && DomUtil.testValidPath(resourceURL)) {
|
|
|
let stylesheetContent = await Download.getContent(resourceURL);
|
|
let stylesheetContent = await Download.getContent(resourceURL);
|
|
|
stylesheetContent = await DomProcessorHelper.resolveImportURLs(stylesheetContent, resourceURL);
|
|
stylesheetContent = await DomProcessorHelper.resolveImportURLs(stylesheetContent, resourceURL);
|
|
|
stylesheetContent = DomUtil.wrapMediaQuery(stylesheetContent, media);
|
|
stylesheetContent = DomUtil.wrapMediaQuery(stylesheetContent, media);
|
|
@@ -386,7 +384,7 @@ const SingleFileCore = (() => {
|
|
|
await Promise.all(urlFunctions.map(async urlFunction => {
|
|
await Promise.all(urlFunctions.map(async urlFunction => {
|
|
|
let resourceURL = DomUtil.matchURL(urlFunction);
|
|
let resourceURL = DomUtil.matchURL(urlFunction);
|
|
|
resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
|
- if (resourceURL && resourceURL != baseURI && !resourceURL.startsWith(DATA_URI_PREFIX)) {
|
|
|
|
|
|
|
+ if (resourceURL && resourceURL != baseURI && DomUtil.testValidPath(resourceURL)) {
|
|
|
const dataURI = await batchRequest.addURL(resourceURL);
|
|
const dataURI = await batchRequest.addURL(resourceURL);
|
|
|
stylesheetContent = stylesheetContent.replace(urlFunction, urlFunction.replace(resourceURL, dataURI));
|
|
stylesheetContent = stylesheetContent.replace(urlFunction, urlFunction.replace(resourceURL, dataURI));
|
|
|
}
|
|
}
|
|
@@ -399,7 +397,7 @@ const SingleFileCore = (() => {
|
|
|
let resourceURL = resourceElement.getAttribute(attributeName);
|
|
let resourceURL = resourceElement.getAttribute(attributeName);
|
|
|
if (resourceURL) {
|
|
if (resourceURL) {
|
|
|
resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
|
- if (resourceURL && resourceURL != baseURI && !resourceURL.startsWith(DATA_URI_PREFIX)) {
|
|
|
|
|
|
|
+ if (resourceURL && resourceURL != baseURI && DomUtil.testValidPath(resourceURL)) {
|
|
|
try {
|
|
try {
|
|
|
const dataURI = await batchRequest.addURL(new URL(resourceURL, baseURI).href);
|
|
const dataURI = await batchRequest.addURL(new URL(resourceURL, baseURI).href);
|
|
|
resourceElement.setAttribute(attributeName, dataURI);
|
|
resourceElement.setAttribute(attributeName, dataURI);
|
|
@@ -417,7 +415,7 @@ const SingleFileCore = (() => {
|
|
|
const srcSet = await Promise.all(attributeValue.split(",").map(async src => {
|
|
const srcSet = await Promise.all(attributeValue.split(",").map(async src => {
|
|
|
let [resourceURL, descriptor] = src.trim().split(/\s+/);
|
|
let [resourceURL, descriptor] = src.trim().split(/\s+/);
|
|
|
resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
resourceURL = DomUtil.normalizeURL(resourceURL);
|
|
|
- if (resourceURL && resourceURL != baseURI && !resourceURL.startsWith(DATA_URI_PREFIX)) {
|
|
|
|
|
|
|
+ if (resourceURL && resourceURL != baseURI && DomUtil.testValidPath(resourceURL)) {
|
|
|
try {
|
|
try {
|
|
|
const dataURI = await batchRequest.addURL(new URL(resourceURL, baseURI).href);
|
|
const dataURI = await batchRequest.addURL(new URL(resourceURL, baseURI).href);
|
|
|
return dataURI + (descriptor ? " " + descriptor : "");
|
|
return dataURI + (descriptor ? " " + descriptor : "");
|
|
@@ -434,6 +432,8 @@ const SingleFileCore = (() => {
|
|
|
// -------
|
|
// -------
|
|
|
// DomUtil
|
|
// DomUtil
|
|
|
// -------
|
|
// -------
|
|
|
|
|
+ const DATA_URI_PREFIX = "data:";
|
|
|
|
|
+ const BLOB_URI_PREFIX = "blob:";
|
|
|
const REGEXP_URL_FN = /(url\s*\(\s*'([^']*)'\s*\))|(url\s*\(\s*"([^"]*)"\s*\))|(url\s*\(\s*([^)]*)\s*\))/gi;
|
|
const REGEXP_URL_FN = /(url\s*\(\s*'([^']*)'\s*\))|(url\s*\(\s*"([^"]*)"\s*\))|(url\s*\(\s*([^)]*)\s*\))/gi;
|
|
|
const REGEXP_URL_SIMPLE_QUOTES_FN = /^url\s*\(\s*'([^']*)'\s*\)$/i;
|
|
const REGEXP_URL_SIMPLE_QUOTES_FN = /^url\s*\(\s*'([^']*)'\s*\)$/i;
|
|
|
const REGEXP_URL_DOUBLE_QUOTES_FN = /^url\s*\(\s*"([^"]*)"\s*\)$/i;
|
|
const REGEXP_URL_DOUBLE_QUOTES_FN = /^url\s*\(\s*"([^"]*)"\s*\)$/i;
|
|
@@ -466,6 +466,10 @@ const SingleFileCore = (() => {
|
|
|
return match && match[1];
|
|
return match && match[1];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ static testValidPath(resourceURL) {
|
|
|
|
|
+ return !resourceURL.startsWith(DATA_URI_PREFIX) && !resourceURL.startsWith(BLOB_URI_PREFIX);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
static matchImport(stylesheetContent) {
|
|
static matchImport(stylesheetContent) {
|
|
|
const match = stylesheetContent.match(REGEXP_IMPORT_URL_SIMPLE_QUOTES_FN) ||
|
|
const match = stylesheetContent.match(REGEXP_IMPORT_URL_SIMPLE_QUOTES_FN) ||
|
|
|
stylesheetContent.match(REGEXP_IMPORT_URL_DOUBLE_QUOTES_FN) ||
|
|
stylesheetContent.match(REGEXP_IMPORT_URL_DOUBLE_QUOTES_FN) ||
|