Skip to content
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

Remove i from style tag id #40

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/createUniqueIdentifiers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

module.exports = function createUniqueIdentifiers(identifiers) {
const dupeCount = {};

return identifiers.map((identifier) => {
if (typeof dupeCount[identifier] !== 'undefined') {
dupeCount[identifier] += 1;
} else {
dupeCount[identifier] = 0;
}

return dupeCount[identifier] === 0
? `${identifier}`
: `${identifier}_${dupeCount[identifier]}`;
});
};
8 changes: 8 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,20 @@ module.exports.pitch = function pitch(remainingRequest) {
}

const insertCssPath = path.join(__dirname, './insertCss.js');
const createUniqueIdentifiersPath = path.join(__dirname, './createUniqueIdentifiers.js');
let output = `
var content = require(${stringifyRequest(this, `!!${remainingRequest}`)});
var insertCss = require(${stringifyRequest(this, `!${insertCssPath}`)});
var createUniqueIdentifiers =
require(${stringifyRequest(this, `!${createUniqueIdentifiersPath}`)});

if (typeof content === 'string') {
content = [[module.id, content, '']];
} else {
var identifiers = content.map(x => x[0]);
createUniqueIdentifiers(identifiers).map((identifier, index) => {
content[index][0] = identifier;
})
}

module.exports = content.locals || {};
Expand Down
9 changes: 6 additions & 3 deletions src/insertCss.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

const prefix = 's';
const inserted = {};
let inserted = {};

// Base64 encoding and decoding - The "Unicode Problem"
// https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_Unicode_Problem
Expand Down Expand Up @@ -49,8 +49,7 @@ function insertCss(styles, options) {

const ids = [];
for (let i = 0; i < styles.length; i++) {
const [moduleId, css, media, sourceMap] = styles[i];
const id = `${moduleId}-${i}`;
const [id, css, media, sourceMap] = styles[i];

ids.push(id);

Expand Down Expand Up @@ -103,4 +102,8 @@ function insertCss(styles, options) {
return removeCss.bind(null, ids);
}

insertCss._clearCache = () => {
inserted = {};
};

module.exports = insertCss;
60 changes: 60 additions & 0 deletions test/createUniqueIdentifiersSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Isomorphic CSS style loader for Webpack
*
* Copyright © 2015-2016 Kriasoft, LLC. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE.txt file in the root directory of this source tree.
*/

import { expect } from 'chai';
import createUniqueIdentifiers from '../src/createUniqueIdentifiers';

const { describe, it } = global;

describe('createUniqueIdentifiers', () => {
describe('when all identifiers are unique', () => {
const identifiers = ['1', '23', '13'];

it('retains all identifiers', () => {
expect(createUniqueIdentifiers(identifiers)).to.deep.equal(identifiers);
});
});

describe('when some of the identifiers are non-unique', () => {
const identifiers = ['0', '12', '12', '23'];

it('makes non-unique identifiers unique', () => {
const uniqueIdentifiers = createUniqueIdentifiers(identifiers);
expect(uniqueIdentifiers[1]).to.not.equal(uniqueIdentifiers[2]);
});

it('retains unique identifiers', () => {
const uniqueIdentifiers = createUniqueIdentifiers(identifiers);
expect(uniqueIdentifiers[0]).to.equal(identifiers[0]);
expect(uniqueIdentifiers[3]).to.equal(identifiers[3]);
});
});


describe('when there are multiple groups of non-unique identifiers', () => {
const identifiers = ['12', '14', '12', '4', '800', '800', '801', '12'];

it('makes non-unique identifiers unique', () => {
const uniqueIdentifiers = createUniqueIdentifiers(identifiers);

expect(uniqueIdentifiers[0]).to.not.equal(uniqueIdentifiers[2]);
expect(uniqueIdentifiers[0]).to.not.equal(uniqueIdentifiers[7]);
expect(uniqueIdentifiers[2]).to.not.equal(uniqueIdentifiers[7]);

expect(uniqueIdentifiers[4]).to.not.equal(uniqueIdentifiers[5]);
});

it('retains unique identifiers', () => {
const uniqueIdentifiers = createUniqueIdentifiers(identifiers);
expect(uniqueIdentifiers[1]).to.equal(identifiers[1]);
expect(uniqueIdentifiers[3]).to.equal(identifiers[3]);
expect(uniqueIdentifiers[6]).to.equal(identifiers[6]);
});
});
});
76 changes: 54 additions & 22 deletions test/insertCssSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,69 @@
*/

import jsdom from 'jsdom';
import { describe, it } from 'mocha';
import { expect } from 'chai';
import insertCss from '../src/insertCss';

const { describe, it, beforeEach } = global;

global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = document.parentWindow;

const css1 = 'body { color: red; }';
const css2 = 'body { color: blue; }';

function getStyleTags() {
return global.document.getElementsByTagName('style');
}

describe('insertCss(styles, options)', () => {
it('Should insert and remove <style> element', () => {
const css = 'body { color: red; }';
const removeCss = insertCss([[1, css]]);
let style = global.document.getElementById('s1-0');
expect(style).to.be.ok;
expect(style.textContent).to.be.equal(css);
expect(removeCss).to.be.func;
removeCss();
style = global.document.getElementById('s1-0');
expect(style).to.be.null;
beforeEach(() => {
insertCss._clearCache();
const styles = global.document.getElementsByTagName('style');
for (const style of styles) {
style.parentElement.removeChild(style);
}
});

it('inserts a style element', () => {
insertCss([[1, css1]]);
const styleTags = getStyleTags();
expect(styleTags[0].textContent).to.equal(css1);
});

it('Should insert and remove multiple <style> elements for a single module', () => {
const css1 = 'body { color: red; }';
const css2 = 'body { color: blue; }';
const removeCss = insertCss([[1, css1], [1, css2]]);
let style = global.document.getElementsByTagName('style');
expect(style.length).to.be.equal(2);
expect(style[0].textContent).to.be.equal(css1);
expect(style[1].textContent).to.be.equal(css2);
expect(removeCss).to.be.func;
it('returns a function that removes the style element', () => {
const removeCss = insertCss([[1, css1]]);
expect(removeCss).to.be.a('function');
removeCss();
style = global.document.getElementsByTagName('style');
expect(style.length).to.be.equal(0);
const styleTags = getStyleTags();
expect(styleTags.length).to.equal(0);
});

describe('when a module is added a second time', () => {
it('does nothing', () => {
insertCss([[1, css1]]);
insertCss([[1, css2]]);
const styleTags = getStyleTags();
expect(styleTags.length).to.equal(1);
expect(styleTags[0].textContent).to.equal(css1);
});

describe('and options.replace is set to true', () => {
it('replaces the first module', () => {
insertCss([[1, css1]]);
insertCss([[1, css2]], { replace: true });
const styleTags = getStyleTags();
expect(styleTags.length).to.equal(1);
expect(styleTags[0].textContent).to.equal(css2);
});
});
});

describe('when a module is imported from multiple places', () => {
it('only inserts it once', () => {
insertCss([[2, css1]]);
insertCss([[1, css1], [2, css2]]);
expect(getStyleTags().length).to.equal(2);
});
});
});
2 changes: 1 addition & 1 deletion test/withStylesSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

/* eslint-disable react/prefer-stateless-function */

import { describe, it } from 'mocha';
import { expect } from 'chai';
import React, { createClass, Component } from 'react';
import withStyles from '../src/withStyles';

const { describe, it } = global;

describe('withStyles(ComposedComponent, ...styles)', () => {
class Passthrough extends Component {
Expand Down