@depup/svelte 5.53.3-depup.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/LICENSE.md +7 -0
- package/README.md +41 -0
- package/action.d.ts +1 -0
- package/animate.d.ts +1 -0
- package/compiler/index.js +1 -0
- package/compiler/package.json +3 -0
- package/compiler.d.ts +1 -0
- package/easing.d.ts +1 -0
- package/elements.d.ts +2078 -0
- package/index.d.ts +1 -0
- package/legacy.d.ts +1 -0
- package/motion.d.ts +1 -0
- package/package.json +185 -0
- package/src/animate/index.js +78 -0
- package/src/attachments/index.js +113 -0
- package/src/compiler/errors.js +1719 -0
- package/src/compiler/index.js +198 -0
- package/src/compiler/legacy.js +637 -0
- package/src/compiler/migrate/index.js +1996 -0
- package/src/compiler/phases/1-parse/acorn.js +198 -0
- package/src/compiler/phases/1-parse/index.js +326 -0
- package/src/compiler/phases/1-parse/read/context.js +116 -0
- package/src/compiler/phases/1-parse/read/expression.js +93 -0
- package/src/compiler/phases/1-parse/read/options.js +263 -0
- package/src/compiler/phases/1-parse/read/script.js +97 -0
- package/src/compiler/phases/1-parse/read/style.js +637 -0
- package/src/compiler/phases/1-parse/remove_typescript_nodes.js +180 -0
- package/src/compiler/phases/1-parse/state/element.js +937 -0
- package/src/compiler/phases/1-parse/state/fragment.js +17 -0
- package/src/compiler/phases/1-parse/state/tag.js +751 -0
- package/src/compiler/phases/1-parse/state/text.js +23 -0
- package/src/compiler/phases/1-parse/utils/bracket.js +213 -0
- package/src/compiler/phases/1-parse/utils/create.js +16 -0
- package/src/compiler/phases/1-parse/utils/entities.js +2234 -0
- package/src/compiler/phases/1-parse/utils/fuzzymatch.js +281 -0
- package/src/compiler/phases/1-parse/utils/html.js +127 -0
- package/src/compiler/phases/2-analyze/css/css-analyze.js +331 -0
- package/src/compiler/phases/2-analyze/css/css-prune.js +1206 -0
- package/src/compiler/phases/2-analyze/css/css-warn.js +47 -0
- package/src/compiler/phases/2-analyze/css/utils.js +177 -0
- package/src/compiler/phases/2-analyze/index.js +1300 -0
- package/src/compiler/phases/2-analyze/utils/check_graph_for_cycles.js +47 -0
- package/src/compiler/phases/2-analyze/visitors/AnimateDirective.js +15 -0
- package/src/compiler/phases/2-analyze/visitors/ArrowFunctionExpression.js +11 -0
- package/src/compiler/phases/2-analyze/visitors/AssignmentExpression.js +31 -0
- package/src/compiler/phases/2-analyze/visitors/AttachTag.js +17 -0
- package/src/compiler/phases/2-analyze/visitors/Attribute.js +66 -0
- package/src/compiler/phases/2-analyze/visitors/AwaitBlock.js +48 -0
- package/src/compiler/phases/2-analyze/visitors/AwaitExpression.js +150 -0
- package/src/compiler/phases/2-analyze/visitors/BindDirective.js +280 -0
- package/src/compiler/phases/2-analyze/visitors/CallExpression.js +339 -0
- package/src/compiler/phases/2-analyze/visitors/ClassBody.js +156 -0
- package/src/compiler/phases/2-analyze/visitors/ClassDeclaration.js +25 -0
- package/src/compiler/phases/2-analyze/visitors/ClassDirective.js +13 -0
- package/src/compiler/phases/2-analyze/visitors/Component.js +26 -0
- package/src/compiler/phases/2-analyze/visitors/ConstTag.js +45 -0
- package/src/compiler/phases/2-analyze/visitors/DebugTag.js +15 -0
- package/src/compiler/phases/2-analyze/visitors/EachBlock.js +97 -0
- package/src/compiler/phases/2-analyze/visitors/ExportDefaultDeclaration.js +20 -0
- package/src/compiler/phases/2-analyze/visitors/ExportNamedDeclaration.js +70 -0
- package/src/compiler/phases/2-analyze/visitors/ExportSpecifier.js +30 -0
- package/src/compiler/phases/2-analyze/visitors/ExpressionStatement.js +38 -0
- package/src/compiler/phases/2-analyze/visitors/ExpressionTag.js +26 -0
- package/src/compiler/phases/2-analyze/visitors/Fragment.js +10 -0
- package/src/compiler/phases/2-analyze/visitors/FunctionDeclaration.js +16 -0
- package/src/compiler/phases/2-analyze/visitors/FunctionExpression.js +11 -0
- package/src/compiler/phases/2-analyze/visitors/HtmlTag.js +19 -0
- package/src/compiler/phases/2-analyze/visitors/Identifier.js +194 -0
- package/src/compiler/phases/2-analyze/visitors/IfBlock.js +46 -0
- package/src/compiler/phases/2-analyze/visitors/ImportDeclaration.js +31 -0
- package/src/compiler/phases/2-analyze/visitors/KeyBlock.js +21 -0
- package/src/compiler/phases/2-analyze/visitors/LabeledStatement.js +95 -0
- package/src/compiler/phases/2-analyze/visitors/LetDirective.js +24 -0
- package/src/compiler/phases/2-analyze/visitors/Literal.js +14 -0
- package/src/compiler/phases/2-analyze/visitors/MemberExpression.js +28 -0
- package/src/compiler/phases/2-analyze/visitors/NewExpression.js +17 -0
- package/src/compiler/phases/2-analyze/visitors/OnDirective.js +28 -0
- package/src/compiler/phases/2-analyze/visitors/PropertyDefinition.js +21 -0
- package/src/compiler/phases/2-analyze/visitors/RegularElement.js +240 -0
- package/src/compiler/phases/2-analyze/visitors/RenderTag.js +68 -0
- package/src/compiler/phases/2-analyze/visitors/SlotElement.js +42 -0
- package/src/compiler/phases/2-analyze/visitors/SnippetBlock.js +113 -0
- package/src/compiler/phases/2-analyze/visitors/SpreadAttribute.js +13 -0
- package/src/compiler/phases/2-analyze/visitors/SpreadElement.js +16 -0
- package/src/compiler/phases/2-analyze/visitors/StyleDirective.js +39 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteBody.js +22 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteBoundary.js +30 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteComponent.js +18 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteDocument.js +24 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteElement.js +78 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteFragment.js +27 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteHead.js +18 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteSelf.js +36 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteWindow.js +24 -0
- package/src/compiler/phases/2-analyze/visitors/TaggedTemplateExpression.js +16 -0
- package/src/compiler/phases/2-analyze/visitors/TemplateElement.js +12 -0
- package/src/compiler/phases/2-analyze/visitors/Text.js +52 -0
- package/src/compiler/phases/2-analyze/visitors/TitleElement.js +21 -0
- package/src/compiler/phases/2-analyze/visitors/TransitionDirective.js +19 -0
- package/src/compiler/phases/2-analyze/visitors/UpdateExpression.js +29 -0
- package/src/compiler/phases/2-analyze/visitors/UseDirective.js +18 -0
- package/src/compiler/phases/2-analyze/visitors/VariableDeclarator.js +160 -0
- package/src/compiler/phases/2-analyze/visitors/shared/a11y/constants.js +334 -0
- package/src/compiler/phases/2-analyze/visitors/shared/a11y/index.js +981 -0
- package/src/compiler/phases/2-analyze/visitors/shared/attribute.js +125 -0
- package/src/compiler/phases/2-analyze/visitors/shared/component.js +177 -0
- package/src/compiler/phases/2-analyze/visitors/shared/element.js +160 -0
- package/src/compiler/phases/2-analyze/visitors/shared/fragment.js +15 -0
- package/src/compiler/phases/2-analyze/visitors/shared/function.js +24 -0
- package/src/compiler/phases/2-analyze/visitors/shared/snippets.js +17 -0
- package/src/compiler/phases/2-analyze/visitors/shared/special-element.js +16 -0
- package/src/compiler/phases/2-analyze/visitors/shared/utils.js +301 -0
- package/src/compiler/phases/3-transform/client/transform-client.js +719 -0
- package/src/compiler/phases/3-transform/client/transform-template/fix-attribute-casing.js +18 -0
- package/src/compiler/phases/3-transform/client/transform-template/index.js +67 -0
- package/src/compiler/phases/3-transform/client/transform-template/template.js +164 -0
- package/src/compiler/phases/3-transform/client/utils.js +181 -0
- package/src/compiler/phases/3-transform/client/visitors/AnimateDirective.js +38 -0
- package/src/compiler/phases/3-transform/client/visitors/ArrowFunctionExpression.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/AssignmentExpression.js +247 -0
- package/src/compiler/phases/3-transform/client/visitors/AttachTag.js +26 -0
- package/src/compiler/phases/3-transform/client/visitors/Attribute.js +14 -0
- package/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js +124 -0
- package/src/compiler/phases/3-transform/client/visitors/AwaitExpression.js +25 -0
- package/src/compiler/phases/3-transform/client/visitors/BinaryExpression.js +34 -0
- package/src/compiler/phases/3-transform/client/visitors/BindDirective.js +290 -0
- package/src/compiler/phases/3-transform/client/visitors/BlockStatement.js +32 -0
- package/src/compiler/phases/3-transform/client/visitors/BreakStatement.js +20 -0
- package/src/compiler/phases/3-transform/client/visitors/CallExpression.js +136 -0
- package/src/compiler/phases/3-transform/client/visitors/ClassBody.js +111 -0
- package/src/compiler/phases/3-transform/client/visitors/Comment.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/Component.js +12 -0
- package/src/compiler/phases/3-transform/client/visitors/ConstTag.js +134 -0
- package/src/compiler/phases/3-transform/client/visitors/DebugTag.js +28 -0
- package/src/compiler/phases/3-transform/client/visitors/EachBlock.js +362 -0
- package/src/compiler/phases/3-transform/client/visitors/ExportNamedDeclaration.js +19 -0
- package/src/compiler/phases/3-transform/client/visitors/ExpressionStatement.js +20 -0
- package/src/compiler/phases/3-transform/client/visitors/ForOfStatement.js +25 -0
- package/src/compiler/phases/3-transform/client/visitors/Fragment.js +186 -0
- package/src/compiler/phases/3-transform/client/visitors/FunctionDeclaration.js +12 -0
- package/src/compiler/phases/3-transform/client/visitors/FunctionExpression.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/HtmlTag.js +53 -0
- package/src/compiler/phases/3-transform/client/visitors/Identifier.js +45 -0
- package/src/compiler/phases/3-transform/client/visitors/IfBlock.js +131 -0
- package/src/compiler/phases/3-transform/client/visitors/KeyBlock.js +45 -0
- package/src/compiler/phases/3-transform/client/visitors/LabeledStatement.js +64 -0
- package/src/compiler/phases/3-transform/client/visitors/LetDirective.js +55 -0
- package/src/compiler/phases/3-transform/client/visitors/MemberExpression.js +23 -0
- package/src/compiler/phases/3-transform/client/visitors/OnDirective.js +38 -0
- package/src/compiler/phases/3-transform/client/visitors/Program.js +153 -0
- package/src/compiler/phases/3-transform/client/visitors/RegularElement.js +725 -0
- package/src/compiler/phases/3-transform/client/visitors/RenderTag.js +95 -0
- package/src/compiler/phases/3-transform/client/visitors/SlotElement.js +94 -0
- package/src/compiler/phases/3-transform/client/visitors/SnippetBlock.js +94 -0
- package/src/compiler/phases/3-transform/client/visitors/SpreadAttribute.js +10 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteBody.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteBoundary.js +126 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteComponent.js +13 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteDocument.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteElement.js +161 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteFragment.js +17 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteHead.js +23 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteSelf.js +13 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteWindow.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/TitleElement.js +48 -0
- package/src/compiler/phases/3-transform/client/visitors/TransitionDirective.js +41 -0
- package/src/compiler/phases/3-transform/client/visitors/UpdateExpression.js +55 -0
- package/src/compiler/phases/3-transform/client/visitors/UseDirective.js +49 -0
- package/src/compiler/phases/3-transform/client/visitors/VariableDeclaration.js +422 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/component.js +536 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/declarations.js +53 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/element.js +263 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/events.js +180 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/fragment.js +185 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/function.js +17 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/special_element.js +22 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/utils.js +513 -0
- package/src/compiler/phases/3-transform/css/index.js +479 -0
- package/src/compiler/phases/3-transform/index.js +118 -0
- package/src/compiler/phases/3-transform/server/transform-server.js +428 -0
- package/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js +124 -0
- package/src/compiler/phases/3-transform/server/visitors/AwaitBlock.js +36 -0
- package/src/compiler/phases/3-transform/server/visitors/AwaitExpression.js +40 -0
- package/src/compiler/phases/3-transform/server/visitors/CallExpression.js +71 -0
- package/src/compiler/phases/3-transform/server/visitors/ClassBody.js +81 -0
- package/src/compiler/phases/3-transform/server/visitors/Component.js +13 -0
- package/src/compiler/phases/3-transform/server/visitors/ConstTag.js +49 -0
- package/src/compiler/phases/3-transform/server/visitors/DebugTag.js +24 -0
- package/src/compiler/phases/3-transform/server/visitors/EachBlock.js +76 -0
- package/src/compiler/phases/3-transform/server/visitors/ExpressionStatement.js +23 -0
- package/src/compiler/phases/3-transform/server/visitors/Fragment.js +53 -0
- package/src/compiler/phases/3-transform/server/visitors/HtmlTag.js +25 -0
- package/src/compiler/phases/3-transform/server/visitors/Identifier.js +24 -0
- package/src/compiler/phases/3-transform/server/visitors/IfBlock.js +48 -0
- package/src/compiler/phases/3-transform/server/visitors/KeyBlock.js +22 -0
- package/src/compiler/phases/3-transform/server/visitors/LabeledStatement.js +24 -0
- package/src/compiler/phases/3-transform/server/visitors/MemberExpression.js +19 -0
- package/src/compiler/phases/3-transform/server/visitors/Program.js +25 -0
- package/src/compiler/phases/3-transform/server/visitors/PropertyDefinition.js +37 -0
- package/src/compiler/phases/3-transform/server/visitors/RegularElement.js +216 -0
- package/src/compiler/phases/3-transform/server/visitors/RenderTag.js +45 -0
- package/src/compiler/phases/3-transform/server/visitors/SlotElement.js +68 -0
- package/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js +29 -0
- package/src/compiler/phases/3-transform/server/visitors/SpreadAttribute.js +10 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js +139 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteComponent.js +12 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteElement.js +89 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteFragment.js +11 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteHead.js +25 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteSelf.js +12 -0
- package/src/compiler/phases/3-transform/server/visitors/TitleElement.js +21 -0
- package/src/compiler/phases/3-transform/server/visitors/UpdateExpression.js +35 -0
- package/src/compiler/phases/3-transform/server/visitors/VariableDeclaration.js +247 -0
- package/src/compiler/phases/3-transform/server/visitors/shared/component.js +359 -0
- package/src/compiler/phases/3-transform/server/visitors/shared/element.js +557 -0
- package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +408 -0
- package/src/compiler/phases/3-transform/shared/assignments.js +92 -0
- package/src/compiler/phases/3-transform/shared/transform-async.js +114 -0
- package/src/compiler/phases/3-transform/utils.js +451 -0
- package/src/compiler/phases/bindings.js +227 -0
- package/src/compiler/phases/css.js +14 -0
- package/src/compiler/phases/nodes.js +258 -0
- package/src/compiler/phases/patterns.js +27 -0
- package/src/compiler/phases/scope.js +1432 -0
- package/src/compiler/preprocess/decode_sourcemap.js +96 -0
- package/src/compiler/preprocess/index.js +368 -0
- package/src/compiler/preprocess/replace_in_code.js +72 -0
- package/src/compiler/print/index.js +911 -0
- package/src/compiler/state.js +144 -0
- package/src/compiler/utils/assert.js +9 -0
- package/src/compiler/utils/ast.js +639 -0
- package/src/compiler/utils/builders.js +698 -0
- package/src/compiler/utils/compile_diagnostic.js +107 -0
- package/src/compiler/utils/extract_svelte_ignore.js +104 -0
- package/src/compiler/utils/mapped_code.js +454 -0
- package/src/compiler/utils/push_array.js +13 -0
- package/src/compiler/utils/sanitize_template_string.js +7 -0
- package/src/compiler/utils/slot.js +20 -0
- package/src/compiler/utils/string.js +9 -0
- package/src/compiler/validate-options.js +324 -0
- package/src/compiler/warnings.js +845 -0
- package/src/constants.js +66 -0
- package/src/easing/index.js +286 -0
- package/src/escaping.js +26 -0
- package/src/events/index.js +1 -0
- package/src/html-tree-validation.js +238 -0
- package/src/index-client.js +255 -0
- package/src/index-server.js +56 -0
- package/src/internal/client/constants.js +77 -0
- package/src/internal/client/context.js +258 -0
- package/src/internal/client/dev/assign.js +79 -0
- package/src/internal/client/dev/console-log.js +37 -0
- package/src/internal/client/dev/css.js +31 -0
- package/src/internal/client/dev/debug.js +500 -0
- package/src/internal/client/dev/elements.js +63 -0
- package/src/internal/client/dev/equality.js +101 -0
- package/src/internal/client/dev/hmr.js +89 -0
- package/src/internal/client/dev/inspect.js +72 -0
- package/src/internal/client/dev/legacy.js +25 -0
- package/src/internal/client/dev/ownership.js +81 -0
- package/src/internal/client/dev/tracing.js +162 -0
- package/src/internal/client/dev/validation.js +16 -0
- package/src/internal/client/dom/blocks/async.js +71 -0
- package/src/internal/client/dom/blocks/await.js +142 -0
- package/src/internal/client/dom/blocks/boundary.js +534 -0
- package/src/internal/client/dom/blocks/branches.js +227 -0
- package/src/internal/client/dom/blocks/css-props.js +28 -0
- package/src/internal/client/dom/blocks/each.js +723 -0
- package/src/internal/client/dom/blocks/html.js +128 -0
- package/src/internal/client/dom/blocks/if.js +82 -0
- package/src/internal/client/dom/blocks/key.js +40 -0
- package/src/internal/client/dom/blocks/slot.js +44 -0
- package/src/internal/client/dom/blocks/snippet.js +103 -0
- package/src/internal/client/dom/blocks/svelte-component.js +61 -0
- package/src/internal/client/dom/blocks/svelte-element.js +152 -0
- package/src/internal/client/dom/blocks/svelte-head.js +61 -0
- package/src/internal/client/dom/css.js +33 -0
- package/src/internal/client/dom/elements/actions.js +43 -0
- package/src/internal/client/dom/elements/attachments.js +33 -0
- package/src/internal/client/dom/elements/attributes.js +657 -0
- package/src/internal/client/dom/elements/bindings/document.js +17 -0
- package/src/internal/client/dom/elements/bindings/input.js +312 -0
- package/src/internal/client/dom/elements/bindings/media.js +233 -0
- package/src/internal/client/dom/elements/bindings/navigator.js +11 -0
- package/src/internal/client/dom/elements/bindings/props.js +22 -0
- package/src/internal/client/dom/elements/bindings/select.js +159 -0
- package/src/internal/client/dom/elements/bindings/shared.js +76 -0
- package/src/internal/client/dom/elements/bindings/size.js +107 -0
- package/src/internal/client/dom/elements/bindings/this.js +61 -0
- package/src/internal/client/dom/elements/bindings/universal.js +75 -0
- package/src/internal/client/dom/elements/bindings/window.js +66 -0
- package/src/internal/client/dom/elements/class.js +51 -0
- package/src/internal/client/dom/elements/custom-element.js +344 -0
- package/src/internal/client/dom/elements/customizable-select.js +99 -0
- package/src/internal/client/dom/elements/events.js +355 -0
- package/src/internal/client/dom/elements/misc.js +58 -0
- package/src/internal/client/dom/elements/style.js +57 -0
- package/src/internal/client/dom/elements/transitions.js +471 -0
- package/src/internal/client/dom/hydration.js +125 -0
- package/src/internal/client/dom/legacy/event-modifiers.js +127 -0
- package/src/internal/client/dom/legacy/lifecycle.js +82 -0
- package/src/internal/client/dom/legacy/misc.js +68 -0
- package/src/internal/client/dom/operations.js +293 -0
- package/src/internal/client/dom/reconciler.js +25 -0
- package/src/internal/client/dom/task.js +42 -0
- package/src/internal/client/dom/template.js +401 -0
- package/src/internal/client/error-handling.js +118 -0
- package/src/internal/client/errors.js +510 -0
- package/src/internal/client/hydratable.js +33 -0
- package/src/internal/client/index.js +183 -0
- package/src/internal/client/legacy.js +46 -0
- package/src/internal/client/loop.js +48 -0
- package/src/internal/client/proxy.js +432 -0
- package/src/internal/client/reactivity/async.js +306 -0
- package/src/internal/client/reactivity/batch.js +1057 -0
- package/src/internal/client/reactivity/deriveds.js +426 -0
- package/src/internal/client/reactivity/effects.js +718 -0
- package/src/internal/client/reactivity/equality.js +31 -0
- package/src/internal/client/reactivity/props.js +430 -0
- package/src/internal/client/reactivity/sources.js +370 -0
- package/src/internal/client/reactivity/status.js +25 -0
- package/src/internal/client/reactivity/store.js +203 -0
- package/src/internal/client/reactivity/utils.js +40 -0
- package/src/internal/client/render.js +335 -0
- package/src/internal/client/runtime.js +827 -0
- package/src/internal/client/timing.js +16 -0
- package/src/internal/client/validate.js +54 -0
- package/src/internal/client/warnings.js +271 -0
- package/src/internal/disclose-version.js +6 -0
- package/src/internal/flags/async.js +3 -0
- package/src/internal/flags/index.js +23 -0
- package/src/internal/flags/legacy.js +3 -0
- package/src/internal/flags/tracing.js +3 -0
- package/src/internal/index.js +5 -0
- package/src/internal/server/abort-signal.js +13 -0
- package/src/internal/server/blocks/html.js +11 -0
- package/src/internal/server/blocks/snippet.js +24 -0
- package/src/internal/server/context.js +132 -0
- package/src/internal/server/crypto.js +45 -0
- package/src/internal/server/dev.js +115 -0
- package/src/internal/server/errors.js +131 -0
- package/src/internal/server/hydratable.js +142 -0
- package/src/internal/server/hydration.js +6 -0
- package/src/internal/server/index.js +544 -0
- package/src/internal/server/render-context.js +86 -0
- package/src/internal/server/renderer.js +923 -0
- package/src/internal/server/warnings.js +29 -0
- package/src/internal/shared/attributes.js +225 -0
- package/src/internal/shared/clone.js +137 -0
- package/src/internal/shared/dev.js +65 -0
- package/src/internal/shared/errors.js +134 -0
- package/src/internal/shared/utils.js +144 -0
- package/src/internal/shared/validate.js +47 -0
- package/src/internal/shared/warnings.js +40 -0
- package/src/legacy/legacy-client.js +281 -0
- package/src/legacy/legacy-server.js +112 -0
- package/src/motion/index.js +32 -0
- package/src/motion/spring.js +369 -0
- package/src/motion/tweened.js +306 -0
- package/src/motion/utils.js +7 -0
- package/src/reactivity/create-subscriber.js +95 -0
- package/src/reactivity/date.js +118 -0
- package/src/reactivity/index-client.js +7 -0
- package/src/reactivity/index-server.js +23 -0
- package/src/reactivity/map.js +273 -0
- package/src/reactivity/media-query.js +55 -0
- package/src/reactivity/reactive-value.js +24 -0
- package/src/reactivity/set.js +213 -0
- package/src/reactivity/url-search-params.js +174 -0
- package/src/reactivity/url.js +205 -0
- package/src/reactivity/window/index.js +161 -0
- package/src/server/index.js +1 -0
- package/src/store/index-client.js +169 -0
- package/src/store/index-server.js +101 -0
- package/src/store/shared/index.js +209 -0
- package/src/store/utils.js +36 -0
- package/src/transition/index.js +300 -0
- package/src/utils.js +504 -0
- package/src/version.js +8 -0
- package/store.d.ts +1 -0
- package/svelte-html.d.ts +245 -0
- package/transition.d.ts +1 -0
- package/types/compiler/interfaces.d.ts +1 -0
- package/types/compiler/preprocess.d.ts +1 -0
- package/types/index.d.ts +3744 -0
- package/types/index.d.ts.map +280 -0
|
@@ -0,0 +1,1206 @@
|
|
|
1
|
+
/** @import * as Compiler from '#compiler' */
|
|
2
|
+
import { walk } from 'zimmerframe';
|
|
3
|
+
import {
|
|
4
|
+
get_parent_rules,
|
|
5
|
+
get_possible_values,
|
|
6
|
+
is_outer_global,
|
|
7
|
+
is_unscoped_pseudo_class
|
|
8
|
+
} from './utils.js';
|
|
9
|
+
import { regex_ends_with_whitespace, regex_starts_with_whitespace } from '../../patterns.js';
|
|
10
|
+
import { get_attribute_chunks, is_text_attribute } from '../../../utils/ast.js';
|
|
11
|
+
|
|
12
|
+
/** @typedef {typeof NODE_PROBABLY_EXISTS | typeof NODE_DEFINITELY_EXISTS} NodeExistsValue */
|
|
13
|
+
/** @typedef {typeof FORWARD | typeof BACKWARD} Direction */
|
|
14
|
+
|
|
15
|
+
const NODE_PROBABLY_EXISTS = 0;
|
|
16
|
+
const NODE_DEFINITELY_EXISTS = 1;
|
|
17
|
+
const FORWARD = 0;
|
|
18
|
+
const BACKWARD = 1;
|
|
19
|
+
|
|
20
|
+
const whitelist_attribute_selector = new Map([
|
|
21
|
+
['details', ['open']],
|
|
22
|
+
['dialog', ['open']]
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* HTML attributes whose enumerated values are case-insensitive per the HTML spec.
|
|
27
|
+
* CSS attribute selectors match these values case-insensitively in HTML documents.
|
|
28
|
+
* @see {@link https://html.spec.whatwg.org/multipage/semantics-other.html#case-sensitivity-of-selectors HTML spec}
|
|
29
|
+
*/
|
|
30
|
+
const case_insensitive_attributes = new Set([
|
|
31
|
+
'accept-charset',
|
|
32
|
+
'autocapitalize',
|
|
33
|
+
'autocomplete',
|
|
34
|
+
'behavior',
|
|
35
|
+
'charset',
|
|
36
|
+
'crossorigin',
|
|
37
|
+
'decoding',
|
|
38
|
+
'dir',
|
|
39
|
+
'direction',
|
|
40
|
+
'draggable',
|
|
41
|
+
'enctype',
|
|
42
|
+
'enterkeyhint',
|
|
43
|
+
'fetchpriority',
|
|
44
|
+
'formenctype',
|
|
45
|
+
'formmethod',
|
|
46
|
+
'formtarget',
|
|
47
|
+
'hidden',
|
|
48
|
+
'http-equiv',
|
|
49
|
+
'inputmode',
|
|
50
|
+
'kind',
|
|
51
|
+
'loading',
|
|
52
|
+
'method',
|
|
53
|
+
'preload',
|
|
54
|
+
'referrerpolicy',
|
|
55
|
+
'rel',
|
|
56
|
+
'rev',
|
|
57
|
+
'role',
|
|
58
|
+
'rules',
|
|
59
|
+
'scope',
|
|
60
|
+
'shape',
|
|
61
|
+
'spellcheck',
|
|
62
|
+
'target',
|
|
63
|
+
'translate',
|
|
64
|
+
'type',
|
|
65
|
+
'valign',
|
|
66
|
+
'wrap'
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
/** @type {Compiler.AST.CSS.Combinator} */
|
|
70
|
+
const descendant_combinator = {
|
|
71
|
+
type: 'Combinator',
|
|
72
|
+
name: ' ',
|
|
73
|
+
start: -1,
|
|
74
|
+
end: -1
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/** @type {Compiler.AST.CSS.RelativeSelector} */
|
|
78
|
+
const nesting_selector = {
|
|
79
|
+
type: 'RelativeSelector',
|
|
80
|
+
start: -1,
|
|
81
|
+
end: -1,
|
|
82
|
+
combinator: null,
|
|
83
|
+
selectors: [
|
|
84
|
+
{
|
|
85
|
+
type: 'NestingSelector',
|
|
86
|
+
name: '&',
|
|
87
|
+
start: -1,
|
|
88
|
+
end: -1
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
metadata: {
|
|
92
|
+
is_global: false,
|
|
93
|
+
is_global_like: false,
|
|
94
|
+
scoped: false
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/** @type {Compiler.AST.CSS.RelativeSelector} */
|
|
99
|
+
const any_selector = {
|
|
100
|
+
type: 'RelativeSelector',
|
|
101
|
+
start: -1,
|
|
102
|
+
end: -1,
|
|
103
|
+
combinator: null,
|
|
104
|
+
selectors: [
|
|
105
|
+
{
|
|
106
|
+
type: 'TypeSelector',
|
|
107
|
+
name: '*',
|
|
108
|
+
start: -1,
|
|
109
|
+
end: -1
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
metadata: {
|
|
113
|
+
is_global: false,
|
|
114
|
+
is_global_like: false,
|
|
115
|
+
scoped: false
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Snippets encountered already (avoids infinite loops)
|
|
121
|
+
* @type {Set<Compiler.AST.SnippetBlock>}
|
|
122
|
+
*/
|
|
123
|
+
const seen = new Set();
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
*
|
|
127
|
+
* @param {Compiler.AST.CSS.StyleSheet} stylesheet
|
|
128
|
+
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement} element
|
|
129
|
+
*/
|
|
130
|
+
export function prune(stylesheet, element) {
|
|
131
|
+
walk(/** @type {Compiler.AST.CSS.Node} */ (stylesheet), null, {
|
|
132
|
+
Rule(node, context) {
|
|
133
|
+
if (node.metadata.is_global_block) {
|
|
134
|
+
context.visit(node.prelude);
|
|
135
|
+
} else {
|
|
136
|
+
context.next();
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
ComplexSelector(node) {
|
|
140
|
+
const selectors = get_relative_selectors(node);
|
|
141
|
+
|
|
142
|
+
seen.clear();
|
|
143
|
+
|
|
144
|
+
if (
|
|
145
|
+
apply_selector(
|
|
146
|
+
selectors,
|
|
147
|
+
/** @type {Compiler.AST.CSS.Rule} */ (node.metadata.rule),
|
|
148
|
+
element,
|
|
149
|
+
BACKWARD
|
|
150
|
+
)
|
|
151
|
+
) {
|
|
152
|
+
node.metadata.used = true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// note: we don't call context.next() here, we only recurse into
|
|
156
|
+
// selectors that don't belong to rules (i.e. inside `:is(...)` etc)
|
|
157
|
+
// when we encounter them below
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Retrieves the relative selectors (minus the trailing globals) from a complex selector.
|
|
164
|
+
* Also searches them for any existing `&` selectors and adds one if none are found.
|
|
165
|
+
* This ensures we traverse up to the parent rule when the inner selectors match and we're
|
|
166
|
+
* trying to see if the parent rule also matches.
|
|
167
|
+
* @param {Compiler.AST.CSS.ComplexSelector} node
|
|
168
|
+
*/
|
|
169
|
+
function get_relative_selectors(node) {
|
|
170
|
+
const selectors = truncate(node);
|
|
171
|
+
|
|
172
|
+
if (node.metadata.rule?.metadata.parent_rule && selectors.length > 0) {
|
|
173
|
+
let has_explicit_nesting_selector = false;
|
|
174
|
+
|
|
175
|
+
// nesting could be inside pseudo classes like :is, :has or :where
|
|
176
|
+
for (let selector of selectors) {
|
|
177
|
+
walk(selector, null, {
|
|
178
|
+
// @ts-ignore
|
|
179
|
+
NestingSelector() {
|
|
180
|
+
has_explicit_nesting_selector = true;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// if we found one we can break from the others
|
|
185
|
+
if (has_explicit_nesting_selector) break;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (!has_explicit_nesting_selector) {
|
|
189
|
+
if (selectors[0].combinator === null) {
|
|
190
|
+
selectors[0] = {
|
|
191
|
+
...selectors[0],
|
|
192
|
+
combinator: descendant_combinator
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
selectors.unshift(nesting_selector);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return selectors;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Discard trailing `:global(...)` selectors, these are unused for scoping purposes
|
|
205
|
+
* @param {Compiler.AST.CSS.ComplexSelector} node
|
|
206
|
+
*/
|
|
207
|
+
function truncate(node) {
|
|
208
|
+
const i = node.children.findLastIndex(({ metadata, selectors }) => {
|
|
209
|
+
const first = selectors[0];
|
|
210
|
+
return (
|
|
211
|
+
// not after a :global selector
|
|
212
|
+
!metadata.is_global_like &&
|
|
213
|
+
!(first.type === 'PseudoClassSelector' && first.name === 'global' && first.args === null) &&
|
|
214
|
+
// not a :global(...) without a :has/is/where(...) modifier that is scoped
|
|
215
|
+
!metadata.is_global
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
return node.children.slice(0, i + 1).map((child) => {
|
|
220
|
+
// In case of `:root.y:has(...)`, `y` is unscoped, but everything in `:has(...)` should be scoped (if not global).
|
|
221
|
+
// To properly accomplish that, we gotta filter out all selector types except `:has`.
|
|
222
|
+
const root = child.selectors.find((s) => s.type === 'PseudoClassSelector' && s.name === 'root');
|
|
223
|
+
if (!root || child.metadata.is_global_like) return child;
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
...child,
|
|
227
|
+
selectors: child.selectors.filter((s) => s.type === 'PseudoClassSelector' && s.name === 'has')
|
|
228
|
+
};
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @param {Compiler.AST.CSS.RelativeSelector[]} relative_selectors
|
|
234
|
+
* @param {Compiler.AST.CSS.Rule} rule
|
|
235
|
+
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement} element
|
|
236
|
+
* @param {Direction} direction
|
|
237
|
+
* @returns {boolean}
|
|
238
|
+
*/
|
|
239
|
+
function apply_selector(relative_selectors, rule, element, direction) {
|
|
240
|
+
const rest_selectors = relative_selectors.slice();
|
|
241
|
+
const relative_selector = direction === FORWARD ? rest_selectors.shift() : rest_selectors.pop();
|
|
242
|
+
|
|
243
|
+
const matched =
|
|
244
|
+
!!relative_selector &&
|
|
245
|
+
relative_selector_might_apply_to_node(relative_selector, rule, element, direction) &&
|
|
246
|
+
apply_combinator(relative_selector, rest_selectors, rule, element, direction);
|
|
247
|
+
|
|
248
|
+
if (matched) {
|
|
249
|
+
if (!is_outer_global(relative_selector)) {
|
|
250
|
+
relative_selector.metadata.scoped = true;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
element.metadata.scoped = true;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return matched;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @param {Compiler.AST.CSS.RelativeSelector} relative_selector
|
|
261
|
+
* @param {Compiler.AST.CSS.RelativeSelector[]} rest_selectors
|
|
262
|
+
* @param {Compiler.AST.CSS.Rule} rule
|
|
263
|
+
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.RenderTag | Compiler.AST.Component | Compiler.AST.SvelteComponent | Compiler.AST.SvelteSelf} node
|
|
264
|
+
* @param {Direction} direction
|
|
265
|
+
* @returns {boolean}
|
|
266
|
+
*/
|
|
267
|
+
function apply_combinator(relative_selector, rest_selectors, rule, node, direction) {
|
|
268
|
+
const combinator =
|
|
269
|
+
direction == FORWARD ? rest_selectors[0]?.combinator : relative_selector.combinator;
|
|
270
|
+
if (!combinator) return true;
|
|
271
|
+
|
|
272
|
+
switch (combinator.name) {
|
|
273
|
+
case ' ':
|
|
274
|
+
case '>': {
|
|
275
|
+
const is_adjacent = combinator.name === '>';
|
|
276
|
+
const parents =
|
|
277
|
+
direction === FORWARD
|
|
278
|
+
? get_descendant_elements(node, is_adjacent)
|
|
279
|
+
: get_ancestor_elements(node, is_adjacent);
|
|
280
|
+
let parent_matched = false;
|
|
281
|
+
|
|
282
|
+
for (const parent of parents) {
|
|
283
|
+
if (apply_selector(rest_selectors, rule, parent, direction)) {
|
|
284
|
+
parent_matched = true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return (
|
|
289
|
+
parent_matched ||
|
|
290
|
+
(direction === BACKWARD &&
|
|
291
|
+
(!is_adjacent || parents.length === 0) &&
|
|
292
|
+
rest_selectors.every((selector) => is_global(selector, rule)))
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
case '+':
|
|
297
|
+
case '~': {
|
|
298
|
+
const siblings = get_possible_element_siblings(node, direction, combinator.name === '+');
|
|
299
|
+
|
|
300
|
+
let sibling_matched = false;
|
|
301
|
+
|
|
302
|
+
for (const possible_sibling of siblings.keys()) {
|
|
303
|
+
if (
|
|
304
|
+
possible_sibling.type === 'RenderTag' ||
|
|
305
|
+
possible_sibling.type === 'SlotElement' ||
|
|
306
|
+
possible_sibling.type === 'Component'
|
|
307
|
+
) {
|
|
308
|
+
// `{@render foo()}<p>foo</p>` with `:global(.x) + p` is a match
|
|
309
|
+
if (rest_selectors.length === 1 && rest_selectors[0].metadata.is_global) {
|
|
310
|
+
sibling_matched = true;
|
|
311
|
+
}
|
|
312
|
+
} else if (apply_selector(rest_selectors, rule, possible_sibling, direction)) {
|
|
313
|
+
sibling_matched = true;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return (
|
|
318
|
+
sibling_matched ||
|
|
319
|
+
(direction === BACKWARD &&
|
|
320
|
+
get_element_parent(node) === null &&
|
|
321
|
+
rest_selectors.every((selector) => is_global(selector, rule)))
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
default:
|
|
326
|
+
// TODO other combinators
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Returns `true` if the relative selector is global, meaning
|
|
333
|
+
* it's a `:global(...)` or unscopeable selector, or
|
|
334
|
+
* is an `:is(...)` or `:where(...)` selector that contains
|
|
335
|
+
* a global selector
|
|
336
|
+
* @param {Compiler.AST.CSS.RelativeSelector} selector
|
|
337
|
+
* @param {Compiler.AST.CSS.Rule} rule
|
|
338
|
+
* @returns {boolean}
|
|
339
|
+
*/
|
|
340
|
+
function is_global(selector, rule) {
|
|
341
|
+
if (selector.metadata.is_global || selector.metadata.is_global_like) {
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
let explicitly_global = false;
|
|
346
|
+
|
|
347
|
+
for (const s of selector.selectors) {
|
|
348
|
+
/** @type {Compiler.AST.CSS.SelectorList | null} */
|
|
349
|
+
let selector_list = null;
|
|
350
|
+
let can_be_global = false;
|
|
351
|
+
let owner = rule;
|
|
352
|
+
|
|
353
|
+
if (s.type === 'PseudoClassSelector') {
|
|
354
|
+
if ((s.name === 'is' || s.name === 'where') && s.args) {
|
|
355
|
+
selector_list = s.args;
|
|
356
|
+
} else {
|
|
357
|
+
can_be_global = is_unscoped_pseudo_class(s);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (s.type === 'NestingSelector') {
|
|
362
|
+
owner = /** @type {Compiler.AST.CSS.Rule} */ (rule.metadata.parent_rule);
|
|
363
|
+
selector_list = owner.prelude;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const has_global_selectors = !!selector_list?.children.some((complex_selector) => {
|
|
367
|
+
return complex_selector.children.every((relative_selector) =>
|
|
368
|
+
is_global(relative_selector, owner)
|
|
369
|
+
);
|
|
370
|
+
});
|
|
371
|
+
explicitly_global ||= has_global_selectors;
|
|
372
|
+
|
|
373
|
+
if (!has_global_selectors && !can_be_global) {
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return explicitly_global || selector.selectors.length === 0;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const regex_backslash_and_following_character = /\\(.)/g;
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Ensure that `element` satisfies each simple selector in `relative_selector`
|
|
385
|
+
*
|
|
386
|
+
* @param {Compiler.AST.CSS.RelativeSelector} relative_selector
|
|
387
|
+
* @param {Compiler.AST.CSS.Rule} rule
|
|
388
|
+
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement} element
|
|
389
|
+
* @param {Direction} direction
|
|
390
|
+
* @returns {boolean}
|
|
391
|
+
*/
|
|
392
|
+
function relative_selector_might_apply_to_node(relative_selector, rule, element, direction) {
|
|
393
|
+
// Sort :has(...) selectors in one bucket and everything else into another
|
|
394
|
+
const has_selectors = [];
|
|
395
|
+
const other_selectors = [];
|
|
396
|
+
|
|
397
|
+
for (const selector of relative_selector.selectors) {
|
|
398
|
+
if (selector.type === 'PseudoClassSelector' && selector.name === 'has' && selector.args) {
|
|
399
|
+
has_selectors.push(selector);
|
|
400
|
+
} else {
|
|
401
|
+
other_selectors.push(selector);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// If we're called recursively from a :has(...) selector, we're on the way of checking if the other selectors match.
|
|
406
|
+
// In that case ignore this check (because we just came from this) to avoid an infinite loop.
|
|
407
|
+
if (has_selectors.length > 0) {
|
|
408
|
+
// If this is a :has inside a global selector, we gotta include the element itself, too,
|
|
409
|
+
// because the global selector might be for an element that's outside the component,
|
|
410
|
+
// e.g. :root:has(.scoped), :global(.foo):has(.scoped), or :root { &:has(.scoped) {} }
|
|
411
|
+
const rules = get_parent_rules(rule);
|
|
412
|
+
const include_self =
|
|
413
|
+
rules.some((r) => r.prelude.children.some((c) => c.children.some((s) => is_global(s, r)))) ||
|
|
414
|
+
rules[rules.length - 1].prelude.children.some((c) =>
|
|
415
|
+
c.children.some((r) =>
|
|
416
|
+
r.selectors.some(
|
|
417
|
+
(s) =>
|
|
418
|
+
s.type === 'PseudoClassSelector' &&
|
|
419
|
+
(s.name === 'root' || (s.name === 'global' && s.args))
|
|
420
|
+
)
|
|
421
|
+
)
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
// :has(...) is special in that it means "look downwards in the CSS tree". Since our matching algorithm goes
|
|
425
|
+
// upwards and back-to-front, we need to first check the selectors inside :has(...), then check the rest of the
|
|
426
|
+
// selector in a way that is similar to ancestor matching. In a sense, we're treating `.x:has(.y)` as `.x .y`.
|
|
427
|
+
for (const has_selector of has_selectors) {
|
|
428
|
+
const complex_selectors = /** @type {Compiler.AST.CSS.SelectorList} */ (has_selector.args)
|
|
429
|
+
.children;
|
|
430
|
+
let matched = false;
|
|
431
|
+
|
|
432
|
+
for (const complex_selector of complex_selectors) {
|
|
433
|
+
const [first, ...rest] = truncate(complex_selector);
|
|
434
|
+
// if it was just a :global(...)
|
|
435
|
+
if (!first) {
|
|
436
|
+
complex_selector.metadata.used = true;
|
|
437
|
+
matched = true;
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if (include_self) {
|
|
442
|
+
const selector_including_self = [
|
|
443
|
+
first.combinator ? { ...first, combinator: null } : first,
|
|
444
|
+
...rest
|
|
445
|
+
];
|
|
446
|
+
if (apply_selector(selector_including_self, rule, element, FORWARD)) {
|
|
447
|
+
complex_selector.metadata.used = true;
|
|
448
|
+
matched = true;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const selector_excluding_self = [
|
|
453
|
+
any_selector,
|
|
454
|
+
first.combinator ? first : { ...first, combinator: descendant_combinator },
|
|
455
|
+
...rest
|
|
456
|
+
];
|
|
457
|
+
if (apply_selector(selector_excluding_self, rule, element, FORWARD)) {
|
|
458
|
+
complex_selector.metadata.used = true;
|
|
459
|
+
matched = true;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (!matched) {
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
for (const selector of other_selectors) {
|
|
470
|
+
if (selector.type === 'Percentage' || selector.type === 'Nth') continue;
|
|
471
|
+
|
|
472
|
+
const name = selector.name.replace(regex_backslash_and_following_character, '$1');
|
|
473
|
+
|
|
474
|
+
switch (selector.type) {
|
|
475
|
+
case 'PseudoClassSelector': {
|
|
476
|
+
if (name === 'host' || name === 'root') return false;
|
|
477
|
+
|
|
478
|
+
if (
|
|
479
|
+
name === 'global' &&
|
|
480
|
+
selector.args !== null &&
|
|
481
|
+
relative_selector.selectors.length === 1
|
|
482
|
+
) {
|
|
483
|
+
const args = selector.args;
|
|
484
|
+
const complex_selector = args.children[0];
|
|
485
|
+
return apply_selector(complex_selector.children, rule, element, BACKWARD);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// We came across a :global, everything beyond it is global and therefore a potential match
|
|
489
|
+
if (name === 'global' && selector.args === null) return true;
|
|
490
|
+
|
|
491
|
+
// :not(...) contents should stay unscoped. Scoping them would achieve the opposite of what we want,
|
|
492
|
+
// because they are then _more_ likely to bleed out of the component. The exception is complex selectors
|
|
493
|
+
// with descendants, in which case we scope them all.
|
|
494
|
+
if (name === 'not' && selector.args) {
|
|
495
|
+
for (const complex_selector of selector.args.children) {
|
|
496
|
+
walk(complex_selector, null, {
|
|
497
|
+
ComplexSelector(node, context) {
|
|
498
|
+
node.metadata.used = true;
|
|
499
|
+
context.next();
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
const relative = truncate(complex_selector);
|
|
503
|
+
|
|
504
|
+
if (complex_selector.children.length > 1) {
|
|
505
|
+
// foo:not(bar foo) means that bar is an ancestor of foo (side note: ending with foo is the only way the selector make sense).
|
|
506
|
+
// We can't fully check if that actually matches with our current algorithm, so we just assume it does.
|
|
507
|
+
// The result may not match a real element, so the only drawback is the missing prune.
|
|
508
|
+
for (const selector of relative) {
|
|
509
|
+
selector.metadata.scoped = true;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/** @type {Compiler.AST.RegularElement | Compiler.AST.SvelteElement | null} */
|
|
513
|
+
let el = element;
|
|
514
|
+
while (el) {
|
|
515
|
+
el.metadata.scoped = true;
|
|
516
|
+
el = get_element_parent(el);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
break;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if ((name === 'is' || name === 'where') && selector.args) {
|
|
525
|
+
let matched = false;
|
|
526
|
+
|
|
527
|
+
for (const complex_selector of selector.args.children) {
|
|
528
|
+
const relative = truncate(complex_selector);
|
|
529
|
+
const is_global = relative.length === 0;
|
|
530
|
+
|
|
531
|
+
if (is_global) {
|
|
532
|
+
complex_selector.metadata.used = true;
|
|
533
|
+
matched = true;
|
|
534
|
+
} else if (apply_selector(relative, rule, element, BACKWARD)) {
|
|
535
|
+
complex_selector.metadata.used = true;
|
|
536
|
+
matched = true;
|
|
537
|
+
} else if (complex_selector.children.length > 1 && (name == 'is' || name == 'where')) {
|
|
538
|
+
// foo :is(bar baz) can also mean that bar is an ancestor of foo, and baz a descendant.
|
|
539
|
+
// We can't fully check if that actually matches with our current algorithm, so we just assume it does.
|
|
540
|
+
// The result may not match a real element, so the only drawback is the missing prune.
|
|
541
|
+
complex_selector.metadata.used = true;
|
|
542
|
+
matched = true;
|
|
543
|
+
for (const selector of relative) {
|
|
544
|
+
selector.metadata.scoped = true;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
if (!matched) {
|
|
550
|
+
return false;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
case 'PseudoElementSelector': {
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
case 'AttributeSelector': {
|
|
562
|
+
const whitelisted = whitelist_attribute_selector.get(element.name.toLowerCase());
|
|
563
|
+
if (
|
|
564
|
+
!whitelisted?.includes(selector.name.toLowerCase()) &&
|
|
565
|
+
!attribute_matches(
|
|
566
|
+
element,
|
|
567
|
+
selector.name,
|
|
568
|
+
selector.value && unquote(selector.value),
|
|
569
|
+
selector.matcher,
|
|
570
|
+
(selector.flags?.includes('i') ?? false) ||
|
|
571
|
+
(!selector.flags?.includes('s') &&
|
|
572
|
+
case_insensitive_attributes.has(selector.name.toLowerCase()))
|
|
573
|
+
)
|
|
574
|
+
) {
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
break;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
case 'ClassSelector': {
|
|
581
|
+
if (!attribute_matches(element, 'class', name, '~=', false)) {
|
|
582
|
+
return false;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
break;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
case 'IdSelector': {
|
|
589
|
+
if (!attribute_matches(element, 'id', name, '=', false)) {
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
break;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
case 'TypeSelector': {
|
|
597
|
+
if (
|
|
598
|
+
element.name.toLowerCase() !== name.toLowerCase() &&
|
|
599
|
+
name !== '*' &&
|
|
600
|
+
element.type !== 'SvelteElement'
|
|
601
|
+
) {
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
case 'NestingSelector': {
|
|
609
|
+
let matched = false;
|
|
610
|
+
|
|
611
|
+
const parent = /** @type {Compiler.AST.CSS.Rule} */ (rule.metadata.parent_rule);
|
|
612
|
+
|
|
613
|
+
for (const complex_selector of parent.prelude.children) {
|
|
614
|
+
if (
|
|
615
|
+
apply_selector(get_relative_selectors(complex_selector), parent, element, direction) ||
|
|
616
|
+
complex_selector.children.every((s) => is_global(s, parent))
|
|
617
|
+
) {
|
|
618
|
+
complex_selector.metadata.used = true;
|
|
619
|
+
matched = true;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
if (!matched) {
|
|
624
|
+
return false;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
break;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// possible match
|
|
633
|
+
return true;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* @param {any} operator
|
|
638
|
+
* @param {any} expected_value
|
|
639
|
+
* @param {any} case_insensitive
|
|
640
|
+
* @param {any} value
|
|
641
|
+
*/
|
|
642
|
+
function test_attribute(operator, expected_value, case_insensitive, value) {
|
|
643
|
+
if (case_insensitive) {
|
|
644
|
+
expected_value = expected_value.toLowerCase();
|
|
645
|
+
value = value.toLowerCase();
|
|
646
|
+
}
|
|
647
|
+
switch (operator) {
|
|
648
|
+
case '=':
|
|
649
|
+
return value === expected_value;
|
|
650
|
+
case '~=':
|
|
651
|
+
return value.split(/\s/).includes(expected_value);
|
|
652
|
+
case '|=':
|
|
653
|
+
return `${value}-`.startsWith(`${expected_value}-`);
|
|
654
|
+
case '^=':
|
|
655
|
+
return value.startsWith(expected_value);
|
|
656
|
+
case '$=':
|
|
657
|
+
return value.endsWith(expected_value);
|
|
658
|
+
case '*=':
|
|
659
|
+
return value.includes(expected_value);
|
|
660
|
+
default:
|
|
661
|
+
throw new Error("this shouldn't happen");
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement} node
|
|
667
|
+
* @param {string} name
|
|
668
|
+
* @param {string | null} expected_value
|
|
669
|
+
* @param {string | null} operator
|
|
670
|
+
* @param {boolean} case_insensitive
|
|
671
|
+
*/
|
|
672
|
+
function attribute_matches(node, name, expected_value, operator, case_insensitive) {
|
|
673
|
+
for (const attribute of node.attributes) {
|
|
674
|
+
if (attribute.type === 'SpreadAttribute') return true;
|
|
675
|
+
if (attribute.type === 'BindDirective' && attribute.name === name) return true;
|
|
676
|
+
|
|
677
|
+
const name_lower = name.toLowerCase();
|
|
678
|
+
// match attributes against the corresponding directive but bail out on exact matching
|
|
679
|
+
if (attribute.type === 'StyleDirective' && name_lower === 'style') return true;
|
|
680
|
+
if (attribute.type === 'ClassDirective' && name_lower === 'class') {
|
|
681
|
+
if (operator === '~=') {
|
|
682
|
+
if (attribute.name === expected_value) return true;
|
|
683
|
+
} else {
|
|
684
|
+
return true;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
if (attribute.type !== 'Attribute') continue;
|
|
689
|
+
if (attribute.name.toLowerCase() !== name_lower) continue;
|
|
690
|
+
|
|
691
|
+
if (attribute.value === true) return operator === null;
|
|
692
|
+
if (expected_value === null) return true;
|
|
693
|
+
|
|
694
|
+
if (is_text_attribute(attribute)) {
|
|
695
|
+
const matches = test_attribute(
|
|
696
|
+
operator,
|
|
697
|
+
expected_value,
|
|
698
|
+
case_insensitive,
|
|
699
|
+
attribute.value[0].data
|
|
700
|
+
);
|
|
701
|
+
// continue if we still may match against a class/style directive
|
|
702
|
+
if (!matches && (name_lower === 'class' || name_lower === 'style')) continue;
|
|
703
|
+
return matches;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
const chunks = get_attribute_chunks(attribute.value);
|
|
707
|
+
const possible_values = new Set();
|
|
708
|
+
|
|
709
|
+
/** @type {string[]} */
|
|
710
|
+
let prev_values = [];
|
|
711
|
+
for (const chunk of chunks) {
|
|
712
|
+
const current_possible_values = get_possible_values(chunk, name_lower === 'class');
|
|
713
|
+
|
|
714
|
+
// impossible to find out all combinations
|
|
715
|
+
if (!current_possible_values) return true;
|
|
716
|
+
|
|
717
|
+
if (prev_values.length > 0) {
|
|
718
|
+
/** @type {string[]} */
|
|
719
|
+
const start_with_space = [];
|
|
720
|
+
|
|
721
|
+
/** @type {string[]} */
|
|
722
|
+
const remaining = [];
|
|
723
|
+
|
|
724
|
+
current_possible_values.forEach((current_possible_value) => {
|
|
725
|
+
if (regex_starts_with_whitespace.test(current_possible_value)) {
|
|
726
|
+
start_with_space.push(current_possible_value);
|
|
727
|
+
} else {
|
|
728
|
+
remaining.push(current_possible_value);
|
|
729
|
+
}
|
|
730
|
+
});
|
|
731
|
+
if (remaining.length > 0) {
|
|
732
|
+
if (start_with_space.length > 0) {
|
|
733
|
+
prev_values.forEach((prev_value) => possible_values.add(prev_value));
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/** @type {string[]} */
|
|
737
|
+
const combined = [];
|
|
738
|
+
|
|
739
|
+
prev_values.forEach((prev_value) => {
|
|
740
|
+
remaining.forEach((value) => {
|
|
741
|
+
combined.push(prev_value + value);
|
|
742
|
+
});
|
|
743
|
+
});
|
|
744
|
+
prev_values = combined;
|
|
745
|
+
start_with_space.forEach((value) => {
|
|
746
|
+
if (regex_ends_with_whitespace.test(value)) {
|
|
747
|
+
possible_values.add(value);
|
|
748
|
+
} else {
|
|
749
|
+
prev_values.push(value);
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
continue;
|
|
753
|
+
} else {
|
|
754
|
+
prev_values.forEach((prev_value) => possible_values.add(prev_value));
|
|
755
|
+
prev_values = [];
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
current_possible_values.forEach((current_possible_value) => {
|
|
759
|
+
if (regex_ends_with_whitespace.test(current_possible_value)) {
|
|
760
|
+
possible_values.add(current_possible_value);
|
|
761
|
+
} else {
|
|
762
|
+
prev_values.push(current_possible_value);
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
if (prev_values.length < current_possible_values.length) {
|
|
766
|
+
prev_values.push(' ');
|
|
767
|
+
}
|
|
768
|
+
if (prev_values.length > 20) {
|
|
769
|
+
// might grow exponentially, bail out
|
|
770
|
+
return true;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
prev_values.forEach((prev_value) => possible_values.add(prev_value));
|
|
774
|
+
|
|
775
|
+
for (const value of possible_values) {
|
|
776
|
+
if (test_attribute(operator, expected_value, case_insensitive, value)) return true;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
return false;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/** @param {string} str */
|
|
784
|
+
function unquote(str) {
|
|
785
|
+
if ((str[0] === str[str.length - 1] && str[0] === "'") || str[0] === '"') {
|
|
786
|
+
return str.slice(1, str.length - 1);
|
|
787
|
+
}
|
|
788
|
+
return str;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.RenderTag | Compiler.AST.Component | Compiler.AST.SvelteComponent | Compiler.AST.SvelteSelf} node
|
|
793
|
+
* @param {boolean} adjacent_only
|
|
794
|
+
* @param {Set<Compiler.AST.SnippetBlock>} seen
|
|
795
|
+
*/
|
|
796
|
+
function get_ancestor_elements(node, adjacent_only, seen = new Set()) {
|
|
797
|
+
/** @type {Array<Compiler.AST.RegularElement | Compiler.AST.SvelteElement>} */
|
|
798
|
+
const ancestors = [];
|
|
799
|
+
|
|
800
|
+
const path = node.metadata.path;
|
|
801
|
+
let i = path.length;
|
|
802
|
+
|
|
803
|
+
while (i--) {
|
|
804
|
+
const parent = path[i];
|
|
805
|
+
|
|
806
|
+
if (parent.type === 'SnippetBlock') {
|
|
807
|
+
if (!seen.has(parent)) {
|
|
808
|
+
seen.add(parent);
|
|
809
|
+
|
|
810
|
+
for (const site of parent.metadata.sites) {
|
|
811
|
+
ancestors.push(...get_ancestor_elements(site, adjacent_only, seen));
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
break;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
if (parent.type === 'RegularElement' || parent.type === 'SvelteElement') {
|
|
819
|
+
// Special handling for <option> inside <select>: elements inside <option> should
|
|
820
|
+
// also be considered descendants of <selectedcontent>, which clones the selected option's content
|
|
821
|
+
if (parent.type === 'RegularElement' && parent.name === 'option') {
|
|
822
|
+
const is_direct_child = ancestors.length === 0;
|
|
823
|
+
|
|
824
|
+
const select_element = path.findLast(
|
|
825
|
+
(element, j) => element.type === 'RegularElement' && element.name === 'select' && j < i
|
|
826
|
+
);
|
|
827
|
+
|
|
828
|
+
if (select_element && (!adjacent_only || is_direct_child)) {
|
|
829
|
+
/** @type {Compiler.AST.RegularElement | null} */
|
|
830
|
+
let selectedcontent_element = null;
|
|
831
|
+
walk(select_element, null, {
|
|
832
|
+
RegularElement(child, context) {
|
|
833
|
+
if (child.name === 'selectedcontent') {
|
|
834
|
+
selectedcontent_element = child;
|
|
835
|
+
context.stop();
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
context.next();
|
|
839
|
+
}
|
|
840
|
+
});
|
|
841
|
+
|
|
842
|
+
if (adjacent_only && is_direct_child && selectedcontent_element) {
|
|
843
|
+
return [selectedcontent_element, parent];
|
|
844
|
+
} else if (selectedcontent_element) {
|
|
845
|
+
ancestors.push(selectedcontent_element);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
ancestors.push(parent);
|
|
851
|
+
|
|
852
|
+
if (adjacent_only) {
|
|
853
|
+
break;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
return ancestors;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/**
|
|
862
|
+
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.RenderTag | Compiler.AST.Component | Compiler.AST.SvelteComponent | Compiler.AST.SvelteSelf} node
|
|
863
|
+
* @param {boolean} adjacent_only
|
|
864
|
+
* @param {Set<Compiler.AST.SnippetBlock>} seen
|
|
865
|
+
*/
|
|
866
|
+
function get_descendant_elements(node, adjacent_only, seen = new Set()) {
|
|
867
|
+
/** @type {Array<Compiler.AST.RegularElement | Compiler.AST.SvelteElement>} */
|
|
868
|
+
const descendants = [];
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* @param {Compiler.AST.SvelteNode} node
|
|
872
|
+
*/
|
|
873
|
+
function walk_children(node) {
|
|
874
|
+
walk(node, null, {
|
|
875
|
+
_(node, context) {
|
|
876
|
+
if (node.type === 'RegularElement' || node.type === 'SvelteElement') {
|
|
877
|
+
descendants.push(node);
|
|
878
|
+
|
|
879
|
+
if (!adjacent_only) {
|
|
880
|
+
context.next();
|
|
881
|
+
}
|
|
882
|
+
} else if (node.type === 'RenderTag') {
|
|
883
|
+
for (const snippet of node.metadata.snippets) {
|
|
884
|
+
if (seen.has(snippet)) continue;
|
|
885
|
+
|
|
886
|
+
seen.add(snippet);
|
|
887
|
+
walk_children(snippet.body);
|
|
888
|
+
}
|
|
889
|
+
} else {
|
|
890
|
+
context.next();
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
walk_children(node.type === 'RenderTag' ? node : node.fragment);
|
|
897
|
+
|
|
898
|
+
// Special handling for <selectedcontent>: it clones the content of the selected <option>,
|
|
899
|
+
// so descendants of <option> elements in the same <select> should also be considered descendants
|
|
900
|
+
if (node.type === 'RegularElement' && node.name === 'selectedcontent') {
|
|
901
|
+
const path = node.metadata.path;
|
|
902
|
+
const select_element = path.findLast(
|
|
903
|
+
(/** @type {Compiler.AST.SvelteNode} */ element) =>
|
|
904
|
+
element.type === 'RegularElement' && element.name === 'select'
|
|
905
|
+
);
|
|
906
|
+
|
|
907
|
+
if (select_element) {
|
|
908
|
+
walk(
|
|
909
|
+
select_element,
|
|
910
|
+
{ inside_option: false },
|
|
911
|
+
{
|
|
912
|
+
_(child, context) {
|
|
913
|
+
if (child.type === 'RegularElement' && child.name === 'option') {
|
|
914
|
+
context.next({ inside_option: true });
|
|
915
|
+
} else if (context.state.inside_option) {
|
|
916
|
+
walk_children(child);
|
|
917
|
+
} else {
|
|
918
|
+
context.next();
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
return descendants;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/**
|
|
930
|
+
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.RenderTag | Compiler.AST.Component | Compiler.AST.SvelteComponent | Compiler.AST.SvelteSelf} node
|
|
931
|
+
* @returns {Compiler.AST.RegularElement | Compiler.AST.SvelteElement | null}
|
|
932
|
+
*/
|
|
933
|
+
function get_element_parent(node) {
|
|
934
|
+
let path = node.metadata.path;
|
|
935
|
+
let i = path.length;
|
|
936
|
+
|
|
937
|
+
while (i--) {
|
|
938
|
+
const parent = path[i];
|
|
939
|
+
|
|
940
|
+
if (parent.type === 'RegularElement' || parent.type === 'SvelteElement') {
|
|
941
|
+
return parent;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
return null;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/**
|
|
949
|
+
* @param {Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.RenderTag | Compiler.AST.Component | Compiler.AST.SvelteComponent | Compiler.AST.SvelteSelf} node
|
|
950
|
+
* @param {Direction} direction
|
|
951
|
+
* @param {boolean} adjacent_only
|
|
952
|
+
* @param {Set<Compiler.AST.SnippetBlock>} seen
|
|
953
|
+
* @returns {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.SlotElement | Compiler.AST.RenderTag | Compiler.AST.Component, NodeExistsValue>}
|
|
954
|
+
*/
|
|
955
|
+
function get_possible_element_siblings(node, direction, adjacent_only, seen = new Set()) {
|
|
956
|
+
/** @type {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement | Compiler.AST.SlotElement | Compiler.AST.RenderTag | Compiler.AST.Component, NodeExistsValue>} */
|
|
957
|
+
const result = new Map();
|
|
958
|
+
const path = node.metadata.path;
|
|
959
|
+
|
|
960
|
+
/** @type {Compiler.AST.SvelteNode} */
|
|
961
|
+
let current = node;
|
|
962
|
+
|
|
963
|
+
let i = path.length;
|
|
964
|
+
|
|
965
|
+
while (i--) {
|
|
966
|
+
const fragment = /** @type {Compiler.AST.Fragment} */ (path[i--]);
|
|
967
|
+
let j = fragment.nodes.indexOf(current) + (direction === FORWARD ? 1 : -1);
|
|
968
|
+
|
|
969
|
+
while (j >= 0 && j < fragment.nodes.length) {
|
|
970
|
+
const node = fragment.nodes[j];
|
|
971
|
+
|
|
972
|
+
if (node.type === 'RegularElement') {
|
|
973
|
+
const has_slot_attribute = node.attributes.some(
|
|
974
|
+
(attr) => attr.type === 'Attribute' && attr.name.toLowerCase() === 'slot'
|
|
975
|
+
);
|
|
976
|
+
|
|
977
|
+
if (!has_slot_attribute) {
|
|
978
|
+
result.set(node, NODE_DEFINITELY_EXISTS);
|
|
979
|
+
|
|
980
|
+
if (adjacent_only) {
|
|
981
|
+
return result;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
// Special case: slots, render tags and svelte:element tags could resolve to no siblings,
|
|
985
|
+
// so we want to continue until we find a definite sibling even with the adjacent-only combinator
|
|
986
|
+
} else if (is_block(node) || node.type === 'Component') {
|
|
987
|
+
if (node.type === 'SlotElement' || node.type === 'Component') {
|
|
988
|
+
result.set(node, NODE_PROBABLY_EXISTS);
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
const possible_last_child = get_possible_nested_siblings(node, direction, adjacent_only);
|
|
992
|
+
add_to_map(possible_last_child, result);
|
|
993
|
+
if (
|
|
994
|
+
adjacent_only &&
|
|
995
|
+
node.type !== 'Component' &&
|
|
996
|
+
has_definite_elements(possible_last_child)
|
|
997
|
+
) {
|
|
998
|
+
return result;
|
|
999
|
+
}
|
|
1000
|
+
} else if (node.type === 'SvelteElement') {
|
|
1001
|
+
result.set(node, NODE_PROBABLY_EXISTS);
|
|
1002
|
+
} else if (node.type === 'RenderTag') {
|
|
1003
|
+
result.set(node, NODE_PROBABLY_EXISTS);
|
|
1004
|
+
for (const snippet of node.metadata.snippets) {
|
|
1005
|
+
add_to_map(get_possible_nested_siblings(snippet, direction, adjacent_only), result);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
j = direction === FORWARD ? j + 1 : j - 1;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
current = path[i];
|
|
1013
|
+
|
|
1014
|
+
if (!current) break;
|
|
1015
|
+
|
|
1016
|
+
if (
|
|
1017
|
+
current.type === 'Component' ||
|
|
1018
|
+
current.type === 'SvelteComponent' ||
|
|
1019
|
+
current.type === 'SvelteSelf'
|
|
1020
|
+
) {
|
|
1021
|
+
continue;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
if (current.type === 'SnippetBlock') {
|
|
1025
|
+
if (seen.has(current)) break;
|
|
1026
|
+
seen.add(current);
|
|
1027
|
+
|
|
1028
|
+
for (const site of current.metadata.sites) {
|
|
1029
|
+
const siblings = get_possible_element_siblings(site, direction, adjacent_only, seen);
|
|
1030
|
+
add_to_map(siblings, result);
|
|
1031
|
+
|
|
1032
|
+
if (adjacent_only && current.metadata.sites.size === 1 && has_definite_elements(siblings)) {
|
|
1033
|
+
return result;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
if (!is_block(current)) break;
|
|
1039
|
+
|
|
1040
|
+
if (current.type === 'EachBlock' && fragment === current.body) {
|
|
1041
|
+
// `{#each ...}<a /><b />{/each}` — `<b>` can be previous sibling of `<a />`
|
|
1042
|
+
add_to_map(get_possible_nested_siblings(current, direction, adjacent_only), result);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
return result;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
/**
|
|
1050
|
+
* @param {Compiler.AST.EachBlock | Compiler.AST.IfBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock | Compiler.AST.SlotElement | Compiler.AST.SnippetBlock | Compiler.AST.Component} node
|
|
1051
|
+
* @param {Direction} direction
|
|
1052
|
+
* @param {boolean} adjacent_only
|
|
1053
|
+
* @param {Set<Compiler.AST.SnippetBlock>} seen
|
|
1054
|
+
* @returns {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement, NodeExistsValue>}
|
|
1055
|
+
*/
|
|
1056
|
+
function get_possible_nested_siblings(node, direction, adjacent_only, seen = new Set()) {
|
|
1057
|
+
/** @type {Array<Compiler.AST.Fragment | undefined | null>} */
|
|
1058
|
+
let fragments = [];
|
|
1059
|
+
|
|
1060
|
+
switch (node.type) {
|
|
1061
|
+
case 'EachBlock':
|
|
1062
|
+
fragments.push(node.body, node.fallback);
|
|
1063
|
+
break;
|
|
1064
|
+
|
|
1065
|
+
case 'IfBlock':
|
|
1066
|
+
fragments.push(node.consequent, node.alternate);
|
|
1067
|
+
break;
|
|
1068
|
+
|
|
1069
|
+
case 'AwaitBlock':
|
|
1070
|
+
fragments.push(node.pending, node.then, node.catch);
|
|
1071
|
+
break;
|
|
1072
|
+
|
|
1073
|
+
case 'KeyBlock':
|
|
1074
|
+
case 'SlotElement':
|
|
1075
|
+
fragments.push(node.fragment);
|
|
1076
|
+
break;
|
|
1077
|
+
|
|
1078
|
+
case 'SnippetBlock':
|
|
1079
|
+
if (seen.has(node)) {
|
|
1080
|
+
return new Map();
|
|
1081
|
+
}
|
|
1082
|
+
seen.add(node);
|
|
1083
|
+
fragments.push(node.body);
|
|
1084
|
+
break;
|
|
1085
|
+
|
|
1086
|
+
case 'Component':
|
|
1087
|
+
fragments.push(node.fragment, ...[...node.metadata.snippets].map((s) => s.body));
|
|
1088
|
+
break;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/** @type {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement, NodeExistsValue>} NodeMap */
|
|
1092
|
+
const result = new Map();
|
|
1093
|
+
|
|
1094
|
+
let exhaustive = node.type !== 'SlotElement' && node.type !== 'SnippetBlock';
|
|
1095
|
+
|
|
1096
|
+
for (const fragment of fragments) {
|
|
1097
|
+
if (fragment == null) {
|
|
1098
|
+
exhaustive = false;
|
|
1099
|
+
continue;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
const map = loop_child(fragment.nodes, direction, adjacent_only, seen);
|
|
1103
|
+
exhaustive &&= has_definite_elements(map);
|
|
1104
|
+
|
|
1105
|
+
add_to_map(map, result);
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
if (!exhaustive) {
|
|
1109
|
+
for (const key of result.keys()) {
|
|
1110
|
+
result.set(key, NODE_PROBABLY_EXISTS);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
return result;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
/**
|
|
1118
|
+
* @param {Map<unknown, NodeExistsValue>} result
|
|
1119
|
+
* @returns {boolean}
|
|
1120
|
+
*/
|
|
1121
|
+
function has_definite_elements(result) {
|
|
1122
|
+
if (result.size === 0) return false;
|
|
1123
|
+
for (const exist of result.values()) {
|
|
1124
|
+
if (exist === NODE_DEFINITELY_EXISTS) {
|
|
1125
|
+
return true;
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
return false;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
/**
|
|
1132
|
+
* @template T2
|
|
1133
|
+
* @template {T2} T1
|
|
1134
|
+
* @param {Map<T1, NodeExistsValue>} from
|
|
1135
|
+
* @param {Map<T2, NodeExistsValue>} to
|
|
1136
|
+
* @returns {void}
|
|
1137
|
+
*/
|
|
1138
|
+
function add_to_map(from, to) {
|
|
1139
|
+
from.forEach((exist, element) => {
|
|
1140
|
+
to.set(element, higher_existence(exist, to.get(element)));
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
/**
|
|
1145
|
+
* @param {NodeExistsValue} exist1
|
|
1146
|
+
* @param {NodeExistsValue | undefined} exist2
|
|
1147
|
+
* @returns {NodeExistsValue}
|
|
1148
|
+
*/
|
|
1149
|
+
function higher_existence(exist1, exist2) {
|
|
1150
|
+
if (exist2 === undefined) return exist1;
|
|
1151
|
+
return exist1 > exist2 ? exist1 : exist2;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
/**
|
|
1155
|
+
* @param {Compiler.AST.SvelteNode[]} children
|
|
1156
|
+
* @param {Direction} direction
|
|
1157
|
+
* @param {boolean} adjacent_only
|
|
1158
|
+
* @param {Set<Compiler.AST.SnippetBlock>} seen
|
|
1159
|
+
*/
|
|
1160
|
+
function loop_child(children, direction, adjacent_only, seen) {
|
|
1161
|
+
/** @type {Map<Compiler.AST.RegularElement | Compiler.AST.SvelteElement, NodeExistsValue>} */
|
|
1162
|
+
const result = new Map();
|
|
1163
|
+
|
|
1164
|
+
let i = direction === FORWARD ? 0 : children.length - 1;
|
|
1165
|
+
|
|
1166
|
+
while (i >= 0 && i < children.length) {
|
|
1167
|
+
const child = children[i];
|
|
1168
|
+
|
|
1169
|
+
if (child.type === 'RegularElement') {
|
|
1170
|
+
result.set(child, NODE_DEFINITELY_EXISTS);
|
|
1171
|
+
if (adjacent_only) {
|
|
1172
|
+
break;
|
|
1173
|
+
}
|
|
1174
|
+
} else if (child.type === 'SvelteElement') {
|
|
1175
|
+
result.set(child, NODE_PROBABLY_EXISTS);
|
|
1176
|
+
} else if (child.type === 'RenderTag') {
|
|
1177
|
+
for (const snippet of child.metadata.snippets) {
|
|
1178
|
+
add_to_map(get_possible_nested_siblings(snippet, direction, adjacent_only, seen), result);
|
|
1179
|
+
}
|
|
1180
|
+
} else if (is_block(child)) {
|
|
1181
|
+
const child_result = get_possible_nested_siblings(child, direction, adjacent_only, seen);
|
|
1182
|
+
add_to_map(child_result, result);
|
|
1183
|
+
if (adjacent_only && has_definite_elements(child_result)) {
|
|
1184
|
+
break;
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
i = direction === FORWARD ? i + 1 : i - 1;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
return result;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
/**
|
|
1195
|
+
* @param {Compiler.AST.SvelteNode} node
|
|
1196
|
+
* @returns {node is Compiler.AST.IfBlock | Compiler.AST.EachBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock | Compiler.AST.SlotElement}
|
|
1197
|
+
*/
|
|
1198
|
+
function is_block(node) {
|
|
1199
|
+
return (
|
|
1200
|
+
node.type === 'IfBlock' ||
|
|
1201
|
+
node.type === 'EachBlock' ||
|
|
1202
|
+
node.type === 'AwaitBlock' ||
|
|
1203
|
+
node.type === 'KeyBlock' ||
|
|
1204
|
+
node.type === 'SlotElement'
|
|
1205
|
+
);
|
|
1206
|
+
}
|