svelte 5.2.7 → 5.2.8
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/compiler/index.js +1 -1
- package/package.json +1 -1
- package/src/ambient.d.ts +3 -11
- package/src/compiler/phases/2-analyze/css/css-prune.js +115 -121
- package/src/compiler/phases/2-analyze/index.js +10 -10
- package/src/compiler/phases/2-analyze/visitors/ExpressionTag.js +3 -1
- package/src/compiler/phases/2-analyze/visitors/RegularElement.js +1 -3
- package/src/compiler/phases/2-analyze/visitors/RenderTag.js +1 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteElement.js +2 -2
- package/src/compiler/phases/2-analyze/visitors/Text.js +3 -1
- package/src/compiler/phases/2-analyze/visitors/shared/a11y.js +10 -9
- package/src/compiler/types/template.d.ts +2 -0
- package/src/internal/client/dom/elements/attributes.js +2 -25
- package/src/internal/client/dom/operations.js +11 -2
- package/src/legacy/legacy-client.js +5 -0
- package/src/version.js +1 -1
- package/types/index.d.ts +10 -11
- package/types/index.d.ts.map +2 -1
package/package.json
CHANGED
package/src/ambient.d.ts
CHANGED
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
declare module '*.svelte' {
|
|
2
2
|
// use prettier-ignore for a while because of https://github.com/sveltejs/language-tools/commit/026111228b5814a9109cc4d779d37fb02955fb8b
|
|
3
3
|
// prettier-ignore
|
|
4
|
-
import { SvelteComponent
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// prettier-ignore
|
|
8
|
-
interface ComponentType {
|
|
9
|
-
(
|
|
10
|
-
...args: Parameters<Component<Record<string, any>>>
|
|
11
|
-
): ReturnType<Component<Record<string, any>, Record<string, any>>>
|
|
12
|
-
new (o: ComponentConstructorOptions): SvelteComponent
|
|
13
|
-
}
|
|
14
|
-
const Comp: ComponentType;
|
|
4
|
+
import { SvelteComponent } from 'svelte'
|
|
5
|
+
import { LegacyComponentType } from 'svelte/legacy';
|
|
6
|
+
const Comp: LegacyComponentType;
|
|
15
7
|
type Comp = SvelteComponent;
|
|
16
8
|
export default Comp;
|
|
17
9
|
}
|
|
@@ -260,12 +260,15 @@ function apply_combinator(combinator, relative_selector, parent_selectors, rule,
|
|
|
260
260
|
switch (name) {
|
|
261
261
|
case ' ':
|
|
262
262
|
case '>': {
|
|
263
|
-
let parent = /** @type {Compiler.TemplateNode | null} */ (element.parent);
|
|
264
|
-
|
|
265
263
|
let parent_matched = false;
|
|
266
264
|
let crossed_component_boundary = false;
|
|
267
265
|
|
|
268
|
-
|
|
266
|
+
const path = element.metadata.path;
|
|
267
|
+
let i = path.length;
|
|
268
|
+
|
|
269
|
+
while (i--) {
|
|
270
|
+
const parent = path[i];
|
|
271
|
+
|
|
269
272
|
if (parent.type === 'Component' || parent.type === 'SvelteComponent') {
|
|
270
273
|
crossed_component_boundary = true;
|
|
271
274
|
}
|
|
@@ -289,8 +292,6 @@ function apply_combinator(combinator, relative_selector, parent_selectors, rule,
|
|
|
289
292
|
|
|
290
293
|
if (name === '>') return parent_matched;
|
|
291
294
|
}
|
|
292
|
-
|
|
293
|
-
parent = /** @type {Compiler.TemplateNode | null} */ (parent.parent);
|
|
294
295
|
}
|
|
295
296
|
|
|
296
297
|
return parent_matched || parent_selectors.every((selector) => is_global(selector, rule));
|
|
@@ -679,51 +680,50 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element,
|
|
|
679
680
|
* @param {boolean} include_self
|
|
680
681
|
*/
|
|
681
682
|
function get_following_sibling_elements(element, include_self) {
|
|
682
|
-
|
|
683
|
-
let
|
|
683
|
+
const path = element.metadata.path;
|
|
684
|
+
let i = path.length;
|
|
685
|
+
|
|
686
|
+
/** @type {Compiler.SvelteNode} */
|
|
687
|
+
let start = element;
|
|
688
|
+
let nodes = /** @type {Compiler.SvelteNode[]} */ (
|
|
689
|
+
/** @type {Compiler.AST.Fragment} */ (path[0]).nodes
|
|
690
|
+
);
|
|
691
|
+
|
|
692
|
+
// find the set of nodes to walk...
|
|
693
|
+
while (i--) {
|
|
694
|
+
const node = path[i];
|
|
684
695
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
696
|
+
if (node.type === 'RegularElement' || node.type === 'SvelteElement') {
|
|
697
|
+
nodes = node.fragment.nodes;
|
|
698
|
+
break;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
if (node.type !== 'Fragment') {
|
|
702
|
+
start = node;
|
|
689
703
|
}
|
|
690
704
|
}
|
|
691
705
|
|
|
692
706
|
/** @type {Array<Compiler.AST.RegularElement | Compiler.AST.SvelteElement>} */
|
|
693
|
-
const
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
},
|
|
705
|
-
SvelteElement(node) {
|
|
706
|
-
sibling_elements.push(node);
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
);
|
|
710
|
-
} else {
|
|
711
|
-
/** @type {any} */
|
|
712
|
-
let child = element;
|
|
713
|
-
while (child !== el && child !== parent) {
|
|
714
|
-
child = child.parent;
|
|
715
|
-
}
|
|
716
|
-
if (child === el) {
|
|
717
|
-
found_parent = true;
|
|
707
|
+
const siblings = [];
|
|
708
|
+
|
|
709
|
+
// ...then walk them, starting from the node after the one
|
|
710
|
+
// containing the element in question
|
|
711
|
+
for (const node of nodes.slice(nodes.indexOf(start) + 1)) {
|
|
712
|
+
walk(node, null, {
|
|
713
|
+
RegularElement(node) {
|
|
714
|
+
siblings.push(node);
|
|
715
|
+
},
|
|
716
|
+
SvelteElement(node) {
|
|
717
|
+
siblings.push(node);
|
|
718
718
|
}
|
|
719
|
-
}
|
|
719
|
+
});
|
|
720
720
|
}
|
|
721
721
|
|
|
722
722
|
if (include_self) {
|
|
723
|
-
|
|
723
|
+
siblings.push(element);
|
|
724
724
|
}
|
|
725
725
|
|
|
726
|
-
return
|
|
726
|
+
return siblings;
|
|
727
727
|
}
|
|
728
728
|
|
|
729
729
|
/**
|
|
@@ -867,15 +867,18 @@ function unquote(str) {
|
|
|
867
867
|
* @returns {Compiler.AST.RegularElement | Compiler.AST.SvelteElement | null}
|
|
868
868
|
*/
|
|
869
869
|
function get_element_parent(node) {
|
|
870
|
-
|
|
871
|
-
let
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
parent.type
|
|
877
|
-
|
|
878
|
-
|
|
870
|
+
let path = node.metadata.path;
|
|
871
|
+
let i = path.length;
|
|
872
|
+
|
|
873
|
+
while (i--) {
|
|
874
|
+
const parent = path[i];
|
|
875
|
+
|
|
876
|
+
if (parent.type === 'RegularElement' || parent.type === 'SvelteElement') {
|
|
877
|
+
return parent;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
return null;
|
|
879
882
|
}
|
|
880
883
|
|
|
881
884
|
/**
|
|
@@ -920,7 +923,7 @@ function find_previous_sibling(node) {
|
|
|
920
923
|
while (current_node?.type === 'SlotElement') {
|
|
921
924
|
const slot_children = current_node.fragment.nodes;
|
|
922
925
|
if (slot_children.length > 0) {
|
|
923
|
-
current_node = slot_children.
|
|
926
|
+
current_node = slot_children[slot_children.length - 1];
|
|
924
927
|
} else {
|
|
925
928
|
break;
|
|
926
929
|
}
|
|
@@ -952,7 +955,7 @@ function get_possible_element_siblings(node, adjacent_only) {
|
|
|
952
955
|
if (adjacent_only) {
|
|
953
956
|
break;
|
|
954
957
|
}
|
|
955
|
-
} else if (prev
|
|
958
|
+
} else if (is_block(prev)) {
|
|
956
959
|
const possible_last_child = get_possible_last_child(prev, adjacent_only);
|
|
957
960
|
add_to_map(possible_last_child, result);
|
|
958
961
|
if (adjacent_only && has_definite_elements(possible_last_child)) {
|
|
@@ -976,7 +979,7 @@ function get_possible_element_siblings(node, adjacent_only) {
|
|
|
976
979
|
while (
|
|
977
980
|
// @ts-expect-error TODO
|
|
978
981
|
(parent = parent?.parent) &&
|
|
979
|
-
(parent
|
|
982
|
+
is_block(parent)
|
|
980
983
|
) {
|
|
981
984
|
const possible_siblings = get_possible_element_siblings(parent, adjacent_only);
|
|
982
985
|
add_to_map(possible_siblings, result);
|
|
@@ -997,73 +1000,57 @@ function get_possible_element_siblings(node, adjacent_only) {
|
|
|
997
1000
|
}
|
|
998
1001
|
|
|
999
1002
|
/**
|
|
1000
|
-
* @param {Compiler.AST.EachBlock | Compiler.AST.IfBlock | Compiler.AST.AwaitBlock}
|
|
1003
|
+
* @param {Compiler.AST.EachBlock | Compiler.AST.IfBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock} node
|
|
1001
1004
|
* @param {boolean} adjacent_only
|
|
1002
1005
|
* @returns {Map<Compiler.AST.RegularElement, NodeExistsValue>}
|
|
1003
1006
|
*/
|
|
1004
|
-
function get_possible_last_child(
|
|
1007
|
+
function get_possible_last_child(node, adjacent_only) {
|
|
1005
1008
|
/** @typedef {Map<Compiler.AST.RegularElement, NodeExistsValue>} NodeMap */
|
|
1006
1009
|
|
|
1010
|
+
/** @type {Array<Compiler.AST.Fragment | undefined | null>} */
|
|
1011
|
+
let fragments = [];
|
|
1012
|
+
|
|
1013
|
+
switch (node.type) {
|
|
1014
|
+
case 'EachBlock':
|
|
1015
|
+
fragments.push(node.body, node.fallback);
|
|
1016
|
+
break;
|
|
1017
|
+
|
|
1018
|
+
case 'IfBlock':
|
|
1019
|
+
fragments.push(node.consequent, node.alternate);
|
|
1020
|
+
break;
|
|
1021
|
+
|
|
1022
|
+
case 'AwaitBlock':
|
|
1023
|
+
fragments.push(node.pending, node.then, node.catch);
|
|
1024
|
+
break;
|
|
1025
|
+
|
|
1026
|
+
case 'KeyBlock':
|
|
1027
|
+
fragments.push(node.fragment);
|
|
1028
|
+
break;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1007
1031
|
/** @type {NodeMap} */
|
|
1008
1032
|
const result = new Map();
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
: new Map();
|
|
1017
|
-
const not_exhaustive = !has_definite_elements(else_result);
|
|
1018
|
-
if (not_exhaustive) {
|
|
1019
|
-
mark_as_probably(each_result);
|
|
1020
|
-
mark_as_probably(else_result);
|
|
1021
|
-
}
|
|
1022
|
-
add_to_map(each_result, result);
|
|
1023
|
-
add_to_map(else_result, result);
|
|
1024
|
-
} else if (relative_selector.type === 'IfBlock') {
|
|
1025
|
-
/** @type {NodeMap} */
|
|
1026
|
-
const if_result = loop_child(relative_selector.consequent.nodes, adjacent_only);
|
|
1027
|
-
|
|
1028
|
-
/** @type {NodeMap} */
|
|
1029
|
-
const else_result = relative_selector.alternate
|
|
1030
|
-
? loop_child(relative_selector.alternate.nodes, adjacent_only)
|
|
1031
|
-
: new Map();
|
|
1032
|
-
const not_exhaustive = !has_definite_elements(if_result) || !has_definite_elements(else_result);
|
|
1033
|
-
if (not_exhaustive) {
|
|
1034
|
-
mark_as_probably(if_result);
|
|
1035
|
-
mark_as_probably(else_result);
|
|
1033
|
+
|
|
1034
|
+
let exhaustive = true;
|
|
1035
|
+
|
|
1036
|
+
for (const fragment of fragments) {
|
|
1037
|
+
if (fragment == null) {
|
|
1038
|
+
exhaustive = false;
|
|
1039
|
+
continue;
|
|
1036
1040
|
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
? loop_child(relative_selector.then.nodes, adjacent_only)
|
|
1048
|
-
: new Map();
|
|
1049
|
-
|
|
1050
|
-
/** @type {NodeMap} */
|
|
1051
|
-
const catch_result = relative_selector.catch
|
|
1052
|
-
? loop_child(relative_selector.catch.nodes, adjacent_only)
|
|
1053
|
-
: new Map();
|
|
1054
|
-
const not_exhaustive =
|
|
1055
|
-
!has_definite_elements(pending_result) ||
|
|
1056
|
-
!has_definite_elements(then_result) ||
|
|
1057
|
-
!has_definite_elements(catch_result);
|
|
1058
|
-
if (not_exhaustive) {
|
|
1059
|
-
mark_as_probably(pending_result);
|
|
1060
|
-
mark_as_probably(then_result);
|
|
1061
|
-
mark_as_probably(catch_result);
|
|
1041
|
+
|
|
1042
|
+
const map = loop_child(fragment.nodes, adjacent_only);
|
|
1043
|
+
exhaustive &&= has_definite_elements(map);
|
|
1044
|
+
|
|
1045
|
+
add_to_map(map, result);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
if (!exhaustive) {
|
|
1049
|
+
for (const key of result.keys()) {
|
|
1050
|
+
result.set(key, NODE_PROBABLY_EXISTS);
|
|
1062
1051
|
}
|
|
1063
|
-
add_to_map(pending_result, result);
|
|
1064
|
-
add_to_map(then_result, result);
|
|
1065
|
-
add_to_map(catch_result, result);
|
|
1066
1052
|
}
|
|
1053
|
+
|
|
1067
1054
|
return result;
|
|
1068
1055
|
}
|
|
1069
1056
|
|
|
@@ -1104,13 +1091,6 @@ function higher_existence(exist1, exist2) {
|
|
|
1104
1091
|
return exist1 > exist2 ? exist1 : exist2;
|
|
1105
1092
|
}
|
|
1106
1093
|
|
|
1107
|
-
/** @param {Map<Compiler.AST.RegularElement, NodeExistsValue>} result */
|
|
1108
|
-
function mark_as_probably(result) {
|
|
1109
|
-
for (const key of result.keys()) {
|
|
1110
|
-
result.set(key, NODE_PROBABLY_EXISTS);
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
1094
|
/**
|
|
1115
1095
|
* @param {Compiler.SvelteNode[]} children
|
|
1116
1096
|
* @param {boolean} adjacent_only
|
|
@@ -1118,18 +1098,18 @@ function mark_as_probably(result) {
|
|
|
1118
1098
|
function loop_child(children, adjacent_only) {
|
|
1119
1099
|
/** @type {Map<Compiler.AST.RegularElement, NodeExistsValue>} */
|
|
1120
1100
|
const result = new Map();
|
|
1121
|
-
|
|
1101
|
+
|
|
1102
|
+
let i = children.length;
|
|
1103
|
+
|
|
1104
|
+
while (i--) {
|
|
1122
1105
|
const child = children[i];
|
|
1106
|
+
|
|
1123
1107
|
if (child.type === 'RegularElement') {
|
|
1124
1108
|
result.set(child, NODE_DEFINITELY_EXISTS);
|
|
1125
1109
|
if (adjacent_only) {
|
|
1126
1110
|
break;
|
|
1127
1111
|
}
|
|
1128
|
-
} else if (
|
|
1129
|
-
child.type === 'EachBlock' ||
|
|
1130
|
-
child.type === 'IfBlock' ||
|
|
1131
|
-
child.type === 'AwaitBlock'
|
|
1132
|
-
) {
|
|
1112
|
+
} else if (is_block(child)) {
|
|
1133
1113
|
const child_result = get_possible_last_child(child, adjacent_only);
|
|
1134
1114
|
add_to_map(child_result, result);
|
|
1135
1115
|
if (adjacent_only && has_definite_elements(child_result)) {
|
|
@@ -1137,5 +1117,19 @@ function loop_child(children, adjacent_only) {
|
|
|
1137
1117
|
}
|
|
1138
1118
|
}
|
|
1139
1119
|
}
|
|
1120
|
+
|
|
1140
1121
|
return result;
|
|
1141
1122
|
}
|
|
1123
|
+
|
|
1124
|
+
/**
|
|
1125
|
+
* @param {Compiler.SvelteNode} node
|
|
1126
|
+
* @returns {node is Compiler.AST.IfBlock | Compiler.AST.EachBlock | Compiler.AST.AwaitBlock | Compiler.AST.KeyBlock}
|
|
1127
|
+
*/
|
|
1128
|
+
function is_block(node) {
|
|
1129
|
+
return (
|
|
1130
|
+
node.type === 'IfBlock' ||
|
|
1131
|
+
node.type === 'EachBlock' ||
|
|
1132
|
+
node.type === 'AwaitBlock' ||
|
|
1133
|
+
node.type === 'KeyBlock'
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
@@ -709,8 +709,8 @@ export function analyze_component(root, source, options) {
|
|
|
709
709
|
analyze_css(analysis.css.ast, analysis);
|
|
710
710
|
|
|
711
711
|
// mark nodes as scoped/unused/empty etc
|
|
712
|
-
for (const
|
|
713
|
-
prune(analysis.css.ast,
|
|
712
|
+
for (const node of analysis.elements) {
|
|
713
|
+
prune(analysis.css.ast, node);
|
|
714
714
|
}
|
|
715
715
|
|
|
716
716
|
const { comment } = analysis.css.ast.content;
|
|
@@ -724,18 +724,18 @@ export function analyze_component(root, source, options) {
|
|
|
724
724
|
warn_unused(analysis.css.ast);
|
|
725
725
|
}
|
|
726
726
|
|
|
727
|
-
outer: for (const
|
|
728
|
-
if (
|
|
727
|
+
outer: for (const node of analysis.elements) {
|
|
728
|
+
if (node.type === 'RenderTag') continue;
|
|
729
729
|
|
|
730
|
-
if (
|
|
730
|
+
if (node.metadata.scoped) {
|
|
731
731
|
// Dynamic elements in dom mode always use spread for attributes and therefore shouldn't have a class attribute added to them
|
|
732
732
|
// TODO this happens during the analysis phase, which shouldn't know anything about client vs server
|
|
733
|
-
if (
|
|
733
|
+
if (node.type === 'SvelteElement' && options.generate === 'client') continue;
|
|
734
734
|
|
|
735
735
|
/** @type {AST.Attribute | undefined} */
|
|
736
736
|
let class_attribute = undefined;
|
|
737
737
|
|
|
738
|
-
for (const attribute of
|
|
738
|
+
for (const attribute of node.attributes) {
|
|
739
739
|
if (attribute.type === 'SpreadAttribute') {
|
|
740
740
|
// The spread method appends the hash to the end of the class attribute on its own
|
|
741
741
|
continue outer;
|
|
@@ -768,7 +768,7 @@ export function analyze_component(root, source, options) {
|
|
|
768
768
|
}
|
|
769
769
|
}
|
|
770
770
|
} else {
|
|
771
|
-
|
|
771
|
+
node.attributes.push(
|
|
772
772
|
create_attribute('class', -1, -1, [
|
|
773
773
|
{
|
|
774
774
|
type: 'Text',
|
|
@@ -780,8 +780,8 @@ export function analyze_component(root, source, options) {
|
|
|
780
780
|
}
|
|
781
781
|
])
|
|
782
782
|
);
|
|
783
|
-
if (is_custom_element_node(
|
|
784
|
-
mark_subtree_dynamic(
|
|
783
|
+
if (is_custom_element_node(node) && node.attributes.length === 1) {
|
|
784
|
+
mark_subtree_dynamic(node.metadata.path);
|
|
785
785
|
}
|
|
786
786
|
}
|
|
787
787
|
}
|
|
@@ -9,7 +9,9 @@ import { mark_subtree_dynamic } from './shared/fragment.js';
|
|
|
9
9
|
* @param {Context} context
|
|
10
10
|
*/
|
|
11
11
|
export function ExpressionTag(node, context) {
|
|
12
|
-
|
|
12
|
+
const in_attribute = context.path.at(-1)?.type === 'Attribute';
|
|
13
|
+
|
|
14
|
+
if (!in_attribute && context.state.parent_element) {
|
|
13
15
|
if (!is_tag_valid_with_parent('#text', context.state.parent_element)) {
|
|
14
16
|
e.node_invalid_placement(node, '`{expression}`', context.state.parent_element);
|
|
15
17
|
}
|
|
@@ -19,11 +19,9 @@ import { mark_subtree_dynamic } from './shared/fragment.js';
|
|
|
19
19
|
*/
|
|
20
20
|
export function RegularElement(node, context) {
|
|
21
21
|
validate_element(node, context);
|
|
22
|
-
|
|
23
|
-
check_element(node, context.state);
|
|
22
|
+
check_element(node, context);
|
|
24
23
|
|
|
25
24
|
node.metadata.path = [...context.path];
|
|
26
|
-
|
|
27
25
|
context.state.analysis.elements.push(node);
|
|
28
26
|
|
|
29
27
|
// Special case: Move the children of <textarea> into a value attribute if they are dynamic
|
|
@@ -12,6 +12,7 @@ import { mark_subtree_dynamic } from './shared/fragment.js';
|
|
|
12
12
|
export function RenderTag(node, context) {
|
|
13
13
|
validate_opening_tag(node, context.state, '@');
|
|
14
14
|
|
|
15
|
+
node.metadata.path = [...context.path];
|
|
15
16
|
context.state.analysis.elements.push(node);
|
|
16
17
|
|
|
17
18
|
const callee = unwrap_optional(node.expression).callee;
|
|
@@ -12,9 +12,9 @@ import { mark_subtree_dynamic } from './shared/fragment.js';
|
|
|
12
12
|
*/
|
|
13
13
|
export function SvelteElement(node, context) {
|
|
14
14
|
validate_element(node, context);
|
|
15
|
+
check_element(node, context);
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
node.metadata.path = [...context.path];
|
|
18
18
|
context.state.analysis.elements.push(node);
|
|
19
19
|
|
|
20
20
|
const xmlns = /** @type {AST.Attribute & { value: [AST.Text] } | undefined} */ (
|
|
@@ -9,7 +9,9 @@ import * as e from '../../../errors.js';
|
|
|
9
9
|
* @param {Context} context
|
|
10
10
|
*/
|
|
11
11
|
export function Text(node, context) {
|
|
12
|
-
|
|
12
|
+
const in_attribute = context.path.at(-1)?.type === 'Attribute';
|
|
13
|
+
|
|
14
|
+
if (!in_attribute && context.state.parent_element && regex_not_whitespace.test(node.data)) {
|
|
13
15
|
if (!is_tag_valid_with_parent('#text', context.state.parent_element)) {
|
|
14
16
|
e.node_invalid_placement(node, 'Text node', context.state.parent_element);
|
|
15
17
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @import {
|
|
1
|
+
/** @import { Context } from '../../types.js' */
|
|
2
2
|
/** @import { AST, SvelteNode, TemplateNode } from '#compiler' */
|
|
3
3
|
/** @import { ARIARoleDefinitionKey, ARIARoleRelationConcept, ARIAProperty, ARIAPropertyDefinition, ARIARoleDefinition } from 'aria-query' */
|
|
4
4
|
import { roles as roles_map, aria, elementRoles } from 'aria-query';
|
|
@@ -582,16 +582,17 @@ function get_implicit_role(name, attribute_map) {
|
|
|
582
582
|
const invisible_elements = ['meta', 'html', 'script', 'style'];
|
|
583
583
|
|
|
584
584
|
/**
|
|
585
|
-
* @param {SvelteNode
|
|
585
|
+
* @param {SvelteNode[]} path
|
|
586
586
|
* @param {string[]} elements
|
|
587
587
|
*/
|
|
588
|
-
function is_parent(
|
|
589
|
-
|
|
588
|
+
function is_parent(path, elements) {
|
|
589
|
+
let i = path.length;
|
|
590
|
+
while (i--) {
|
|
591
|
+
const parent = path[i];
|
|
590
592
|
if (parent.type === 'SvelteElement') return true; // unknown, play it safe, so we don't warn
|
|
591
593
|
if (parent.type === 'RegularElement') {
|
|
592
594
|
return elements.includes(parent.name);
|
|
593
595
|
}
|
|
594
|
-
parent = /** @type {TemplateNode} */ (parent).parent;
|
|
595
596
|
}
|
|
596
597
|
return false;
|
|
597
598
|
}
|
|
@@ -683,9 +684,9 @@ function get_static_text_value(attribute) {
|
|
|
683
684
|
|
|
684
685
|
/**
|
|
685
686
|
* @param {AST.RegularElement | AST.SvelteElement} node
|
|
686
|
-
* @param {
|
|
687
|
+
* @param {Context} context
|
|
687
688
|
*/
|
|
688
|
-
export function check_element(node,
|
|
689
|
+
export function check_element(node, context) {
|
|
689
690
|
/** @type {Map<string, AST.Attribute>} */
|
|
690
691
|
const attribute_map = new Map();
|
|
691
692
|
|
|
@@ -792,7 +793,7 @@ export function check_element(node, state) {
|
|
|
792
793
|
}
|
|
793
794
|
|
|
794
795
|
// Footers and headers are special cases, and should not have redundant roles unless they are the children of sections or articles.
|
|
795
|
-
const is_parent_section_or_article = is_parent(
|
|
796
|
+
const is_parent_section_or_article = is_parent(context.path, ['section', 'article']);
|
|
796
797
|
if (!is_parent_section_or_article) {
|
|
797
798
|
const has_nested_redundant_role =
|
|
798
799
|
current_role === a11y_nested_implicit_semantics.get(node.name);
|
|
@@ -1114,7 +1115,7 @@ export function check_element(node, state) {
|
|
|
1114
1115
|
}
|
|
1115
1116
|
|
|
1116
1117
|
if (node.name === 'figcaption') {
|
|
1117
|
-
if (!is_parent(
|
|
1118
|
+
if (!is_parent(context.path, ['figure'])) {
|
|
1118
1119
|
w.a11y_figcaption_parent(node);
|
|
1119
1120
|
}
|
|
1120
1121
|
}
|
|
@@ -167,6 +167,7 @@ export namespace AST {
|
|
|
167
167
|
metadata: {
|
|
168
168
|
dynamic: boolean;
|
|
169
169
|
args_with_call_expression: Set<number>;
|
|
170
|
+
path: SvelteNode[];
|
|
170
171
|
};
|
|
171
172
|
}
|
|
172
173
|
|
|
@@ -344,6 +345,7 @@ export namespace AST {
|
|
|
344
345
|
*/
|
|
345
346
|
mathml: boolean;
|
|
346
347
|
scoped: boolean;
|
|
348
|
+
path: SvelteNode[];
|
|
347
349
|
};
|
|
348
350
|
}
|
|
349
351
|
|
|
@@ -5,7 +5,7 @@ import { create_event, delegate } from './events.js';
|
|
|
5
5
|
import { add_form_reset_listener, autofocus } from './misc.js';
|
|
6
6
|
import * as w from '../../warnings.js';
|
|
7
7
|
import { LOADING_ATTR_SYMBOL } from '../../constants.js';
|
|
8
|
-
import { queue_idle_task
|
|
8
|
+
import { queue_idle_task } from '../task.js';
|
|
9
9
|
import { is_capture_event, is_delegated, normalize_attribute } from '../../../../utils.js';
|
|
10
10
|
import {
|
|
11
11
|
active_effect,
|
|
@@ -209,8 +209,6 @@ export function set_attributes(
|
|
|
209
209
|
|
|
210
210
|
// @ts-expect-error
|
|
211
211
|
var attributes = /** @type {Record<string, unknown>} **/ (element.__attributes ??= {});
|
|
212
|
-
/** @type {Array<[string, any, () => void]>} */
|
|
213
|
-
var events = [];
|
|
214
212
|
|
|
215
213
|
// since key is captured we use const
|
|
216
214
|
for (const key in next) {
|
|
@@ -277,15 +275,7 @@ export function set_attributes(
|
|
|
277
275
|
current[key].call(this, evt);
|
|
278
276
|
}
|
|
279
277
|
|
|
280
|
-
|
|
281
|
-
events.push([
|
|
282
|
-
key,
|
|
283
|
-
value,
|
|
284
|
-
() => (current[event_handle_key] = create_event(event_name, element, handle, opts))
|
|
285
|
-
]);
|
|
286
|
-
} else {
|
|
287
|
-
current[event_handle_key] = create_event(event_name, element, handle, opts);
|
|
288
|
-
}
|
|
278
|
+
current[event_handle_key] = create_event(event_name, element, handle, opts);
|
|
289
279
|
} else {
|
|
290
280
|
// @ts-ignore
|
|
291
281
|
element[`__${event_name}`] = value;
|
|
@@ -325,19 +315,6 @@ export function set_attributes(
|
|
|
325
315
|
}
|
|
326
316
|
}
|
|
327
317
|
|
|
328
|
-
// On the first run, ensure that events are added after bindings so
|
|
329
|
-
// that their listeners fire after the binding listeners
|
|
330
|
-
if (!prev) {
|
|
331
|
-
queue_micro_task(() => {
|
|
332
|
-
if (!element.isConnected) return;
|
|
333
|
-
for (const [key, value, evt] of events) {
|
|
334
|
-
if (current[key] === value) {
|
|
335
|
-
evt();
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
|
|
341
318
|
return current;
|
|
342
319
|
}
|
|
343
320
|
|
|
@@ -154,8 +154,10 @@ export function first_child(fragment, is_text) {
|
|
|
154
154
|
*/
|
|
155
155
|
export function sibling(node, count = 1, is_text = false) {
|
|
156
156
|
let next_sibling = hydrating ? hydrate_node : node;
|
|
157
|
+
var last_sibling;
|
|
157
158
|
|
|
158
159
|
while (count--) {
|
|
160
|
+
last_sibling = next_sibling;
|
|
159
161
|
next_sibling = /** @type {TemplateNode} */ (get_next_sibling(next_sibling));
|
|
160
162
|
}
|
|
161
163
|
|
|
@@ -163,13 +165,20 @@ export function sibling(node, count = 1, is_text = false) {
|
|
|
163
165
|
return next_sibling;
|
|
164
166
|
}
|
|
165
167
|
|
|
166
|
-
var type = next_sibling
|
|
168
|
+
var type = next_sibling?.nodeType;
|
|
167
169
|
|
|
168
170
|
// if a sibling {expression} is empty during SSR, there might be no
|
|
169
171
|
// text node to hydrate — we must therefore create one
|
|
170
172
|
if (is_text && type !== 3) {
|
|
171
173
|
var text = create_text();
|
|
172
|
-
|
|
174
|
+
// If the next sibling is `null` and we're handling text then it's because
|
|
175
|
+
// the SSR content was empty for the text, so we need to generate a new text
|
|
176
|
+
// node and insert it after the last sibling
|
|
177
|
+
if (next_sibling === null) {
|
|
178
|
+
last_sibling?.after(text);
|
|
179
|
+
} else {
|
|
180
|
+
next_sibling.before(text);
|
|
181
|
+
}
|
|
173
182
|
set_hydrate_node(text);
|
|
174
183
|
return text;
|
|
175
184
|
}
|
|
@@ -63,6 +63,11 @@ export function asClassComponent(component) {
|
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Support using the component as both a class and function during the transition period
|
|
68
|
+
* @typedef {{new (o: ComponentConstructorOptions): SvelteComponent;(...args: Parameters<Component<Record<string, any>>>): ReturnType<Component<Record<string, any>, Record<string, any>>>;}} LegacyComponentType
|
|
69
|
+
*/
|
|
70
|
+
|
|
66
71
|
class Svelte4Component {
|
|
67
72
|
/** @type {any} */
|
|
68
73
|
#events;
|
package/src/version.js
CHANGED