Skip to content

Commit

Permalink
Merge pull request #256 from Khan/string-handlers-important
Browse files Browse the repository at this point in the history
Make String Handlers Use useImportant
  • Loading branch information
jeresig authored Jul 14, 2017
2 parents 12300db + 51b08e5 commit 8a5afdf
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 15 deletions.
12 changes: 9 additions & 3 deletions src/generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ export const generateCSS = (
const runStringHandlers = (
declarations /* : OrderedElements */,
stringHandlers /* : StringHandlers */,
selectorHandlers /* : SelectorHandler[] */
selectorHandlers /* : SelectorHandler[] */,
useImportant /* : boolean */
) /* : OrderedElements */ => {
if (!stringHandlers) {
return declarations;
Expand All @@ -219,7 +220,11 @@ const runStringHandlers = (
// handlers are very specialized and do complex things.
declarations.set(
key,
stringHandlers[key](declarations.get(key), selectorHandlers)
stringHandlers[key](
declarations.get(key),
selectorHandlers,
useImportant
)
);
}
}
Expand Down Expand Up @@ -276,7 +281,8 @@ export const generateCSSRuleset = (
selectorHandlers /* : SelectorHandler[] */
) /* : string */ => {
// Mutates declarations
runStringHandlers(declarations, stringHandlers, selectorHandlers);
runStringHandlers(declarations, stringHandlers, selectorHandlers,
useImportant);

const originalElements = {...declarations.elements};

Expand Down
16 changes: 10 additions & 6 deletions src/inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ const stringHandlers = {
// them as @font-face rules that we need to inject. The value of fontFamily
// can either be a string (as normal), an object (a single font face), or
// an array of objects and strings.
fontFamily: function fontFamily(val) {
fontFamily: function fontFamily(val, selectorHandlers, useImportant) {
if (Array.isArray(val)) {
return val.map(fontFamily).join(",");
return val.map((val) =>
fontFamily(val, selectorHandlers, useImportant)).join(",");
} else if (typeof val === "object") {
injectStyleOnce(val.src, "@font-face", [val], false);
injectStyleOnce(val.src, "@font-face", [val], useImportant);
return `"${val.fontFamily}"`;
} else {
return val;
Expand All @@ -91,7 +92,8 @@ const stringHandlers = {
// TODO(emily): `stringHandlers` doesn't let us rename the key, so I have
// to use `animationName` here. Improve that so we can call this
// `animation` instead of `animationName`.
animationName: function animationName(val, selectorHandlers) {
animationName: function animationName(val, selectorHandlers,
useImportant) {
if (Array.isArray(val)) {
return val.map(v => animationName(v, selectorHandlers)).join(",");
} else if (typeof val === "object") {
Expand All @@ -113,12 +115,14 @@ const stringHandlers = {
if (val instanceof OrderedElements) {
val.forEach((valVal, valKey) => {
finalVal += generateCSS(
valKey, [valVal], selectorHandlers, stringHandlers, false);
valKey, [valVal], selectorHandlers, stringHandlers,
useImportant);
});
} else {
Object.keys(val).forEach(key => {
finalVal += generateCSS(
key, [val[key]], selectorHandlers, stringHandlers, false);
key, [val[key]], selectorHandlers, stringHandlers,
useImportant);
});
}
finalVal += '}';
Expand Down
10 changes: 5 additions & 5 deletions tests/inject_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,8 @@ describe('String handlers', () => {
flushToStyleTag();

assertStylesInclude('font-family:"CoolFont",sans-serif !important');
assertStylesInclude('font-family:CoolFont;');
assertStylesInclude("src:url('coolfont.ttf');");
assertStylesInclude('font-family:CoolFont !important;');
assertStylesInclude("src:url('coolfont.ttf') !important;");
});
});

Expand Down Expand Up @@ -370,9 +370,9 @@ describe('String handlers', () => {
flushToStyleTag();

assertStylesInclude('@keyframes keyframe_tmjr6');
assertStylesInclude('from{left:10px;}');
assertStylesInclude('50%{left:20px;}');
assertStylesInclude('to{left:40px;}');
assertStylesInclude('from{left:10px !important;}');
assertStylesInclude('50%{left:20px !important;}');
assertStylesInclude('to{left:40px !important;}');
assertStylesInclude('animation-name:keyframe_tmjr6');
});

Expand Down
116 changes: 115 additions & 1 deletion tests/no-important_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
StyleSheet,
css
} from '../src/no-important.js';
import { reset } from '../src/inject.js';
import { reset, startBuffering, flushToStyleTag } from '../src/inject.js';

describe('css', () => {
beforeEach(() => {
Expand Down Expand Up @@ -39,3 +39,117 @@ describe('css', () => {
});
});
});

describe('String handlers with no !important', () => {
beforeEach(() => {
global.document = jsdom.jsdom();
reset();
});

afterEach(() => {
global.document.close();
global.document = undefined;
});

function assertStylesInclude(str) {
const styleTags = global.document.getElementsByTagName("style");
const styles = styleTags[0].textContent;

assert.include(styles, str);
}

describe('fontFamily', () => {
it('leaves plain strings alone', () => {
const sheet = StyleSheet.create({
base: {
fontFamily: "Helvetica",
},
});

startBuffering();
css(sheet.base);
flushToStyleTag();

assertStylesInclude('font-family:Helvetica');
});

it('concatenates arrays', () => {
const sheet = StyleSheet.create({
base: {
fontFamily: ["Helvetica", "sans-serif"],
},
});

startBuffering();
css(sheet.base);
flushToStyleTag();

assertStylesInclude('font-family:Helvetica,sans-serif');
});

it('adds @font-face rules for objects', () => {
const fontface = {
fontFamily: "CoolFont",
src: "url('coolfont.ttf')",
};

const sheet = StyleSheet.create({
base: {
fontFamily: [fontface, "sans-serif"],
},
});

startBuffering();
css(sheet.base);
flushToStyleTag();

assertStylesInclude('font-family:"CoolFont",sans-serif');
assertStylesInclude('font-family:CoolFont;');
assertStylesInclude("src:url('coolfont.ttf');");
});
});

describe('animationName', () => {
it('leaves plain strings alone', () => {
const sheet = StyleSheet.create({
animate: {
animationName: "boo",
},
});

startBuffering();
css(sheet.animate);
flushToStyleTag();

assertStylesInclude('animation-name:boo;');
});

it('generates css for keyframes', () => {
const sheet = StyleSheet.create({
animate: {
animationName: {
'from': {
left: 10,
},
'50%': {
left: 20,
},
'to': {
left: 40,
},
},
},
});

startBuffering();
css(sheet.animate);
flushToStyleTag();

assertStylesInclude('@keyframes keyframe_tmjr6');
assertStylesInclude('from{left:10px;}');
assertStylesInclude('50%{left:20px;}');
assertStylesInclude('to{left:40px;}');
assertStylesInclude('animation-name:keyframe_tmjr6');
});
});
});

0 comments on commit 8a5afdf

Please sign in to comment.