diff --git a/src/cascade.ts b/src/cascade.ts index ed4241d..019d9e7 100644 --- a/src/cascade.ts +++ b/src/cascade.ts @@ -70,7 +70,7 @@ function expandInsetShorthands(node: CssNode, block?: Block) { }; if (node.property === 'inset') { - const values = node.value.children.toArray(); + const values = node.value.children?.toArray() || []; // `inset` shorthand expands to top, right, bottom, left // See https://drafts.csswg.org/css-position/#inset-shorthands const [top, right, bottom, left] = (() => { @@ -92,7 +92,7 @@ function expandInsetShorthands(node: CssNode, block?: Block) { appendProperty('bottom', bottom); appendProperty('left', left); } else if (node.property === 'inset-block') { - const values = node.value.children.toArray(); + const values = node.value.children?.toArray() || []; const [blockStart, blockEnd] = (() => { switch (values.length) { case 1: @@ -106,7 +106,7 @@ function expandInsetShorthands(node: CssNode, block?: Block) { appendProperty('inset-block-start', blockStart); appendProperty('inset-block-end', blockEnd); } else if (node.property === 'inset-inline') { - const values = node.value.children.toArray(); + const values = node.value.children?.toArray() || []; const [inlineStart, inlineEnd] = (() => { switch (values.length) { case 1: diff --git a/src/fallback.ts b/src/fallback.ts index 43ee7a4..9e88280 100644 --- a/src/fallback.ts +++ b/src/fallback.ts @@ -319,7 +319,7 @@ function mapMargin( ) { // TODO: Handle flip-start if (key === 'margin') { - const [first, second, third, fourth] = valueAst.children.toArray(); + const [first, second, third, fourth] = valueAst.children?.toArray() || []; if (tactic === 'flip-block') { if (fourth) { valueAst.children.fromArray([third, second, first, fourth]); @@ -332,14 +332,14 @@ function mapMargin( } // No change needed for 1, 2 or 3 values } } else if (key === 'margin-block') { - const [first, second] = valueAst.children.toArray(); + const [first, second] = valueAst.children?.toArray() || []; if (tactic === 'flip-block') { if (second) { valueAst.children.fromArray([second, first]); } } } else if (key === 'margin-inline') { - const [first, second] = valueAst.children.toArray(); + const [first, second] = valueAst.children?.toArray() || []; if (tactic === 'flip-inline') { if (second) { valueAst.children.fromArray([second, first]); @@ -351,9 +351,9 @@ function mapMargin( // Parses a value into an AST. const getValueAST = (property: string, val: string) => { const ast = getAST(`#id{${property}: ${val};}`) as Block; - const astDeclaration = (ast.children.first as Rule)?.block.children - .first as Declaration; - return astDeclaration.value as Value; + const astDeclaration = (ast.children?.first as Rule)?.block?.children + ?.first as Declaration; + return astDeclaration?.value as Value; }; export function applyTryTacticToBlock( @@ -453,7 +453,7 @@ function parsePositionTryFallbacks(list: List) { } function getPositionTryFallbacksDeclaration(node: Declaration) { - if (isPositionTryFallbacksDeclaration(node) && node.value.children.first) { + if (isPositionTryFallbacksDeclaration(node) && node.value.children?.first) { return parsePositionTryFallbacks(node.value.children); } return []; @@ -463,11 +463,11 @@ export function getPositionTryDeclaration(node: Declaration): { order?: PositionTryOrder; options?: PositionTryObject[]; } { - if (isPositionTryDeclaration(node) && node.value.children.first) { + if (isPositionTryDeclaration(node) && node.value.children?.first) { const declarationNode = clone(node) as DeclarationWithValue; let order: PositionTryOrder | undefined; // get potential order - const firstName = (declarationNode.value.children.first as Identifier).name; + const firstName = (declarationNode.value.children?.first as Identifier)?.name; if (firstName && isPositionTryOrder(firstName)) { order = firstName; declarationNode.value.children.shift(); @@ -480,9 +480,9 @@ export function getPositionTryDeclaration(node: Declaration): { } function getPositionTryOrderDeclaration(node: Declaration) { - if (isPositionTryOrderDeclaration(node) && node.value.children.first) { + if (isPositionTryOrderDeclaration(node) && node.value.children?.first) { return { - order: (node.value.children.first as Identifier).name as PositionTryOrder, + order: (node.value.children.first as Identifier)?.name as PositionTryOrder, }; } return {}; diff --git a/src/index-wpt.ts b/src/index-wpt.ts index bb11d4d..1b7d949 100644 --- a/src/index-wpt.ts +++ b/src/index-wpt.ts @@ -2,13 +2,15 @@ import { polyfill } from './polyfill.js'; // Used by the WPT test harness to delay test assertions // and give the polyfill time to apply changes -window.CHECK_LAYOUT_DELAY = true; +if (typeof window !== 'undefined') { + window.CHECK_LAYOUT_DELAY = true; -// apply polyfill -if (document.readyState !== 'complete') { - window.addEventListener('load', () => { + // apply polyfill + if (document.readyState !== 'complete') { + window.addEventListener('load', () => { + polyfill(true); + }); + } else { polyfill(true); - }); -} else { - polyfill(true); + } } diff --git a/src/index.ts b/src/index.ts index 575e326..9b24c17 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,12 @@ import { polyfill } from './polyfill.js'; // apply polyfill -if (document.readyState !== 'complete') { - window.addEventListener('load', () => { +if (typeof window !== 'undefined') { + if (document.readyState !== 'complete') { + window.addEventListener('load', () => { + polyfill(); + }); + } else { polyfill(); - }); -} else { - polyfill(); + } } diff --git a/src/parse.ts b/src/parse.ts index a91a1b5..f8112cc 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -142,7 +142,7 @@ function parseAnchorFn( customPropName: string | undefined; const args: CssNode[] = []; - node.children.toArray().forEach((child) => { + node.children?.toArray()?.forEach((child) => { if (foundComma) { fallbackValue = `${fallbackValue}${generateCSS(child)}`; return; @@ -164,9 +164,9 @@ function parseAnchorFn( if (isIdentifier(name) && name.name.startsWith('--')) { // Store anchor name anchorName = name.name; - } else if (isVarFunction(name) && name.children.first) { + } else if (isVarFunction(name) && name.children?.first) { // Store CSS custom prop for anchor name - customPropName = (name.children.first as Identifier).name; + customPropName = (name.children.first as Identifier)?.name; } } if (sideOrSize) { @@ -210,7 +210,7 @@ function parseAnchorFn( } function getAnchorNames(node: DeclarationWithValue) { - return (node.value.children as List).map(({ name }) => name); + return (node.value.children as List)?.map(({ name }) => name) || []; } let anchorNames: AnchorSelectors = {}; @@ -427,8 +427,8 @@ export async function parseCSS( isVarFunction(node) && declaration && prop && - node.children.first && - customPropsToCheck.has((node.children.first as Identifier).name) && + node.children?.first && + customPropsToCheck.has((node.children.first as Identifier)?.name) && // For now, we only want assignments to other CSS custom properties prop.startsWith('--') ) { @@ -496,7 +496,7 @@ export async function parseCSS( isVarFunction(node) && declaration && prop && - node.children.first && + node.children?.first && // Now we only want assignments to inset/sizing properties (isInsetProp(prop) || isSizingProp(prop)) ) { @@ -649,7 +649,7 @@ export async function parseCSS( enter(node) { if ( isVarFunction(node) && - (node.children.first as Identifier)?.name?.startsWith('--') && + (node.children?.first as Identifier)?.name?.startsWith('--') && this.declaration?.property?.startsWith('--') && this.block ) { diff --git a/src/position-area.ts b/src/position-area.ts index 8f3fc29..756e57f 100644 --- a/src/position-area.ts +++ b/src/position-area.ts @@ -457,8 +457,8 @@ function isPositionAreaDeclaration( function parsePositionAreaValue(node: DeclarationWithValue) { const value = (node.value.children as List) - .toArray() - .map(({ name }) => name); + ?.toArray() + ?.map(({ name }) => name) || []; if (value.length === 1) { if (axisForPositionAreaValue(value[0]) === 'ambiguous') { value.push(value[0]); diff --git a/src/utils.ts b/src/utils.ts index 58b7bb3..3245e24 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -61,7 +61,7 @@ export function isDeclaration(node: CssNode): node is DeclarationWithValue { } export function getDeclarationValue(node: DeclarationWithValue) { - return (node.value.children.first as Identifier).name; + return (node.value.children?.first as Identifier)?.name; } export interface StyleData { @@ -95,7 +95,7 @@ export function getSelectors(rule: SelectorList | undefined) { if (!rule) return []; return (rule.children as List) - .map((selector) => { + ?.map((selector) => { let pseudoElementPart: string | undefined; if (selector.children.last?.type === 'PseudoElementSelector') { @@ -112,7 +112,7 @@ export function getSelectors(rule: SelectorList | undefined) { pseudoElementPart, } satisfies Selector; }) - .toArray(); + .toArray() || []; } export function reportParseErrorsOnFailure() {