-
-
Notifications
You must be signed in to change notification settings - Fork 470
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add support for iframes (options.insertInto
)
#248
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
test/basicTest.js
Outdated
let expected = 'requiredStyle '; | ||
|
||
runCompilerTest(expected, done, function() { | ||
return this.document.querySelector(selector).contentDocument.head.innerHTML; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this.document
and not just document
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, I can improve that ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it works without the this
prefix, better ditch it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
)
lib/addStyles.js
Outdated
@@ -28,9 +28,19 @@ var getElement = (function (fn) { | |||
|
|||
return function(selector) { | |||
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/s/insetead/instead
lib/addStyles.js
Outdated
// noop | ||
}; | ||
} | ||
result = options.transform(obj.css); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this formatting fix is needed. Any thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
lib/addStyles.js
Outdated
return function() { | ||
// noop | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
lib/addStyles.js
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
README.md
Outdated
@@ -286,7 +286,8 @@ By default, the style-loader appends `<style>` elements to the end of the style | |||
``` | |||
|
|||
### `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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iframe
=> [IFrame](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tobias-zucali Thx
When will this feature be published in npm repo? |
What kind of change does this PR introduce?
insertInto
settingDid 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