diff --git a/README.md b/README.md index e7e7bec2..a35fac12 100644 --- a/README.md +++ b/README.md @@ -540,6 +540,46 @@ module.exports = { Insert styles at top of `head` tag. +You can pass any parameters to `style.use(anythingHere)` and this value will be passed to `insert` function. These options will be passed to `styleTagTransform` function too. + +**webpack.config.js** + +```js +module.exports = { + module: { + rules: [ + { + test: /\.css$/i, + use: [ + { + loader: "style-loader", + options: { + insert: function insertIntoTarget(element, options) { + var parent = options.target || document.querySelector("head"); + parent.appendChild(element); + }, + }, + }, + "css-loader", + ], + }, + ], + }, +}; +``` + +Insert styles to the provided element or to the `head` tag if target isn't provided. Now you can inject styles into Shadow DOM (or any other element). + +**component.js** + +```js +import style from "./file.css"; + +style.use({ + target: document.querySelector('#myShadowDom').shadowRoot, +}) +``` + ### `styleTagTransform` Type: `String | Function` diff --git a/src/index.js b/src/index.js index 5f3c0711..f0db579c 100644 --- a/src/index.js +++ b/src/index.js @@ -125,7 +125,8 @@ ${getInsertOptionCode(insertType, options)} options.domAPI = ${getdomAPI(isAuto)}; options.insertStyleElement = insertStyleElement; -exported.use = function() { +exported.use = function(insertOptions) { + options.insertOptions = insertOptions; if (!(refs++)) { update = API(content, options); } diff --git a/src/runtime/insertStyleElement.js b/src/runtime/insertStyleElement.js index 62199710..5295e18e 100644 --- a/src/runtime/insertStyleElement.js +++ b/src/runtime/insertStyleElement.js @@ -4,7 +4,7 @@ function insertStyleElement(options) { options.setAttributes(style, options.attributes); - options.insert(style); + options.insert(style, options.insertOptions); return style; } diff --git a/src/runtime/styleDomAPI.js b/src/runtime/styleDomAPI.js index fe3eb9fb..a9e2612d 100644 --- a/src/runtime/styleDomAPI.js +++ b/src/runtime/styleDomAPI.js @@ -18,7 +18,7 @@ function apply(style, options, obj) { // For old IE /* istanbul ignore if */ - options.styleTagTransform(css, style); + options.styleTagTransform(css, style, options.insertOptions); } function removeStyleElement(style) { diff --git a/test/fixtures/lazy-insertOptions.js b/test/fixtures/lazy-insertOptions.js new file mode 100644 index 00000000..e4aea6d2 --- /dev/null +++ b/test/fixtures/lazy-insertOptions.js @@ -0,0 +1,7 @@ +import style from './style.css'; + +style.use({ + insertInto: document.body, + additionalStyles: '.some-element {color: red;}' +}); + diff --git a/test/lazyStyleTag-insertOptions.test.js b/test/lazyStyleTag-insertOptions.test.js new file mode 100644 index 00000000..53809d7c --- /dev/null +++ b/test/lazyStyleTag-insertOptions.test.js @@ -0,0 +1,53 @@ +/* eslint-env browser */ + +import { + compile, + getCompiler, + getEntryByInjectType, + getErrors, + getWarnings, + runInJsDom, +} from "./helpers/index"; + +describe('lazyStyleTag insertOptions', () => { + it(`should pass "insertOption" to "insert" function`, async () => { + expect.assertions(3); + + const entry = getEntryByInjectType("insertOptions.js", 'lazyStyleTag'); + const compiler = getCompiler(entry, { + injectType: 'lazyStyleTag', + insert: (styleTag, options) => { + options.insertInto.appendChild(styleTag); + } + }); + const stats = await compile(compiler); + + runInJsDom("main.bundle.js", compiler, stats, (dom) => { + expect(dom.serialize()).toMatchSnapshot("DOM"); + }); + + expect(getWarnings(stats)).toMatchSnapshot("warnings"); + expect(getErrors(stats)).toMatchSnapshot("errors"); + }); + + it(`should pass "insertOption" to "styleTagTransform" function`, async () => { + expect.assertions(3); + + const entry = getEntryByInjectType("insertOptions.js", 'lazyStyleTag'); + const compiler = getCompiler(entry, { + injectType: 'lazyStyleTag', + styleTagTransform: (css, styleTag, options) => { + // eslint-disable-next-line no-param-reassign + styleTag.innerHTML = `${css}.${options.additionalStyles}\n`; + } + }); + const stats = await compile(compiler); + + runInJsDom("main.bundle.js", compiler, stats, (dom) => { + expect(dom.serialize()).toMatchSnapshot("DOM"); + }); + + expect(getWarnings(stats)).toMatchSnapshot("warnings"); + expect(getErrors(stats)).toMatchSnapshot("errors"); + }); +});