@wix/zero-config-implementation 1.72.0 → 1.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-CdHu4-o-.js → index-K3lIO4FC.js} +11986 -11771
- package/dist/{index-CSi4SZpQ.js → index-NbI-_ozJ.js} +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/src/converters/to-editor-component.test.ts +88 -0
- package/src/converters/to-editor-component.ts +11 -0
- package/src/information-extractors/css/parse.test.ts +49 -1
- package/src/information-extractors/css/parse.ts +167 -3
- package/src/information-extractors/css/selector-matcher.ts +3 -1
- package/src/information-extractors/css/types.ts +11 -0
- package/src/information-extractors/react/extractors/css-properties.test.ts +294 -2
- package/src/information-extractors/react/extractors/css-properties.ts +246 -98
- package/src/information-extractors/react/extractors/index.ts +1 -0
- package/src/information-extractors/react/index.ts +1 -0
- package/src/manifest-pipeline.ts +3 -1
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
* CSS Properties Extractor
|
|
3
3
|
*
|
|
4
4
|
* Determines which CSS properties are relevant to each element
|
|
5
|
-
* based on
|
|
5
|
+
* based on semantic traits and effective display behavior.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { CSS_PROPERTIES } from '@wix/react-component-schema'
|
|
9
|
+
import { resolveCssPropertyValue } from '../../css/parse'
|
|
9
10
|
import type { MatchedCssData } from '../../css/types'
|
|
10
11
|
import type { ExtractedElement } from './core/tree-builder'
|
|
11
12
|
import type { CreateElementEvent, ReactExtractor } from './core/types'
|
|
@@ -19,14 +20,9 @@ export interface CssPropertiesData {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
22
|
-
//
|
|
23
|
+
// Semantic Traits
|
|
23
24
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
24
25
|
|
|
25
|
-
/**
|
|
26
|
-
* Layout Containers - structural boxes focused on spacing and positioning
|
|
27
|
-
*/
|
|
28
|
-
const LAYOUT_CONTAINER_TAGS = new Set(['div', 'section', 'article', 'header', 'footer', 'main', 'nav', 'aside'])
|
|
29
|
-
|
|
30
26
|
/**
|
|
31
27
|
* Text & Typography - elements where readability and hierarchy are primary
|
|
32
28
|
*/
|
|
@@ -53,21 +49,17 @@ const TEXT_TAGS = new Set([
|
|
|
53
49
|
*/
|
|
54
50
|
const MEDIA_TAGS = new Set(['img', 'video', 'canvas', 'picture'])
|
|
55
51
|
|
|
56
|
-
/**
|
|
57
|
-
* Form Inputs & Interactive Elements - require state-based styling
|
|
58
|
-
*/
|
|
59
|
-
const INTERACTIVE_TAGS = new Set(['button', 'input', 'textarea', 'select'])
|
|
60
|
-
|
|
61
52
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
62
53
|
// CSS Property Sets (using logical properties)
|
|
63
54
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
64
55
|
|
|
65
56
|
/**
|
|
66
|
-
* CSS properties for
|
|
57
|
+
* CSS properties for box-generating elements. These are visual box styles,
|
|
58
|
+
* not child-layout controls such as `gap`.
|
|
67
59
|
*/
|
|
68
60
|
const { CSS_PROPERTY_TYPE } = CSS_PROPERTIES
|
|
69
61
|
|
|
70
|
-
const
|
|
62
|
+
const BOX_CSS_PROPERTIES = [
|
|
71
63
|
CSS_PROPERTY_TYPE.background,
|
|
72
64
|
CSS_PROPERTY_TYPE.borderTop,
|
|
73
65
|
CSS_PROPERTY_TYPE.borderBottom,
|
|
@@ -113,81 +105,52 @@ const MEDIA_CSS_PROPERTIES = [
|
|
|
113
105
|
CSS_PROPERTY_TYPE.boxShadow,
|
|
114
106
|
]
|
|
115
107
|
|
|
116
|
-
|
|
117
|
-
// Category Detection
|
|
118
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
119
|
-
|
|
120
|
-
type ElementCategory = 'layout' | 'text' | 'media' | 'interactive' | 'unknown'
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Determines the category of an element based on its tag and role
|
|
124
|
-
*/
|
|
125
|
-
function getElementCategory(tag: string, role?: string): ElementCategory {
|
|
108
|
+
function hasTextSemantics(tag: string, role?: string): boolean {
|
|
126
109
|
const normalizedTag = tag.toLowerCase()
|
|
127
|
-
|
|
128
|
-
// Check role-based overrides first
|
|
129
110
|
if (role) {
|
|
130
111
|
const normalizedRole = role.toLowerCase()
|
|
131
|
-
if (normalizedRole === 'button' || normalizedRole === 'textbox') {
|
|
132
|
-
return 'interactive'
|
|
133
|
-
}
|
|
134
112
|
if (normalizedRole === 'heading' || normalizedRole === 'paragraph') {
|
|
135
|
-
return
|
|
136
|
-
}
|
|
137
|
-
if (normalizedRole === 'img' || normalizedRole === 'figure') {
|
|
138
|
-
return 'media'
|
|
113
|
+
return true
|
|
139
114
|
}
|
|
140
115
|
}
|
|
116
|
+
return TEXT_TAGS.has(normalizedTag)
|
|
117
|
+
}
|
|
141
118
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (MEDIA_TAGS.has(normalizedTag)) {
|
|
150
|
-
return 'media'
|
|
151
|
-
}
|
|
152
|
-
if (LAYOUT_CONTAINER_TAGS.has(normalizedTag)) {
|
|
153
|
-
return 'layout'
|
|
119
|
+
function hasMediaSemantics(tag: string, role?: string): boolean {
|
|
120
|
+
const normalizedTag = tag.toLowerCase()
|
|
121
|
+
if (role) {
|
|
122
|
+
const normalizedRole = role.toLowerCase()
|
|
123
|
+
if (normalizedRole === 'img' || normalizedRole === 'figure') {
|
|
124
|
+
return true
|
|
125
|
+
}
|
|
154
126
|
}
|
|
155
|
-
|
|
156
|
-
return 'unknown'
|
|
127
|
+
return MEDIA_TAGS.has(normalizedTag)
|
|
157
128
|
}
|
|
158
129
|
|
|
159
130
|
/**
|
|
160
|
-
* Gets CSS properties relevant to an element
|
|
131
|
+
* Gets CSS properties relevant to an element from composable traits:
|
|
132
|
+
* text semantics, media semantics, and box-generating display.
|
|
161
133
|
* Note: hasTextContent determination is deferred to tree building since
|
|
162
134
|
* we can't know during createElement if a child will have text content.
|
|
163
135
|
*/
|
|
164
136
|
export function getCssPropertiesForTag(tag: string, role?: string): string[] {
|
|
165
|
-
const category = getElementCategory(tag, role)
|
|
166
137
|
const properties: string[] = []
|
|
138
|
+
const hasTextProperties = hasTextSemantics(tag, role)
|
|
139
|
+
const hasMediaProperties = hasMediaSemantics(tag, role)
|
|
140
|
+
const hasBoxProperties = hasContainerLikeDefaultDisplay(tag) && !hasMediaProperties
|
|
167
141
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
break
|
|
177
|
-
|
|
178
|
-
case 'media':
|
|
179
|
-
properties.push(...MEDIA_CSS_PROPERTIES)
|
|
180
|
-
break
|
|
181
|
-
|
|
182
|
-
case 'unknown':
|
|
183
|
-
// For unknown elements, default to container properties
|
|
184
|
-
// (can be refined during tree building based on children)
|
|
185
|
-
properties.push(...CONTAINER_CSS_PROPERTIES)
|
|
186
|
-
break
|
|
142
|
+
if (hasTextProperties) {
|
|
143
|
+
properties.push(...TEXT_CSS_PROPERTIES)
|
|
144
|
+
}
|
|
145
|
+
if (hasMediaProperties) {
|
|
146
|
+
properties.push(...MEDIA_CSS_PROPERTIES)
|
|
147
|
+
}
|
|
148
|
+
if (hasBoxProperties) {
|
|
149
|
+
properties.push(...BOX_CSS_PROPERTIES)
|
|
187
150
|
}
|
|
188
151
|
|
|
189
152
|
properties.push(CSS_PROPERTY_TYPE.display)
|
|
190
|
-
return properties
|
|
153
|
+
return [...new Set(properties)]
|
|
191
154
|
}
|
|
192
155
|
|
|
193
156
|
/**
|
|
@@ -204,6 +167,19 @@ export function addTextProperties(existing: string[]): string[] {
|
|
|
204
167
|
return result
|
|
205
168
|
}
|
|
206
169
|
|
|
170
|
+
/**
|
|
171
|
+
* Adds box CSS properties to an existing property list without duplicates.
|
|
172
|
+
*/
|
|
173
|
+
export function addBoxProperties(existing: string[]): string[] {
|
|
174
|
+
const result = [...existing]
|
|
175
|
+
for (const property of BOX_CSS_PROPERTIES) {
|
|
176
|
+
if (!result.includes(property)) {
|
|
177
|
+
result.push(property)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return result
|
|
181
|
+
}
|
|
182
|
+
|
|
207
183
|
/**
|
|
208
184
|
* Adds gap CSS property to an existing property list if not already present.
|
|
209
185
|
*/
|
|
@@ -216,21 +192,91 @@ export function addGapProperty(existing: string[]): string[] {
|
|
|
216
192
|
// Display Value Resolution
|
|
217
193
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
218
194
|
|
|
195
|
+
// Based on WebKit and Blink UA stylesheets. The map is intentionally limited
|
|
196
|
+
// to element defaults rather than pseudo-elements or internal control parts.
|
|
219
197
|
const TAG_DEFAULT_DISPLAY: Record<string, string> = {
|
|
220
|
-
span: 'inline',
|
|
221
198
|
a: 'inline',
|
|
222
|
-
|
|
223
|
-
|
|
199
|
+
address: 'block',
|
|
200
|
+
area: 'none',
|
|
201
|
+
article: 'block',
|
|
202
|
+
aside: 'block',
|
|
203
|
+
audio: 'inline',
|
|
224
204
|
b: 'inline',
|
|
205
|
+
base: 'none',
|
|
206
|
+
basefont: 'none',
|
|
207
|
+
blockquote: 'block',
|
|
208
|
+
body: 'block',
|
|
209
|
+
button: 'inline-block',
|
|
210
|
+
canvas: 'inline',
|
|
211
|
+
caption: 'table-caption',
|
|
212
|
+
center: 'block',
|
|
213
|
+
col: 'table-column',
|
|
214
|
+
colgroup: 'table-column-group',
|
|
215
|
+
datalist: 'none',
|
|
216
|
+
dd: 'block',
|
|
217
|
+
dir: 'block',
|
|
218
|
+
div: 'block',
|
|
219
|
+
dl: 'block',
|
|
220
|
+
dt: 'block',
|
|
221
|
+
em: 'inline',
|
|
222
|
+
embed: 'inline',
|
|
223
|
+
fieldset: 'block',
|
|
224
|
+
figcaption: 'block',
|
|
225
|
+
figure: 'block',
|
|
226
|
+
footer: 'block',
|
|
227
|
+
form: 'block',
|
|
228
|
+
h1: 'block',
|
|
229
|
+
h2: 'block',
|
|
230
|
+
h3: 'block',
|
|
231
|
+
h4: 'block',
|
|
232
|
+
h5: 'block',
|
|
233
|
+
h6: 'block',
|
|
234
|
+
head: 'none',
|
|
235
|
+
header: 'block',
|
|
236
|
+
hgroup: 'block',
|
|
237
|
+
hr: 'block',
|
|
238
|
+
html: 'block',
|
|
225
239
|
i: 'inline',
|
|
226
|
-
|
|
240
|
+
iframe: 'inline',
|
|
227
241
|
img: 'inline',
|
|
228
|
-
input: 'inline',
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
button: 'inline-block',
|
|
242
|
+
input: 'inline-block',
|
|
243
|
+
label: 'inline',
|
|
244
|
+
legend: 'block',
|
|
232
245
|
li: 'list-item',
|
|
246
|
+
link: 'none',
|
|
247
|
+
main: 'block',
|
|
248
|
+
map: 'inline',
|
|
249
|
+
marquee: 'inline-block',
|
|
250
|
+
menu: 'block',
|
|
251
|
+
meta: 'none',
|
|
252
|
+
nav: 'block',
|
|
253
|
+
noembed: 'none',
|
|
254
|
+
noframes: 'none',
|
|
255
|
+
object: 'inline',
|
|
256
|
+
ol: 'block',
|
|
257
|
+
p: 'block',
|
|
258
|
+
param: 'none',
|
|
259
|
+
q: 'inline',
|
|
260
|
+
rp: 'none',
|
|
261
|
+
script: 'none',
|
|
262
|
+
search: 'block',
|
|
263
|
+
section: 'block',
|
|
264
|
+
select: 'inline-block',
|
|
265
|
+
span: 'inline',
|
|
266
|
+
strong: 'inline',
|
|
267
|
+
style: 'none',
|
|
233
268
|
table: 'table',
|
|
269
|
+
tbody: 'table-row-group',
|
|
270
|
+
td: 'table-cell',
|
|
271
|
+
template: 'none',
|
|
272
|
+
textarea: 'inline-block',
|
|
273
|
+
tfoot: 'table-footer-group',
|
|
274
|
+
th: 'table-cell',
|
|
275
|
+
thead: 'table-header-group',
|
|
276
|
+
title: 'none',
|
|
277
|
+
tr: 'table-row',
|
|
278
|
+
ul: 'block',
|
|
279
|
+
video: 'inline',
|
|
234
280
|
}
|
|
235
281
|
|
|
236
282
|
export function getDefaultDisplayForTag(tag: string): string {
|
|
@@ -238,27 +284,44 @@ export function getDefaultDisplayForTag(tag: string): string {
|
|
|
238
284
|
}
|
|
239
285
|
|
|
240
286
|
/**
|
|
241
|
-
* Resolves the current `display` value from matched CSS data
|
|
242
|
-
*
|
|
243
|
-
* Returns the resolved value, or `undefined` if `display` is not declared
|
|
244
|
-
* or uses a variable that cannot be resolved.
|
|
287
|
+
* Resolves the current `display` value from matched CSS data using the
|
|
288
|
+
* CSS-layer value resolver, including var() fallback handling.
|
|
245
289
|
*/
|
|
246
|
-
|
|
290
|
+
function getDisplayPropertyMatch(matcherData: MatchedCssData) {
|
|
291
|
+
let matchedDisplayProperty: (typeof matcherData.matches)[number]['properties'][number] | undefined
|
|
292
|
+
let matchedDisplaySpecificity: [number, number, number] | undefined
|
|
293
|
+
|
|
247
294
|
for (const match of matcherData.matches) {
|
|
248
295
|
for (const property of match.properties) {
|
|
249
|
-
if (property.name
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
296
|
+
if (property.name === 'display') {
|
|
297
|
+
if (!matchedDisplaySpecificity || compareSpecificity(match.specificity, matchedDisplaySpecificity) >= 0) {
|
|
298
|
+
matchedDisplayProperty = property
|
|
299
|
+
matchedDisplaySpecificity = match.specificity
|
|
300
|
+
}
|
|
253
301
|
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return matchedDisplayProperty
|
|
305
|
+
}
|
|
254
306
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
307
|
+
function compareSpecificity(
|
|
308
|
+
leftSpecificity: [number, number, number],
|
|
309
|
+
rightSpecificity: [number, number, number],
|
|
310
|
+
): number {
|
|
311
|
+
for (let specificityIndex = 0; specificityIndex < leftSpecificity.length; specificityIndex += 1) {
|
|
312
|
+
const difference = leftSpecificity[specificityIndex] - rightSpecificity[specificityIndex]
|
|
313
|
+
if (difference !== 0) {
|
|
314
|
+
return difference
|
|
259
315
|
}
|
|
260
316
|
}
|
|
261
|
-
|
|
317
|
+
|
|
318
|
+
return 0
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export function resolveDisplayValue(matcherData: MatchedCssData): string | undefined {
|
|
322
|
+
const displayProperty = getDisplayPropertyMatch(matcherData)
|
|
323
|
+
if (!displayProperty) return undefined
|
|
324
|
+
return resolveCssPropertyValue(displayProperty, matcherData.customProperties)
|
|
262
325
|
}
|
|
263
326
|
|
|
264
327
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -266,20 +329,62 @@ export function resolveDisplayValue(matcherData: MatchedCssData): string | undef
|
|
|
266
329
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
267
330
|
|
|
268
331
|
const FLEX_GRID_DISPLAY_VALUES = new Set(['flex', 'grid', 'inline-flex', 'inline-grid'])
|
|
332
|
+
const NON_CONTAINER_DISPLAY_VALUES = new Set(['inline', 'contents', 'none'])
|
|
333
|
+
const BOX_GENERATING_DISPLAY_VALUES = new Set([
|
|
334
|
+
'block',
|
|
335
|
+
'flex',
|
|
336
|
+
'grid',
|
|
337
|
+
'flow-root',
|
|
338
|
+
'inline-block',
|
|
339
|
+
'inline-flex',
|
|
340
|
+
'inline-grid',
|
|
341
|
+
'inline-table',
|
|
342
|
+
'table',
|
|
343
|
+
'list-item',
|
|
344
|
+
'table-caption',
|
|
345
|
+
'table-cell',
|
|
346
|
+
'table-column',
|
|
347
|
+
'table-column-group',
|
|
348
|
+
'table-footer-group',
|
|
349
|
+
'table-header-group',
|
|
350
|
+
'table-row',
|
|
351
|
+
'table-row-group',
|
|
352
|
+
])
|
|
353
|
+
|
|
354
|
+
function normalizeDisplayValue(displayValue: string): string {
|
|
355
|
+
return displayValue.trim().toLowerCase().replace(/\s+/g, ' ')
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function displayCreatesContainerBox(displayValue: string): boolean {
|
|
359
|
+
const normalizedDisplayValue = normalizeDisplayValue(displayValue)
|
|
360
|
+
if (NON_CONTAINER_DISPLAY_VALUES.has(normalizedDisplayValue)) return false
|
|
361
|
+
|
|
362
|
+
const displayTokens = normalizedDisplayValue.split(' ')
|
|
363
|
+
|
|
364
|
+
return displayTokens.some((displayToken) => BOX_GENERATING_DISPLAY_VALUES.has(displayToken))
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function displayUsesFlexOrGridLayout(displayValue: string): boolean {
|
|
368
|
+
const normalizedDisplayValue = normalizeDisplayValue(displayValue)
|
|
369
|
+
const displayTokens = normalizedDisplayValue.split(' ')
|
|
370
|
+
|
|
371
|
+
return displayTokens.some((displayToken) => FLEX_GRID_DISPLAY_VALUES.has(displayToken))
|
|
372
|
+
}
|
|
269
373
|
|
|
270
374
|
/**
|
|
271
375
|
* Returns true if display uses a CSS variable that cannot be resolved --
|
|
272
376
|
* we optimistically assume it could be flex/grid.
|
|
273
377
|
*/
|
|
274
378
|
function hasUnresolvableDisplayVar(matcherData: MatchedCssData): boolean {
|
|
379
|
+
const displayProperty = getDisplayPropertyMatch(matcherData)
|
|
380
|
+
if (!displayProperty?.varRefs || displayProperty.varRefs.length === 0) return false
|
|
381
|
+
return resolveCssPropertyValue(displayProperty, matcherData.customProperties) === undefined
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function hasDisplayDeclaration(matcherData: MatchedCssData): boolean {
|
|
275
385
|
for (const match of matcherData.matches) {
|
|
276
386
|
for (const property of match.properties) {
|
|
277
|
-
if (property.name
|
|
278
|
-
if (property.varRefs && property.varRefs.length > 0) {
|
|
279
|
-
for (const varName of property.varRefs) {
|
|
280
|
-
if (matcherData.customProperties[varName] === undefined) return true
|
|
281
|
-
}
|
|
282
|
-
}
|
|
387
|
+
if (property.name === 'display') return true
|
|
283
388
|
}
|
|
284
389
|
}
|
|
285
390
|
return false
|
|
@@ -287,10 +392,28 @@ function hasUnresolvableDisplayVar(matcherData: MatchedCssData): boolean {
|
|
|
287
392
|
|
|
288
393
|
export function hasFlexOrGridDisplay(matcherData: MatchedCssData): boolean {
|
|
289
394
|
const displayValue = resolveDisplayValue(matcherData)
|
|
290
|
-
if (displayValue !== undefined) return
|
|
395
|
+
if (displayValue !== undefined) return displayUsesFlexOrGridLayout(displayValue)
|
|
291
396
|
return hasUnresolvableDisplayVar(matcherData)
|
|
292
397
|
}
|
|
293
398
|
|
|
399
|
+
export function hasContainerLikeDisplay(matcherData: MatchedCssData): boolean {
|
|
400
|
+
const displayValue = resolveDisplayValue(matcherData)
|
|
401
|
+
if (displayValue !== undefined) return displayCreatesContainerBox(displayValue)
|
|
402
|
+
return hasUnresolvableDisplayVar(matcherData)
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function hasContainerLikeDefaultDisplay(tag: string): boolean {
|
|
406
|
+
return displayCreatesContainerBox(getDefaultDisplayForTag(tag))
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function hasEffectiveContainerDisplay(tag: string, matcherData?: MatchedCssData): boolean {
|
|
410
|
+
if (matcherData && hasDisplayDeclaration(matcherData)) {
|
|
411
|
+
return hasContainerLikeDisplay(matcherData)
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return hasContainerLikeDefaultDisplay(tag)
|
|
415
|
+
}
|
|
416
|
+
|
|
294
417
|
/**
|
|
295
418
|
* Walks the element tree and adds `gap` to relevant CSS properties
|
|
296
419
|
* for elements that have display: flex|grid and more than 1 child.
|
|
@@ -316,6 +439,31 @@ export function enrichGapProperties(elements: ExtractedElement[]): ExtractedElem
|
|
|
316
439
|
})
|
|
317
440
|
}
|
|
318
441
|
|
|
442
|
+
/**
|
|
443
|
+
* Walks the element tree and adds box properties to selected text tags
|
|
444
|
+
* when CSS overrides `display` or default UA display creates a box.
|
|
445
|
+
*/
|
|
446
|
+
export function enrichContainerProperties(elements: ExtractedElement[]): ExtractedElement[] {
|
|
447
|
+
return elements.map((element) => {
|
|
448
|
+
const role = element.attributes.role
|
|
449
|
+
if (hasTextSemantics(element.tag, role)) {
|
|
450
|
+
const matcherData = element.extractorData.get('css-matcher') as MatchedCssData | undefined
|
|
451
|
+
const cssData = element.extractorData.get('css-properties') as CssPropertiesData | undefined
|
|
452
|
+
|
|
453
|
+
if (cssData && hasEffectiveContainerDisplay(element.tag, matcherData)) {
|
|
454
|
+
element.extractorData.set('css-properties', {
|
|
455
|
+
relevant: addBoxProperties(cssData.relevant),
|
|
456
|
+
})
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
return {
|
|
461
|
+
...element,
|
|
462
|
+
children: enrichContainerProperties(element.children),
|
|
463
|
+
}
|
|
464
|
+
})
|
|
465
|
+
}
|
|
466
|
+
|
|
319
467
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
320
468
|
// Factory
|
|
321
469
|
// ─────────────────────────────────────────────────────────────────────────────
|
package/src/manifest-pipeline.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type RunExtractorsOptions,
|
|
10
10
|
createCssPropertiesExtractor,
|
|
11
11
|
createPropTrackerExtractor,
|
|
12
|
+
enrichContainerProperties,
|
|
12
13
|
enrichGapProperties,
|
|
13
14
|
runExtractors,
|
|
14
15
|
} from './information-extractors/react'
|
|
@@ -163,7 +164,8 @@ export function processComponent(
|
|
|
163
164
|
if (html && extractedElements.length > 0 && css.length > 0) {
|
|
164
165
|
try {
|
|
165
166
|
const matchResult = matchCssSelectors(html, extractedElements, css)
|
|
166
|
-
const
|
|
167
|
+
const containerEnrichedElements = enrichContainerProperties(matchResult.elements)
|
|
168
|
+
const gapEnrichedElements = enrichGapProperties(containerEnrichedElements)
|
|
167
169
|
enhancedInfo = {
|
|
168
170
|
...enhancedInfo,
|
|
169
171
|
elements: convertElements(gapEnrichedElements),
|