always `loadScript` with a script tag (#6411)
to avoid Content Security Policy unsafe-line violations
This commit is contained in:
parent
38b48997fc
commit
373d6e3fe6
|
@ -1,8 +1,6 @@
|
|||
import loadScript from "discourse/lib/load-script";
|
||||
import { observes } from "ember-addons/ember-computed-decorators";
|
||||
|
||||
const LOAD_ASYNC = !Ember.testing;
|
||||
|
||||
export default Ember.Component.extend({
|
||||
mode: "css",
|
||||
classNames: ["ace-wrapper"],
|
||||
|
@ -26,7 +24,7 @@ export default Ember.Component.extend({
|
|||
|
||||
@observes("mode")
|
||||
modeChanged() {
|
||||
if (LOAD_ASYNC && this._editor && !this._skipContentChangeEvent) {
|
||||
if (this._editor && !this._skipContentChangeEvent) {
|
||||
this._editor.getSession().setMode("ace/mode/" + this.get("mode"));
|
||||
}
|
||||
},
|
||||
|
@ -71,21 +69,17 @@ export default Ember.Component.extend({
|
|||
didInsertElement() {
|
||||
this._super();
|
||||
|
||||
loadScript("/javascripts/ace/ace.js", { scriptTag: true }).then(() => {
|
||||
loadScript("/javascripts/ace/ace.js").then(() => {
|
||||
window.ace.require(["ace/ace"], loadedAce => {
|
||||
if (!this.element || this.isDestroying || this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
const editor = loadedAce.edit(this.$(".ace")[0]);
|
||||
|
||||
if (LOAD_ASYNC) {
|
||||
editor.setTheme("ace/theme/chrome");
|
||||
}
|
||||
editor.setTheme("ace/theme/chrome");
|
||||
editor.setShowPrintMargin(false);
|
||||
editor.setOptions({ fontSize: "14px" });
|
||||
if (LOAD_ASYNC) {
|
||||
editor.getSession().setMode("ace/mode/" + this.get("mode"));
|
||||
}
|
||||
editor.getSession().setMode("ace/mode/" + this.get("mode"));
|
||||
editor.on("change", () => {
|
||||
this._skipContentChangeEvent = true;
|
||||
this.set("content", editor.getSession().getValue());
|
||||
|
|
|
@ -44,7 +44,7 @@ export default function loadScript(url, opts) {
|
|||
$("script").each((i, tag) => {
|
||||
const src = tag.getAttribute("src");
|
||||
|
||||
if (src && (opts.scriptTag || src !== url)) {
|
||||
if (src && src !== url) {
|
||||
_loaded[tag.getAttribute("src")] = true;
|
||||
}
|
||||
});
|
||||
|
@ -86,22 +86,15 @@ export default function loadScript(url, opts) {
|
|||
cdnUrl = Discourse.CDN.replace(/\/$/, "") + url;
|
||||
}
|
||||
|
||||
// Some javascript depends on the path of where it is loaded (ace editor)
|
||||
// to dynamically load more JS. In that case, add the `scriptTag: true`
|
||||
// option.
|
||||
if (opts.scriptTag) {
|
||||
if (Ember.testing) {
|
||||
throw new Error(
|
||||
`In test mode scripts cannot be loaded async ${cdnUrl}`
|
||||
);
|
||||
}
|
||||
loadWithTag(cdnUrl, cb);
|
||||
} else {
|
||||
if (opts.css) {
|
||||
ajax({
|
||||
url: cdnUrl,
|
||||
dataType: opts.css ? "text" : "script",
|
||||
dataType: "text",
|
||||
cache: true
|
||||
}).then(cb);
|
||||
} else {
|
||||
// Always load JavaScript with script tag to avoid Content Security Policy inline violations
|
||||
loadWithTag(cdnUrl, cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import loadScript from "discourse/lib/load-script";
|
||||
|
||||
QUnit.module("lib:load-script");
|
||||
|
||||
QUnit.test(
|
||||
"load with a script tag, and callbacks are only executed after script is loaded",
|
||||
async assert => {
|
||||
const src = "/javascripts/ace/ace.js";
|
||||
|
||||
await loadScript(src).then(() => {
|
||||
assert.ok(
|
||||
typeof ace !== "undefined",
|
||||
"callbacks should only be executed after the script has fully loaded"
|
||||
);
|
||||
|
||||
// cannot use the `find` test helper here because the script tag is injected outside of the test sandbox frame
|
||||
const scriptTags = Array.from(document.getElementsByTagName("script"));
|
||||
assert.ok(
|
||||
scriptTags.some(scriptTag => scriptTag.src.includes(src)),
|
||||
"the script should be loaded with a script tag"
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
|
@ -52,7 +52,6 @@ window.MessageBus.stop();
|
|||
|
||||
// Trick JSHint into allow document.write
|
||||
var d = document;
|
||||
d.write('<script src="/javascripts/ace/ace.js"></script>');
|
||||
d.write(
|
||||
'<div id="ember-testing-container"><div id="ember-testing"></div></div>'
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue