import hyphenateStyleName from "hyphenate-style-name"; import createReactDOMStyle from "react-native-web/dist/exports/StyleSheet/createReactDOMStyle"; import prefixStyles from "react-native-web/dist/modules/prefixStyles"; export function createWebCssRule(selector: string, cssRules: {}) { const css = createDeclarationBlock(cssRules); const identifier = murmurHash(`${selector}${css}`); if (selector.substr(0, 1) === "@") { // selector is a media query return { identifier, rule: `/*${identifier}*/${selector}{[data-testid~="${identifier}"][data-testid~="${identifier}"]${css}}`, }; } // selector is something else such as ":hover" return { identifier, rule: `[data-testid~="${identifier}"][data-testid~="${identifier}"]${selector}${css}`, }; } function createDeclarationBlock(style: any) { const domStyle = prefixStyles(createReactDOMStyle(style)); const declarationsString = Object.keys(domStyle) .map((property) => { const value = domStyle[property]; const prop = hyphenateStyleName(property); if (Array.isArray(value)) { return value.map((v) => `${prop}:${v}`).join(";"); } else { return `${prop}:${value}`; } }) .sort() .join(";"); return `{${declarationsString};}`; } export function murmurHash(str: string) { /* tslint:disable:no-bitwise */ let l = str.length; let h = l ^ l; let i = 0; let k; while (l >= 4) { k = (str.charCodeAt(i) & 0xff) | ((str.charCodeAt(++i) & 0xff) << 8) | ((str.charCodeAt(++i) & 0xff) << 16) | ((str.charCodeAt(++i) & 0xff) << 24); k = (k & 0xffff) * 0x5bd1e995 + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16); k ^= k >>> 24; k = (k & 0xffff) * 0x5bd1e995 + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16); h = ((h & 0xffff) * 0x5bd1e995 + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k; l -= 4; ++i; } switch (l) { case 3: h ^= (str.charCodeAt(i + 2) & 0xff) << 16; case 2: h ^= (str.charCodeAt(i + 1) & 0xff) << 8; case 1: h ^= str.charCodeAt(i) & 0xff; h = (h & 0xffff) * 0x5bd1e995 + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16); } h ^= h >>> 13; h = (h & 0xffff) * 0x5bd1e995 + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16); h ^= h >>> 15; return (h >>> 0).toString(36); /* tslint:enable */ }