439 lines
13 KiB
JavaScript
Executable File
439 lines
13 KiB
JavaScript
Executable File
import { StyleSheet } from '@emotion/sheet';
|
|
import { dealloc, alloc, next, token, from, peek, delimit, slice, position, RULESET, combine, match, serialize, copy, replace, WEBKIT, MOZ, MS, KEYFRAMES, DECLARATION, hash, charat, strlen, indexof, stringify, rulesheet, middleware, compile } from 'stylis';
|
|
import '@emotion/weak-memoize';
|
|
import '@emotion/memoize';
|
|
|
|
var identifierWithPointTracking = function identifierWithPointTracking(begin, points, index) {
|
|
var previous = 0;
|
|
var character = 0;
|
|
|
|
while (true) {
|
|
previous = character;
|
|
character = peek(); // &\f
|
|
|
|
if (previous === 38 && character === 12) {
|
|
points[index] = 1;
|
|
}
|
|
|
|
if (token(character)) {
|
|
break;
|
|
}
|
|
|
|
next();
|
|
}
|
|
|
|
return slice(begin, position);
|
|
};
|
|
|
|
var toRules = function toRules(parsed, points) {
|
|
// pretend we've started with a comma
|
|
var index = -1;
|
|
var character = 44;
|
|
|
|
do {
|
|
switch (token(character)) {
|
|
case 0:
|
|
// &\f
|
|
if (character === 38 && peek() === 12) {
|
|
// this is not 100% correct, we don't account for literal sequences here - like for example quoted strings
|
|
// stylis inserts \f after & to know when & where it should replace this sequence with the context selector
|
|
// and when it should just concatenate the outer and inner selectors
|
|
// it's very unlikely for this sequence to actually appear in a different context, so we just leverage this fact here
|
|
points[index] = 1;
|
|
}
|
|
|
|
parsed[index] += identifierWithPointTracking(position - 1, points, index);
|
|
break;
|
|
|
|
case 2:
|
|
parsed[index] += delimit(character);
|
|
break;
|
|
|
|
case 4:
|
|
// comma
|
|
if (character === 44) {
|
|
// colon
|
|
parsed[++index] = peek() === 58 ? '&\f' : '';
|
|
points[index] = parsed[index].length;
|
|
break;
|
|
}
|
|
|
|
// fallthrough
|
|
|
|
default:
|
|
parsed[index] += from(character);
|
|
}
|
|
} while (character = next());
|
|
|
|
return parsed;
|
|
};
|
|
|
|
var getRules = function getRules(value, points) {
|
|
return dealloc(toRules(alloc(value), points));
|
|
}; // WeakSet would be more appropriate, but only WeakMap is supported in IE11
|
|
|
|
|
|
var fixedElements = /* #__PURE__ */new WeakMap();
|
|
var compat = function compat(element) {
|
|
if (element.type !== 'rule' || !element.parent || // positive .length indicates that this rule contains pseudo
|
|
// negative .length indicates that this rule has been already prefixed
|
|
element.length < 1) {
|
|
return;
|
|
}
|
|
|
|
var value = element.value;
|
|
var parent = element.parent;
|
|
var isImplicitRule = element.column === parent.column && element.line === parent.line;
|
|
|
|
while (parent.type !== 'rule') {
|
|
parent = parent.parent;
|
|
if (!parent) return;
|
|
} // short-circuit for the simplest case
|
|
|
|
|
|
if (element.props.length === 1 && value.charCodeAt(0) !== 58
|
|
/* colon */
|
|
&& !fixedElements.get(parent)) {
|
|
return;
|
|
} // if this is an implicitly inserted rule (the one eagerly inserted at the each new nested level)
|
|
// then the props has already been manipulated beforehand as they that array is shared between it and its "rule parent"
|
|
|
|
|
|
if (isImplicitRule) {
|
|
return;
|
|
}
|
|
|
|
fixedElements.set(element, true);
|
|
var points = [];
|
|
var rules = getRules(value, points);
|
|
var parentRules = parent.props;
|
|
|
|
for (var i = 0, k = 0; i < rules.length; i++) {
|
|
for (var j = 0; j < parentRules.length; j++, k++) {
|
|
element.props[k] = points[i] ? rules[i].replace(/&\f/g, parentRules[j]) : parentRules[j] + " " + rules[i];
|
|
}
|
|
}
|
|
};
|
|
var removeLabel = function removeLabel(element) {
|
|
if (element.type === 'decl') {
|
|
var value = element.value;
|
|
|
|
if ( // charcode for l
|
|
value.charCodeAt(0) === 108 && // charcode for b
|
|
value.charCodeAt(2) === 98) {
|
|
// this ignores label
|
|
element["return"] = '';
|
|
element.value = '';
|
|
}
|
|
}
|
|
};
|
|
|
|
/* eslint-disable no-fallthrough */
|
|
|
|
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;
|
|
}
|
|
|
|
var prefixer = function 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 '';
|
|
});
|
|
}
|
|
};
|
|
|
|
var defaultStylisPlugins = [prefixer];
|
|
|
|
var createCache = function createCache(options) {
|
|
var key = options.key;
|
|
|
|
if (key === 'css') {
|
|
var ssrStyles = document.querySelectorAll("style[data-emotion]:not([data-s])"); // get SSRed styles out of the way of React's hydration
|
|
// document.head is a safe place to move them to(though note document.head is not necessarily the last place they will be)
|
|
// note this very very intentionally targets all style elements regardless of the key to ensure
|
|
// that creating a cache works inside of render of a React component
|
|
|
|
Array.prototype.forEach.call(ssrStyles, function (node) {
|
|
// we want to only move elements which have a space in the data-emotion attribute value
|
|
// because that indicates that it is an Emotion 11 server-side rendered style elements
|
|
// while we will already ignore Emotion 11 client-side inserted styles because of the :not([data-s]) part in the selector
|
|
// Emotion 10 client-side inserted styles did not have data-s (but importantly did not have a space in their data-emotion attributes)
|
|
// so checking for the space ensures that loading Emotion 11 after Emotion 10 has inserted some styles
|
|
// will not result in the Emotion 10 styles being destroyed
|
|
var dataEmotionAttribute = node.getAttribute('data-emotion');
|
|
|
|
if (dataEmotionAttribute.indexOf(' ') === -1) {
|
|
return;
|
|
}
|
|
|
|
document.head.appendChild(node);
|
|
node.setAttribute('data-s', '');
|
|
});
|
|
}
|
|
|
|
var stylisPlugins = options.stylisPlugins || defaultStylisPlugins;
|
|
|
|
var inserted = {};
|
|
var container;
|
|
var nodesToHydrate = [];
|
|
|
|
{
|
|
container = options.container || document.head;
|
|
Array.prototype.forEach.call( // this means we will ignore elements which don't have a space in them which
|
|
// means that the style elements we're looking at are only Emotion 11 server-rendered style elements
|
|
document.querySelectorAll("style[data-emotion^=\"" + key + " \"]"), function (node) {
|
|
var attrib = node.getAttribute("data-emotion").split(' ');
|
|
|
|
for (var i = 1; i < attrib.length; i++) {
|
|
inserted[attrib[i]] = true;
|
|
}
|
|
|
|
nodesToHydrate.push(node);
|
|
});
|
|
}
|
|
|
|
var _insert;
|
|
|
|
var omnipresentPlugins = [compat, removeLabel];
|
|
|
|
{
|
|
var currentSheet;
|
|
var finalizingPlugins = [stringify, rulesheet(function (rule) {
|
|
currentSheet.insert(rule);
|
|
})];
|
|
var serializer = middleware(omnipresentPlugins.concat(stylisPlugins, finalizingPlugins));
|
|
|
|
var stylis = function stylis(styles) {
|
|
return serialize(compile(styles), serializer);
|
|
};
|
|
|
|
_insert = function insert(selector, serialized, sheet, shouldCache) {
|
|
currentSheet = sheet;
|
|
|
|
stylis(selector ? selector + "{" + serialized.styles + "}" : serialized.styles);
|
|
|
|
if (shouldCache) {
|
|
cache.inserted[serialized.name] = true;
|
|
}
|
|
};
|
|
}
|
|
|
|
var cache = {
|
|
key: key,
|
|
sheet: new StyleSheet({
|
|
key: key,
|
|
container: container,
|
|
nonce: options.nonce,
|
|
speedy: options.speedy,
|
|
prepend: options.prepend,
|
|
insertionPoint: options.insertionPoint
|
|
}),
|
|
nonce: options.nonce,
|
|
inserted: inserted,
|
|
registered: {},
|
|
insert: _insert
|
|
};
|
|
cache.sheet.hydrate(nodesToHydrate);
|
|
return cache;
|
|
};
|
|
|
|
export { createCache as default };
|