diff --git a/.eslintrc b/.eslintrc
index e2728a18a1d..e396864f776 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -26,8 +26,8 @@
clearTimeout: true,
setInterval: true,
clearInterval: true,
+ CSSStyleSheet: true,
Blob: true,
- cvox: true,
alert: true,
prompt: true,
XMLHttpRequest: true,
diff --git a/demo/csp-simple.html b/demo/csp-simple.html
new file mode 100644
index 00000000000..e1d66f7cabd
--- /dev/null
+++ b/demo/csp-simple.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ Editor
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/csp.html b/demo/csp.html
index a03f0fcae37..77f08a2ebf8 100644
--- a/demo/csp.html
+++ b/demo/csp.html
@@ -6,7 +6,7 @@
Editor
diff --git a/src/ace_test.js b/src/ace_test.js
index 2f1921fe1cf..6552245f758 100644
--- a/src/ace_test.js
+++ b/src/ace_test.js
@@ -89,7 +89,9 @@ module.exports = {
"test: useStrictCSP": function() {
ace.config.set("useStrictCSP", undefined);
function getStyleNode() {
- return document.getElementById("test.css");
+ return document.adoptedStyleSheets ?
+ document.adoptedStyleSheets.find(sheet => sheet.$id === "test.css") :
+ document.getElementById("test.css");
}
assert.ok(!getStyleNode());
dom.importCssString("test{}", "test.css", false);
@@ -170,6 +172,26 @@ module.exports = {
var editor = ace.edit(el);
assert.equal(editor.container, el);
editor.destroy();
+ },
+ "test: use adoptedStyleSheets": function() {
+ dom.$resetCssModeForTests();
+ var div = document.createElement("div");
+ div.adoptedStyleSheets = [];
+ div.getRootNode = function() {
+ return div;
+ };
+ if (!window.CSSStyleSheet) {
+ window.CSSStyleSheet = function() {
+ this.cssRules = [];
+ this.replaceSync = function() {};
+ };
+ }
+
+ var editor = ace.edit(div);
+ console.log(div.adoptedStyleSheets);
+
+ editor.destroy();
+ dom.$resetCssModeForTests();
}
};
diff --git a/src/lib/dom.js b/src/lib/dom.js
index a83b0a6f3bf..350cbfbeab5 100644
--- a/src/lib/dom.js
+++ b/src/lib/dom.js
@@ -271,17 +271,48 @@ function importCssString(cssText, id, target) {
if (id)
cssText += "\n/*# sourceURL=ace/css/" + id + " */";
+ if (!USE_STYLE_TAG) {
+ try {
+ var stylesheet = styles[id];
+ if (!stylesheet) {
+ stylesheet = styles[id] = new CSSStyleSheet();
+ stylesheet.$id = id;
+ stylesheet.replaceSync(cssText);
+ }
+ container.adoptedStyleSheets.push(stylesheet);
+ USE_STYLE_TAG = false;
+ return;
+ } catch(e) {
+ if (USE_STYLE_TAG === null) {
+ USE_STYLE_TAG = true;
+ } else {
+ setTimeout(function() {
+ throw e;
+ });
+ }
+ }
+ }
+
var style = exports.createElement("style");
style.appendChild(doc.createTextNode(cssText));
if (id)
style.id = id;
-
if (container == doc)
container = exports.getDocumentHead(doc);
container.insertBefore(style, container.firstChild);
}
+var USE_STYLE_TAG = null;
+var styles = Object.create(null);
+
exports.importCssString = importCssString;
+exports.$resetCssModeForTests = function(useStyleTag) {
+ USE_STYLE_TAG = useStyleTag == undefined ? null : useStyleTag;
+ styles = Object.create(null);
+ strictCSP = undefined;
+ cssCache = [];
+};
+
/**
* @param {string} uri
* @param {Document} [doc]