// 1:1 with Rust import { memoize } from "../core/memo"; import { DeclValueRoot, RootValue } from "./decl-value-ast"; export enum SelectorScopeKind { Element = "Element", Document = "Document", } type BaseSelectorScope = { kind: TKind; }; export type ElementSelectorScope = BaseSelectorScope; export type DocumentSelectorScope = BaseSelectorScope; export type SelectorScope = ElementSelectorScope | DocumentSelectorScope; export enum SelectorInfoKind { List = "list", All = "All", Element = "Element", PseudoElement = "PseudoElement", PsuedoParamElement = "PseudoParamElement", Attribute = "Attribute", Not = "Not", Id = "Id", Class = "Class", Combo = "Combo", Child = "Child", Descendent = "Descendent", Adjacent = "Adjacent", Sibling = "Sibling", } export type BaseSelectorInfo = { kind: TKind; }; export type GroupSelectorInfo = { selectors: Array>; } & BaseSelectorInfo; export type TargetSelectorInfo = { value: string; } & BaseSelectorInfo; export type WrapperSelectorInfo = { selector: BaseSelectorInfo; } & BaseSelectorInfo; export type BinarySelectorInfo = { left: BaseSelectorInfo; right: BaseSelectorInfo; } & BaseSelectorInfo; export type ListSelectorInfo = GroupSelectorInfo; export type ElementSelectorInfo = TargetSelectorInfo; export type AllSelectorInfo = GroupSelectorInfo; export type PseudoElementSelectorInfo = TargetSelectorInfo; export type PseudoParamElementSelectorInfo = TargetSelectorInfo; export type AttributeSelectorInfo = TargetSelectorInfo; export type NotSelectorInfo = WrapperSelectorInfo; export type IdSelectorInfo = TargetSelectorInfo; export type ClassSelectorInfo = { name: string; value: string; scope: SelectorScope; } & BaseSelectorInfo; export type ComboSelectorInfo = GroupSelectorInfo; export type ChildSelectorInfo = BinarySelectorInfo; export type DescendentSelectorInfo = BinarySelectorInfo; export type AdjacentSelectorInfo = BinarySelectorInfo; export type SiblingSelectorInfo = BinarySelectorInfo; export type SelectorInfo = | ListSelectorInfo | ElementSelectorInfo | AllSelectorInfo | PseudoElementSelectorInfo | PseudoParamElementSelectorInfo | AttributeSelectorInfo | NotSelectorInfo | IdSelectorInfo | ClassSelectorInfo | ComboSelectorInfo | ChildSelectorInfo | DescendentSelectorInfo | AdjacentSelectorInfo | SiblingSelectorInfo; export type StyleDeclarationInfo = { sourceId: string; name: string; rawValue: string; value: DeclValueRoot; active: boolean; }; export type MediaInfo = { conditionText: string; active: boolean; }; export type StyleRuleInfo = { selectorText: string; inherited: boolean; selectorInfo: SelectorInfo; pseudoElementName?: string; sourceId: string; sourceUri: string; media?: MediaInfo; declarations: StyleDeclarationInfo[]; specificity: number; }; export type NodeStyleInspection = { styleRules: StyleRuleInfo[]; }; export type ComputedDeclarationInfo = { name: string; rawValue: string; value: DeclValueRoot; variable?: boolean; sourceRules: StyleRuleInfo[]; }; export type SquashedStyleInspection = Record; const INHERITED_DECLS = [ "border-collapse", "border-spacing", "caption-side", "color", "cursor", "direction", "empty-cells", "font-family", "font-size", "font-style", "font-variant", "font-weight", "font-size-adjust", "font-stretch", "font", "letter-spacing", "line-height", "list-style-image", "list-style-position", "list-style-type", "list-style", "orphans", "quotes", "tab-size", "text-align", "text-align-last", "text-decoration-color", "text-indent", "text-justify", "text-shadow", "text-transform", "visibility", "white-space", "widows", "word-break", "word-spacing", "word-wrap", ]; export const squashInspection = memoize( (inspection: NodeStyleInspection): ComputedDeclarationInfo[] => { const squashed: Array = []; const used: Record = {}; for (const rule of inspection.styleRules) { for (const declaration of rule.declarations) { if (rule.inherited && !INHERITED_DECLS.includes(declaration.name)) { continue; } if (!used[declaration.name]) { squashed.push( (used[declaration.name] = { name: declaration.name, variable: declaration.name.indexOf("--") === 0, value: declaration.value, rawValue: declaration.rawValue, sourceRules: [], }) ); } used[declaration.name].sourceRules.push(rule); } } return squashed; } );