meno-core 1.0.53 → 1.0.54
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/.claude/settings.local.json +1 -3
- package/bin/cli.ts +48 -57
- package/build-astro.ts +131 -113
- package/build-next.ts +109 -96
- package/build-static.test.ts +39 -10
- package/build-static.ts +120 -122
- package/dist/bin/cli.js +34 -38
- package/dist/bin/cli.js.map +2 -2
- package/dist/build-static.js +12 -11
- package/dist/chunks/chunk-2AR55GYH.js +42 -0
- package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
- package/dist/chunks/{chunk-IGYR22T6.js → chunk-2FN4UOVO.js} +512 -239
- package/dist/chunks/chunk-2FN4UOVO.js.map +7 -0
- package/dist/chunks/chunk-3XER4E5W.js +168 -0
- package/dist/chunks/chunk-3XER4E5W.js.map +7 -0
- package/dist/chunks/{chunk-X754AHS5.js → chunk-5ETZFREW.js} +9 -12
- package/dist/chunks/chunk-5ETZFREW.js.map +7 -0
- package/dist/chunks/{chunk-2MHDV5BF.js → chunk-7E4IF5L7.js} +15 -21
- package/dist/chunks/chunk-7E4IF5L7.js.map +7 -0
- package/dist/chunks/{chunk-JGWFTO6P.js → chunk-7HWQUVTU.js} +1578 -1349
- package/dist/chunks/chunk-7HWQUVTU.js.map +7 -0
- package/dist/chunks/{chunk-O3NAGJP4.js → chunk-AE3QK5QW.js} +110 -21
- package/dist/chunks/chunk-AE3QK5QW.js.map +7 -0
- package/dist/chunks/{chunk-GZHGVVW3.js → chunk-F6KTJYGV.js} +7 -7
- package/dist/chunks/chunk-F6KTJYGV.js.map +7 -0
- package/dist/chunks/{chunk-WQFG7PAH.js → chunk-FZITJSSS.js} +2 -6
- package/dist/chunks/chunk-FZITJSSS.js.map +7 -0
- package/dist/chunks/{chunk-QB2LNO4W.js → chunk-GSYYA5GX.js} +2 -2
- package/dist/chunks/chunk-GSYYA5GX.js.map +7 -0
- package/dist/chunks/{chunk-YBLHKYFF.js → chunk-HIZMY3EP.js} +1 -1
- package/dist/chunks/chunk-HIZMY3EP.js.map +7 -0
- package/dist/chunks/{chunk-AZQYF6KE.js → chunk-I2WEGYA7.js} +41 -176
- package/dist/chunks/chunk-I2WEGYA7.js.map +7 -0
- package/dist/chunks/{chunk-I7YIGZXT.js → chunk-JNO3CNLJ.js} +6 -9
- package/dist/chunks/chunk-JNO3CNLJ.js.map +7 -0
- package/dist/chunks/{chunk-UB44F4Z2.js → chunk-NVRBTSQG.js} +2 -4
- package/dist/chunks/chunk-NVRBTSQG.js.map +7 -0
- package/dist/chunks/{chunk-JGP5A3Y5.js → chunk-Q4OBWKXG.js} +40 -33
- package/dist/chunks/chunk-Q4OBWKXG.js.map +7 -0
- package/dist/chunks/{chunk-R6XHAFBF.js → chunk-QTE32Y53.js} +250 -242
- package/dist/chunks/chunk-QTE32Y53.js.map +7 -0
- package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-STDY3OVM.js} +214 -85
- package/dist/chunks/chunk-STDY3OVM.js.map +7 -0
- package/dist/chunks/configService-PRJZF7Y6.js +14 -0
- package/dist/chunks/{constants-STK2YBIW.js → constants-KIQEYMAM.js} +2 -2
- package/dist/chunks/{fs-JGINUXGL.js → fs-ZI5JEU7V.js} +2 -2
- package/dist/entries/server-router.js +14 -19
- package/dist/entries/server-router.js.map +2 -2
- package/dist/lib/client/index.js +638 -332
- package/dist/lib/client/index.js.map +2 -2
- package/dist/lib/server/index.js +177 -235
- package/dist/lib/server/index.js.map +2 -2
- package/dist/lib/shared/index.js +80 -44
- package/dist/lib/shared/index.js.map +2 -2
- package/dist/lib/shared/richtext/index.js +1 -1
- package/dist/lib/test-utils/index.js +38 -60
- package/dist/lib/test-utils/index.js.map +2 -2
- package/entries/client-router.tsx +10 -8
- package/entries/server-router.tsx +1 -7
- package/lib/client/ClientInitializer.ts +8 -8
- package/lib/client/ErrorBoundary.test.tsx +146 -143
- package/lib/client/ErrorBoundary.tsx +175 -127
- package/lib/client/componentRegistry.test.ts +96 -108
- package/lib/client/componentRegistry.ts +1 -2
- package/lib/client/contexts/ThemeContext.tsx +3 -2
- package/lib/client/core/ComponentBuilder.test.ts +513 -560
- package/lib/client/core/ComponentBuilder.ts +318 -146
- package/lib/client/core/ComponentRenderer.test.tsx +1 -2
- package/lib/client/core/ComponentRenderer.tsx +46 -33
- package/lib/client/core/builders/embedBuilder.ts +241 -53
- package/lib/client/core/builders/linkBuilder.ts +71 -44
- package/lib/client/core/builders/linkNodeBuilder.ts +78 -53
- package/lib/client/core/builders/listBuilder.ts +115 -86
- package/lib/client/core/builders/localeListBuilder.ts +95 -60
- package/lib/client/core/builders/types.ts +5 -5
- package/lib/client/core/cmsTemplateProcessor.ts +7 -7
- package/lib/client/elementRegistry.ts +3 -3
- package/lib/client/fontFamiliesService.test.ts +2 -10
- package/lib/client/fontFamiliesService.ts +3 -3
- package/lib/client/hmr/HMRManager.tsx +8 -0
- package/lib/client/hmrCssReload.ts +14 -8
- package/lib/client/hmrWebSocket.ts +9 -14
- package/lib/client/hooks/useColorVariables.test.ts +21 -21
- package/lib/client/hooks/useColorVariables.ts +12 -10
- package/lib/client/hooks/usePropertyAutocomplete.ts +3 -5
- package/lib/client/hooks/useVariables.ts +4 -4
- package/lib/client/hydration/HydrationUtils.test.ts +24 -25
- package/lib/client/hydration/HydrationUtils.ts +3 -4
- package/lib/client/i18nConfigService.test.ts +2 -7
- package/lib/client/i18nConfigService.ts +2 -2
- package/lib/client/meno-filter/MenoFilter.test.ts +19 -21
- package/lib/client/meno-filter/MenoFilter.ts +5 -9
- package/lib/client/meno-filter/bindings.ts +15 -40
- package/lib/client/meno-filter/init.ts +1 -1
- package/lib/client/meno-filter/renderer.ts +23 -29
- package/lib/client/meno-filter/script.generated.ts +1 -3
- package/lib/client/meno-filter/ui.ts +3 -5
- package/lib/client/meno-filter/updates.ts +15 -21
- package/lib/client/navigation.test.ts +159 -159
- package/lib/client/navigation.ts +0 -1
- package/lib/client/responsiveStyleResolver.test.ts +230 -228
- package/lib/client/responsiveStyleResolver.ts +13 -16
- package/lib/client/routing/RouteLoader.test.ts +23 -24
- package/lib/client/routing/RouteLoader.ts +22 -35
- package/lib/client/routing/Router.tsx +31 -3
- package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
- package/lib/client/scripts/ScriptExecutor.ts +15 -33
- package/lib/client/services/PrefetchService.test.ts +2 -2
- package/lib/client/services/PrefetchService.ts +10 -24
- package/lib/client/styleProcessor.test.ts +9 -9
- package/lib/client/styleProcessor.ts +18 -15
- package/lib/client/styles/StyleInjector.test.ts +122 -115
- package/lib/client/styles/StyleInjector.ts +9 -6
- package/lib/client/styles/UtilityClassCollector.ts +19 -26
- package/lib/client/styles/cspNonce.test.ts +2 -5
- package/lib/client/templateEngine.test.ts +554 -482
- package/lib/client/templateEngine.ts +200 -64
- package/lib/client/theme.ts +0 -1
- package/lib/client/utils/toast.ts +0 -1
- package/lib/server/__integration__/api-routes.test.ts +8 -4
- package/lib/server/__integration__/cms-integration.test.ts +1 -4
- package/lib/server/__integration__/server-lifecycle.test.ts +2 -5
- package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
- package/lib/server/__integration__/static-assets.test.ts +1 -1
- package/lib/server/__integration__/test-helpers.ts +84 -70
- package/lib/server/ab/generateFunctions.ts +12 -10
- package/lib/server/astro/cmsPageEmitter.ts +23 -38
- package/lib/server/astro/componentEmitter.ts +25 -36
- package/lib/server/astro/cssCollector.ts +10 -26
- package/lib/server/astro/nodeToAstro.test.ts +1750 -30
- package/lib/server/astro/nodeToAstro.ts +198 -187
- package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +105 -109
- package/lib/server/astro/normalizeOrphanTemplateProps.ts +4 -12
- package/lib/server/astro/pageEmitter.ts +9 -13
- package/lib/server/astro/tailwindMapper.test.ts +10 -37
- package/lib/server/astro/tailwindMapper.ts +33 -40
- package/lib/server/astro/templateTransformer.ts +14 -17
- package/lib/server/createServer.ts +5 -17
- package/lib/server/cssGenerator.test.ts +35 -44
- package/lib/server/cssGenerator.ts +6 -17
- package/lib/server/fileWatcher.test.ts +124 -10
- package/lib/server/fileWatcher.ts +124 -118
- package/lib/server/index.ts +7 -1
- package/lib/server/jsonLoader.test.ts +39 -2
- package/lib/server/jsonLoader.ts +33 -31
- package/lib/server/middleware/cors.test.ts +20 -20
- package/lib/server/middleware/cors.ts +28 -4
- package/lib/server/middleware/errorHandler.test.ts +5 -3
- package/lib/server/middleware/errorHandler.ts +3 -8
- package/lib/server/middleware/index.ts +0 -1
- package/lib/server/middleware/logger.test.ts +7 -5
- package/lib/server/middleware/logger.ts +10 -22
- package/lib/server/pageCache.test.ts +76 -77
- package/lib/server/pageCache.ts +0 -1
- package/lib/server/projectContext.ts +4 -3
- package/lib/server/providers/fileSystemCMSProvider.test.ts +124 -95
- package/lib/server/providers/fileSystemCMSProvider.ts +35 -20
- package/lib/server/providers/fileSystemPageProvider.test.ts +84 -0
- package/lib/server/providers/fileSystemPageProvider.ts +31 -12
- package/lib/server/routes/api/cms.test.ts +26 -14
- package/lib/server/routes/api/cms.ts +9 -14
- package/lib/server/routes/api/components.ts +30 -34
- package/lib/server/routes/api/config.ts +0 -1
- package/lib/server/routes/api/core-routes.ts +47 -74
- package/lib/server/routes/api/functions.ts +8 -16
- package/lib/server/routes/api/index.ts +3 -6
- package/lib/server/routes/api/pages.ts +8 -11
- package/lib/server/routes/api/shared.test.ts +1 -1
- package/lib/server/routes/api/shared.ts +12 -9
- package/lib/server/routes/api/variables.test.ts +1 -3
- package/lib/server/routes/api/variables.ts +1 -1
- package/lib/server/routes/index.ts +23 -26
- package/lib/server/routes/pages.ts +34 -29
- package/lib/server/routes/static.ts +16 -4
- package/lib/server/runtime/bundler.ts +47 -32
- package/lib/server/runtime/fs.ts +3 -13
- package/lib/server/runtime/httpServer.ts +5 -9
- package/lib/server/services/ColorService.ts +32 -27
- package/lib/server/services/EnumService.test.ts +2 -6
- package/lib/server/services/EnumService.ts +7 -2
- package/lib/server/services/VariableService.test.ts +1 -5
- package/lib/server/services/VariableService.ts +6 -1
- package/lib/server/services/cmsService.test.ts +116 -78
- package/lib/server/services/cmsService.ts +24 -54
- package/lib/server/services/componentService.test.ts +122 -36
- package/lib/server/services/componentService.ts +54 -38
- package/lib/server/services/configService.test.ts +9 -31
- package/lib/server/services/configService.ts +20 -27
- package/lib/server/services/fileWatcherService.ts +40 -6
- package/lib/server/services/index.ts +0 -1
- package/lib/server/services/pageService.test.ts +1 -3
- package/lib/server/services/pageService.ts +14 -13
- package/lib/server/ssr/attributeBuilder.ts +16 -6
- package/lib/server/ssr/buildErrorOverlay.ts +11 -12
- package/lib/server/ssr/clientDataInjector.ts +7 -21
- package/lib/server/ssr/cmsSSRProcessor.ts +3 -6
- package/lib/server/ssr/cssCollector.ts +1 -1
- package/lib/server/ssr/errorOverlay.test.ts +1 -1
- package/lib/server/ssr/errorOverlay.ts +3 -9
- package/lib/server/ssr/htmlGenerator.nonce.test.ts +3 -9
- package/lib/server/ssr/htmlGenerator.test.ts +120 -43
- package/lib/server/ssr/htmlGenerator.ts +120 -85
- package/lib/server/ssr/imageMetadata.test.ts +3 -1
- package/lib/server/ssr/imageMetadata.ts +25 -19
- package/lib/server/ssr/jsCollector.test.ts +3 -13
- package/lib/server/ssr/jsCollector.ts +3 -8
- package/lib/server/ssr/liveReloadIntegration.test.ts +69 -28
- package/lib/server/ssr/metaTagGenerator.ts +2 -2
- package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
- package/lib/server/ssr/ssrRenderer.test.ts +196 -246
- package/lib/server/ssr/ssrRenderer.ts +609 -225
- package/lib/server/ssrRenderer.test.ts +1044 -950
- package/lib/server/utils/jsonLineMapper.test.ts +28 -28
- package/lib/server/utils/jsonLineMapper.ts +1 -1
- package/lib/server/validateStyleCoverage.ts +18 -20
- package/lib/server/webflow/buildWebflow.ts +41 -53
- package/lib/server/webflow/nodeToWebflow.test.ts +150 -218
- package/lib/server/webflow/nodeToWebflow.ts +195 -258
- package/lib/server/webflow/styleMapper.test.ts +15 -56
- package/lib/server/webflow/styleMapper.ts +33 -41
- package/lib/server/webflow/types.ts +1 -8
- package/lib/server/websocketManager.ts +16 -19
- package/lib/shared/attributeNodeUtils.test.ts +15 -15
- package/lib/shared/attributeNodeUtils.ts +5 -12
- package/lib/shared/breakpoints.ts +4 -11
- package/lib/shared/cmsQueryParser.test.ts +50 -42
- package/lib/shared/cmsQueryParser.ts +49 -31
- package/lib/shared/colorVariableUtils.test.ts +5 -5
- package/lib/shared/colorVariableUtils.ts +3 -8
- package/lib/shared/componentRefs.ts +1 -5
- package/lib/shared/constants.test.ts +3 -3
- package/lib/shared/constants.ts +4 -8
- package/lib/shared/cssGeneration.test.ts +262 -144
- package/lib/shared/cssGeneration.ts +189 -516
- package/lib/shared/cssNamedColors.ts +152 -30
- package/lib/shared/cssProperties.test.ts +5 -6
- package/lib/shared/cssProperties.ts +296 -112
- package/lib/shared/elementClassName.test.ts +109 -109
- package/lib/shared/elementClassName.ts +1 -1
- package/lib/shared/elementUtils.ts +12 -16
- package/lib/shared/errorLogger.ts +2 -10
- package/lib/shared/errors.test.ts +2 -13
- package/lib/shared/errors.ts +2 -8
- package/lib/shared/expressionEvaluator.test.ts +119 -0
- package/lib/shared/expressionEvaluator.ts +43 -24
- package/lib/shared/fontLoader.test.ts +19 -5
- package/lib/shared/friendlyError.ts +2 -3
- package/lib/shared/gradientUtils.test.ts +1 -5
- package/lib/shared/gradientUtils.ts +2 -6
- package/lib/shared/hrefRefs.ts +2 -10
- package/lib/shared/i18n.test.ts +1 -1
- package/lib/shared/i18n.ts +13 -34
- package/lib/shared/index.ts +4 -0
- package/lib/shared/inlineSvgStyleRules.ts +2 -4
- package/lib/shared/interactiveStyleMappings.test.ts +11 -33
- package/lib/shared/interactiveStyleMappings.ts +9 -16
- package/lib/shared/interactiveStyles.test.ts +165 -188
- package/lib/shared/interfaces/contentProvider.ts +1 -1
- package/lib/shared/itemTemplateUtils.test.ts +6 -12
- package/lib/shared/itemTemplateUtils.ts +19 -35
- package/lib/shared/jsonRepair.ts +8 -2
- package/lib/shared/libraryLoader.test.ts +15 -49
- package/lib/shared/libraryLoader.ts +7 -22
- package/lib/shared/netlifyLocale404.test.ts +179 -0
- package/lib/shared/netlifyLocale404.ts +110 -0
- package/lib/shared/nodeUtils.test.ts +24 -16
- package/lib/shared/nodeUtils.ts +49 -19
- package/lib/shared/pathArrayUtils.test.ts +1 -2
- package/lib/shared/pathArrayUtils.ts +1 -1
- package/lib/shared/pathSecurity.ts +1 -1
- package/lib/shared/pathUtils.test.ts +4 -6
- package/lib/shared/pathUtils.ts +42 -48
- package/lib/shared/paths/Path.test.ts +2 -2
- package/lib/shared/paths/Path.ts +0 -1
- package/lib/shared/paths/PathConverter.test.ts +1 -1
- package/lib/shared/paths/PathConverter.ts +14 -17
- package/lib/shared/paths/PathUtils.ts +9 -10
- package/lib/shared/paths/PathValidator.test.ts +2 -15
- package/lib/shared/paths/PathValidator.ts +11 -9
- package/lib/shared/paths/index.ts +1 -2
- package/lib/shared/propResolver.test.ts +240 -244
- package/lib/shared/propResolver.ts +14 -25
- package/lib/shared/pxToRem.test.ts +7 -6
- package/lib/shared/pxToRem.ts +2 -5
- package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +9 -5
- package/lib/shared/registry/ClientRegistry.ts +0 -1
- package/lib/shared/registry/ComponentRegistry.test.ts +43 -29
- package/lib/shared/registry/ComponentRegistry.ts +9 -11
- package/lib/shared/registry/NodeTypeDefinition.ts +15 -8
- package/lib/shared/registry/RegistryManager.ts +1 -2
- package/lib/shared/registry/SSRRegistry.ts +0 -1
- package/lib/shared/registry/createNodeType.ts +7 -9
- package/lib/shared/registry/defineNodeType.ts +2 -6
- package/lib/shared/registry/index.ts +0 -1
- package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
- package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
- package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +47 -18
- package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
- package/lib/shared/registry/nodeTypes/ListNodeType.ts +78 -74
- package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
- package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +6 -7
- package/lib/shared/registry/nodeTypes/index.ts +10 -2
- package/lib/shared/responsiveScaling.test.ts +15 -31
- package/lib/shared/responsiveScaling.ts +55 -37
- package/lib/shared/responsiveStyleUtils.ts +11 -13
- package/lib/shared/richtext/htmlToTiptap.test.ts +23 -14
- package/lib/shared/richtext/htmlToTiptap.ts +1 -3
- package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
- package/lib/shared/richtext/types.ts +1 -8
- package/lib/shared/slugTranslator.test.ts +13 -13
- package/lib/shared/slugTranslator.ts +12 -16
- package/lib/shared/slugify.ts +9 -15
- package/lib/shared/styleNodeUtils.test.ts +8 -8
- package/lib/shared/styleNodeUtils.ts +5 -10
- package/lib/shared/styleUtils.test.ts +87 -61
- package/lib/shared/styleUtils.ts +5 -6
- package/lib/shared/themeDefaults.test.ts +11 -11
- package/lib/shared/themeDefaults.ts +3 -4
- package/lib/shared/tree/PathBuilder.test.ts +62 -138
- package/lib/shared/tree/PathBuilder.ts +49 -39
- package/lib/shared/treePathUtils.test.ts +2 -10
- package/lib/shared/treePathUtils.ts +54 -59
- package/lib/shared/types/api.ts +1 -2
- package/lib/shared/types/cms.ts +25 -21
- package/lib/shared/types/comment.ts +49 -16
- package/lib/shared/types/components.ts +27 -25
- package/lib/shared/types/errors.test.ts +1 -6
- package/lib/shared/types/errors.ts +3 -7
- package/lib/shared/types/experiments.ts +28 -28
- package/lib/shared/types/index.ts +2 -2
- package/lib/shared/types/styles.ts +0 -1
- package/lib/shared/types/variables.test.ts +4 -13
- package/lib/shared/types/variables.ts +48 -27
- package/lib/shared/types.ts +1 -2
- package/lib/shared/utilityClassConfig.ts +648 -321
- package/lib/shared/utilityClassMapper.test.ts +203 -92
- package/lib/shared/utilityClassMapper.ts +188 -246
- package/lib/shared/utilityClassNames.ts +326 -0
- package/lib/shared/utils.test.ts +2 -10
- package/lib/shared/utils.ts +19 -10
- package/lib/shared/validation/cmsValidators.ts +2 -1
- package/lib/shared/validation/commentValidators.test.ts +53 -0
- package/lib/shared/validation/commentValidators.ts +12 -1
- package/lib/shared/validation/propValidator.test.ts +18 -20
- package/lib/shared/validation/propValidator.ts +12 -17
- package/lib/shared/validation/schemas.test.ts +24 -33
- package/lib/shared/validation/schemas.ts +469 -344
- package/lib/shared/validation/validators.test.ts +1 -6
- package/lib/shared/validation/validators.ts +89 -68
- package/lib/shared/viewportUnits.integration.test.ts +14 -10
- package/lib/shared/viewportUnits.test.ts +11 -23
- package/lib/test-utils/dom-setup.ts +1 -1
- package/lib/test-utils/factories/ConsoleMockFactory.ts +3 -7
- package/lib/test-utils/factories/DomMockFactory.ts +7 -19
- package/lib/test-utils/factories/EventMockFactory.ts +7 -13
- package/lib/test-utils/factories/FetchMockFactory.ts +39 -57
- package/lib/test-utils/factories/ServerMockFactory.ts +5 -9
- package/lib/test-utils/factories/StoreMockFactory.ts +14 -25
- package/lib/test-utils/fixtures.ts +45 -45
- package/lib/test-utils/helpers/asyncHelpers.test.ts +15 -18
- package/lib/test-utils/helpers/asyncHelpers.ts +11 -20
- package/lib/test-utils/helpers.ts +1 -5
- package/lib/test-utils/index.ts +0 -4
- package/lib/test-utils/mockFactories.ts +12 -18
- package/lib/test-utils/mocks.ts +4 -2
- package/package.json +1 -1
- package/scripts/build-meno-filter.ts +1 -4
- package/vite.config.ts +4 -4
- package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
- package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
- package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
- package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
- package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
- package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
- package/dist/chunks/chunk-JGP5A3Y5.js.map +0 -7
- package/dist/chunks/chunk-JGWFTO6P.js.map +0 -7
- package/dist/chunks/chunk-O3NAGJP4.js.map +0 -7
- package/dist/chunks/chunk-QB2LNO4W.js.map +0 -7
- package/dist/chunks/chunk-R6XHAFBF.js.map +0 -7
- package/dist/chunks/chunk-UB44F4Z2.js.map +0 -7
- package/dist/chunks/chunk-WQFG7PAH.js.map +0 -7
- package/dist/chunks/chunk-X754AHS5.js.map +0 -7
- package/dist/chunks/chunk-YBLHKYFF.js.map +0 -7
- package/dist/chunks/configService-R3OGU2UD.js +0 -13
- /package/dist/chunks/{configService-R3OGU2UD.js.map → configService-PRJZF7Y6.js.map} +0 -0
- /package/dist/chunks/{constants-STK2YBIW.js.map → constants-KIQEYMAM.js.map} +0 -0
- /package/dist/chunks/{fs-JGINUXGL.js.map → fs-ZI5JEU7V.js.map} +0 -0
|
@@ -53,7 +53,12 @@ import {
|
|
|
53
53
|
MENO_BIND_SENTINEL_EXACT_RE,
|
|
54
54
|
} from './types';
|
|
55
55
|
import { mapStylesToWebflow, buildInstanceStyleCombo } from './styleMapper';
|
|
56
|
-
import {
|
|
56
|
+
import {
|
|
57
|
+
processCodeTemplates,
|
|
58
|
+
hasTemplates as hasCodeTemplates,
|
|
59
|
+
resolveHtmlMapping,
|
|
60
|
+
isHtmlMapping,
|
|
61
|
+
} from '../../client/templateEngine';
|
|
57
62
|
import { resolvePropsFromDefinition } from '../../shared/propResolver';
|
|
58
63
|
import { readFile } from 'fs/promises';
|
|
59
64
|
import { join, basename, extname } from 'path';
|
|
@@ -253,7 +258,11 @@ function themedClassSuffix(ctx: WebflowEmitContext): string {
|
|
|
253
258
|
const t = ctx.currentTheme;
|
|
254
259
|
if (!t) return '';
|
|
255
260
|
if (ctx.defaultTheme && t === ctx.defaultTheme) return '';
|
|
256
|
-
const safe = t
|
|
261
|
+
const safe = t
|
|
262
|
+
.toLowerCase()
|
|
263
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
264
|
+
.replace(/-+/g, '-')
|
|
265
|
+
.replace(/^-|-$/g, '');
|
|
257
266
|
if (!safe) return '';
|
|
258
267
|
return `-theme-${safe}`;
|
|
259
268
|
}
|
|
@@ -295,7 +304,7 @@ function mintInstanceComboName(ctx: WebflowEmitContext, identity: string): strin
|
|
|
295
304
|
* skip default-baking entirely).
|
|
296
305
|
*/
|
|
297
306
|
function extractInterfaceDefaults(
|
|
298
|
-
iface: Record<string, { default?: unknown }> | undefined
|
|
307
|
+
iface: Record<string, { default?: unknown }> | undefined,
|
|
299
308
|
): Record<string, unknown> | undefined {
|
|
300
309
|
if (!iface) return undefined;
|
|
301
310
|
const out: Record<string, unknown> = {};
|
|
@@ -316,10 +325,7 @@ function extractInterfaceDefaults(
|
|
|
316
325
|
* Page-level walks (no enclosing component) still get a usable context — we
|
|
317
326
|
* just won't have `instanceProps` to layer on top.
|
|
318
327
|
*/
|
|
319
|
-
function buildTemplateProps(
|
|
320
|
-
ctx: WebflowEmitContext,
|
|
321
|
-
instanceProps?: Record<string, unknown>
|
|
322
|
-
): Record<string, unknown> {
|
|
328
|
+
function buildTemplateProps(ctx: WebflowEmitContext, instanceProps?: Record<string, unknown>): Record<string, unknown> {
|
|
323
329
|
return {
|
|
324
330
|
...(ctx.templateContext ?? {}),
|
|
325
331
|
...(ctx.cmsContext ?? {}),
|
|
@@ -336,16 +342,10 @@ function buildTemplateProps(
|
|
|
336
342
|
* `RAW_HTML_PREFIX`-marked rich-text values get flattened to visible text after
|
|
337
343
|
* substitution so the sentinel + inline HTML can't leak into a tag/attribute.
|
|
338
344
|
*/
|
|
339
|
-
function resolveStringTemplate(
|
|
340
|
-
text: string,
|
|
341
|
-
ctx: WebflowEmitContext,
|
|
342
|
-
instanceProps?: Record<string, unknown>
|
|
343
|
-
): string {
|
|
345
|
+
function resolveStringTemplate(text: string, ctx: WebflowEmitContext, instanceProps?: Record<string, unknown>): string {
|
|
344
346
|
if (!hasCodeTemplates(text)) return text;
|
|
345
347
|
const out = processCodeTemplates(text, buildTemplateProps(ctx, instanceProps));
|
|
346
|
-
return out.startsWith(RAW_HTML_PREFIX)
|
|
347
|
-
? flattenInlineHtmlToText(out.slice(RAW_HTML_PREFIX.length))
|
|
348
|
-
: out;
|
|
348
|
+
return out.startsWith(RAW_HTML_PREFIX) ? flattenInlineHtmlToText(out.slice(RAW_HTML_PREFIX.length)) : out;
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
const HEADING_TAGS = new Set(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']);
|
|
@@ -428,11 +428,7 @@ function applyLinkTextDecorationDefault(cls: WebflowStyleClass): void {
|
|
|
428
428
|
* across re-imports and is unique to this exact body root (the outer combo
|
|
429
429
|
* name is keyed by the instance's outer location).
|
|
430
430
|
*/
|
|
431
|
-
function mergeComboClasses(
|
|
432
|
-
inner: WebflowStyleClass,
|
|
433
|
-
outer: WebflowStyleClass,
|
|
434
|
-
parentName: string,
|
|
435
|
-
): WebflowStyleClass {
|
|
431
|
+
function mergeComboClasses(inner: WebflowStyleClass, outer: WebflowStyleClass, parentName: string): WebflowStyleClass {
|
|
436
432
|
const innerSuffix = inner.name.startsWith('is-') ? inner.name.slice(3) : inner.name;
|
|
437
433
|
const merged: WebflowStyleClass = {
|
|
438
434
|
name: `${outer.name}_${innerSuffix}`,
|
|
@@ -528,9 +524,14 @@ async function maybeInlineLocalImage(element: WebflowElement, src: string): Prom
|
|
|
528
524
|
* are decoded; comments are stripped.
|
|
529
525
|
*/
|
|
530
526
|
function flattenInlineHtmlToText(raw: string): string {
|
|
531
|
-
const decode = (s: string) =>
|
|
532
|
-
|
|
533
|
-
|
|
527
|
+
const decode = (s: string) =>
|
|
528
|
+
s
|
|
529
|
+
.replace(/&/g, '&')
|
|
530
|
+
.replace(/</g, '<')
|
|
531
|
+
.replace(/>/g, '>')
|
|
532
|
+
.replace(/"/g, '"')
|
|
533
|
+
.replace(/'/g, "'")
|
|
534
|
+
.replace(/ /g, ' ');
|
|
534
535
|
|
|
535
536
|
let out = '';
|
|
536
537
|
const tagRe = /<!--[\s\S]*?-->|<\/?([a-zA-Z][a-zA-Z0-9]*)[^>]*>/g;
|
|
@@ -562,11 +563,7 @@ function flattenInlineHtmlToText(raw: string): string {
|
|
|
562
563
|
* breakpoint parameter lets us materialize the same `var(--h1-fs)` reference
|
|
563
564
|
* to its scaled value at every Meno breakpoint.
|
|
564
565
|
*/
|
|
565
|
-
function resolveVarsInValue(
|
|
566
|
-
value: string,
|
|
567
|
-
ctx: WebflowEmitContext,
|
|
568
|
-
breakpoint: string = 'base'
|
|
569
|
-
): string {
|
|
566
|
+
function resolveVarsInValue(value: string, ctx: WebflowEmitContext, breakpoint: string = 'base'): string {
|
|
570
567
|
if (!value || (!ctx.themeVars && !ctx.projectVars)) return value;
|
|
571
568
|
// If `currentTheme` names a theme that doesn't exist in this project's
|
|
572
569
|
// colors.json, fall back to the project default — that mirrors runtime
|
|
@@ -575,14 +572,10 @@ function resolveVarsInValue(
|
|
|
575
572
|
// would survive the substitution pass and ship as literal `var(--…)` to
|
|
576
573
|
// Webflow.
|
|
577
574
|
const themeMap = ctx.themeVars
|
|
578
|
-
? (
|
|
579
|
-
|
|
580
|
-
?? (ctx.defaultTheme ? ctx.themeVars[ctx.defaultTheme] : undefined)
|
|
581
|
-
)
|
|
582
|
-
: undefined;
|
|
583
|
-
const projectMap = ctx.projectVars
|
|
584
|
-
? (ctx.projectVars[breakpoint] || ctx.projectVars.base)
|
|
575
|
+
? ((ctx.currentTheme && ctx.themeVars[ctx.currentTheme]) ??
|
|
576
|
+
(ctx.defaultTheme ? ctx.themeVars[ctx.defaultTheme] : undefined))
|
|
585
577
|
: undefined;
|
|
578
|
+
const projectMap = ctx.projectVars ? ctx.projectVars[breakpoint] || ctx.projectVars.base : undefined;
|
|
586
579
|
const pattern = /var\(\s*(--[\w-]+)\s*(?:,\s*([^)]+))?\)/g;
|
|
587
580
|
|
|
588
581
|
let current = value;
|
|
@@ -608,7 +601,7 @@ function resolveVarsInValue(
|
|
|
608
601
|
function substituteVarsInStyleObject(
|
|
609
602
|
style: StyleObject,
|
|
610
603
|
ctx: WebflowEmitContext,
|
|
611
|
-
breakpoint: string = 'base'
|
|
604
|
+
breakpoint: string = 'base',
|
|
612
605
|
): StyleObject {
|
|
613
606
|
const out: StyleObject = {};
|
|
614
607
|
for (const [k, v] of Object.entries(style)) {
|
|
@@ -637,7 +630,7 @@ function projectBreakpointNames(ctx: WebflowEmitContext): string[] {
|
|
|
637
630
|
function expandResponsiveVarsInto(
|
|
638
631
|
baseStyle: StyleObject,
|
|
639
632
|
responsive: ResponsiveStyleObject,
|
|
640
|
-
ctx: WebflowEmitContext
|
|
633
|
+
ctx: WebflowEmitContext,
|
|
641
634
|
): void {
|
|
642
635
|
if (!ctx.projectVars) return;
|
|
643
636
|
const bps = projectBreakpointNames(ctx);
|
|
@@ -673,7 +666,7 @@ function expandResponsiveVarsInto(
|
|
|
673
666
|
*/
|
|
674
667
|
function substituteVarsInStyle(
|
|
675
668
|
style: StyleObject | ResponsiveStyleObject | undefined,
|
|
676
|
-
ctx: WebflowEmitContext
|
|
669
|
+
ctx: WebflowEmitContext,
|
|
677
670
|
): StyleObject | ResponsiveStyleObject | undefined {
|
|
678
671
|
if (!style) return style;
|
|
679
672
|
if (isResponsiveStyleObject(style)) {
|
|
@@ -700,13 +693,16 @@ function substituteVarsInStyle(
|
|
|
700
693
|
|
|
701
694
|
function substituteVarsInInteractive(
|
|
702
695
|
rules: InteractiveStyles | undefined,
|
|
703
|
-
ctx: WebflowEmitContext
|
|
696
|
+
ctx: WebflowEmitContext,
|
|
704
697
|
): InteractiveStyles | undefined {
|
|
705
698
|
if (!rules) return rules;
|
|
706
|
-
return rules.map(
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
699
|
+
return rules.map(
|
|
700
|
+
(rule): InteractiveStyleRule => ({
|
|
701
|
+
...rule,
|
|
702
|
+
style: (substituteVarsInStyle(rule.style as StyleObject | ResponsiveStyleObject, ctx) ??
|
|
703
|
+
rule.style) as StyleValue,
|
|
704
|
+
}),
|
|
705
|
+
);
|
|
710
706
|
}
|
|
711
707
|
|
|
712
708
|
/**
|
|
@@ -769,10 +765,7 @@ function substituteVarsInStyleClass(cls: WebflowStyleClass, ctx: WebflowEmitCont
|
|
|
769
765
|
* Kept private so we don't widen styleMapper's public surface just for the
|
|
770
766
|
* combo-class expansion above.
|
|
771
767
|
*/
|
|
772
|
-
function menoBreakpointToWebflowTier(
|
|
773
|
-
bpName: string,
|
|
774
|
-
breakpoints: BreakpointConfig
|
|
775
|
-
): string {
|
|
768
|
+
function menoBreakpointToWebflowTier(bpName: string, breakpoints: BreakpointConfig): string {
|
|
776
769
|
if (bpName === 'tablet') return 'medium';
|
|
777
770
|
if (bpName === 'mobile') return 'small';
|
|
778
771
|
const entry = breakpoints[bpName];
|
|
@@ -810,7 +803,7 @@ function isResponsiveStyleObject(style: StyleObject | ResponsiveStyleObject): st
|
|
|
810
803
|
function extractBaseColor(
|
|
811
804
|
style: StyleObject | ResponsiveStyleObject | undefined,
|
|
812
805
|
ctx?: WebflowEmitContext,
|
|
813
|
-
instanceProps?: Record<string, unknown
|
|
806
|
+
instanceProps?: Record<string, unknown>,
|
|
814
807
|
): string | undefined {
|
|
815
808
|
if (!style) return undefined;
|
|
816
809
|
const flat: StyleObject | undefined = isResponsiveStyleObject(style)
|
|
@@ -860,10 +853,7 @@ function inlineCurrentColorInSvg(svg: string, color: string): string {
|
|
|
860
853
|
* styleMapper can still emit them as Webflow combo classes. Values without
|
|
861
854
|
* templates pass through unchanged.
|
|
862
855
|
*/
|
|
863
|
-
function resolveTemplatesInStyleObject(
|
|
864
|
-
style: StyleObject,
|
|
865
|
-
props: Record<string, unknown>
|
|
866
|
-
): StyleObject {
|
|
856
|
+
function resolveTemplatesInStyleObject(style: StyleObject, props: Record<string, unknown>): StyleObject {
|
|
867
857
|
const result: StyleObject = {};
|
|
868
858
|
for (const [key, value] of Object.entries(style)) {
|
|
869
859
|
if (typeof value === 'string' && hasCodeTemplates(value)) {
|
|
@@ -882,7 +872,7 @@ function resolveTemplatesInStyleObject(
|
|
|
882
872
|
*/
|
|
883
873
|
function resolveStyleTemplates(
|
|
884
874
|
style: StyleObject | ResponsiveStyleObject | undefined,
|
|
885
|
-
props: Record<string, unknown> | undefined
|
|
875
|
+
props: Record<string, unknown> | undefined,
|
|
886
876
|
): StyleObject | ResponsiveStyleObject | undefined {
|
|
887
877
|
if (!style || !props) return style;
|
|
888
878
|
if (isResponsiveStyleObject(style)) {
|
|
@@ -927,7 +917,7 @@ function extractSingleTemplateProp(value: string): { prop: string; prefix: strin
|
|
|
927
917
|
function templatesToSyntheticMappings(
|
|
928
918
|
style: StyleObject,
|
|
929
919
|
componentDefaults: Record<string, unknown>,
|
|
930
|
-
instanceProps: Record<string, unknown
|
|
920
|
+
instanceProps: Record<string, unknown>,
|
|
931
921
|
): StyleObject {
|
|
932
922
|
const out: StyleObject = {};
|
|
933
923
|
for (const [key, value] of Object.entries(style)) {
|
|
@@ -973,7 +963,7 @@ function templatesToSyntheticMappings(
|
|
|
973
963
|
function convertStyleTemplatesToMappings(
|
|
974
964
|
style: StyleObject | ResponsiveStyleObject | undefined,
|
|
975
965
|
componentDefaults: Record<string, unknown> | undefined,
|
|
976
|
-
instanceProps: Record<string, unknown> | undefined
|
|
966
|
+
instanceProps: Record<string, unknown> | undefined,
|
|
977
967
|
): StyleObject | ResponsiveStyleObject | undefined {
|
|
978
968
|
if (!style || !componentDefaults || !instanceProps) return style;
|
|
979
969
|
if (isResponsiveStyleObject(style)) {
|
|
@@ -995,10 +985,7 @@ function convertStyleTemplatesToMappings(
|
|
|
995
985
|
* context is available to decide, default to rendering (true) so we don't drop
|
|
996
986
|
* nodes that would otherwise be shown.
|
|
997
987
|
*/
|
|
998
|
-
function shouldRenderNode(
|
|
999
|
-
node: ComponentNode,
|
|
1000
|
-
instanceProps?: Record<string, unknown>
|
|
1001
|
-
): boolean {
|
|
988
|
+
function shouldRenderNode(node: ComponentNode, instanceProps?: Record<string, unknown>): boolean {
|
|
1002
989
|
if (!hasIf(node)) return true;
|
|
1003
990
|
const ifValue = node.if;
|
|
1004
991
|
|
|
@@ -1014,12 +1001,7 @@ function shouldRenderNode(
|
|
|
1014
1001
|
if (typeof ifValue === 'string') {
|
|
1015
1002
|
if (!instanceProps) return true;
|
|
1016
1003
|
const resolved = processCodeTemplates(ifValue, instanceProps);
|
|
1017
|
-
return (
|
|
1018
|
-
Boolean(resolved) &&
|
|
1019
|
-
resolved !== 'false' &&
|
|
1020
|
-
resolved !== '0' &&
|
|
1021
|
-
resolved !== ''
|
|
1022
|
-
);
|
|
1004
|
+
return Boolean(resolved) && resolved !== 'false' && resolved !== '0' && resolved !== '';
|
|
1023
1005
|
}
|
|
1024
1006
|
|
|
1025
1007
|
return true;
|
|
@@ -1030,13 +1012,16 @@ function shouldRenderNode(
|
|
|
1030
1012
|
*/
|
|
1031
1013
|
function resolveInteractiveStyleTemplates(
|
|
1032
1014
|
rules: InteractiveStyles | undefined,
|
|
1033
|
-
props: Record<string, unknown> | undefined
|
|
1015
|
+
props: Record<string, unknown> | undefined,
|
|
1034
1016
|
): InteractiveStyles | undefined {
|
|
1035
1017
|
if (!rules || !props) return rules;
|
|
1036
|
-
return rules.map(
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1018
|
+
return rules.map(
|
|
1019
|
+
(rule): InteractiveStyleRule => ({
|
|
1020
|
+
...rule,
|
|
1021
|
+
style: (resolveStyleTemplates(rule.style as StyleObject | ResponsiveStyleObject, props) ??
|
|
1022
|
+
rule.style) as StyleValue,
|
|
1023
|
+
}),
|
|
1024
|
+
);
|
|
1040
1025
|
}
|
|
1041
1026
|
|
|
1042
1027
|
// ---------------------------------------------------------------------------
|
|
@@ -1053,7 +1038,7 @@ function resolveInteractiveStyleTemplates(
|
|
|
1053
1038
|
export async function nodeToWebflow(
|
|
1054
1039
|
node: ComponentNode | ComponentNode[] | string | number | null | undefined,
|
|
1055
1040
|
ctx: WebflowEmitContext,
|
|
1056
|
-
instanceProps?: Record<string, unknown
|
|
1041
|
+
instanceProps?: Record<string, unknown>,
|
|
1057
1042
|
): Promise<WebflowElement[]> {
|
|
1058
1043
|
if (node === null || node === undefined) return [];
|
|
1059
1044
|
|
|
@@ -1115,7 +1100,7 @@ export async function nodeToWebflow(
|
|
|
1115
1100
|
async function emitHtmlNode(
|
|
1116
1101
|
node: HtmlNode,
|
|
1117
1102
|
ctx: WebflowEmitContext,
|
|
1118
|
-
instanceProps?: Record<string, unknown
|
|
1103
|
+
instanceProps?: Record<string, unknown>,
|
|
1119
1104
|
): Promise<WebflowElement> {
|
|
1120
1105
|
// Resolve `{{...}}` in the tag against the same layered context meno-core
|
|
1121
1106
|
// walks at runtime — page-level / slot-injected nodes don't have
|
|
@@ -1128,15 +1113,14 @@ async function emitHtmlNode(
|
|
|
1128
1113
|
const attributes: Record<string, string | number | boolean> = {};
|
|
1129
1114
|
if (node.attributes) {
|
|
1130
1115
|
for (const [key, value] of Object.entries(node.attributes)) {
|
|
1131
|
-
attributes[key] =
|
|
1132
|
-
? resolveStringTemplate(value, ctx, instanceProps)
|
|
1133
|
-
: value;
|
|
1116
|
+
attributes[key] = typeof value === 'string' ? resolveStringTemplate(value, ctx, instanceProps) : value;
|
|
1134
1117
|
}
|
|
1135
1118
|
}
|
|
1136
1119
|
|
|
1137
|
-
const themedCtx: WebflowEmitContext =
|
|
1138
|
-
|
|
1139
|
-
|
|
1120
|
+
const themedCtx: WebflowEmitContext =
|
|
1121
|
+
typeof attributes.theme === 'string' && attributes.theme
|
|
1122
|
+
? { ...ctx, currentTheme: attributes.theme as string }
|
|
1123
|
+
: ctx;
|
|
1140
1124
|
|
|
1141
1125
|
const rawStyle = node.style as StyleObject | ResponsiveStyleObject | undefined;
|
|
1142
1126
|
const rawInteractiveStyles = node.interactiveStyles as InteractiveStyles | undefined;
|
|
@@ -1144,18 +1128,11 @@ async function emitHtmlNode(
|
|
|
1144
1128
|
// StyleMappings before resolution, so values driven by an interface prop
|
|
1145
1129
|
// emit per-instance combo classes (`is-maxwidth-640px`) instead of
|
|
1146
1130
|
// collapsing into a single primary class shared by every instance.
|
|
1147
|
-
const styleWithMappings = convertStyleTemplatesToMappings(
|
|
1148
|
-
|
|
1149
|
-
ctx.componentDefaults,
|
|
1150
|
-
instanceProps,
|
|
1151
|
-
);
|
|
1152
|
-
const style = substituteVarsInStyle(
|
|
1153
|
-
resolveStyleTemplates(styleWithMappings, instanceProps),
|
|
1154
|
-
themedCtx
|
|
1155
|
-
);
|
|
1131
|
+
const styleWithMappings = convertStyleTemplatesToMappings(rawStyle, ctx.componentDefaults, instanceProps);
|
|
1132
|
+
const style = substituteVarsInStyle(resolveStyleTemplates(styleWithMappings, instanceProps), themedCtx);
|
|
1156
1133
|
const interactiveStyles = substituteVarsInInteractive(
|
|
1157
1134
|
resolveInteractiveStyleTemplates(rawInteractiveStyles, instanceProps),
|
|
1158
|
-
themedCtx
|
|
1135
|
+
themedCtx,
|
|
1159
1136
|
);
|
|
1160
1137
|
|
|
1161
1138
|
// Generate element class and map styles.
|
|
@@ -1170,15 +1147,26 @@ async function emitHtmlNode(
|
|
|
1170
1147
|
const isLinkLike = LINK_LIKE_TAGS.has(tagLower);
|
|
1171
1148
|
const isParagraph = tagLower === 'p';
|
|
1172
1149
|
const isList = LIST_TAGS.has(tagLower);
|
|
1173
|
-
const needsClass =
|
|
1150
|
+
const needsClass =
|
|
1151
|
+
style ||
|
|
1152
|
+
(interactiveStyles && interactiveStyles.length > 0) ||
|
|
1153
|
+
node.generateElementClass ||
|
|
1154
|
+
isHeading ||
|
|
1155
|
+
isLinkLike ||
|
|
1156
|
+
isParagraph ||
|
|
1157
|
+
isList;
|
|
1174
1158
|
let className: string | undefined;
|
|
1175
1159
|
let comboClassNames: string[] | undefined;
|
|
1176
1160
|
|
|
1177
1161
|
if (needsClass) {
|
|
1178
1162
|
const elementClass = withThemeSuffix(buildElementClass(ctx, node.label), themedCtx);
|
|
1179
1163
|
const { primaryClass, comboClasses } = mapStylesToWebflow(
|
|
1180
|
-
elementClass,
|
|
1181
|
-
|
|
1164
|
+
elementClass,
|
|
1165
|
+
style,
|
|
1166
|
+
interactiveStyles,
|
|
1167
|
+
ctx.breakpoints,
|
|
1168
|
+
ctx.responsiveScales,
|
|
1169
|
+
{ instanceProps, componentDefaults: ctx.componentDefaults, themeSuffix: themedClassSuffix(themedCtx) },
|
|
1182
1170
|
);
|
|
1183
1171
|
|
|
1184
1172
|
substituteVarsInStyleClass(primaryClass, themedCtx);
|
|
@@ -1203,11 +1191,7 @@ async function emitHtmlNode(
|
|
|
1203
1191
|
// can later run them through `generateInteractiveCSS` for any rules
|
|
1204
1192
|
// Webflow's class system can't represent (descendant selectors via
|
|
1205
1193
|
// `prefix`, class-style postfixes, breakpoint-divided pseudos).
|
|
1206
|
-
if (
|
|
1207
|
-
ctx.interactiveStylesMap
|
|
1208
|
-
&& Array.isArray(interactiveStyles)
|
|
1209
|
-
&& interactiveStyles.length > 0
|
|
1210
|
-
) {
|
|
1194
|
+
if (ctx.interactiveStylesMap && Array.isArray(interactiveStyles) && interactiveStyles.length > 0) {
|
|
1211
1195
|
ctx.interactiveStylesMap.set(primaryClass.name, interactiveStyles);
|
|
1212
1196
|
}
|
|
1213
1197
|
}
|
|
@@ -1220,11 +1204,7 @@ async function emitHtmlNode(
|
|
|
1220
1204
|
// Optimize: single string child becomes textContent instead of child element
|
|
1221
1205
|
if (typeof node.children === 'string') {
|
|
1222
1206
|
textContent = resolveStringTemplate(node.children, ctx, instanceProps);
|
|
1223
|
-
} else if (
|
|
1224
|
-
Array.isArray(node.children) &&
|
|
1225
|
-
node.children.length === 1 &&
|
|
1226
|
-
typeof node.children[0] === 'string'
|
|
1227
|
-
) {
|
|
1207
|
+
} else if (Array.isArray(node.children) && node.children.length === 1 && typeof node.children[0] === 'string') {
|
|
1228
1208
|
const text = node.children[0] as string;
|
|
1229
1209
|
textContent = resolveStringTemplate(text, ctx, instanceProps);
|
|
1230
1210
|
} else {
|
|
@@ -1270,7 +1250,7 @@ async function emitHtmlNode(
|
|
|
1270
1250
|
async function emitComponentInstance(
|
|
1271
1251
|
node: ComponentInstanceNode,
|
|
1272
1252
|
ctx: WebflowEmitContext,
|
|
1273
|
-
parentProps?: Record<string, unknown
|
|
1253
|
+
parentProps?: Record<string, unknown>,
|
|
1274
1254
|
): Promise<WebflowElement[]> {
|
|
1275
1255
|
const compDef = ctx.globalComponents[node.component];
|
|
1276
1256
|
if (!compDef) {
|
|
@@ -1293,9 +1273,8 @@ async function emitComponentInstance(
|
|
|
1293
1273
|
const parentTemplateProps = parentProps ?? buildTemplateProps(ctx);
|
|
1294
1274
|
for (const [key, value] of Object.entries(node.props)) {
|
|
1295
1275
|
if (key === 'children') continue;
|
|
1296
|
-
passedProps[key] =
|
|
1297
|
-
? processCodeTemplates(value, parentTemplateProps)
|
|
1298
|
-
: value;
|
|
1276
|
+
passedProps[key] =
|
|
1277
|
+
typeof value === 'string' && hasCodeTemplates(value) ? processCodeTemplates(value, parentTemplateProps) : value;
|
|
1299
1278
|
}
|
|
1300
1279
|
}
|
|
1301
1280
|
|
|
@@ -1331,17 +1310,11 @@ async function emitComponentInstance(
|
|
|
1331
1310
|
// promotion for that instance and fall through to inline expansion so
|
|
1332
1311
|
// `emitInlineComponentBody` attaches the per-property combos directly.
|
|
1333
1312
|
const hasInstanceStyleOverrides =
|
|
1334
|
-
Boolean(structured?.acceptsStyles)
|
|
1335
|
-
&& (
|
|
1336
|
-
(node.
|
|
1337
|
-
|| (Array.isArray(node.interactiveStyles) && node.interactiveStyles.length > 0)
|
|
1338
|
-
);
|
|
1313
|
+
Boolean(structured?.acceptsStyles) &&
|
|
1314
|
+
((node.style && Object.keys(node.style as object).length > 0) ||
|
|
1315
|
+
(Array.isArray(node.interactiveStyles) && node.interactiveStyles.length > 0));
|
|
1339
1316
|
const promotedNames = ctx.promotedComponentNames || PROMOTED_TO_WEBFLOW_COMPONENT;
|
|
1340
|
-
if (
|
|
1341
|
-
promotedNames.has(node.component)
|
|
1342
|
-
&& ctx.promotedComponents
|
|
1343
|
-
&& !hasInstanceStyleOverrides
|
|
1344
|
-
) {
|
|
1317
|
+
if (promotedNames.has(node.component) && ctx.promotedComponents && !hasInstanceStyleOverrides) {
|
|
1345
1318
|
const promoted = ctx.promotedComponents;
|
|
1346
1319
|
if (!promoted.has(node.component)) {
|
|
1347
1320
|
const defaultProps: Record<string, unknown> = {};
|
|
@@ -1408,8 +1381,8 @@ async function emitInlineComponentBody(
|
|
|
1408
1381
|
// Container's body fires its own slot, the marker is the only thing
|
|
1409
1382
|
// available, has no slot context left, and renders nothing.
|
|
1410
1383
|
let effectiveChildren = node.children;
|
|
1411
|
-
|
|
1412
|
-
let inheritedSlotInstanceProps: Record<string, unknown> | undefined
|
|
1384
|
+
const inheritedSlotEmitContext = ctx.slotEmitContext;
|
|
1385
|
+
let inheritedSlotInstanceProps: Record<string, unknown> | undefined;
|
|
1413
1386
|
let didForwardSlot = false;
|
|
1414
1387
|
if (node.children != null && typeof node.children !== 'string') {
|
|
1415
1388
|
const childArr = Array.isArray(node.children) ? node.children : [node.children];
|
|
@@ -1450,13 +1423,14 @@ async function emitInlineComponentBody(
|
|
|
1450
1423
|
fileName: node.component,
|
|
1451
1424
|
elementPath: [0],
|
|
1452
1425
|
slotChildren: effectiveChildren,
|
|
1453
|
-
slotEmitContext:
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1426
|
+
slotEmitContext:
|
|
1427
|
+
didForwardSlot && inheritedSlotEmitContext
|
|
1428
|
+
? inheritedSlotEmitContext
|
|
1429
|
+
: {
|
|
1430
|
+
fileType: ctx.fileType,
|
|
1431
|
+
fileName: ctx.fileName,
|
|
1432
|
+
elementPath: [...ctx.elementPath],
|
|
1433
|
+
},
|
|
1460
1434
|
// Slot children authored alongside this instance refer to the OUTER
|
|
1461
1435
|
// component's interface (the one whose body contains `<Component …>{slot
|
|
1462
1436
|
// children}</Component>`). When the body hits its `<slot/>`, those
|
|
@@ -1475,9 +1449,7 @@ async function emitInlineComponentBody(
|
|
|
1475
1449
|
// alongside resolved props. resolvedProps wins on key conflicts so
|
|
1476
1450
|
// explicit instance props still override.
|
|
1477
1451
|
const ctxTemplate = ctx.templateContext as Record<string, unknown> | undefined;
|
|
1478
|
-
const bodyProps = ctxTemplate
|
|
1479
|
-
? { ...ctxTemplate, ...resolvedProps }
|
|
1480
|
-
: resolvedProps;
|
|
1452
|
+
const bodyProps = ctxTemplate ? { ...ctxTemplate, ...resolvedProps } : resolvedProps;
|
|
1481
1453
|
const emitted = await nodeToWebflow(body, compCtx, bodyProps);
|
|
1482
1454
|
|
|
1483
1455
|
// `acceptsStyles`: forward instance-level style / interactiveStyles
|
|
@@ -1487,12 +1459,10 @@ async function emitInlineComponentBody(
|
|
|
1487
1459
|
// named after the instance's outer location so two instances of the same
|
|
1488
1460
|
// component on the same page don't share a single class.
|
|
1489
1461
|
if (
|
|
1490
|
-
structured?.acceptsStyles
|
|
1491
|
-
|
|
1492
|
-
&& (
|
|
1493
|
-
(node.
|
|
1494
|
-
|| (Array.isArray(node.interactiveStyles) && node.interactiveStyles.length > 0)
|
|
1495
|
-
)
|
|
1462
|
+
structured?.acceptsStyles &&
|
|
1463
|
+
emitted.length > 0 &&
|
|
1464
|
+
((node.style && Object.keys(node.style as object).length > 0) ||
|
|
1465
|
+
(Array.isArray(node.interactiveStyles) && node.interactiveStyles.length > 0))
|
|
1496
1466
|
) {
|
|
1497
1467
|
const root = emitted[0];
|
|
1498
1468
|
if (root && typeof root === 'object') {
|
|
@@ -1508,10 +1478,7 @@ async function emitInlineComponentBody(
|
|
|
1508
1478
|
|
|
1509
1479
|
const rawStyle = node.style as StyleObject | ResponsiveStyleObject | undefined;
|
|
1510
1480
|
const rawInteractive = node.interactiveStyles as InteractiveStyles | undefined;
|
|
1511
|
-
const resolvedStyle = substituteVarsInStyle(
|
|
1512
|
-
resolveStyleTemplates(rawStyle, parentProps),
|
|
1513
|
-
ctx,
|
|
1514
|
-
);
|
|
1481
|
+
const resolvedStyle = substituteVarsInStyle(resolveStyleTemplates(rawStyle, parentProps), ctx);
|
|
1515
1482
|
const resolvedInteractive = substituteVarsInInteractive(
|
|
1516
1483
|
resolveInteractiveStyleTemplates(rawInteractive, parentProps),
|
|
1517
1484
|
ctx,
|
|
@@ -1542,9 +1509,8 @@ async function emitInlineComponentBody(
|
|
|
1542
1509
|
// override into a fresh merged class instead of stacking. Outer
|
|
1543
1510
|
// instance overrides land last so they win on key conflicts,
|
|
1544
1511
|
// mirroring SSR's merge order in `ssrRenderer.ts:1244`.
|
|
1545
|
-
const existingComboName =
|
|
1546
|
-
? root.comboClasses[0]
|
|
1547
|
-
: undefined;
|
|
1512
|
+
const existingComboName =
|
|
1513
|
+
Array.isArray(root.comboClasses) && root.comboClasses.length > 0 ? root.comboClasses[0] : undefined;
|
|
1548
1514
|
const inner = existingComboName ? ctx.styleClasses.get(existingComboName) : undefined;
|
|
1549
1515
|
if (inner) {
|
|
1550
1516
|
const merged = mergeComboClasses(inner, combo, root.className);
|
|
@@ -1570,17 +1536,13 @@ async function emitInlineComponentBody(
|
|
|
1570
1536
|
if (root && typeof root === 'object') {
|
|
1571
1537
|
root.attributes = root.attributes || {};
|
|
1572
1538
|
const existing = root.attributes['data-component'];
|
|
1573
|
-
root.attributes['data-component'] = existing
|
|
1574
|
-
? `${existing} ${node.component}`
|
|
1575
|
-
: node.component;
|
|
1539
|
+
root.attributes['data-component'] = existing ? `${existing} ${node.component}` : node.component;
|
|
1576
1540
|
|
|
1577
1541
|
// Serialize defineVars-exposed props into data-props, keyed by component
|
|
1578
1542
|
// name so nested components don't clobber each other on a shared root.
|
|
1579
1543
|
const defineVars = structured.defineVars;
|
|
1580
1544
|
if (defineVars) {
|
|
1581
|
-
const varsToExpose = defineVars === true
|
|
1582
|
-
? Object.keys(structured.interface || {})
|
|
1583
|
-
: defineVars;
|
|
1545
|
+
const varsToExpose = defineVars === true ? Object.keys(structured.interface || {}) : defineVars;
|
|
1584
1546
|
const propsForJS: Record<string, unknown> = {};
|
|
1585
1547
|
for (const varName of varsToExpose) {
|
|
1586
1548
|
if (resolvedProps[varName] !== undefined) {
|
|
@@ -1597,7 +1559,9 @@ async function emitInlineComponentBody(
|
|
|
1597
1559
|
if (parsed && typeof parsed === 'object') {
|
|
1598
1560
|
existingPropsMap = parsed as Record<string, unknown>;
|
|
1599
1561
|
}
|
|
1600
|
-
} catch {
|
|
1562
|
+
} catch {
|
|
1563
|
+
/* ignore malformed */
|
|
1564
|
+
}
|
|
1601
1565
|
}
|
|
1602
1566
|
existingPropsMap[node.component] = propsForJS;
|
|
1603
1567
|
// URL-encode the serialized JSON. Webflow's `<DOM>`-type element
|
|
@@ -1616,7 +1580,7 @@ async function emitInlineComponentBody(
|
|
|
1616
1580
|
async function emitSlotMarker(
|
|
1617
1581
|
node: SlotMarker,
|
|
1618
1582
|
ctx: WebflowEmitContext,
|
|
1619
|
-
instanceProps?: Record<string, unknown
|
|
1583
|
+
instanceProps?: Record<string, unknown>,
|
|
1620
1584
|
): Promise<WebflowElement[]> {
|
|
1621
1585
|
// Use instance children passed via context to fill the slot
|
|
1622
1586
|
if (ctx.slotChildren) {
|
|
@@ -1655,28 +1619,26 @@ async function emitSlotMarker(
|
|
|
1655
1619
|
async function emitEmbedNode(
|
|
1656
1620
|
node: EmbedNode,
|
|
1657
1621
|
ctx: WebflowEmitContext,
|
|
1658
|
-
instanceProps?: Record<string, unknown
|
|
1622
|
+
instanceProps?: Record<string, unknown>,
|
|
1659
1623
|
): Promise<WebflowElement> {
|
|
1660
1624
|
const style = substituteVarsInStyle(
|
|
1661
|
-
resolveStyleTemplates(
|
|
1662
|
-
|
|
1663
|
-
instanceProps
|
|
1664
|
-
),
|
|
1665
|
-
ctx
|
|
1625
|
+
resolveStyleTemplates(node.style as StyleObject | ResponsiveStyleObject | undefined, instanceProps),
|
|
1626
|
+
ctx,
|
|
1666
1627
|
);
|
|
1667
1628
|
const interactiveStyles = substituteVarsInInteractive(
|
|
1668
|
-
resolveInteractiveStyleTemplates(
|
|
1669
|
-
|
|
1670
|
-
instanceProps
|
|
1671
|
-
),
|
|
1672
|
-
ctx
|
|
1629
|
+
resolveInteractiveStyleTemplates(node.interactiveStyles as InteractiveStyles | undefined, instanceProps),
|
|
1630
|
+
ctx,
|
|
1673
1631
|
);
|
|
1674
1632
|
|
|
1675
1633
|
let className: string | undefined;
|
|
1676
1634
|
if (style || (interactiveStyles && interactiveStyles.length > 0)) {
|
|
1677
1635
|
const elementClass = withThemeSuffix(buildElementClass(ctx, node.label), ctx);
|
|
1678
1636
|
const { primaryClass } = mapStylesToWebflow(
|
|
1679
|
-
elementClass,
|
|
1637
|
+
elementClass,
|
|
1638
|
+
style,
|
|
1639
|
+
interactiveStyles,
|
|
1640
|
+
ctx.breakpoints,
|
|
1641
|
+
ctx.responsiveScales,
|
|
1680
1642
|
);
|
|
1681
1643
|
substituteVarsInStyleClass(primaryClass, ctx);
|
|
1682
1644
|
className = primaryClass.name;
|
|
@@ -1777,7 +1739,7 @@ function resolveLinkHref(rawHref: string, ctx: WebflowEmitContext): string {
|
|
|
1777
1739
|
ctx.locale,
|
|
1778
1740
|
ctx.i18nConfig.defaultLocale,
|
|
1779
1741
|
ctx.i18nConfig.defaultLocale,
|
|
1780
|
-
ctx.slugIndex
|
|
1742
|
+
ctx.slugIndex,
|
|
1781
1743
|
);
|
|
1782
1744
|
|
|
1783
1745
|
return translated + suffix;
|
|
@@ -1786,21 +1748,15 @@ function resolveLinkHref(rawHref: string, ctx: WebflowEmitContext): string {
|
|
|
1786
1748
|
async function emitLinkNode(
|
|
1787
1749
|
node: LinkNode,
|
|
1788
1750
|
ctx: WebflowEmitContext,
|
|
1789
|
-
instanceProps?: Record<string, unknown
|
|
1751
|
+
instanceProps?: Record<string, unknown>,
|
|
1790
1752
|
): Promise<WebflowElement> {
|
|
1791
1753
|
const style = substituteVarsInStyle(
|
|
1792
|
-
resolveStyleTemplates(
|
|
1793
|
-
|
|
1794
|
-
instanceProps
|
|
1795
|
-
),
|
|
1796
|
-
ctx
|
|
1754
|
+
resolveStyleTemplates(node.style as StyleObject | ResponsiveStyleObject | undefined, instanceProps),
|
|
1755
|
+
ctx,
|
|
1797
1756
|
);
|
|
1798
1757
|
const interactiveStyles = substituteVarsInInteractive(
|
|
1799
|
-
resolveInteractiveStyleTemplates(
|
|
1800
|
-
|
|
1801
|
-
instanceProps
|
|
1802
|
-
),
|
|
1803
|
-
ctx
|
|
1758
|
+
resolveInteractiveStyleTemplates(node.interactiveStyles as InteractiveStyles | undefined, instanceProps),
|
|
1759
|
+
ctx,
|
|
1804
1760
|
);
|
|
1805
1761
|
|
|
1806
1762
|
// Always assign a class so we can default `text-decoration: none` —
|
|
@@ -1811,8 +1767,12 @@ async function emitLinkNode(
|
|
|
1811
1767
|
{
|
|
1812
1768
|
const elementClass = withThemeSuffix(buildElementClass(ctx, node.label), ctx);
|
|
1813
1769
|
const { primaryClass, comboClasses } = mapStylesToWebflow(
|
|
1814
|
-
elementClass,
|
|
1815
|
-
|
|
1770
|
+
elementClass,
|
|
1771
|
+
style,
|
|
1772
|
+
interactiveStyles,
|
|
1773
|
+
ctx.breakpoints,
|
|
1774
|
+
ctx.responsiveScales,
|
|
1775
|
+
{ instanceProps, componentDefaults: ctx.componentDefaults, themeSuffix: themedClassSuffix(ctx) },
|
|
1816
1776
|
);
|
|
1817
1777
|
substituteVarsInStyleClass(primaryClass, ctx);
|
|
1818
1778
|
applyLinkTextDecorationDefault(primaryClass);
|
|
@@ -1829,11 +1789,7 @@ async function emitLinkNode(
|
|
|
1829
1789
|
}
|
|
1830
1790
|
}
|
|
1831
1791
|
|
|
1832
|
-
if (
|
|
1833
|
-
ctx.interactiveStylesMap
|
|
1834
|
-
&& Array.isArray(interactiveStyles)
|
|
1835
|
-
&& interactiveStyles.length > 0
|
|
1836
|
-
) {
|
|
1792
|
+
if (ctx.interactiveStylesMap && Array.isArray(interactiveStyles) && interactiveStyles.length > 0) {
|
|
1837
1793
|
ctx.interactiveStylesMap.set(primaryClass.name, interactiveStyles);
|
|
1838
1794
|
}
|
|
1839
1795
|
}
|
|
@@ -1851,9 +1807,7 @@ async function emitLinkNode(
|
|
|
1851
1807
|
const attributes: Record<string, string | number | boolean> = { href };
|
|
1852
1808
|
if (node.attributes) {
|
|
1853
1809
|
for (const [key, value] of Object.entries(node.attributes)) {
|
|
1854
|
-
attributes[key] =
|
|
1855
|
-
? resolveStringTemplate(value, ctx, instanceProps)
|
|
1856
|
-
: value;
|
|
1810
|
+
attributes[key] = typeof value === 'string' ? resolveStringTemplate(value, ctx, instanceProps) : value;
|
|
1857
1811
|
}
|
|
1858
1812
|
}
|
|
1859
1813
|
|
|
@@ -1905,7 +1859,7 @@ function resolveItemI18n(item: CMSItem, ctx: WebflowEmitContext): CMSItem {
|
|
|
1905
1859
|
async function getCollectionItemsForExport(
|
|
1906
1860
|
node: ListNode,
|
|
1907
1861
|
source: string,
|
|
1908
|
-
ctx: WebflowEmitContext
|
|
1862
|
+
ctx: WebflowEmitContext,
|
|
1909
1863
|
): Promise<CMSItem[]> {
|
|
1910
1864
|
if (!ctx.cmsService) return [];
|
|
1911
1865
|
|
|
@@ -1923,16 +1877,16 @@ async function getCollectionItemsForExport(
|
|
|
1923
1877
|
for (const part of fieldPath.split('.')) {
|
|
1924
1878
|
if (value && typeof value === 'object' && part in (value as object)) {
|
|
1925
1879
|
value = (value as Record<string, unknown>)[part];
|
|
1926
|
-
} else {
|
|
1880
|
+
} else {
|
|
1881
|
+
value = undefined;
|
|
1882
|
+
break;
|
|
1883
|
+
}
|
|
1927
1884
|
}
|
|
1928
1885
|
if (value !== null && value !== undefined) {
|
|
1929
|
-
resolvedIds = Array.isArray(value) ? value.map(v => String(v)) : String(value);
|
|
1886
|
+
resolvedIds = Array.isArray(value) ? value.map((v) => String(v)) : String(value);
|
|
1930
1887
|
}
|
|
1931
1888
|
} else {
|
|
1932
|
-
resolvedIds = resolveItemsTemplate(
|
|
1933
|
-
itemsField,
|
|
1934
|
-
(ctx.templateContext || { _type: 'template' }) as any
|
|
1935
|
-
);
|
|
1889
|
+
resolvedIds = resolveItemsTemplate(itemsField, (ctx.templateContext || { _type: 'template' }) as any);
|
|
1936
1890
|
}
|
|
1937
1891
|
if (!resolvedIds) return [];
|
|
1938
1892
|
const ids = Array.isArray(resolvedIds) ? resolvedIds : [resolvedIds];
|
|
@@ -1942,7 +1896,7 @@ async function getCollectionItemsForExport(
|
|
|
1942
1896
|
items = await ctx.cmsService.getItemsByIds(source, ids);
|
|
1943
1897
|
}
|
|
1944
1898
|
if (ctx.locale) {
|
|
1945
|
-
items = items.filter(it => !isItemDraftForLocale(it, ctx.locale!));
|
|
1899
|
+
items = items.filter((it) => !isItemDraftForLocale(it, ctx.locale!));
|
|
1946
1900
|
}
|
|
1947
1901
|
} else {
|
|
1948
1902
|
items = await ctx.cmsService.queryItems({
|
|
@@ -1957,13 +1911,17 @@ async function getCollectionItemsForExport(
|
|
|
1957
1911
|
|
|
1958
1912
|
if ((node as any).excludeCurrentItem && ctx.cmsContext?.cms?._id) {
|
|
1959
1913
|
const currentId = ctx.cmsContext.cms._id as string;
|
|
1960
|
-
items = items.filter(it => it._id !== currentId);
|
|
1914
|
+
items = items.filter((it) => it._id !== currentId);
|
|
1961
1915
|
}
|
|
1962
1916
|
|
|
1963
1917
|
return items;
|
|
1964
1918
|
}
|
|
1965
1919
|
|
|
1966
|
-
function getPropItemsForExport(
|
|
1920
|
+
function getPropItemsForExport(
|
|
1921
|
+
source: string,
|
|
1922
|
+
ctx: WebflowEmitContext,
|
|
1923
|
+
instanceProps?: Record<string, unknown>,
|
|
1924
|
+
): unknown[] {
|
|
1967
1925
|
// Template expression like "{{items}}" or "{{category.items}}". SSR pre-
|
|
1968
1926
|
// substitutes these against the merged prop scope via `processStructure`
|
|
1969
1927
|
// before the list node is reached, so its `getPropItems` only needs to look
|
|
@@ -2086,10 +2044,7 @@ function applyBindingMarkers(el: WebflowElement): void {
|
|
|
2086
2044
|
|
|
2087
2045
|
// Image inlining produced bytes for a sentinel src — drop them; user will
|
|
2088
2046
|
// re-bind the image to a real CMS field after insertion.
|
|
2089
|
-
if (
|
|
2090
|
-
el.menoBind?.attrFields?.src
|
|
2091
|
-
&& (el.imageDataBase64 || el.imageSrc)
|
|
2092
|
-
) {
|
|
2047
|
+
if (el.menoBind?.attrFields?.src && (el.imageDataBase64 || el.imageSrc)) {
|
|
2093
2048
|
delete el.imageDataBase64;
|
|
2094
2049
|
delete el.imageDataMime;
|
|
2095
2050
|
delete el.imageDataFileName;
|
|
@@ -2119,9 +2074,7 @@ function applyBindingMarkers(el: WebflowElement): void {
|
|
|
2119
2074
|
* Walks recursively, in-place. Idempotent: existing `<li>` children pass
|
|
2120
2075
|
* through untouched.
|
|
2121
2076
|
*/
|
|
2122
|
-
export function normalizeListChildren(
|
|
2123
|
-
elements: Array<WebflowElement | string> | undefined
|
|
2124
|
-
): void {
|
|
2077
|
+
export function normalizeListChildren(elements: Array<WebflowElement | string> | undefined): void {
|
|
2125
2078
|
if (!Array.isArray(elements)) return;
|
|
2126
2079
|
for (const el of elements) {
|
|
2127
2080
|
if (typeof el === 'string') continue;
|
|
@@ -2147,11 +2100,11 @@ export function normalizeListChildren(
|
|
|
2147
2100
|
async function emitListNode(
|
|
2148
2101
|
node: ListNode,
|
|
2149
2102
|
ctx: WebflowEmitContext,
|
|
2150
|
-
instanceProps?: Record<string, unknown
|
|
2103
|
+
instanceProps?: Record<string, unknown>,
|
|
2151
2104
|
): Promise<WebflowElement[]> {
|
|
2152
2105
|
const nodeType = node.type as string;
|
|
2153
2106
|
const isLegacyCMSList = nodeType === 'cms-list';
|
|
2154
|
-
const sourceType = isLegacyCMSList ? 'collection' :
|
|
2107
|
+
const sourceType = isLegacyCMSList ? 'collection' : node.sourceType || 'prop';
|
|
2155
2108
|
|
|
2156
2109
|
if (sourceType === 'collection' && !ctx.cmsService) return [];
|
|
2157
2110
|
|
|
@@ -2171,13 +2124,7 @@ async function emitListNode(
|
|
|
2171
2124
|
if (sourceType === 'collection' && ctx.bindCollectionLists && ctx.cmsService && source) {
|
|
2172
2125
|
const schema = ctx.cmsService.getSchema(source) || undefined;
|
|
2173
2126
|
const placeholder = buildBindingPlaceholderItem(schema);
|
|
2174
|
-
const templateContext = buildTemplateContext(
|
|
2175
|
-
variableName,
|
|
2176
|
-
placeholder,
|
|
2177
|
-
0,
|
|
2178
|
-
1,
|
|
2179
|
-
ctx.templateContext as any
|
|
2180
|
-
);
|
|
2127
|
+
const templateContext = buildTemplateContext(variableName, placeholder, 0, 1, ctx.templateContext as any);
|
|
2181
2128
|
const childCtx: WebflowEmitContext = {
|
|
2182
2129
|
...ctx,
|
|
2183
2130
|
templateContext: templateContext as Record<string, unknown>,
|
|
@@ -2186,17 +2133,17 @@ async function emitListNode(
|
|
|
2186
2133
|
...(instanceProps || {}),
|
|
2187
2134
|
...templateContext,
|
|
2188
2135
|
};
|
|
2189
|
-
const renderedChildren = node.children
|
|
2190
|
-
? await convertChildren(node.children as any, childCtx, mergedProps)
|
|
2191
|
-
: [];
|
|
2136
|
+
const renderedChildren = node.children ? await convertChildren(node.children as any, childCtx, mergedProps) : [];
|
|
2192
2137
|
for (const child of renderedChildren) {
|
|
2193
2138
|
if (typeof child !== 'string') applyBindingMarkers(child);
|
|
2194
2139
|
}
|
|
2195
|
-
return [
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2140
|
+
return [
|
|
2141
|
+
{
|
|
2142
|
+
tag: COLLECTION_LIST_TAG,
|
|
2143
|
+
menoCollectionRef: source,
|
|
2144
|
+
children: renderedChildren,
|
|
2145
|
+
},
|
|
2146
|
+
];
|
|
2200
2147
|
}
|
|
2201
2148
|
|
|
2202
2149
|
let items: unknown[];
|
|
@@ -2221,29 +2168,22 @@ async function expandListItems(
|
|
|
2221
2168
|
instanceProps: Record<string, unknown> | undefined,
|
|
2222
2169
|
items: unknown[],
|
|
2223
2170
|
variableName: string,
|
|
2224
|
-
source: string
|
|
2171
|
+
source: string,
|
|
2225
2172
|
): Promise<WebflowElement[]> {
|
|
2226
2173
|
if (items.length === 0) return [];
|
|
2227
2174
|
|
|
2228
|
-
const schema: CMSSchema | undefined = ctx.cmsService
|
|
2229
|
-
? (ctx.cmsService.getSchema(source) || undefined)
|
|
2230
|
-
: undefined;
|
|
2175
|
+
const schema: CMSSchema | undefined = ctx.cmsService ? ctx.cmsService.getSchema(source) || undefined : undefined;
|
|
2231
2176
|
|
|
2232
2177
|
const out: WebflowElement[] = [];
|
|
2233
2178
|
for (let i = 0; i < items.length; i++) {
|
|
2234
2179
|
const rawItem = items[i] as Record<string, unknown>;
|
|
2235
|
-
const enriched =
|
|
2236
|
-
|
|
2237
|
-
|
|
2180
|
+
const enriched =
|
|
2181
|
+
schema && ctx.locale && ctx.i18nConfig
|
|
2182
|
+
? addItemUrl(rawItem as CMSItem, schema, ctx.locale, ctx.i18nConfig)
|
|
2183
|
+
: (rawItem as CMSItem);
|
|
2238
2184
|
const item = resolveItemI18n(enriched, ctx);
|
|
2239
2185
|
|
|
2240
|
-
const templateContext = buildTemplateContext(
|
|
2241
|
-
variableName,
|
|
2242
|
-
item,
|
|
2243
|
-
i,
|
|
2244
|
-
items.length,
|
|
2245
|
-
(ctx.templateContext as any)
|
|
2246
|
-
);
|
|
2186
|
+
const templateContext = buildTemplateContext(variableName, item, i, items.length, ctx.templateContext as any);
|
|
2247
2187
|
|
|
2248
2188
|
const childCtx: WebflowEmitContext = {
|
|
2249
2189
|
...ctx,
|
|
@@ -2275,7 +2215,7 @@ async function expandListItems(
|
|
|
2275
2215
|
async function emitLocaleListNode(
|
|
2276
2216
|
node: LocaleListNode,
|
|
2277
2217
|
ctx: WebflowEmitContext,
|
|
2278
|
-
instanceProps?: Record<string, unknown
|
|
2218
|
+
instanceProps?: Record<string, unknown>,
|
|
2279
2219
|
): Promise<WebflowElement[]> {
|
|
2280
2220
|
if (!ctx.slugMappings || !ctx.pagePath || !ctx.i18nConfig || !ctx.locale) {
|
|
2281
2221
|
return [{ tag: 'div', attributes: { 'data-locale-list': 'true' } }];
|
|
@@ -2298,49 +2238,40 @@ async function emitLocaleListNode(
|
|
|
2298
2238
|
|
|
2299
2239
|
// Build container style class
|
|
2300
2240
|
const containerStyle = substituteVarsInStyle(
|
|
2301
|
-
resolveStyleTemplates(
|
|
2302
|
-
|
|
2303
|
-
instanceProps
|
|
2304
|
-
),
|
|
2305
|
-
ctx
|
|
2241
|
+
resolveStyleTemplates(node.style as StyleObject | ResponsiveStyleObject | undefined, instanceProps),
|
|
2242
|
+
ctx,
|
|
2306
2243
|
);
|
|
2307
2244
|
const containerInteractive = substituteVarsInInteractive(
|
|
2308
|
-
resolveInteractiveStyleTemplates(
|
|
2309
|
-
|
|
2310
|
-
instanceProps
|
|
2311
|
-
),
|
|
2312
|
-
ctx
|
|
2245
|
+
resolveInteractiveStyleTemplates(node.interactiveStyles as InteractiveStyles | undefined, instanceProps),
|
|
2246
|
+
ctx,
|
|
2313
2247
|
);
|
|
2314
2248
|
|
|
2315
2249
|
let containerClass: string | undefined;
|
|
2316
2250
|
if (containerStyle || (containerInteractive && containerInteractive.length > 0)) {
|
|
2317
2251
|
const elementClass = withThemeSuffix(buildElementClass(ctx, node.label), ctx);
|
|
2318
2252
|
const { primaryClass } = mapStylesToWebflow(
|
|
2319
|
-
elementClass,
|
|
2253
|
+
elementClass,
|
|
2254
|
+
containerStyle,
|
|
2255
|
+
containerInteractive,
|
|
2256
|
+
ctx.breakpoints,
|
|
2257
|
+
ctx.responsiveScales,
|
|
2320
2258
|
);
|
|
2321
2259
|
substituteVarsInStyleClass(primaryClass, ctx);
|
|
2322
2260
|
containerClass = primaryClass.name;
|
|
2323
2261
|
ctx.styleClasses.set(primaryClass.name, primaryClass);
|
|
2324
2262
|
}
|
|
2325
2263
|
|
|
2326
|
-
const buildSubClass = (
|
|
2327
|
-
style: unknown,
|
|
2328
|
-
suffix: string
|
|
2329
|
-
): string | undefined => {
|
|
2264
|
+
const buildSubClass = (style: unknown, suffix: string): string | undefined => {
|
|
2330
2265
|
const resolved = substituteVarsInStyle(
|
|
2331
|
-
resolveStyleTemplates(
|
|
2332
|
-
|
|
2333
|
-
instanceProps
|
|
2334
|
-
),
|
|
2335
|
-
ctx
|
|
2266
|
+
resolveStyleTemplates(style as StyleObject | ResponsiveStyleObject | undefined, instanceProps),
|
|
2267
|
+
ctx,
|
|
2336
2268
|
);
|
|
2337
2269
|
if (!resolved) return undefined;
|
|
2338
2270
|
const className = withThemeSuffix(`${buildElementClass(ctx, node.label)}-${suffix}`, ctx);
|
|
2339
2271
|
const { primaryClass } = mapStylesToWebflow(className, resolved, undefined, ctx.breakpoints, ctx.responsiveScales);
|
|
2340
2272
|
substituteVarsInStyleClass(primaryClass, ctx);
|
|
2341
|
-
if (Object.keys(primaryClass.base).length === 0
|
|
2342
|
-
|
|
2343
|
-
&& !primaryClass.pseudoStates) return undefined;
|
|
2273
|
+
if (Object.keys(primaryClass.base).length === 0 && !primaryClass.breakpoints && !primaryClass.pseudoStates)
|
|
2274
|
+
return undefined;
|
|
2344
2275
|
ctx.styleClasses.set(primaryClass.name, primaryClass);
|
|
2345
2276
|
return primaryClass.name;
|
|
2346
2277
|
};
|
|
@@ -2390,10 +2321,16 @@ async function emitLocaleListNode(
|
|
|
2390
2321
|
|
|
2391
2322
|
let displayText: string;
|
|
2392
2323
|
switch (displayType) {
|
|
2393
|
-
case 'code':
|
|
2394
|
-
|
|
2324
|
+
case 'code':
|
|
2325
|
+
displayText = link.locale.toUpperCase();
|
|
2326
|
+
break;
|
|
2327
|
+
case 'name':
|
|
2328
|
+
displayText = link.name;
|
|
2329
|
+
break;
|
|
2395
2330
|
case 'nativeName':
|
|
2396
|
-
default:
|
|
2331
|
+
default:
|
|
2332
|
+
displayText = link.nativeName;
|
|
2333
|
+
break;
|
|
2397
2334
|
}
|
|
2398
2335
|
innerChildren.push({ tag: 'div', textContent: displayText });
|
|
2399
2336
|
anchor.children = innerChildren;
|
|
@@ -2418,7 +2355,7 @@ async function emitLocaleListNode(
|
|
|
2418
2355
|
async function convertChildren(
|
|
2419
2356
|
children: (ComponentNode | string)[] | string | ComponentNode | null | undefined,
|
|
2420
2357
|
ctx: WebflowEmitContext,
|
|
2421
|
-
instanceProps?: Record<string, unknown
|
|
2358
|
+
instanceProps?: Record<string, unknown>,
|
|
2422
2359
|
): Promise<WebflowElement[]> {
|
|
2423
2360
|
if (!children) return [];
|
|
2424
2361
|
|