import type { ShallowRef, ExtractPropTypes, InjectionKey, Ref } from 'vue'; import { provide, defineComponent, unref, inject, watch, shallowRef, getCurrentInstance, } from 'vue'; import CacheEntity from './Cache'; import type { Linter } from './linters/interface'; import type { Transformer } from './transformers/interface'; import { arrayType, booleanType, objectType, someType, stringType, withInstall } from '../type'; export const ATTR_TOKEN = 'data-token-hash'; export const ATTR_MARK = 'data-css-hash'; export const ATTR_CACHE_PATH = 'data-cache-path'; // Mark css-in-js instance in style element export const CSS_IN_JS_INSTANCE = '__cssinjs_instance__'; export function createCache() { const cssinjsInstanceId = Math.random().toString(12).slice(2); // Tricky SSR: Move all inline style to the head. // PS: We do not recommend tricky mode. if (typeof document !== 'undefined' && document.head && document.body) { const styles = document.body.querySelectorAll(`style[${ATTR_MARK}]`) || []; const { firstChild } = document.head; Array.from(styles).forEach(style => { (style as any)[CSS_IN_JS_INSTANCE] = (style as any)[CSS_IN_JS_INSTANCE] || cssinjsInstanceId; // Not force move if no head // Not force move if no head if ((style as any)[CSS_IN_JS_INSTANCE] === cssinjsInstanceId) { document.head.insertBefore(style, firstChild); } }); // Deduplicate of moved styles const styleHash: Record = {}; Array.from(document.querySelectorAll(`style[${ATTR_MARK}]`)).forEach(style => { const hash = style.getAttribute(ATTR_MARK)!; if (styleHash[hash]) { if ((style as any)[CSS_IN_JS_INSTANCE] === cssinjsInstanceId) { style.parentNode?.removeChild(style); } } else { styleHash[hash] = true; } }); } return new CacheEntity(cssinjsInstanceId); } export type HashPriority = 'low' | 'high'; export interface StyleContextProps { autoClear?: boolean; /** @private Test only. Not work in production. */ mock?: 'server' | 'client'; /** * Only set when you need ssr to extract style on you own. * If not provided, it will auto create