-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
More tests, use fns from utils and rework core #191
Changes from 9 commits
dfb3943
67d6619
66c9032
5d3f8b7
5f943b2
fa1c700
66ab550
81b133b
d6b58ca
606b3e8
a47320f
bdea0c8
469a64d
746c6fe
1c5416e
6b48149
38e8508
499577a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
// @flow | ||
import { StyleSheet } from './sheet' | ||
import { forEach, map, reduce } from './utils' | ||
import { forEach, map, reduce, keys } from './utils' | ||
import { hashString as hash, hashObject } from './hash' | ||
import { createMarkupForStyles } from './glamor/CSSPropertyOperations' | ||
import clean from './glamor/clean.js' | ||
|
@@ -45,27 +45,15 @@ function _getRegistered (rule) { | |
return rule | ||
} | ||
|
||
// The idea on how to merge object class names come from glamorous | ||
// 💄 | ||
// https://github.com/paypal/glamorous/blob/master/src/get-glamor-classname.js | ||
function getEmotionStylesFromClassName (className) { | ||
const id = className.trim().slice('css-'.length) | ||
if (sheet.registered[id]) { | ||
return sheet.registered[id].style | ||
} else { | ||
return [] | ||
} | ||
} | ||
|
||
function buildStyles (objs) { | ||
let computedClassName = '' | ||
let objectStyles = [] | ||
|
||
// This needs to be moved into the core | ||
forEach(objs, (cls): void => { | ||
if (typeof cls === 'string') { | ||
if (cls.trim().indexOf('css-') === 0) { | ||
objectStyles.push(getEmotionStylesFromClassName(cls)) | ||
const match = emotionClassRegex.exec(cls) | ||
if (match) { | ||
objectStyles.push(ruleCache[match[1]]) | ||
} else { | ||
computedClassName && (computedClassName += ' ') | ||
computedClassName += cls | ||
|
@@ -118,7 +106,7 @@ export function injectGlobal ( | |
// injectGlobal is flattened by postcss | ||
// we don't support nested selectors on objects | ||
forEach(combined, obj => { | ||
forEach(Object.keys(obj), selector => { | ||
forEach(keys(obj), selector => { | ||
insertRawRule(`${selector} {${createMarkupForStyles(obj[selector])}}`) | ||
}) | ||
}) | ||
|
@@ -141,7 +129,7 @@ export function fontFace ( | |
function insertKeyframe (spec) { | ||
if (!inserted[spec.id]) { | ||
const inner = map( | ||
Object.keys(spec.keyframes), | ||
keys(spec.keyframes), | ||
kf => `${kf} {${createMarkupForStyles(spec.keyframes[kf])}}` | ||
).join('') | ||
|
||
|
@@ -181,16 +169,12 @@ type EmotionRule = { [string]: any } | |
|
||
type CSSRuleList = Array<EmotionRule> | ||
|
||
type EmotionClassName = { | ||
[string]: any | ||
} | ||
|
||
let cachedCss: (rules: CSSRuleList) => EmotionClassName = | ||
let cachedCss: (rules: CSSRuleList) => EmotionRule = | ||
typeof WeakMap !== 'undefined' ? multiIndexCache(_css) : _css | ||
|
||
// 🍩 | ||
// https://github.com/threepointone/glamor | ||
export function objStyle (...rules: CSSRuleList): EmotionClassName { | ||
export function objStyle (...rules: CSSRuleList): EmotionRule { | ||
rules = clean(rules) | ||
if (!rules) { | ||
return nullrule | ||
|
@@ -211,21 +195,22 @@ function _css (rules) { | |
return toRule(spec) | ||
} | ||
|
||
const emotionClassRegex = /css-([a-zA-Z0-9]+)/ | ||
|
||
// of shape { 'data-css-<id>': '' } | ||
export function isLikeRule (rule: EmotionRule) { | ||
let keys = Object.keys(rule).filter(x => x !== 'toString') | ||
if (keys.length !== 1) { | ||
let ruleKeys = keys(rule).filter(x => x !== 'toString') | ||
if (ruleKeys.length !== 1) { | ||
return false | ||
} | ||
return !!/css-([a-zA-Z0-9]+)/.exec(keys[0]) | ||
return !!emotionClassRegex.exec(ruleKeys[0]) | ||
} | ||
|
||
// extracts id from a { 'css-<id>': ''} like object | ||
export function idFor (rule: EmotionRule) { | ||
let keys = Object.keys(rule).filter(x => x !== 'toString') | ||
if (keys.length !== 1) throw new Error('not a rule') | ||
let regex = /css-([a-zA-Z0-9]+)/ | ||
let match = regex.exec(keys[0]) | ||
let ruleKeys = keys(rule).filter(x => x !== 'toString') | ||
if (ruleKeys.length !== 1) throw new Error('not a rule') | ||
let match = emotionClassRegex.exec(ruleKeys[0]) | ||
if (!match) throw new Error('not a rule') | ||
return match[1] | ||
} | ||
|
@@ -236,21 +221,22 @@ function selector (id: string, path: string = '') { | |
} | ||
if (!path) return `.css-${id}` | ||
|
||
let x = path | ||
.split(',') | ||
.map( | ||
x => | ||
x.indexOf('&') >= 0 ? x.replace(/&/gm, `.css-${id}`) : `.css-${id}${x}` | ||
) | ||
.join(',') | ||
let x = map( | ||
path.split(','), | ||
x => | ||
x.indexOf('&') >= 0 ? x.replace(/&/gm, `.css-${id}`) : `.css-${id}${x}` | ||
).join(',') | ||
|
||
return x | ||
} | ||
|
||
function deconstruct (style) { | ||
// we can be sure it's not infinitely nested here | ||
let plain, selects, medias, supports | ||
Object.keys(style).forEach(key => { | ||
let plain | ||
let selects | ||
let medias | ||
let supports | ||
forEach(keys(style), key => { | ||
if (key.indexOf('&') >= 0) { | ||
selects = selects || {} | ||
selects[key] = style[key] | ||
|
@@ -276,17 +262,17 @@ function deconstructedStyleToCSS (id, style) { | |
css.push(`${selector(id)}{${createMarkupForStyles(plain)}}`) | ||
} | ||
if (selects) { | ||
Object.keys(selects).forEach((key: string) => | ||
forEach(keys(selects), (key: string) => | ||
css.push(`${selector(id, key)}{${createMarkupForStyles(selects[key])}}`) | ||
) | ||
} | ||
if (medias) { | ||
Object.keys(medias).forEach(key => | ||
forEach(keys(medias), key => | ||
css.push(`${key}{${deconstructedStyleToCSS(id, medias[key]).join('')}}`) | ||
) | ||
} | ||
if (supports) { | ||
Object.keys(supports).forEach(key => | ||
forEach(keys(supports), key => | ||
css.push(`${key}{${deconstructedStyleToCSS(id, supports[key]).join('')}}`) | ||
) | ||
} | ||
|
@@ -298,7 +284,7 @@ function insert (spec) { | |
if (!inserted[spec.id]) { | ||
inserted[spec.id] = true | ||
let deconstructed = deconstruct(spec.style) | ||
deconstructedStyleToCSS(spec.id, deconstructed).map(cssRule => | ||
map(deconstructedStyleToCSS(spec.id, deconstructed), cssRule => | ||
sheet.insert(cssRule) | ||
) | ||
} | ||
|
@@ -342,9 +328,11 @@ function joinSelectors (a, b) { | |
let as = map(a.split(','), a => (!(a.indexOf('&') >= 0) ? '&' + a : a)) | ||
let bs = map(b.split(','), b => (!(b.indexOf('&') >= 0) ? '&' + b : b)) | ||
|
||
return bs | ||
.reduce((arr, b) => arr.concat(as.map(a => b.replace(/&/g, a))), []) | ||
.join(',') | ||
return reduce( | ||
bs, | ||
(arr, b) => arr.concat(map(as, a => b.replace(/&/g, a))), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could hoist this up as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can't because it uses There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wait, i might be wrong There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can't hoist it because it uses |
||
[] | ||
).join(',') | ||
} | ||
|
||
function joinMediaQueries (a, b) { | ||
|
@@ -366,10 +354,11 @@ function joinSupports (a, b) { | |
// flatten a nested array | ||
function flatten (inArr) { | ||
let arr = [] | ||
for (let i = 0; i < inArr.length; i++) { | ||
if (Array.isArray(inArr[i])) arr = arr.concat(flatten(inArr[i])) | ||
else arr = arr.concat(inArr[i]) | ||
} | ||
forEach(inArr, val => { | ||
if (Array.isArray(val)) arr = arr.concat(flatten(val)) | ||
else arr = arr.concat(val) | ||
}) | ||
|
||
return arr | ||
} | ||
|
||
|
@@ -380,7 +369,7 @@ function build (dest, { selector = '', mq = '', supp = '', src = {} }) { | |
} | ||
src = flatten(src) | ||
|
||
src.forEach(_src => { | ||
forEach(src, _src => { | ||
if (isLikeRule(_src)) { | ||
let reg = _getRegistered(_src) | ||
if (reg.type !== 'css') { | ||
|
@@ -392,7 +381,7 @@ function build (dest, { selector = '', mq = '', supp = '', src = {} }) { | |
if (_src && _src.composes) { | ||
build(dest, { selector, mq, supp, src: _src.composes }) | ||
} | ||
Object.keys(_src || {}).forEach(key => { | ||
forEach(keys(_src || {}), key => { | ||
if (isSelector(key)) { | ||
build(dest, { | ||
selector: joinSelectors(selector, key), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably hoist this callback and the regex inside.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't because it uses
id