From d8a13bcae81812d3dff643bcf446709f965f0909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 27 Oct 2022 09:45:48 +0200 Subject: [PATCH] Fork Stylis prefixer (#2890) * Fork Stylis prefixer * Create long-pianos-swim.md * Create short-pianos-swim.md * Update .changeset/long-pianos-swim.md --- .changeset/long-pianos-swim.md | 2 + .changeset/short-pianos-swim.md | 5 + packages/babel-plugin/package.json | 2 +- packages/cache/package.json | 2 +- packages/cache/src/index.js | 2 +- packages/cache/src/prefixer.js | 340 +++++++++++++++++++++++++++ packages/css-prettifier/package.json | 2 +- packages/jest/package.json | 2 +- yarn.lock | 16 +- 9 files changed, 360 insertions(+), 13 deletions(-) create mode 100644 .changeset/long-pianos-swim.md create mode 100644 .changeset/short-pianos-swim.md create mode 100644 packages/cache/src/prefixer.js diff --git a/.changeset/long-pianos-swim.md b/.changeset/long-pianos-swim.md new file mode 100644 index 000000000..a845151cc --- /dev/null +++ b/.changeset/long-pianos-swim.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/short-pianos-swim.md b/.changeset/short-pianos-swim.md new file mode 100644 index 000000000..d1dd4045b --- /dev/null +++ b/.changeset/short-pianos-swim.md @@ -0,0 +1,5 @@ +--- +"@emotion/cache": patch +--- + +An edge case issue with some specific CSS variables being treated as prefixable declarations got fixed by updating the underlying parser ([stylis](https://github.com/thysultan/stylis)). diff --git a/packages/babel-plugin/package.json b/packages/babel-plugin/package.json index 2c80c611e..69aed6e6e 100644 --- a/packages/babel-plugin/package.json +++ b/packages/babel-plugin/package.json @@ -28,7 +28,7 @@ "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.0.13" + "stylis": "4.1.2" }, "peerDependencies": { "@babel/core": "^7.0.0" diff --git a/packages/cache/package.json b/packages/cache/package.json index 33d576387..0e2222e5d 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -29,7 +29,7 @@ "@emotion/sheet": "^1.2.0", "@emotion/utils": "^1.2.0", "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.0.13" + "stylis": "4.1.2" }, "devDependencies": { "@definitelytyped/dtslint": "0.0.112", diff --git a/packages/cache/src/index.js b/packages/cache/src/index.js index 4545d8037..39d66bf91 100644 --- a/packages/cache/src/index.js +++ b/packages/cache/src/index.js @@ -7,7 +7,6 @@ import { middleware, rulesheet, stringify, - prefixer, COMMENT } from 'stylis' import weakMemoize from '@emotion/weak-memoize' @@ -18,6 +17,7 @@ import { createUnsafeSelectorsAlarm, incorrectImportAlarm } from './stylis-plugins' +import { prefixer } from './prefixer' import type { StylisPlugin } from './types' let isBrowser = typeof document !== 'undefined' diff --git a/packages/cache/src/prefixer.js b/packages/cache/src/prefixer.js new file mode 100644 index 000000000..030a60897 --- /dev/null +++ b/packages/cache/src/prefixer.js @@ -0,0 +1,340 @@ +/* eslint-disable no-fallthrough */ +/* eslint-disable eqeqeq */ +import { + charat, + combine, + copy, + DECLARATION, + hash, + indexof, + KEYFRAMES, + match, + MOZ, + MS, + replace, + RULESET, + serialize, + strlen, + WEBKIT +} from 'stylis' + +// this is a copy of stylis@4.0.13 prefixer, the latter version introduced grid prefixing which we don't want + +function prefix(value, length) { + switch (hash(value, length)) { + // color-adjust + case 5103: + return WEBKIT + 'print-' + value + value + // animation, animation-(delay|direction|duration|fill-mode|iteration-count|name|play-state|timing-function) + case 5737: + case 4201: + case 3177: + case 3433: + case 1641: + case 4457: + case 2921: + // text-decoration, filter, clip-path, backface-visibility, column, box-decoration-break + case 5572: + case 6356: + case 5844: + case 3191: + case 6645: + case 3005: + // mask, mask-image, mask-(mode|clip|size), mask-(repeat|origin), mask-position, mask-composite, + case 6391: + case 5879: + case 5623: + case 6135: + case 4599: + case 4855: + // background-clip, columns, column-(count|fill|gap|rule|rule-color|rule-style|rule-width|span|width) + case 4215: + case 6389: + case 5109: + case 5365: + case 5621: + case 3829: + return WEBKIT + value + value + // appearance, user-select, transform, hyphens, text-size-adjust + case 5349: + case 4246: + case 4810: + case 6968: + case 2756: + return WEBKIT + value + MOZ + value + MS + value + value + // flex, flex-direction + case 6828: + case 4268: + return WEBKIT + value + MS + value + value + // order + case 6165: + return WEBKIT + value + MS + 'flex-' + value + value + // align-items + case 5187: + return ( + WEBKIT + + value + + replace( + value, + /(\w+).+(:[^]+)/, + WEBKIT + 'box-$1$2' + MS + 'flex-$1$2' + ) + + value + ) + // align-self + case 5443: + return ( + WEBKIT + + value + + MS + + 'flex-item-' + + replace(value, /flex-|-self/, '') + + value + ) + // align-content + case 4675: + return ( + WEBKIT + + value + + MS + + 'flex-line-pack' + + replace(value, /align-content|flex-|-self/, '') + + value + ) + // flex-shrink + case 5548: + return WEBKIT + value + MS + replace(value, 'shrink', 'negative') + value + // flex-basis + case 5292: + return ( + WEBKIT + value + MS + replace(value, 'basis', 'preferred-size') + value + ) + // flex-grow + case 6060: + return ( + WEBKIT + + 'box-' + + replace(value, '-grow', '') + + WEBKIT + + value + + MS + + replace(value, 'grow', 'positive') + + value + ) + // transition + case 4554: + return ( + WEBKIT + + replace(value, /([^-])(transform)/g, '$1' + WEBKIT + '$2') + + value + ) + // cursor + case 6187: + return ( + replace( + replace( + replace(value, /(zoom-|grab)/, WEBKIT + '$1'), + /(image-set)/, + WEBKIT + '$1' + ), + value, + '' + ) + value + ) + // background, background-image + case 5495: + case 3959: + return replace(value, /(image-set\([^]*)/, WEBKIT + '$1' + '$`$1') + // justify-content + case 4968: + return ( + replace( + replace( + value, + /(.+:)(flex-)?(.*)/, + WEBKIT + 'box-pack:$3' + MS + 'flex-pack:$3' + ), + /s.+-b[^;]+/, + 'justify' + ) + + WEBKIT + + value + + value + ) + // (margin|padding)-inline-(start|end) + case 4095: + case 3583: + case 4068: + case 2532: + return replace(value, /(.+)-inline(.+)/, WEBKIT + '$1$2') + value + // (min|max)?(width|height|inline-size|block-size) + case 8116: + case 7059: + case 5753: + case 5535: + case 5445: + case 5701: + case 4933: + case 4677: + case 5533: + case 5789: + case 5021: + case 4765: + // stretch, max-content, min-content, fill-available + if (strlen(value) - 1 - length > 6) + switch (charat(value, length + 1)) { + // (m)ax-content, (m)in-content + case 109: + // - + if (charat(value, length + 4) !== 45) break + // (f)ill-available, (f)it-content + case 102: + return ( + replace( + value, + /(.+:)(.+)-([^]+)/, + '$1' + + WEBKIT + + '$2-$3' + + '$1' + + MOZ + + (charat(value, length + 3) == 108 ? '$3' : '$2-$3') + ) + value + ) + // (s)tretch + case 115: + return ~indexof(value, 'stretch') + ? prefix(replace(value, 'stretch', 'fill-available'), length) + + value + : value + } + break + // position: sticky + case 4949: + // (s)ticky? + if (charat(value, length + 1) !== 115) break + // display: (flex|inline-flex) + case 6444: + switch ( + charat(value, strlen(value) - 3 - (~indexof(value, '!important') && 10)) + ) { + // stic(k)y + case 107: + return replace(value, ':', ':' + WEBKIT) + value + // (inline-)?fl(e)x + case 101: + return ( + replace( + value, + /(.+:)([^;!]+)(;|!.+)?/, + '$1' + + WEBKIT + + (charat(value, 14) === 45 ? 'inline-' : '') + + 'box$3' + + '$1' + + WEBKIT + + '$2$3' + + '$1' + + MS + + '$2box$3' + ) + value + ) + } + break + // writing-mode + case 5936: + switch (charat(value, length + 11)) { + // vertical-l(r) + case 114: + return ( + WEBKIT + + value + + MS + + replace(value, /[svh]\w+-[tblr]{2}/, 'tb') + + value + ) + // vertical-r(l) + case 108: + return ( + WEBKIT + + value + + MS + + replace(value, /[svh]\w+-[tblr]{2}/, 'tb-rl') + + value + ) + // horizontal(-)tb + case 45: + return ( + WEBKIT + + value + + MS + + replace(value, /[svh]\w+-[tblr]{2}/, 'lr') + + value + ) + } + + return WEBKIT + value + MS + value + value + } + + return value +} + +export let prefixer = (element, index, children, callback) => { + if (element.length > -1) + if (!element.return) + switch (element.type) { + case DECLARATION: + element.return = prefix(element.value, element.length) + break + case KEYFRAMES: + return serialize( + [ + copy(element, { + value: replace(element.value, '@', '@' + WEBKIT) + }) + ], + callback + ) + case RULESET: + if (element.length) + return combine(element.props, function (value) { + switch (match(value, /(::plac\w+|:read-\w+)/)) { + // :read-(only|write) + case ':read-only': + case ':read-write': + return serialize( + [ + copy(element, { + props: [replace(value, /:(read-\w+)/, ':' + MOZ + '$1')] + }) + ], + callback + ) + // :placeholder + case '::placeholder': + return serialize( + [ + copy(element, { + props: [ + replace( + value, + /:(plac\w+)/, + ':' + WEBKIT + 'input-$1' + ) + ] + }), + copy(element, { + props: [replace(value, /:(plac\w+)/, ':' + MOZ + '$1')] + }), + copy(element, { + props: [replace(value, /:(plac\w+)/, MS + 'input-$1')] + }) + ], + callback + ) + } + + return '' + }) + } +} diff --git a/packages/css-prettifier/package.json b/packages/css-prettifier/package.json index 8ea66778a..c4afe2eca 100644 --- a/packages/css-prettifier/package.json +++ b/packages/css-prettifier/package.json @@ -20,7 +20,7 @@ "repository": "https://github.com/emotion-js/emotion/tree/main/packages/css-prettifier", "dependencies": { "@emotion/memoize": "^0.8.0", - "stylis": "4.0.13" + "stylis": "4.1.2" }, "publishConfig": { "access": "public" diff --git a/packages/jest/package.json b/packages/jest/package.json index ce9e66501..2779d16f6 100644 --- a/packages/jest/package.json +++ b/packages/jest/package.json @@ -40,7 +40,7 @@ "@emotion/css-prettifier": "^1.1.0", "chalk": "^4.1.0", "specificity": "^0.4.1", - "stylis": "4.0.13" + "stylis": "4.1.2" }, "peerDependencies": { "@types/jest": "^26.0.14 || ^27.0.0 || ^28.0.0 || ^29.0.0", diff --git a/yarn.lock b/yarn.lock index 1645aefc1..cf04bae5c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2361,7 +2361,7 @@ __metadata: escape-string-regexp: ^4.0.0 find-root: ^1.1.0 source-map: ^0.5.7 - stylis: 4.0.13 + stylis: 4.1.2 peerDependencies: "@babel/core": ^7.0.0 languageName: unknown @@ -2391,7 +2391,7 @@ __metadata: "@emotion/sheet": ^1.2.0 "@emotion/utils": ^1.2.0 "@emotion/weak-memoize": ^0.3.0 - stylis: 4.0.13 + stylis: 4.1.2 typescript: ^4.5.5 languageName: unknown linkType: soft @@ -2401,7 +2401,7 @@ __metadata: resolution: "@emotion/css-prettifier@workspace:packages/css-prettifier" dependencies: "@emotion/memoize": ^0.8.0 - stylis: 4.0.13 + stylis: 4.1.2 languageName: unknown linkType: soft @@ -2479,7 +2479,7 @@ __metadata: react: 16.14.0 react-dom: 16.14.0 specificity: ^0.4.1 - stylis: 4.0.13 + stylis: 4.1.2 typescript: ^4.5.5 peerDependencies: "@types/jest": ^26.0.14 || ^27.0.0 || ^28.0.0 || ^29.0.0 @@ -28332,10 +28332,10 @@ __metadata: languageName: node linkType: hard -"stylis@npm:4.0.13": - version: 4.0.13 - resolution: "stylis@npm:4.0.13" - checksum: 8ea7a87028b6383c6a982231c4b5b6150031ce028e0fdaf7b2ace82253d28a8af50cc5a9da8a421d3c7c4441592f393086e332795add672aa4a825f0fe3713a3 +"stylis@npm:4.1.2": + version: 4.1.2 + resolution: "stylis@npm:4.1.2" + checksum: de5771526216ca156f7ccdece70d0e2b4d5611a2a64f34d0165707b06bd8b6ba7913f2eb9b7998c0f9145077079f46d5084b6a60c97ec10b8d776bef293e9f8c languageName: node linkType: hard