Skip to content

Commit

Permalink
feat: remove @import support per new behavior in Chrome
Browse files Browse the repository at this point in the history
>
> also update error messages and tests
  • Loading branch information
calebdwilliams committed Aug 19, 2020
1 parent e3b76a0 commit 8fa34a9
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 14 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ from the `element.adoptedStyleSheets` array. The behavior here is supposed to
emulate a `FrozenArray`, so modifying the array in question will have no effect
until the value is changed using a setter.

## A note about versioning

This packages doesn't necessarily follow semantic versioning. As the spec is still under consideration and implementation by browser vendors, the features supported by this package will change (generally following Chrome's implementation).
17 changes: 6 additions & 11 deletions src/ConstructStyleSheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import {
sheetMetadataRegistry,
state,
} from './shared';
import {instanceOfStyleSheet} from './utils';

const importPattern = /@import/;
import {instanceOfStyleSheet, rejectImports} from './utils';

const cssStyleSheetMethods = [
'addImport',
Expand Down Expand Up @@ -96,34 +94,31 @@ export default class ConstructStyleSheet {
}

replace(contents) {
const sanitized = rejectImports(contents);
return new Promise((resolve, reject) => {
if (sheetMetadataRegistry.has(this)) {
const {basicStyleElement} = sheetMetadataRegistry.get(this);

basicStyleElement.innerHTML = contents;
basicStyleElement.innerHTML = sanitized;
resolve(basicStyleElement.sheet);
updateAdopters(this);
} else {
reject(
new Error(
"Failed to execute 'replace' on 'CSSStyleSheet': Can't call replace on non-constructed CSSStyleSheets.",
"Can't call replace on non-constructed CSSStyleSheets.",
),
);
}
});
}

replaceSync(contents) {
if (importPattern.test(contents)) {
throw new Error(
'@import rules are not allowed when creating stylesheet synchronously',
);
}
const sanitized = rejectImports(contents);

if (sheetMetadataRegistry.has(this)) {
const {basicStyleElement} = sheetMetadataRegistry.get(this);

basicStyleElement.innerHTML = contents;
basicStyleElement.innerHTML = sanitized;
updateAdopters(this);

return basicStyleElement.sheet;
Expand Down
9 changes: 7 additions & 2 deletions src/adopt.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,20 @@ export function adoptStyleSheets(location) {

export function removeExcludedStyleSheets(location, oldSheets) {
const sheets = getAdoptedStyleSheet(location);

for (let i = 0, len = oldSheets.length; i < len; i++) {
if (sheets.indexOf(oldSheets[i]) > -1) {
continue;
}

const {adopters} = sheetMetadataRegistry.get(oldSheets[i]);
const observer = observerRegistry.get(location);
const styleElement = adopters.get(location);
let styleElement = adopters.get(location);

// In case the sheet was saved to document.head
// before the document was ready
if (!styleElement) {
styleElement = adopters.get(document.head);
}

observer.disconnect();
styleElement.parentNode.removeChild(styleElement);
Expand Down
16 changes: 16 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {adoptedSheetsRegistry, frame, OldCSSStyleSheet} from './shared';

const importPattern = /@import\surl(.*?);/gi;

export function instanceOfStyleSheet(instance) {
return (
instance instanceof OldCSSStyleSheet ||
Expand Down Expand Up @@ -41,3 +43,17 @@ export function getAdoptedStyleSheet(location) {
: location,
);
}

export function rejectImports(contents) {
const imports = contents.match(importPattern, '') || [];
let sheetContent = contents;
if (imports.length) {
console.warn(
'@import rules are not allowed here. See https://github.com/WICG/construct-stylesheets/issues/119#issuecomment-588352418'
);
imports.forEach(_import => {
sheetContent = sheetContent.replace(_import, '');
});
}
return sheetContent;
}
2 changes: 1 addition & 1 deletion test/polyfill.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ describe('Constructible Style Sheets polyfill', () => {
.replace('.only-test { color: blue; }')
.catch(error => {
expect(error.message).toBe(
"Failed to execute 'replace' on 'CSSStyleSheet': Can't call replace on non-constructed CSSStyleSheets.",
"Can't call replace on non-constructed CSSStyleSheets.",
);
});
});
Expand Down

0 comments on commit 8fa34a9

Please sign in to comment.