Skip to content

Commit 326361b

Browse files
committed
feat: re-implement accordion item parsing and update block item structure
1 parent 832d453 commit 326361b

2 files changed

Lines changed: 67 additions & 92 deletions

File tree

src/parsers/website/index.ts

Lines changed: 54 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ import type {
1313
ContextTreeLevelItem,
1414
Style,
1515
StylesheetItem,
16+
WebAccordionItem,
1617
WebBlock,
18+
WebBlockItem,
1719
WebElement,
1820
WebElementComponent,
1921
WebImage,
@@ -1990,28 +1992,17 @@ function parseSidebar<T extends ReadonlyArray<string>>(
19901992
return returnSidebar;
19911993
}
19921994

1993-
/**
1994-
* Parses raw text element data for accordion layout with items support
1995-
*
1996-
* @param elementResource - Raw element resource data in OCHRE format
1997-
* @returns Parsed text WebElement with items array
1998-
*/
1999-
function parseWebElementForAccordion<T extends ReadonlyArray<string>>(
1995+
function parseWebAccordionItem<T extends ReadonlyArray<string>>(
20001996
elementResource: XMLWebsiteResource,
1997+
childResources: Array<XMLWebsiteResource>,
20011998
options: ParserOptions<T>,
2002-
): Extract<WebElement<T>, { component: "text" }> & {
2003-
items: Array<WebElement<T> | WebBlock<T>>;
2004-
} {
2005-
const textElement = parseWebElement(elementResource, options) as Extract<
2006-
WebElement<T>,
2007-
{ component: "text" }
2008-
>;
2009-
2010-
const childResources = elementResource.resource
2011-
? normalizeWebsiteResources(elementResource.resource)
2012-
: [];
1999+
): WebAccordionItem<T> {
2000+
const trigger = parseWebElement(
2001+
elementResource,
2002+
options,
2003+
) as WebAccordionItem<T>["trigger"];
20132004

2014-
const items: Array<WebElement<T> | WebBlock<T>> = [];
2005+
const items: Array<WebBlockItem<T>> = [];
20152006
for (const resource of childResources) {
20162007
const resourceProperties = resource.properties
20172008
? parseSimplifiedProperties(resource.properties, options)
@@ -2040,7 +2031,7 @@ function parseWebElementForAccordion<T extends ReadonlyArray<string>>(
20402031
}
20412032
}
20422033

2043-
return { ...textElement, items };
2034+
return { uuid: trigger.uuid, type: "accordion-item", trigger, items };
20442035
}
20452036

20462037
/**
@@ -2231,83 +2222,60 @@ function parseWebBlock<T extends ReadonlyArray<string>>(
22312222
? normalizeWebsiteResources(blockResource.resource)
22322223
: [];
22332224

2234-
if (returnBlock.properties.default.layout === "accordion") {
2235-
const accordionItems: Array<
2236-
Extract<WebElement<T>, { component: "text" }> & {
2237-
items: Array<WebElement<T> | WebBlock<T>>;
2238-
}
2239-
> = [];
2240-
2241-
for (const resource of blockResources) {
2242-
const resourceProperties = resource.properties
2243-
? parseSimplifiedProperties(resource.properties, options)
2244-
: [];
2245-
const resourceReader = websitePresentationReader(resourceProperties);
2246-
2247-
const resourceType = resourceReader.value<"element" | "block">(
2248-
"presentation",
2249-
);
2225+
const supportsAccordionItems =
2226+
returnBlock.properties.default.layout === "accordion" ||
2227+
returnBlock.properties.tablet?.layout === "accordion" ||
2228+
returnBlock.properties.mobile?.layout === "accordion";
22502229

2251-
if (resourceType !== "element") {
2252-
throw new Error(
2253-
`Accordion only accepts elements, but got “${resourceType}” (${formatXMLWebsiteResourceMetadata(
2254-
resource,
2255-
)})`,
2256-
{ cause: resource },
2257-
);
2258-
}
2259-
2260-
const componentType = resourceReader
2261-
.nestedByValue("presentation", "element")
2262-
.value<string>("component");
2263-
2264-
if (componentType !== "text") {
2265-
throw new Error(
2266-
`Accordion only accepts text components, but got “${componentType}” (${formatXMLWebsiteResourceMetadata(
2267-
resource,
2268-
)})`,
2269-
{ cause: resource },
2270-
);
2271-
}
2230+
const blockItems: Array<WebAccordionItem<T> | WebBlockItem<T>> = [];
2231+
for (const resource of blockResources) {
2232+
const resourceProperties = resource.properties
2233+
? parseSimplifiedProperties(resource.properties, options)
2234+
: [];
2235+
const resourceReader = websitePresentationReader(resourceProperties);
22722236

2273-
const element = parseWebElementForAccordion(resource, options);
2274-
accordionItems.push(element);
2237+
const resourceType = resourceReader.value<"element" | "block">(
2238+
"presentation",
2239+
);
2240+
if (resourceType === null) {
2241+
continue;
22752242
}
22762243

2277-
returnBlock.items = accordionItems;
2278-
} else {
2279-
const blockItems: Array<WebElement<T> | WebBlock<T>> = [];
2280-
for (const resource of blockResources) {
2281-
const resourceProperties = resource.properties
2282-
? parseSimplifiedProperties(resource.properties, options)
2283-
: [];
2284-
2285-
const resourceType = websitePresentationReader(resourceProperties).value<
2286-
"element" | "block"
2287-
>("presentation");
2288-
if (resourceType === null) {
2289-
continue;
2290-
}
2291-
2292-
switch (resourceType) {
2293-
case "element": {
2294-
const element = parseWebElement(resource, options);
2295-
blockItems.push(element);
2244+
switch (resourceType) {
2245+
case "element": {
2246+
const childResources = resource.resource
2247+
? normalizeWebsiteResources(resource.resource)
2248+
: [];
2249+
const componentType = resourceReader
2250+
.nestedByValue("presentation", "element")
2251+
.value<string>("component");
2252+
2253+
if (
2254+
supportsAccordionItems &&
2255+
componentType === "text" &&
2256+
childResources.length > 0
2257+
) {
2258+
const item = parseWebAccordionItem(resource, childResources, options);
2259+
blockItems.push(item);
22962260
break;
22972261
}
2298-
case "block": {
2299-
const block = parseWebBlock(resource, options);
2300-
if (block) {
2301-
blockItems.push(block);
2302-
}
2303-
break;
2262+
2263+
const element = parseWebElement(resource, options);
2264+
blockItems.push(element);
2265+
break;
2266+
}
2267+
case "block": {
2268+
const block = parseWebBlock(resource, options);
2269+
if (block) {
2270+
blockItems.push(block);
23042271
}
2272+
break;
23052273
}
23062274
}
2307-
2308-
returnBlock.items = blockItems;
23092275
}
23102276

2277+
returnBlock.items = blockItems;
2278+
23112279
returnBlock.cssStyles = parseResponsiveCssStyles(blockProperties);
23122280

23132281
return returnBlock;

src/types/website.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,17 @@ export type WebBlockLayout =
496496
| "horizontal-flex"
497497
| "accordion";
498498

499+
export type WebBlockItem<T extends LanguageCodes = LanguageCodes> =
500+
| WebElement<T>
501+
| WebBlock<T>;
502+
503+
export type WebAccordionItem<T extends LanguageCodes = LanguageCodes> = {
504+
uuid: string;
505+
type: "accordion-item";
506+
trigger: WebElementOf<"text", T>;
507+
items: Array<WebBlockItem<T>>;
508+
};
509+
499510
/**
500511
* Represents a block of vertical or horizontal content alignment
501512
*/
@@ -507,12 +518,8 @@ export type WebBlock<
507518
type: "block";
508519
title: WebTitle<T>;
509520
items: U extends "accordion"
510-
? Array<
511-
Extract<WebElement<T>, { component: "text" }> & {
512-
items: Array<WebElement<T> | WebBlock<T>>;
513-
}
514-
>
515-
: Array<WebElement<T> | WebBlock<T>>;
521+
? Array<WebAccordionItem<T> | WebBlockItem<T>>
522+
: Array<WebBlockItem<T>>;
516523
properties: {
517524
default: {
518525
layout: U;

0 commit comments

Comments
 (0)