Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: webpack-contrib/style-loader
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.22.1
Choose a base ref
...
head repository: webpack-contrib/style-loader
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.23.0
Choose a head ref
  • 2 commits
  • 5 files changed
  • 2 contributors

Commits on Aug 27, 2018

  1. Copy the full SHA
    2588aca View commit details
  2. Copy the full SHA
    da83a28 View commit details
Showing with 154 additions and 21 deletions.
  1. +10 −0 CHANGELOG.md
  2. +1 −1 package-lock.json
  3. +1 −1 package.json
  4. +124 −18 test/useable.test.js
  5. +18 −1 useable.js
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,16 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

<a name="0.23.0"></a>
# [0.23.0](https://github.com/webpack-contrib/style-loader/compare/v0.22.1...v0.23.0) (2018-08-27)


### Features

* **useable:** add `insertInto` support (`options.insertInto`) ([#341](https://github.com/webpack-contrib/style-loader/issues/341)) ([2588aca](https://github.com/webpack-contrib/style-loader/commit/2588aca))



<a name="0.22.1"></a>
## [0.22.1](https://github.com/webpack-contrib/style-loader/compare/v0.22.0...v0.22.1) (2018-08-08)

2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "style-loader",
"version": "0.22.1",
"version": "0.23.0",
"author": "Tobias Koppers @sokra",
"description": "style loader module for webpack",
"engines": {
142 changes: 124 additions & 18 deletions test/useable.test.js
Original file line number Diff line number Diff line change
@@ -8,30 +8,136 @@ var loaderUtils = require('loader-utils');
var useable = require("../useable");

describe("useable tests", function () {
var sandbox = sinon.sandbox.create();
var getOptions;
describe('hmr', function () {
var sandbox = sinon.sandbox.create();
var getOptions;

beforeEach(() => {
// Mock loaderUtils to override options
getOptions = sandbox.stub(loaderUtils, 'getOptions');
});
beforeEach(() => {
// Mock loaderUtils to override options
getOptions = sandbox.stub(loaderUtils, 'getOptions');
});

afterEach(() => {
sandbox.restore();
});
afterEach(() => {
sandbox.restore();
});

it("should output HMR code by default", function () {
assert.equal(/(module\.hot)/g.test(useable.pitch()), true);
});
it("should output HMR code by default", function () {
assert.equal(/(module\.hot)/g.test(useable.pitch()), true);
});

it("should NOT output HMR code when options.hmr is false", function () {
getOptions.returns({hmr: false});
assert.equal(/(module\.hot)/g.test(useable.pitch()), false);
it("should NOT output HMR code when options.hmr is false", function () {
getOptions.returns({hmr: false});
assert.equal(/(module\.hot)/g.test(useable.pitch()), false);
});

it("should output HMR code when options.hmr is true", function () {
getOptions.returns({hmr: true});
assert.equal(/(module\.hot)/g.test(useable.pitch()), true);
});
});

it("should output HMR code when options.hmr is true", function () {
getOptions.returns({hmr: true});
assert.equal(/(module\.hot)/g.test(useable.pitch()), true);
describe('insert into', function () {
var path = require("path");

var utils = require("./utils"),
runCompilerTest = utils.runCompilerTest;

var fs;

var requiredCss = ".required { color: blue }",
requiredCssTwo = ".requiredTwo { color: cyan }",
localScopedCss = ":local(.className) { background: red; }",
localComposingCss = `
:local(.composingClass) {
composes: className from './localScoped.css';
color: blue;
}
`,
requiredStyle = `<style type="text/css">${requiredCss}</style>`,
existingStyle = `<style id="existing-style">.existing { color: yellow }</style>`,
checkValue = '<div class="check">check</div>',
rootDir = path.resolve(__dirname + "/../") + "/",
jsdomHtml = [
"<html>",
"<head id='head'>",
existingStyle,
"</head>",
"<body>",
"<div class='target'>",
checkValue,
"</div>",
"<iframe class='iframeTarget'/>",
"</body>",
"</html>"
].join("\n"),
requiredJS = [
"var el = document.createElement('div');",
"el.id = \"test-shadow\";",
"document.body.appendChild(el)",
"var css = require('./style.css');",
"css.use();",
].join("\n");

var styleLoaderOptions = {};
var cssRule = {};

var defaultCssRule = {
test: /\.css?$/,
use: [
{
loader: "style-loader/useable",
options: styleLoaderOptions
},
"css-loader"
]
};

var webpackConfig = {
entry: "./main.js",
output: {
filename: "bundle.js"
},
module: {
rules: [cssRule]
}
};

var setupWebpackConfig = function() {
fs = utils.setup(webpackConfig, jsdomHtml);

// Create a tiny file system. rootDir is used because loaders are referring to absolute paths.
fs.mkdirpSync(rootDir);
fs.writeFileSync(rootDir + "main.js", requiredJS);
fs.writeFileSync(rootDir + "style.css", requiredCss);
fs.writeFileSync(rootDir + "styleTwo.css", requiredCssTwo);
fs.writeFileSync(rootDir + "localScoped.css", localScopedCss);
fs.writeFileSync(rootDir + "localComposing.css", localComposingCss);
};

beforeEach(function() {
// Reset all style-loader options
for (var member in styleLoaderOptions) {
delete styleLoaderOptions[member];
}

for (var member in defaultCssRule) {
cssRule[member] = defaultCssRule[member];
}

setupWebpackConfig();
}); // before each

it("insert into iframe", function(done) {
let selector = "iframe.iframeTarget";
styleLoaderOptions.insertInto = selector;

let expected = requiredStyle;

runCompilerTest(expected, done, function() {
return this.document.querySelector(selector).contentDocument.head.innerHTML;
}, selector);
}); // it insert into

});

});
19 changes: 18 additions & 1 deletion useable.js
Original file line number Diff line number Diff line change
@@ -18,6 +18,21 @@ module.exports.pitch = function (request) {

options.hmr = typeof options.hmr === 'undefined' ? true : options.hmr;

// The variable is needed, because the function should be inlined.
// If is just stored it in options, JSON.stringify will quote
// the function and it would be just a string at runtime
var insertInto;

if (typeof options.insertInto === "function") {
insertInto = options.insertInto.toString();
}

// We need to check if it a string, or variable will be "undefined"
// and the loader crashes
if (typeof options.insertInto === "string") {
insertInto = '"' + options.insertInto + '"';
}

var hmr = [
// Hot Module Replacement
"if(module.hot) {",
@@ -48,14 +63,16 @@ module.exports.pitch = function (request) {
"var refs = 0;",
"var dispose;",
"var content = require(" + loaderUtils.stringifyRequest(this, "!!" + request) + ");",
"var options = " + JSON.stringify(options) + ";",
"options.insertInto = " + insertInto + ";",
"",
"if(typeof content === 'string') content = [[module.id, content, '']];",
// Export CSS Modules
"if(content.locals) exports.locals = content.locals;",
"",
"exports.use = exports.ref = function() {",
" if(!(refs++)) {",
" dispose = require(" + loaderUtils.stringifyRequest(this, "!" + path.join(__dirname, "lib", "addStyles.js")) + ")(content, " + JSON.stringify(options) + ");",
" dispose = require(" + loaderUtils.stringifyRequest(this, "!" + path.join(__dirname, "lib", "addStyles.js")) + ")(content, options);",
" }",
"",
" return exports;",