74 lines
1.7 KiB
JavaScript
74 lines
1.7 KiB
JavaScript
/* Riot WIP, @license MIT */
|
|
import $ from 'bianco.query';
|
|
import { set } from 'bianco.attr';
|
|
|
|
const CSS_BY_NAME = new Map();
|
|
const STYLE_NODE_SELECTOR = 'style[riot]'; // memoized curried function
|
|
|
|
const getStyleNode = (style => {
|
|
return () => {
|
|
// lazy evaluation:
|
|
// if this function was already called before
|
|
// we return its cached result
|
|
if (style) return style; // create a new style element or use an existing one
|
|
// and cache it internally
|
|
|
|
style = $(STYLE_NODE_SELECTOR)[0] || document.createElement('style');
|
|
set(style, 'type', 'text/css');
|
|
/* istanbul ignore next */
|
|
|
|
if (!style.parentNode) document.head.appendChild(style);
|
|
return style;
|
|
};
|
|
})();
|
|
/**
|
|
* Object that will be used to inject and manage the css of every tag instance
|
|
*/
|
|
|
|
|
|
const cssManager = {
|
|
CSS_BY_NAME,
|
|
|
|
/**
|
|
* Save a tag style to be later injected into DOM
|
|
* @param { string } name - if it's passed we will map the css to a tagname
|
|
* @param { string } css - css string
|
|
* @returns {Object} self
|
|
*/
|
|
add(name, css) {
|
|
if (!CSS_BY_NAME.has(name)) {
|
|
CSS_BY_NAME.set(name, css);
|
|
this.inject();
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Inject all previously saved tag styles into DOM
|
|
* innerHTML seems slow: http://jsperf.com/riot-insert-style
|
|
* @returns {Object} self
|
|
*/
|
|
inject() {
|
|
getStyleNode().innerHTML = [...CSS_BY_NAME.values()].join('\n');
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Remove a tag style from the DOM
|
|
* @param {string} name a registered tagname
|
|
* @returns {Object} self
|
|
*/
|
|
remove(name) {
|
|
if (CSS_BY_NAME.has(name)) {
|
|
CSS_BY_NAME.delete(name);
|
|
this.inject();
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
};
|
|
|
|
export { CSS_BY_NAME, STYLE_NODE_SELECTOR, cssManager as default };
|