Skip to content

Commit 9682d57

Browse files
committed
chore: remove references to node.parent
1 parent dd9abea commit 9682d57

File tree

7 files changed

+30
-25
lines changed

7 files changed

+30
-25
lines changed

packages/svelte/src/compiler/phases/2-analyze/index.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ export function analyze_component(root, source, options) {
710710

711711
// mark nodes as scoped/unused/empty etc
712712
for (const element of analysis.elements) {
713-
prune(analysis.css.ast, element);
713+
prune(analysis.css.ast, element.node);
714714
}
715715

716716
const { comment } = analysis.css.ast.content;
@@ -724,18 +724,18 @@ export function analyze_component(root, source, options) {
724724
warn_unused(analysis.css.ast);
725725
}
726726

727-
outer: for (const element of analysis.elements) {
728-
if (element.type === 'RenderTag') continue;
727+
outer: for (const { node } of analysis.elements) {
728+
if (node.type === 'RenderTag') continue;
729729

730-
if (element.metadata.scoped) {
730+
if (node.metadata.scoped) {
731731
// Dynamic elements in dom mode always use spread for attributes and therefore shouldn't have a class attribute added to them
732732
// TODO this happens during the analysis phase, which shouldn't know anything about client vs server
733-
if (element.type === 'SvelteElement' && options.generate === 'client') continue;
733+
if (node.type === 'SvelteElement' && options.generate === 'client') continue;
734734

735735
/** @type {AST.Attribute | undefined} */
736736
let class_attribute = undefined;
737737

738-
for (const attribute of element.attributes) {
738+
for (const attribute of node.attributes) {
739739
if (attribute.type === 'SpreadAttribute') {
740740
// The spread method appends the hash to the end of the class attribute on its own
741741
continue outer;
@@ -768,7 +768,7 @@ export function analyze_component(root, source, options) {
768768
}
769769
}
770770
} else {
771-
element.attributes.push(
771+
node.attributes.push(
772772
create_attribute('class', -1, -1, [
773773
{
774774
type: 'Text',
@@ -780,8 +780,8 @@ export function analyze_component(root, source, options) {
780780
}
781781
])
782782
);
783-
if (is_custom_element_node(element) && element.attributes.length === 1) {
784-
mark_subtree_dynamic(element.metadata.path);
783+
if (is_custom_element_node(node) && node.attributes.length === 1) {
784+
mark_subtree_dynamic(node.metadata.path);
785785
}
786786
}
787787
}

packages/svelte/src/compiler/phases/2-analyze/visitors/ExpressionTag.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import { mark_subtree_dynamic } from './shared/fragment.js';
99
* @param {Context} context
1010
*/
1111
export function ExpressionTag(node, context) {
12-
if (node.parent && context.state.parent_element) {
12+
const in_attribute = context.path.at(-1)?.type === 'Attribute';
13+
14+
if (!in_attribute && context.state.parent_element) {
1315
if (!is_tag_valid_with_parent('#text', context.state.parent_element)) {
1416
e.node_invalid_placement(node, '`{expression}`', context.state.parent_element);
1517
}

packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ import { mark_subtree_dynamic } from './shared/fragment.js';
2020
export function RegularElement(node, context) {
2121
validate_element(node, context);
2222

23-
check_element(node, context.state);
23+
check_element(node, context);
2424

2525
node.metadata.path = [...context.path];
2626

27-
context.state.analysis.elements.push(node);
27+
context.state.analysis.elements.push({ node, path: context.path });
2828

2929
// Special case: Move the children of <textarea> into a value attribute if they are dynamic
3030
if (node.name === 'textarea' && node.fragment.nodes.length > 0) {

packages/svelte/src/compiler/phases/2-analyze/visitors/RenderTag.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { mark_subtree_dynamic } from './shared/fragment.js';
1212
export function RenderTag(node, context) {
1313
validate_opening_tag(node, context.state, '@');
1414

15-
context.state.analysis.elements.push(node);
15+
context.state.analysis.elements.push({ node, path: context.path });
1616

1717
const callee = unwrap_optional(node.expression).callee;
1818

packages/svelte/src/compiler/phases/2-analyze/visitors/SvelteElement.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import { mark_subtree_dynamic } from './shared/fragment.js';
1313
export function SvelteElement(node, context) {
1414
validate_element(node, context);
1515

16-
check_element(node, context.state);
16+
check_element(node, context);
1717

18-
context.state.analysis.elements.push(node);
18+
context.state.analysis.elements.push({ node, path: context.path });
1919

2020
const xmlns = /** @type {AST.Attribute & { value: [AST.Text] } | undefined} */ (
2121
node.attributes.find(

packages/svelte/src/compiler/phases/2-analyze/visitors/Text.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import * as e from '../../../errors.js';
99
* @param {Context} context
1010
*/
1111
export function Text(node, context) {
12-
if (node.parent && context.state.parent_element && regex_not_whitespace.test(node.data)) {
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)) {
1315
if (!is_tag_valid_with_parent('#text', context.state.parent_element)) {
1416
e.node_invalid_placement(node, 'Text node', context.state.parent_element);
1517
}

packages/svelte/src/compiler/phases/2-analyze/visitors/shared/a11y.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { AnalysisState } from '../../types.js' */
1+
/** @import { Context } from '../../types.js' */
22
/** @import { AST, SvelteNode, TemplateNode } from '#compiler' */
33
/** @import { ARIARoleDefinitionKey, ARIARoleRelationConcept, ARIAProperty, ARIAPropertyDefinition, ARIARoleDefinition } from 'aria-query' */
44
import { roles as roles_map, aria, elementRoles } from 'aria-query';
@@ -582,16 +582,17 @@ function get_implicit_role(name, attribute_map) {
582582
const invisible_elements = ['meta', 'html', 'script', 'style'];
583583

584584
/**
585-
* @param {SvelteNode | null} parent
585+
* @param {SvelteNode[]} path
586586
* @param {string[]} elements
587587
*/
588-
function is_parent(parent, elements) {
589-
while (parent) {
588+
function is_parent(path, elements) {
589+
let i = path.length;
590+
while (i--) {
591+
const parent = path[i];
590592
if (parent.type === 'SvelteElement') return true; // unknown, play it safe, so we don't warn
591593
if (parent.type === 'RegularElement') {
592594
return elements.includes(parent.name);
593595
}
594-
parent = /** @type {TemplateNode} */ (parent).parent;
595596
}
596597
return false;
597598
}
@@ -683,9 +684,9 @@ function get_static_text_value(attribute) {
683684

684685
/**
685686
* @param {AST.RegularElement | AST.SvelteElement} node
686-
* @param {AnalysisState} state
687+
* @param {Context} context
687688
*/
688-
export function check_element(node, state) {
689+
export function check_element(node, context) {
689690
/** @type {Map<string, AST.Attribute>} */
690691
const attribute_map = new Map();
691692

@@ -792,7 +793,7 @@ export function check_element(node, state) {
792793
}
793794

794795
// 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(node.parent, ['section', 'article']);
796+
const is_parent_section_or_article = is_parent(context.path, ['section', 'article']);
796797
if (!is_parent_section_or_article) {
797798
const has_nested_redundant_role =
798799
current_role === a11y_nested_implicit_semantics.get(node.name);
@@ -1114,7 +1115,7 @@ export function check_element(node, state) {
11141115
}
11151116

11161117
if (node.name === 'figcaption') {
1117-
if (!is_parent(node.parent, ['figure'])) {
1118+
if (!is_parent(context.path, ['figure'])) {
11181119
w.a11y_figcaption_parent(node);
11191120
}
11201121
}

0 commit comments

Comments
 (0)