feat: add support for iframes (options.insertInto)#248
Conversation
- add possibility to target an iframe with the `insertInto` setting - select head in the iframes content document - use try/catch to avoid breakting the code if permission is denied - add unit test - extend documentation
| let expected = 'requiredStyle '; | ||
|
|
||
| runCompilerTest(expected, done, function() { | ||
| return this.document.querySelector(selector).contentDocument.head.innerHTML; |
There was a problem hiding this comment.
Why this.document and not just document ?
There was a problem hiding this comment.
True, I can improve that ;-)
There was a problem hiding this comment.
If it works without the this prefix, better ditch it :)
There was a problem hiding this comment.
this is needed. Seems that the test is run in node or so… but scope is explicitly set to window, that's why this works.
options.insertInto)
| if (typeof memo[selector] === "undefined") { | ||
| memo[selector] = fn.call(this, selector); | ||
| var styleTarget = fn.call(this, selector); | ||
| // Special case to return head of iframe insetead of iframe itself |
| // noop | ||
| }; | ||
| } | ||
| result = options.transform(obj.css); |
There was a problem hiding this comment.
I'm not sure if this formatting fix is needed. Any thoughts?
There was a problem hiding this comment.
Was working too fast ;-) was mixed blanks with tabs, but the automatic conversion choose the wrong indent level. Should I fix the indentation level or revert it to mixed blanks/tabs?
There was a problem hiding this comment.
I though it is github display madness with tabs tbh (I will send a style PR converting to spaces 😛).
But in case it's not @tobias-zucali please use the indent the rest of the code currently uses.
|
Fixes #213 |
| return function() { | ||
| // noop | ||
| }; | ||
| } |
There was a problem hiding this comment.
Can you shift this block back, no reason for this to show up in the diff as there are not code changes less what looks like an auto-format.
| var styleTarget = fn.call(this, selector); | ||
| // Special case to return head of iframe instead of iframe itself | ||
| try { | ||
| if (styleTarget instanceof window.HTMLIFrameElement) { |
There was a problem hiding this comment.
Do it not make more sense to check instanceof first? As it stands right now, we are going to execute that try/catch block every time regardless. When in reality, it only needs to execute if styleTarget instanceof window.HTMLIFrameElement
There was a problem hiding this comment.
I was not sure in which environments style-loader can be run … is it possible that window.HTMLIFrameElement does not exist there?
There was a problem hiding this comment.
My point was more that a truthy check is faster than executing a try catch iirc. Given the style loader chain already suffers from performance issues at scale, we need to be efficient when and wherever possible.
//cc @bebraw @michael-ciniawsky
If there are concerns about different execution contexts, we could check window along with that or in a higher scope and it should still be faster. Though historically, our stance on style-loader is that it's intended to load styles into the DOM & to use something like extract-text when you are outside the browser.
There was a problem hiding this comment.
Yep, style-loader should only support environments which expose/mimic a DOM Interface, the tests already use JSDOM which is the primary non-browser target style-loader supports atm. @tobias-zucali Could you try without the try/catch and instanceof check and see if it works ? Maybe add a comment with the current solution in case it heavily breaks other people's setups and we need a hotfix :). Otherwise good to go imho
|
|
||
| ### `insertInto` | ||
| 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 | ||
| 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 make sure you have sufficient access rights, the styles will be injected into the content document head. |
There was a problem hiding this comment.
iframe => [IFrame](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement)
michael-ciniawsky
left a comment
There was a problem hiding this comment.
@tobias-zucali Thx
|
When will this feature be published in npm repo? |
What kind of change does this PR introduce?
insertIntosettingDid you add tests for your changes?
Yes.
If relevant, did you update the README?
Yes.
Summary
Pull request for open issue insertInto for iframes #213
Does this PR introduce a breaking change?
No.
Other information
Closes #213