diff --git a/src/core/__tests__/astish.test.js b/src/core/__tests__/astish.test.js index edebf83f..40e420be 100644 --- a/src/core/__tests__/astish.test.js +++ b/src/core/__tests__/astish.test.js @@ -3,9 +3,12 @@ import { astish } from '../astish'; describe('astish', () => { it('regular', () => { expect( - astish(` + astish( + ` prop: value; - `) + `, + [{}] + ) ).toEqual({ prop: 'value' }); @@ -13,7 +16,8 @@ describe('astish', () => { it('nested', () => { expect( - astish(` + astish( + ` prop: value; @keyframes foo { 0% { @@ -34,7 +38,9 @@ describe('astish', () => { &:hover { -webkit-touch: none; } - `) + `, + [{}] + ) ).toEqual({ prop: 'value', opacity: '0', @@ -61,7 +67,8 @@ describe('astish', () => { it('merging', () => { expect( - astish(` + astish( + ` .c { font-size:24px; } @@ -69,7 +76,9 @@ describe('astish', () => { .c { color:red; } - `) + `, + [{}] + ) ).toEqual({ '.c': { 'font-size': '24px', @@ -80,7 +89,8 @@ describe('astish', () => { it('regression', () => { expect( - astish(` + astish( + ` &.g0ssss { aa: foo; box-shadow: 0 1px rgba(0, 2, 33, 4) inset; @@ -104,7 +114,9 @@ describe('astish', () => { .b { color: blue; } - `) + `, + [{}] + ) ).toEqual({ '&.g0ssss': { aa: 'foo', @@ -135,7 +147,8 @@ describe('astish', () => { it('should strip comments', () => { expect( - astish(` + astish( + ` color: red; /* some comment @@ -148,7 +161,9 @@ describe('astish', () => { font-size: xx-large; /* inline comment */ /* foo: bar */ font-weight: bold; - `) + `, + [{}] + ) ).toEqual({ color: 'red', transform: 'translate3d(0, 0, 0)', @@ -162,11 +177,14 @@ describe('astish', () => { // https://www.w3.org/TR/CSS22/syndata.html#value-def-identifier it('should not mangle valid css identifiers', () => { expect( - astish(` + astish( + ` :root { --azAZ-_中文09: 0; } - `) + `, + [{}] + ) ).toEqual({ ':root': { '--azAZ-_中文09': '0' @@ -176,10 +194,13 @@ describe('astish', () => { it('should parse multiline background declaration', () => { expect( - astish(` + astish( + ` background: url('data:image/svg+xml,') center/contain; - `) + `, + [{}] + ) ).toEqual({ background: `url('data:image/svg+xml,')center/contain` }); @@ -188,7 +209,8 @@ describe('astish', () => { it('should handle inline @media block', () => { expect( astish( - `h1 { font-size: 1rem; } @media only screen and (min-width: 850px) { h1 { font-size: 2rem; } }` + `h1 { font-size: 1rem; } @media only screen and (min-width: 850px) { h1 { font-size: 2rem; } }`, + [{}] ) ).toEqual({ h1: { diff --git a/src/core/__tests__/hash.test.js b/src/core/__tests__/hash.test.js index b71f5d72..81fe8e23 100644 --- a/src/core/__tests__/hash.test.js +++ b/src/core/__tests__/hash.test.js @@ -41,7 +41,7 @@ describe('hash', () => { expect(toHash).toBeCalledWith('compiled'); expect(update).toBeCalledWith('parse()', 'target', undefined); - expect(astish).toBeCalledWith('compiled'); + expect(astish).toBeCalledWith('compiled', [{}]); expect(parse).toBeCalledWith('astish()', '.toHash()'); expect(res).toEqual('toHash()'); diff --git a/src/core/astish.js b/src/core/astish.js index 1d88e438..65459421 100644 --- a/src/core/astish.js +++ b/src/core/astish.js @@ -6,20 +6,20 @@ let ruleClean = /\/\*[^]*?\*\/|\s\s+|\n/g; * @param {String} val * @returns {Object} */ -export let astish = (val) => { - let tree = [{}]; - let block; +export let astish = (val, tree) => { + let block = newRule.exec(val.replace(ruleClean, '')); + if (!block) { + return tree[0]; + } - while ((block = newRule.exec(val.replace(ruleClean, '')))) { - // Remove the current entry - if (block[4]) { - tree.shift(); - } else if (block[3]) { - tree.unshift((tree[0][block[3]] = tree[0][block[3]] || {})); - } else { - tree[0][block[1]] = block[2]; - } + // Remove the current entry + if (block[4]) { + tree.shift(); + } else if (block[3]) { + tree.unshift((tree[0][block[3]] = tree[0][block[3]] || {})); + } else { + tree[0][block[1]] = block[2]; } - return tree[0]; + return astish(val, tree); }; diff --git a/src/core/hash.js b/src/core/hash.js index 6d3b5143..27dbb503 100644 --- a/src/core/hash.js +++ b/src/core/hash.js @@ -43,7 +43,7 @@ export let hash = (compiled, sheet, global, append, keyframes) => { // If there's no entry for the current className if (!cache[className]) { // Build the _ast_-ish structure if needed - let ast = stringifiedCompiled !== compiled ? compiled : astish(compiled); + let ast = stringifiedCompiled !== compiled ? compiled : astish(compiled, [{}]); // Parse it cache[className] = parse(