Skip to content

Commit

Permalink
feat: support 'before' insertions (options.insertAt) (#253)
Browse files Browse the repository at this point in the history
  • Loading branch information
iancw authored and michael-ciniawsky committed Sep 8, 2017
1 parent a2ae3ac commit 67120f8
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 4 deletions.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ Styles are not added on `import/require()`, but instead on call to `use`/`ref`.
|**`base`** |`{Number}`|`true`|Set module ID base (DLLPlugin)|
|**`attrs`**|`{Object}`|`{}`|Add custom attrs to `<style></style>`|
|**`transform`** |`{Function}`|`false`|Transform/Conditionally load CSS by passing a transform/condition function|
|**`insertAt`**|`{String}`|`bottom`|Inserts `<style></style>` at the given position|
|**`insertAt`**|`{String\|Object}`|`bottom`|Inserts `<style></style>` at the given position|
|**`insertInto`**|`{String}`|`<head>`|Inserts `<style></style>` into the given position|
|**`sourceMap`**|`{Boolean}`|`false`|Enable/Disable Sourcemaps|
|**`convertToAbsoluteUrls`**|`{Boolean}`|`false`|Converts relative URLs to absolute urls, when source maps are enabled|
Expand Down Expand Up @@ -285,6 +285,20 @@ By default, the style-loader appends `<style>` elements to the end of the style
}
```

A new `<style>` element can be inserted before a specific element by passing an object, e.g.

**webpack.config.js**
```js
{
loader: 'style-loader'
options: {
insertAt: {
before: '#id'
}
}
}
```

### `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 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.
You can also insert the styles into a [ShadowRoot](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot), e.g
Expand Down
5 changes: 4 additions & 1 deletion lib/addStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,11 @@ function insertStyleElement (options, style) {
stylesInsertedAtTop.push(style);
} else if (options.insertAt === "bottom") {
target.appendChild(style);
} else if (typeof options.insertAt === "object" && options.insertAt.before) {
var nextSibling = getElement(options.insertInto + " " + options.insertAt.before);
target.insertBefore(style, nextSibling);
} else {
throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n");
}
}

Expand Down
2 changes: 1 addition & 1 deletion options.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"type": "object"
},
"insertAt": {
"type": "string"
"type": ["string", "object"]
},
"insertInto": {
"type": "string"
Expand Down
22 changes: 21 additions & 1 deletion test/basicTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe("basic tests", function() {
}
`,
requiredStyle = `<style type="text/css">${requiredCss}</style>`,
existingStyle = "<style>.existing { color: yellow }</style>",
existingStyle = `<style id="existing-style">.existing { color: yellow }</style>`,
checkValue = '<div class="check">check</div>',
rootDir = path.resolve(__dirname + "/../") + "/",
jsdomHtml = [
Expand Down Expand Up @@ -95,6 +95,26 @@ describe("basic tests", function() {
runCompilerTest(expected, done);
}); // it insert at top

it("insert at before", function(done) {
styleLoaderOptions.insertAt = {
before: "#existing-style"
};

let expected = [requiredStyle, existingStyle].join("");

runCompilerTest(expected, done);
}); // it insert at before

it("insert at before invalid selector", function(done) {
styleLoaderOptions.insertAt = {
before: "#missing"
};

let expected = [existingStyle, requiredStyle].join("\n");

runCompilerTest(expected, done);
}); // it insert at before

it("insert into", function(done) {
let selector = "div.target";
styleLoaderOptions.insertInto = selector;
Expand Down

0 comments on commit 67120f8

Please sign in to comment.