Skip to content

Commit 25e8e89

Browse files
Tobias Zucalimichael-ciniawsky
authored andcommitted
feat: add support for iframes (options.insertInto) (#248)
1 parent 69e718b commit 25e8e89

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,8 @@ By default, the style-loader appends `<style>` elements to the end of the style
286286
```
287287

288288
### `insertInto`
289-
By default, the style-loader inserts the `<style>` elements into the `<head>` tag of the page. If you want the tags to be inserted somewhere else, e.g. into a [ShadowRoot](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot), you can specify a CSS selector for that element here, e.g
289+
By default, the style-loader inserts the `<style>` elements into the `<head>` tag of the page. If you want the tags to be inserted somewhere else you can specify a CSS selector for that element here. If you target an [IFrame](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement) make sure you have sufficient access rights, the styles will be injected into the content document head.
290+
You can also insert the styles into a [ShadowRoot](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot), e.g
290291

291292
**webpack.config.js**
292293
```js

lib/addStyles.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,19 @@ var getElement = (function (fn) {
2828

2929
return function(selector) {
3030
if (typeof memo[selector] === "undefined") {
31-
memo[selector] = fn.call(this, selector);
31+
var styleTarget = fn.call(this, selector);
32+
// Special case to return head of iframe instead of iframe itself
33+
if (styleTarget instanceof window.HTMLIFrameElement) {
34+
try {
35+
// This will throw an exception if access to iframe is blocked
36+
// due to cross-origin restrictions
37+
styleTarget = styleTarget.contentDocument.head;
38+
} catch(e) {
39+
styleTarget = null;
40+
}
41+
}
42+
memo[selector] = styleTarget;
3243
}
33-
3444
return memo[selector]
3545
};
3646
})(function (target) {

test/basicTest.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ describe("basic tests", function() {
3131
"<div class='target'>",
3232
checkValue,
3333
"</div>",
34+
"<iframe class='iframeTarget'/>",
3435
"</body>",
3536
"</html>"
3637
].join("\n");
@@ -103,6 +104,17 @@ describe("basic tests", function() {
103104
runCompilerTest(expected, done, undefined, selector);
104105
}); // it insert into
105106

107+
it("insert into iframe", function(done) {
108+
let selector = "iframe.iframeTarget";
109+
styleLoaderOptions.insertInto = selector;
110+
111+
let expected = requiredStyle;
112+
113+
runCompilerTest(expected, done, function() {
114+
return this.document.querySelector(selector).contentDocument.head.innerHTML;
115+
}, selector);
116+
}); // it insert into
117+
106118
it("singleton", function(done) {
107119
// Setup
108120
styleLoaderOptions.singleton = true;

0 commit comments

Comments
 (0)