glamor
Version:
inline css for component systems
1,012 lines (856 loc) • 27.2 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.compose = exports.merge = exports.$ = exports.style = exports.presets = exports.keyframes = exports.fontFace = exports.insertGlobal = exports.insertRule = exports.plugins = exports.styleSheet = undefined;
exports.speedy = speedy;
exports.simulations = simulations;
exports.simulate = simulate;
exports.cssLabels = cssLabels;
exports.isLikeRule = isLikeRule;
exports.idFor = idFor;
exports.css = css;
exports.rehydrate = rehydrate;
exports.flush = flush;
exports.select = select;
exports.parent = parent;
exports.media = media;
exports.pseudo = pseudo;
exports.active = active;
exports.any = any;
exports.checked = checked;
exports.disabled = disabled;
exports.empty = empty;
exports.enabled = enabled;
exports._default = _default;
exports.first = first;
exports.firstChild = firstChild;
exports.firstOfType = firstOfType;
exports.fullscreen = fullscreen;
exports.focus = focus;
exports.hover = hover;
exports.indeterminate = indeterminate;
exports.inRange = inRange;
exports.invalid = invalid;
exports.lastChild = lastChild;
exports.lastOfType = lastOfType;
exports.left = left;
exports.link = link;
exports.onlyChild = onlyChild;
exports.onlyOfType = onlyOfType;
exports.optional = optional;
exports.outOfRange = outOfRange;
exports.readOnly = readOnly;
exports.readWrite = readWrite;
exports.required = required;
exports.right = right;
exports.root = root;
exports.scope = scope;
exports.target = target;
exports.valid = valid;
exports.visited = visited;
exports.dir = dir;
exports.lang = lang;
exports.not = not;
exports.nthChild = nthChild;
exports.nthLastChild = nthLastChild;
exports.nthLastOfType = nthLastOfType;
exports.nthOfType = nthOfType;
exports.after = after;
exports.before = before;
exports.firstLetter = firstLetter;
exports.firstLine = firstLine;
exports.selection = selection;
exports.backdrop = backdrop;
exports.placeholder = placeholder;
exports.cssFor = cssFor;
exports.attribsFor = attribsFor;
var _objectAssign = require('object-assign');
var _objectAssign2 = _interopRequireDefault(_objectAssign);
var _sheet = require('./sheet.js');
var _CSSPropertyOperations = require('./CSSPropertyOperations');
var _clean = require('./clean.js');
var _clean2 = _interopRequireDefault(_clean);
var _plugins = require('./plugins');
var _hash = require('./hash');
var _hash2 = _interopRequireDefault(_hash);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/* stylesheet */
var styleSheet = exports.styleSheet = new _sheet.StyleSheet();
// an isomorphic StyleSheet shim. hides all the nitty gritty.
// /**************** LIFTOFF IN 3... 2... 1... ****************/
styleSheet.inject(); //eslint-disable-line indent
// /**************** TO THE MOOOOOOON ****************/
// convenience function to toggle speedy
function speedy(bool) {
return styleSheet.speedy(bool);
}
// plugins
// we include these by default
var plugins = exports.plugins = styleSheet.plugins = new _plugins.PluginSet([_plugins.prefixes, _plugins.contentWrap, _plugins.fallbacks]);
plugins.media = new _plugins.PluginSet(); // neat! media, font-face, keyframes
plugins.fontFace = new _plugins.PluginSet();
plugins.keyframes = new _plugins.PluginSet([_plugins.prefixes, _plugins.fallbacks]);
// define some constants
var isDev = process.env.NODE_ENV === 'development' || !process.env.NODE_ENV;
var isTest = process.env.NODE_ENV === 'test';
var isBrowser = typeof window !== 'undefined';
/**** simulations ****/
// a flag to enable simulation meta tags on dom nodes
// defaults to true in dev mode. recommend *not* to
// toggle often.
var canSimulate = isDev;
// we use these flags for issuing warnings when simulate is called
// in prod / in incorrect order
var warned1 = false,
warned2 = false;
// toggles simulation activity. shouldn't be needed in most cases
function simulations() {
var bool = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
canSimulate = !!bool;
}
// use this on dom nodes to 'simulate' pseudoclasses
// <div {...hover({ color: 'red' })} {...simulate('hover', 'visited')}>...</div>
// you can even send in some weird ones, as long as it's in simple format
// and matches an existing rule on the element
// eg simulate('nthChild2', ':hover:active') etc
function simulate() {
for (var _len = arguments.length, pseudos = Array(_len), _key = 0; _key < _len; _key++) {
pseudos[_key] = arguments[_key];
}
pseudos = (0, _clean2.default)(pseudos);
if (!pseudos) return {};
if (!canSimulate) {
if (!warned1) {
console.warn('can\'t simulate without once calling simulations(true)'); //eslint-disable-line no-console
warned1 = true;
}
if (!isDev && !isTest && !warned2) {
console.warn('don\'t use simulation outside dev'); //eslint-disable-line no-console
warned2 = true;
}
return {};
}
return pseudos.reduce(function (o, p) {
return o['data-simulate-' + simple(p)] = '', o;
}, {});
}
/**** labels ****/
// toggle for debug labels.
// *shouldn't* have to mess with this manually
var hasLabels = isDev;
function cssLabels(bool) {
hasLabels = !!bool;
}
// takes a string, converts to lowercase, strips out nonalphanumeric.
function simple(str) {
var char = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
return str.toLowerCase().replace(/[^a-z0-9]/g, char);
}
// hashes a string to something 'unique'
// we use this to generate ids for styles
function hashify(obj) {
var str = JSON.stringify(obj);
var toRet = (0, _hash2.default)(str).toString(36);
if (obj.label && obj.label.length > 0 && isDev) {
return simple(obj.label.join('.'), '-') + '-' + toRet;
}
return toRet;
}
// of shape { 'data-css-<id>': '' }
function isLikeRule(rule) {
var keys = Object.keys(rule).filter(function (x) {
return x !== 'toString';
});
if (keys.length !== 1) {
return false;
}
return !!/data\-css\-([a-zA-Z0-9\-_]+)/.exec(keys[0]);
}
// extracts id from a { 'data-css-<id>': ''} like object
function idFor(rule) {
var keys = Object.keys(rule).filter(function (x) {
return x !== 'toString';
});
if (keys.length !== 1) throw new Error('not a rule');
var regex = /data\-css\-([a-zA-Z0-9\-_]+)/;
var match = regex.exec(keys[0]);
if (!match) throw new Error('not a rule');
return match[1];
}
// from https://github.com/j2css/j2c/blob/5d381c2d721d04b54fabe6a165d587247c3087cb/src/helpers.js#L28-L61
// "Tokenizes" the selectors into parts relevant for the next function.
// Strings and comments are matched, but ignored afterwards.
// This is not a full tokenizers. It only recognizes comas, parentheses,
// strings and comments.
// regexp generated by scripts/regexps.js then trimmed by hand
var selectorTokenizer = /[(),]|"(?:\\.|[^"\n])*"|'(?:\\.|[^'\n])*'|\/\*[\s\S]*?\*\//g;
/**
* This will split a coma-separated selector list into individual selectors,
* ignoring comas in strings, comments and in :pseudo-selectors(parameter, lists).
*
* @param {string} selector
* @return {string[]}
*/
function splitSelector(selector) {
if (selector.indexOf(',') === -1) {
return [selector];
}
var indices = [],
res = [],
inParen = 0,
o;
/*eslint-disable no-cond-assign*/
while (o = selectorTokenizer.exec(selector)) {
/*eslint-enable no-cond-assign*/
switch (o[0]) {
case '(':
inParen++;break;
case ')':
inParen--;break;
case ',':
if (inParen) break;indices.push(o.index);
}
}
for (o = indices.length; o--;) {
res.unshift(selector.slice(indices[o] + 1));
selector = selector.slice(0, indices[o]);
}
res.unshift(selector);
return res;
}
function selector(id, path) {
if (!id) {
return path.replace(/\&/g, '');
}
if (!path) return '.css-' + id + ',[data-css-' + id + ']';
var x = splitSelector(path).map(function (x) {
return x.indexOf('&') >= 0 ? [x.replace(/\&/mg, '.css-' + id), x.replace(/\&/mg, '[data-css-' + id + ']')].join(',') // todo - make sure each sub selector has an &
: '.css-' + id + x + ',[data-css-' + id + ']' + x;
}).join(',');
if (canSimulate && /^\&\:/.exec(path) && !/\s/.exec(path)) {
x += ',.css-' + id + '[data-simulate-' + simple(path) + '],[data-css-' + id + '][data-simulate-' + simple(path) + ']';
}
return x;
}
// end https://github.com/j2css/j2c/blob/5d381c2d721d04b54fabe6a165d587247c3087cb/src/helpers.js#L28-L61
function toCSS(_ref) {
var selector = _ref.selector,
style = _ref.style;
var result = plugins.transform({ selector: selector, style: style });
return result.selector + '{' + (0, _CSSPropertyOperations.createMarkupForStyles)(result.style) + '}';
}
function deconstruct(style) {
// we can be sure it's not infinitely nested here
var plain = void 0,
selects = void 0,
medias = void 0,
supports = void 0;
Object.keys(style).forEach(function (key) {
if (key.indexOf('&') >= 0) {
selects = selects || {};
selects[key] = style[key];
} else if (key.indexOf('@media') === 0) {
medias = medias || {};
medias[key] = deconstruct(style[key]);
} else if (key.indexOf('@supports') === 0) {
supports = supports || {};
supports[key] = deconstruct(style[key]);
} else if (key === 'label') {
if (style.label.length > 0) {
plain = plain || {};
plain.label = hasLabels ? style.label.join('.') : '';
}
} else {
plain = plain || {};
plain[key] = style[key];
}
});
return { plain: plain, selects: selects, medias: medias, supports: supports };
}
function deconstructedStyleToCSS(id, style) {
var css = [];
// plugins here
var plain = style.plain,
selects = style.selects,
medias = style.medias,
supports = style.supports;
if (plain) {
css.push(toCSS({ style: plain, selector: selector(id) }));
}
if (selects) {
Object.keys(selects).forEach(function (key) {
return css.push(toCSS({ style: selects[key], selector: selector(id, key) }));
});
}
if (medias) {
Object.keys(medias).forEach(function (key) {
return css.push(key + '{' + deconstructedStyleToCSS(id, medias[key]).join('') + '}');
});
}
if (supports) {
Object.keys(supports).forEach(function (key) {
return css.push(key + '{' + deconstructedStyleToCSS(id, supports[key]).join('') + '}');
});
}
return css;
}
// this cache to track which rules have
// been inserted into the stylesheet
var inserted = styleSheet.inserted = {};
// and helpers to insert rules into said styleSheet
function insert(spec) {
if (!inserted[spec.id]) {
inserted[spec.id] = true;
var deconstructed = deconstruct(spec.style);
var rules = deconstructedStyleToCSS(spec.id, deconstructed);
inserted[spec.id] = isBrowser ? true : rules;
rules.forEach(function (cssRule) {
return styleSheet.insert(cssRule);
});
}
}
// a simple cache to store generated rules
var registered = styleSheet.registered = {};
function register(spec) {
if (!registered[spec.id]) {
registered[spec.id] = spec;
}
}
function _getRegistered(rule) {
if (isLikeRule(rule)) {
var ret = registered[idFor(rule)];
if (ret == null) {
throw new Error('[glamor] an unexpected rule cache miss occurred. This is probably a sign of multiple glamor instances in your app. See https://github.com/threepointone/glamor/issues/79');
}
return ret;
}
return rule;
}
// todo - perf
var ruleCache = {};
function toRule(spec) {
register(spec);
insert(spec);
if (ruleCache[spec.id]) {
return ruleCache[spec.id];
}
var ret = _defineProperty({}, 'data-css-' + spec.id, hasLabels ? spec.label || '' : '');
Object.defineProperty(ret, 'toString', {
enumerable: false, value: function value() {
return 'css-' + spec.id;
}
});
ruleCache[spec.id] = ret;
return ret;
}
function log() {
//eslint-disable-line no-unused-vars
console.log(this); //eslint-disable-line no-console
return this;
}
function isSelector(key) {
var possibles = [':', '.', '[', '>', ' '],
found = false,
ch = key.charAt(0);
for (var i = 0; i < possibles.length; i++) {
if (ch === possibles[i]) {
found = true;
break;
}
}
return found || key.indexOf('&') >= 0;
}
function joinSelectors(a, b) {
var as = splitSelector(a).map(function (a) {
return !(a.indexOf('&') >= 0) ? '&' + a : a;
});
var bs = splitSelector(b).map(function (b) {
return !(b.indexOf('&') >= 0) ? '&' + b : b;
});
return bs.reduce(function (arr, b) {
return arr.concat(as.map(function (a) {
return b.replace(/\&/g, a);
}));
}, []).join(',');
}
function joinMediaQueries(a, b) {
return a ? '@media ' + a.substring(6) + ' and ' + b.substring(6) : b;
}
function isMediaQuery(key) {
return key.indexOf('@media') === 0;
}
function isSupports(key) {
return key.indexOf('@supports') === 0;
}
function joinSupports(a, b) {
return a ? '@supports ' + a.substring(9) + ' and ' + b.substring(9) : b;
}
// flatten a nested array
function flatten(inArr) {
var arr = [];
for (var i = 0; i < inArr.length; i++) {
if (Array.isArray(inArr[i])) arr = arr.concat(flatten(inArr[i]));else arr = arr.concat(inArr[i]);
}
return arr;
}
var prefixedPseudoSelectors = {
'::placeholder': ['::-webkit-input-placeholder', '::-moz-placeholder', '::-ms-input-placeholder'],
':fullscreen': [':-webkit-full-screen', ':-moz-full-screen', ':-ms-fullscreen']
// mutable! modifies dest.
};function build(dest, _ref2) {
var _ref2$selector = _ref2.selector,
selector = _ref2$selector === undefined ? '' : _ref2$selector,
_ref2$mq = _ref2.mq,
mq = _ref2$mq === undefined ? '' : _ref2$mq,
_ref2$supp = _ref2.supp,
supp = _ref2$supp === undefined ? '' : _ref2$supp,
_ref2$src = _ref2.src,
src = _ref2$src === undefined ? {} : _ref2$src;
if (!Array.isArray(src)) {
src = [src];
}
src = flatten(src);
src.forEach(function (_src) {
if (isLikeRule(_src)) {
var reg = _getRegistered(_src);
if (reg.type !== 'css') {
throw new Error('cannot merge this rule');
}
_src = reg.style;
}
_src = (0, _clean2.default)(_src);
if (_src && _src.composes) {
build(dest, { selector: selector, mq: mq, supp: supp, src: _src.composes });
}
Object.keys(_src || {}).forEach(function (key) {
if (isSelector(key)) {
if (prefixedPseudoSelectors[key]) {
prefixedPseudoSelectors[key].forEach(function (p) {
return build(dest, { selector: joinSelectors(selector, p), mq: mq, supp: supp, src: _src[key] });
});
}
build(dest, { selector: joinSelectors(selector, key), mq: mq, supp: supp, src: _src[key] });
} else if (isMediaQuery(key)) {
build(dest, { selector: selector, mq: joinMediaQueries(mq, key), supp: supp, src: _src[key] });
} else if (isSupports(key)) {
build(dest, { selector: selector, mq: mq, supp: joinSupports(supp, key), src: _src[key] });
} else if (key === 'composes') {
// ignore, we already dealth with it
} else {
var _dest = dest;
if (supp) {
_dest[supp] = _dest[supp] || {};
_dest = _dest[supp];
}
if (mq) {
_dest[mq] = _dest[mq] || {};
_dest = _dest[mq];
}
if (selector) {
_dest[selector] = _dest[selector] || {};
_dest = _dest[selector];
}
if (key === 'label') {
if (hasLabels) {
dest.label = dest.label.concat(_src.label);
}
} else {
_dest[key] = _src[key];
}
}
});
});
}
function _css(rules) {
var style = { label: [] };
build(style, { src: rules }); // mutative! but worth it.
var spec = {
id: hashify(style),
style: style, label: hasLabels ? style.label.join('.') : '',
type: 'css'
};
return toRule(spec);
}
var nullrule = {
// 'data-css-nil': ''
};
Object.defineProperty(nullrule, 'toString', {
enumerable: false, value: function value() {
return 'css-nil';
}
});
var inputCaches = typeof WeakMap !== 'undefined' ? [nullrule, new WeakMap(), new WeakMap(), new WeakMap()] : [nullrule];
var warnedWeakMapError = false;
function multiIndexCache(fn) {
return function (args) {
if (inputCaches[args.length]) {
var coi = inputCaches[args.length];
var ctr = 0;
while (ctr < args.length - 1) {
if (!coi.has(args[ctr])) {
coi.set(args[ctr], new WeakMap());
}
coi = coi.get(args[ctr]);
ctr++;
}
if (coi.has(args[args.length - 1])) {
var ret = coi.get(args[ctr]);
if (registered[ret.toString().substring(4)]) {
// make sure it hasn't been flushed
return ret;
}
}
}
var value = fn(args);
if (inputCaches[args.length]) {
var _ctr = 0,
_coi = inputCaches[args.length];
while (_ctr < args.length - 1) {
_coi = _coi.get(args[_ctr]);
_ctr++;
}
try {
_coi.set(args[_ctr], value);
} catch (err) {
if (isDev && !warnedWeakMapError) {
var _console;
warnedWeakMapError = true;
(_console = console).warn.apply(_console, ['failed setting the WeakMap cache for args:'].concat(_toConsumableArray(args))); // eslint-disable-line no-console
console.warn('this should NOT happen, please file a bug on the github repo.'); // eslint-disable-line no-console
}
}
}
return value;
};
}
var cachedCss = typeof WeakMap !== 'undefined' ? multiIndexCache(_css) : _css;
function css() {
for (var _len2 = arguments.length, rules = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
rules[_key2] = arguments[_key2];
}
if (rules[0] && rules[0].length && rules[0].raw) {
throw new Error('you forgot to include glamor/babel in your babel plugins.');
}
rules = (0, _clean2.default)(rules);
if (!rules) {
return nullrule;
}
return cachedCss(rules);
}
css.insert = function (css) {
var spec = {
id: hashify(css),
css: css,
type: 'raw'
};
register(spec);
if (!inserted[spec.id]) {
styleSheet.insert(spec.css);
inserted[spec.id] = isBrowser ? true : [spec.css];
}
};
var insertRule = exports.insertRule = css.insert;
css.global = function (selector, style) {
style = (0, _clean2.default)(style);
if (style) {
return css.insert(toCSS({ selector: selector, style: style }));
}
};
var insertGlobal = exports.insertGlobal = css.global;
function insertKeyframe(spec) {
if (!inserted[spec.id]) {
var inner = Object.keys(spec.keyframes).map(function (kf) {
var result = plugins.keyframes.transform({ id: spec.id, name: kf, style: spec.keyframes[kf] });
return result.name + '{' + (0, _CSSPropertyOperations.createMarkupForStyles)(result.style) + '}';
}).join('');
var rules = ['-webkit-', '-moz-', '-o-', ''].map(function (prefix) {
return '@' + prefix + 'keyframes ' + (spec.name + '_' + spec.id) + '{' + inner + '}';
});
rules.forEach(function (rule) {
return styleSheet.insert(rule);
});
inserted[spec.id] = isBrowser ? true : rules;
}
}
css.keyframes = function (name, kfs) {
if (!kfs) {
kfs = name, name = 'animation';
}
// do not ignore empty keyframe definitions for now.
kfs = (0, _clean2.default)(kfs) || {};
var spec = {
id: hashify({ name: name, kfs: kfs }),
type: 'keyframes',
name: name,
keyframes: kfs
};
register(spec);
insertKeyframe(spec);
return name + '_' + spec.id;
};
// we don't go all out for fonts as much, giving a simple font loading strategy
// use a fancier lib if you need moar power
css.fontFace = function (font) {
font = (0, _clean2.default)(font);
var spec = {
id: hashify(font),
type: 'font-face',
font: font
};
register(spec);
insertFontFace(spec);
return font.fontFamily;
};
var fontFace = exports.fontFace = css.fontFace;
var keyframes = exports.keyframes = css.keyframes;
function insertFontFace(spec) {
if (!inserted[spec.id]) {
var rule = '@font-face{' + (0, _CSSPropertyOperations.createMarkupForStyles)(spec.font) + '}';
styleSheet.insert(rule);
inserted[spec.id] = isBrowser ? true : [rule];
}
}
// rehydrate the insertion cache with ids sent from
// renderStatic / renderStaticOptimized
function rehydrate(ids) {
// load up ids
(0, _objectAssign2.default)(inserted, ids.reduce(function (o, i) {
return o[i] = true, o;
}, {}));
// assume css loaded separately
}
// clears out the cache and empties the stylesheet
// best for tests, though there might be some value for SSR.
function flush() {
inserted = styleSheet.inserted = {};
registered = styleSheet.registered = {};
ruleCache = {};
styleSheet.flush();
styleSheet.inject();
}
var presets = exports.presets = {
mobile: '(min-width: 400px)',
Mobile: '@media (min-width: 400px)',
phablet: '(min-width: 550px)',
Phablet: '@media (min-width: 550px)',
tablet: '(min-width: 750px)',
Tablet: '@media (min-width: 750px)',
desktop: '(min-width: 1000px)',
Desktop: '@media (min-width: 1000px)',
hd: '(min-width: 1200px)',
Hd: '@media (min-width: 1200px)'
};
var style = exports.style = css;
function select(selector) {
for (var _len3 = arguments.length, styles = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
styles[_key3 - 1] = arguments[_key3];
}
if (!selector) {
return style(styles);
}
return css(_defineProperty({}, selector, styles));
}
var $ = exports.$ = select;
function parent(selector) {
for (var _len4 = arguments.length, styles = Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
styles[_key4 - 1] = arguments[_key4];
}
return css(_defineProperty({}, selector + ' &', styles));
}
var merge = exports.merge = css;
var compose = exports.compose = css;
function media(query) {
for (var _len5 = arguments.length, rules = Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
rules[_key5 - 1] = arguments[_key5];
}
return css(_defineProperty({}, '@media ' + query, rules));
}
function pseudo(selector) {
for (var _len6 = arguments.length, styles = Array(_len6 > 1 ? _len6 - 1 : 0), _key6 = 1; _key6 < _len6; _key6++) {
styles[_key6 - 1] = arguments[_key6];
}
return css(_defineProperty({}, selector, styles));
}
// allllll the pseudoclasses
function active(x) {
return pseudo(':active', x);
}
function any(x) {
return pseudo(':any', x);
}
function checked(x) {
return pseudo(':checked', x);
}
function disabled(x) {
return pseudo(':disabled', x);
}
function empty(x) {
return pseudo(':empty', x);
}
function enabled(x) {
return pseudo(':enabled', x);
}
function _default(x) {
return pseudo(':default', x); // note '_default' name
}
function first(x) {
return pseudo(':first', x);
}
function firstChild(x) {
return pseudo(':first-child', x);
}
function firstOfType(x) {
return pseudo(':first-of-type', x);
}
function fullscreen(x) {
return pseudo(':fullscreen', x);
}
function focus(x) {
return pseudo(':focus', x);
}
function hover(x) {
return pseudo(':hover', x);
}
function indeterminate(x) {
return pseudo(':indeterminate', x);
}
function inRange(x) {
return pseudo(':in-range', x);
}
function invalid(x) {
return pseudo(':invalid', x);
}
function lastChild(x) {
return pseudo(':last-child', x);
}
function lastOfType(x) {
return pseudo(':last-of-type', x);
}
function left(x) {
return pseudo(':left', x);
}
function link(x) {
return pseudo(':link', x);
}
function onlyChild(x) {
return pseudo(':only-child', x);
}
function onlyOfType(x) {
return pseudo(':only-of-type', x);
}
function optional(x) {
return pseudo(':optional', x);
}
function outOfRange(x) {
return pseudo(':out-of-range', x);
}
function readOnly(x) {
return pseudo(':read-only', x);
}
function readWrite(x) {
return pseudo(':read-write', x);
}
function required(x) {
return pseudo(':required', x);
}
function right(x) {
return pseudo(':right', x);
}
function root(x) {
return pseudo(':root', x);
}
function scope(x) {
return pseudo(':scope', x);
}
function target(x) {
return pseudo(':target', x);
}
function valid(x) {
return pseudo(':valid', x);
}
function visited(x) {
return pseudo(':visited', x);
}
// parameterized pseudoclasses
function dir(p, x) {
return pseudo(':dir(' + p + ')', x);
}
function lang(p, x) {
return pseudo(':lang(' + p + ')', x);
}
function not(p, x) {
// should this be a plugin?
var selector = p.split(',').map(function (x) {
return x.trim();
}).map(function (x) {
return ':not(' + x + ')';
});
if (selector.length === 1) {
return pseudo(':not(' + p + ')', x);
}
return select(selector.join(''), x);
}
function nthChild(p, x) {
return pseudo(':nth-child(' + p + ')', x);
}
function nthLastChild(p, x) {
return pseudo(':nth-last-child(' + p + ')', x);
}
function nthLastOfType(p, x) {
return pseudo(':nth-last-of-type(' + p + ')', x);
}
function nthOfType(p, x) {
return pseudo(':nth-of-type(' + p + ')', x);
}
// pseudoelements
function after(x) {
return pseudo('::after', x);
}
function before(x) {
return pseudo('::before', x);
}
function firstLetter(x) {
return pseudo('::first-letter', x);
}
function firstLine(x) {
return pseudo('::first-line', x);
}
function selection(x) {
return pseudo('::selection', x);
}
function backdrop(x) {
return pseudo('::backdrop', x);
}
function placeholder(x) {
// https://github.com/threepointone/glamor/issues/14
return css({ '::placeholder': x });
}
/*** helpers for web components ***/
// https://github.com/threepointone/glamor/issues/16
function cssFor() {
for (var _len7 = arguments.length, rules = Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
rules[_key7] = arguments[_key7];
}
rules = (0, _clean2.default)(rules);
return rules ? rules.map(function (r) {
var style = { label: [] };
build(style, { src: r }); // mutative! but worth it.
return deconstructedStyleToCSS(hashify(style), deconstruct(style)).join('');
}).join('') : '';
}
function attribsFor() {
for (var _len8 = arguments.length, rules = Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
rules[_key8] = arguments[_key8];
}
rules = (0, _clean2.default)(rules);
var htmlAttributes = rules ? rules.map(function (rule) {
idFor(rule); // throwaway check for rule
var key = Object.keys(rule)[0],
value = rule[key];
return key + '="' + (value || '') + '"';
}).join(' ') : '';
return htmlAttributes;
}
;