Skip to content

Instantly share code, notes, and snippets.

@zbjornson
Created May 24, 2017 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zbjornson/0332f8d9d92641d546c84404ae0c1d37 to your computer and use it in GitHub Desktop.
Save zbjornson/0332f8d9d92641d546c84404ae0c1d37 to your computer and use it in GitHub Desktop.
Styler utility
/**
* Tool to change styles with dynamic CSS. Use instead of setting style
* properties on individual elements.
*/
function Styler() {
this.styleEl = document.createElement("style");
document.head.appendChild(this.styleEl);
// Map for quickly looking up an existing rule by its selector.
this.ruleMap = new Map();
}
/**
* Sets a property to a value for a selector.
* @param CSS selector, e.g. ".classname"
* @param camelCased property, e.g. "marginTop"
* @param value, e.g. "10px"
*/
Styler.prototype.setRule = function setRule(selector, prop, value) {
var ruleMap = this.ruleMap;
if (ruleMap.has(selector)) {
ruleMap.get(selector).style[prop] = value;
} else {
var strval = `${selector} { }`;
this.styleEl.sheet.insertRule(strval, 0);
var rule = this.styleEl.sheet.cssRules[0];
ruleMap.set(selector, rule);
rule.style[prop] = value;
}
};
/**
* Unsets a value for a selector.
* @param CSS selector, e.g. ".classname"
* @param camelCased property, e.g. "marginTop"
*/
Styler.prototype.unsetRule = function unsetRule(selector, prop) {
if (this.ruleMap.has(selector)) {
this.ruleMap.get(selector).style[prop] = "";
}
};
/**
* Removes the stylesheet from the document.
*/
Styler.prototype.destroy = function destroy() {
document.head.removeChild(this.styleEl);
};
module.exports = Styler;
/* globals it, describe, expect */
describe("Styler", function () {
const Styler = require("./styler.js");
const styler = new Styler();
it("Adds a new rule if the selector does not yet exist", function () {
expect(styler.ruleMap.size).toEqual(0);
styler.setRule(".my-class", "marginTop", "10px");
var rule = styler.ruleMap.get(".my-class");
expect(styler.ruleMap.size).toEqual(1);
expect(rule.style.marginTop).toBe("10px");
});
it("Modifies an existing rule if the selector already exists", function () {
expect(styler.ruleMap.size).toEqual(1);
styler.setRule(".my-class", "marginTop", "15px");
var rule = styler.ruleMap.get(".my-class");
expect(styler.ruleMap.size).toEqual(1);
expect(rule.style.marginTop).toBe("15px");
});
it("Removes the stylesheet when destroyed", function () {
expect(document.head.contains(styler.styleEl)).toBe(true);
styler.destroy();
expect(document.head.contains(styler.styleEl)).toBe(false);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment