Skip to content

Commit 835a647

Browse files
committed
fix(fabric): hoist HTML/SVG fallback Sets to module scope — hbc bug
The previous attempts (2eb1e35 + 1beb374) initialized the HTML_VIEW_TAGS, HTML_TEXT_TAGS, and SVG_TAGS Sets INSIDE createInstance, recomputing them on every host element creation. Each addition shifted the vendor.bundle.hbc into the same Hermes x86_64 bytecode bug we've now hit four times in a row (URL polyfill v1, LogBoxOverlay wrap, Icon+Label in module.exports literal, SVG Set in createInstance). `blank` flipped from PASS → BOOT_FAIL on the SVG push as collateral. Forward-only fix: hoist the three Sets to module-level constants above hostConfig. createInstance now references them by name; the literal initialisers only emit once at module load, not on every call. Different bytecode shape, dodges the bug. Also rolls up the two separate "HTML element fallback" + "SVG element fallback" comment blocks into one to reduce wall-of-text inside the create path. Tracked: task #69. The pattern is now: any time a multi-element literal is added inside the createInstance body, hoist it out.
1 parent 1beb374 commit 835a647

1 file changed

Lines changed: 142 additions & 152 deletions

File tree

apps/playground/runtime/fabricHostConfig.js

Lines changed: 142 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,140 @@ function makeInstance(tag, fabricNode, componentName, type) {
287287
};
288288
}
289289

290+
// HTML + SVG element fallback tables for createInstance below.
291+
// Hoisted to module scope to keep the bytecode shape stable —
292+
// inlining these Set literals inside createInstance with their long
293+
// string-array initialisers triggered a Hermes x86_64 bytecode bug
294+
// that silently blank-screens the host (same family as the URL
295+
// polyfill v1 and the Icon+Label-in-literal regressions, tracked in
296+
// task #69).
297+
const HTML_VIEW_TAGS = new Set([
298+
'div',
299+
'section',
300+
'nav',
301+
'main',
302+
'aside',
303+
'article',
304+
'header',
305+
'footer',
306+
'ul',
307+
'ol',
308+
'li',
309+
'figure',
310+
'figcaption',
311+
'form',
312+
'fieldset',
313+
'label',
314+
'table',
315+
'thead',
316+
'tbody',
317+
'tfoot',
318+
'tr',
319+
'td',
320+
'th',
321+
'colgroup',
322+
'col',
323+
'video',
324+
'audio',
325+
'canvas',
326+
'iframe',
327+
'details',
328+
'summary',
329+
'dialog',
330+
'button',
331+
'a',
332+
]);
333+
const HTML_TEXT_TAGS = new Set([
334+
'p',
335+
'span',
336+
'strong',
337+
'em',
338+
'b',
339+
'i',
340+
'u',
341+
's',
342+
'small',
343+
'h1',
344+
'h2',
345+
'h3',
346+
'h4',
347+
'h5',
348+
'h6',
349+
'pre',
350+
'code',
351+
'kbd',
352+
'samp',
353+
'var',
354+
'mark',
355+
'sub',
356+
'sup',
357+
'abbr',
358+
'cite',
359+
'q',
360+
'time',
361+
'br',
362+
'hr',
363+
]);
364+
const SVG_TAGS = new Set([
365+
'svg',
366+
'g',
367+
'defs',
368+
'symbol',
369+
'use',
370+
'foreignObject',
371+
'path',
372+
'rect',
373+
'circle',
374+
'ellipse',
375+
'line',
376+
'polyline',
377+
'polygon',
378+
'text',
379+
'tspan',
380+
'textPath',
381+
'linearGradient',
382+
'radialGradient',
383+
'stop',
384+
'marker',
385+
'mask',
386+
'clipPath',
387+
'pattern',
388+
'filter',
389+
'feBlend',
390+
'feColorMatrix',
391+
'feComponentTransfer',
392+
'feComposite',
393+
'feConvolveMatrix',
394+
'feDiffuseLighting',
395+
'feDisplacementMap',
396+
'feDistantLight',
397+
'feDropShadow',
398+
'feFlood',
399+
'feFuncA',
400+
'feFuncB',
401+
'feFuncG',
402+
'feFuncR',
403+
'feGaussianBlur',
404+
'feImage',
405+
'feMerge',
406+
'feMergeNode',
407+
'feMorphology',
408+
'feOffset',
409+
'fePointLight',
410+
'feSpecularLighting',
411+
'feSpotLight',
412+
'feTile',
413+
'feTurbulence',
414+
'animate',
415+
'animateMotion',
416+
'animateTransform',
417+
'set',
418+
'mpath',
419+
'title',
420+
'desc',
421+
'metadata',
422+
]);
423+
290424
const hostConfig = {
291425
// Persistence is the natural fit for Fabric — every commit clones
292426
// the affected nodes via nativeFabricUIManager.cloneNodeWith*, then
@@ -492,83 +626,14 @@ const hostConfig = {
492626
return makeInstance(tag, fabricNode, 'Text', type);
493627
}
494628

495-
// HTML element fallback. Expo Router DOM Components, with-html,
496-
// and any example that mixes JSX with a `"use dom"` directive
497-
// emit lowercase HTML element names (`<div>`, `<p>`, `<span>`,
498-
// `<h1>` …) directly into the React tree. We don't have a real
499-
// WebView host, but mapping the structural elements onto View
500-
// and the text-bearing elements onto Paragraph is enough to let
501-
// these trees mount + render the visible text without throwing.
502-
// Layout / styling fidelity is not the goal here — just "boots
503-
// and renders something" so the rest of the app surface gets a
504-
// chance to run.
505-
const HTML_VIEW_TAGS = new Set([
506-
'div',
507-
'section',
508-
'nav',
509-
'main',
510-
'aside',
511-
'article',
512-
'header',
513-
'footer',
514-
'ul',
515-
'ol',
516-
'li',
517-
'figure',
518-
'figcaption',
519-
'form',
520-
'fieldset',
521-
'label',
522-
'table',
523-
'thead',
524-
'tbody',
525-
'tfoot',
526-
'tr',
527-
'td',
528-
'th',
529-
'colgroup',
530-
'col',
531-
'video',
532-
'audio',
533-
'canvas',
534-
'iframe',
535-
'details',
536-
'summary',
537-
'dialog',
538-
'button',
539-
'a',
540-
]);
541-
const HTML_TEXT_TAGS = new Set([
542-
'p',
543-
'span',
544-
'strong',
545-
'em',
546-
'b',
547-
'i',
548-
'u',
549-
's',
550-
'small',
551-
'h1',
552-
'h2',
553-
'h3',
554-
'h4',
555-
'h5',
556-
'h6',
557-
'pre',
558-
'code',
559-
'kbd',
560-
'samp',
561-
'var',
562-
'mark',
563-
'sub',
564-
'sup',
565-
'abbr',
566-
'cite',
567-
'q',
568-
'time',
569-
'br',
570-
'hr',
571-
]);
629+
// HTML / SVG element fallback. Expo Router DOM Components,
630+
// with-html, react-flow's edge markers, every icon set emit
631+
// lowercase HTML/SVG element names directly into the React
632+
// tree. Structural HTML + every SVG primitive map onto View,
633+
// text-bearing HTML onto Paragraph. Goal is "tree mounts" not
634+
// "looks right"; layout / styling fidelity is out of scope.
635+
// The tag sets themselves live at module scope above — see
636+
// the comment there.
572637
if (HTML_VIEW_TAGS.has(type)) {
573638
const tag = newTag();
574639
const fabricNode = currentFabric.createNode(
@@ -592,81 +657,6 @@ const hostConfig = {
592657
return makeInstance(tag, fabricNode, 'Paragraph', type);
593658
}
594659

595-
// SVG element fallback. react-native-svg, expo-router DOM
596-
// Components, and any example that renders inline SVG (lots of
597-
// dashboards, with-react-flow's edge markers, every icon set)
598-
// emit lowercase SVG element names directly into the React tree.
599-
// We don't render actual SVG (would need cairo + librsvg), but
600-
// mapping everything to View lets the tree mount instead of
601-
// throwing — so examples surface their REAL post-SVG failures
602-
// rather than blanking out on `Unknown host element: <stop>`.
603-
const SVG_TAGS = new Set([
604-
// Containers
605-
'svg',
606-
'g',
607-
'defs',
608-
'symbol',
609-
'use',
610-
'foreignObject',
611-
// Shapes
612-
'path',
613-
'rect',
614-
'circle',
615-
'ellipse',
616-
'line',
617-
'polyline',
618-
'polygon',
619-
// Text
620-
'text',
621-
'tspan',
622-
'textPath',
623-
// Gradients + fills
624-
'linearGradient',
625-
'radialGradient',
626-
'stop',
627-
// Markers + clipping + masking
628-
'marker',
629-
'mask',
630-
'clipPath',
631-
'pattern',
632-
'filter',
633-
// Filter primitives
634-
'feBlend',
635-
'feColorMatrix',
636-
'feComponentTransfer',
637-
'feComposite',
638-
'feConvolveMatrix',
639-
'feDiffuseLighting',
640-
'feDisplacementMap',
641-
'feDistantLight',
642-
'feDropShadow',
643-
'feFlood',
644-
'feFuncA',
645-
'feFuncB',
646-
'feFuncG',
647-
'feFuncR',
648-
'feGaussianBlur',
649-
'feImage',
650-
'feMerge',
651-
'feMergeNode',
652-
'feMorphology',
653-
'feOffset',
654-
'fePointLight',
655-
'feSpecularLighting',
656-
'feSpotLight',
657-
'feTile',
658-
'feTurbulence',
659-
// Animation (no-op — we don't drive SMIL)
660-
'animate',
661-
'animateMotion',
662-
'animateTransform',
663-
'set',
664-
'mpath',
665-
// Misc descriptive
666-
'title',
667-
'desc',
668-
'metadata',
669-
]);
670660
if (SVG_TAGS.has(type)) {
671661
const tag = newTag();
672662
const fabricNode = currentFabric.createNode(

0 commit comments

Comments
 (0)