Skip to content

Commit f4edb38

Browse files
author
Rich Harris
committed
Merge branch 'master' into sites
2 parents 5976de8 + d42ca04 commit f4edb38

File tree

46 files changed

+1066
-53
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1066
-53
lines changed

CHANGELOG.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
# Svelte changelog
22

3-
## Unreleased
3+
## 3.58.0
44

55
* Add `bind:innerText` for `contenteditable` elements ([#3311](https://github.com/sveltejs/svelte/issues/3311))
6-
* Relax `a11y-no-noninteractive-element-to-interactive-role` warning ([#8402](https://github.com/sveltejs/svelte/pull/8402))
6+
* Add support for CSS `@container` queries ([#6969](https://github.com/sveltejs/svelte/issues/6969))
7+
* Respect `preserveComments` in DOM output ([#7182](https://github.com/sveltejs/svelte/pull/7182))
8+
* Allow use of `document` for `target` in typings ([#7554](https://github.com/sveltejs/svelte/pull/7554))
79
* Add `a11y-interactive-supports-focus` warning ([#8392](https://github.com/sveltejs/svelte/pull/8392))
810
* Fix equality check when updating dynamic text ([#5931](https://github.com/sveltejs/svelte/issues/5931))
11+
* Relax `a11y-no-noninteractive-element-to-interactive-role` warning ([#8402](https://github.com/sveltejs/svelte/pull/8402))
12+
* Properly handle microdata attributes ([#8413](https://github.com/sveltejs/svelte/issues/8413))
13+
* Prevent name collision when using computed destructuring variables ([#8417](https://github.com/sveltejs/svelte/issues/8417))
14+
* Fix escaping `<textarea value={...}>` values in SSR ([#8429](https://github.com/sveltejs/svelte/issues/8429))
915

1016
## 3.57.0
1117

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "svelte",
3-
"version": "3.57.0",
3+
"version": "3.58.0",
44
"description": "Cybernetically enhanced web apps",
55
"module": "index.mjs",
66
"main": "index",

src/compiler/compile/css/Stylesheet.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ class Atrule {
173173
}
174174

175175
apply(node: Element) {
176-
if (this.node.name === 'media' || this.node.name === 'supports' || this.node.name === 'layer') {
176+
if (this.node.name === 'container' || this.node.name === 'media' || this.node.name === 'supports' || this.node.name === 'layer') {
177177
this.children.forEach(child => {
178178
child.apply(node);
179179
});

src/compiler/compile/nodes/shared/Context.ts

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export type Context = DestructuredVariable | ComputedProperty;
1111

1212
interface ComputedProperty {
1313
type: 'ComputedProperty';
14-
property_name: string;
14+
property_name: Identifier;
1515
key: Expression | PrivateIdentifier;
1616
}
1717

@@ -30,8 +30,7 @@ export function unpack_destructuring({
3030
default_modifier = (node) => node,
3131
scope,
3232
component,
33-
context_rest_properties,
34-
number_of_computed_props = { n: 0 }
33+
context_rest_properties
3534
}: {
3635
contexts: Context[];
3736
node: Node;
@@ -40,10 +39,6 @@ export function unpack_destructuring({
4039
scope: TemplateScope;
4140
component: Component;
4241
context_rest_properties: Map<string, Node>;
43-
// we want to pass this by reference, as a sort of global variable, because
44-
// if we pass this by value, we could get computed_property_# variable collisions
45-
// when we deal with nested object destructuring
46-
number_of_computed_props?: { n: number };
4742
}) {
4843
if (!node) return;
4944

@@ -72,8 +67,7 @@ export function unpack_destructuring({
7267
default_modifier,
7368
scope,
7469
component,
75-
context_rest_properties,
76-
number_of_computed_props
70+
context_rest_properties
7771
});
7872
context_rest_properties.set((element.argument as Identifier).name, element);
7973
} else if (element && element.type === 'AssignmentPattern') {
@@ -93,8 +87,7 @@ export function unpack_destructuring({
9387
)}` as Node,
9488
scope,
9589
component,
96-
context_rest_properties,
97-
number_of_computed_props
90+
context_rest_properties
9891
});
9992
} else {
10093
unpack_destructuring({
@@ -104,8 +97,7 @@ export function unpack_destructuring({
10497
default_modifier,
10598
scope,
10699
component,
107-
context_rest_properties,
108-
number_of_computed_props
100+
context_rest_properties
109101
});
110102
}
111103
});
@@ -124,8 +116,7 @@ export function unpack_destructuring({
124116
default_modifier,
125117
scope,
126118
component,
127-
context_rest_properties,
128-
number_of_computed_props
119+
context_rest_properties
129120
});
130121
context_rest_properties.set((property.argument as Identifier).name, property);
131122
} else if (property.type === 'Property') {
@@ -136,8 +127,7 @@ export function unpack_destructuring({
136127

137128
if (property.computed) {
138129
// e.g { [computedProperty]: ... }
139-
const property_name = `computed_property_${number_of_computed_props.n}`;
140-
number_of_computed_props.n += 1;
130+
const property_name = component.get_unique_name('computed_property');
141131

142132
contexts.push({
143133
type: 'ComputedProperty',
@@ -178,8 +168,7 @@ export function unpack_destructuring({
178168
)}` as Node,
179169
scope,
180170
component,
181-
context_rest_properties,
182-
number_of_computed_props
171+
context_rest_properties
183172
});
184173
} else {
185174
// e.g. { property } or { property: newName }
@@ -190,8 +179,7 @@ export function unpack_destructuring({
190179
default_modifier,
191180
scope,
192181
component,
193-
context_rest_properties,
194-
number_of_computed_props
182+
context_rest_properties
195183
});
196184
}
197185
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import Renderer from '../Renderer';
2+
import Block from '../Block';
3+
import Comment from '../../nodes/Comment';
4+
import Wrapper from './shared/Wrapper';
5+
import { x } from 'code-red';
6+
import { Identifier } from 'estree';
7+
8+
export default class CommentWrapper extends Wrapper {
9+
node: Comment;
10+
var: Identifier;
11+
12+
constructor(
13+
renderer: Renderer,
14+
block: Block,
15+
parent: Wrapper,
16+
node: Comment
17+
) {
18+
super(renderer, block, parent, node);
19+
this.var = x`c` as Identifier;
20+
}
21+
22+
render(block: Block, parent_node: Identifier, parent_nodes: Identifier) {
23+
if (!this.renderer.options.preserveComments) return;
24+
25+
const string_literal = {
26+
type: 'Literal',
27+
value: this.node.data,
28+
loc: {
29+
start: this.renderer.locate(this.node.start),
30+
end: this.renderer.locate(this.node.end)
31+
}
32+
};
33+
34+
block.add_element(
35+
this.var,
36+
x`@comment(${string_literal})`,
37+
parent_nodes && x`@claim_comment(${parent_nodes}, ${string_literal})`,
38+
parent_node
39+
);
40+
}
41+
}

src/compiler/compile/render_dom/wrappers/Element/Attribute.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,6 @@ const attribute_lookup: { [key in BooleanAttributes]: AttributeMetadata } & { [k
364364
indeterminate: { applies_to: ['input'] },
365365
inert: {},
366366
ismap: { property_name: 'isMap', applies_to: ['img'] },
367-
itemscope: {},
368367
loop: { applies_to: ['audio', 'bgsound', 'video'] },
369368
multiple: { applies_to: ['input', 'select'] },
370369
muted: { applies_to: ['audio', 'video'] },

src/compiler/compile/render_dom/wrappers/Fragment.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import RawMustacheTag from './RawMustacheTag';
1414
import Slot from './Slot';
1515
import SlotTemplate from './SlotTemplate';
1616
import Text from './Text';
17+
import Comment from './Comment';
1718
import Title from './Title';
1819
import Window from './Window';
1920
import { INode } from '../../nodes/interfaces';
@@ -27,7 +28,7 @@ import { regex_starts_with_whitespace } from '../../../utils/patterns';
2728
const wrappers = {
2829
AwaitBlock,
2930
Body,
30-
Comment: null,
31+
Comment,
3132
DebugTag,
3233
Document,
3334
EachBlock,
@@ -118,7 +119,7 @@ export default class FragmentWrapper {
118119
link(last_child, last_child = wrapper);
119120
} else {
120121
const Wrapper = wrappers[child.type];
121-
if (!Wrapper) continue;
122+
if (!Wrapper || (child.type === 'Comment' && !renderer.options.preserveComments)) continue;
122123

123124
const wrapper = new Wrapper(renderer, block, parent, child, strip_whitespace, last_child || next_sibling);
124125
this.nodes.unshift(wrapper);

src/compiler/compile/render_ssr/handlers/shared/get_attribute_value.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@ export function get_class_attribute_value(attribute: Attribute): ESTreeExpressio
1919
export function get_attribute_value(attribute: Attribute): ESTreeExpression {
2020
if (attribute.chunks.length === 0) return x`""`;
2121

22+
/**
23+
* For value attribute of textarea, it will render as child node of `<textarea>` element.
24+
* Therefore, we need to escape as content (not attribute).
25+
*/
26+
const is_textarea_value = attribute.parent.name.toLowerCase() === 'textarea' && attribute.name.toLowerCase() === 'value';
27+
2228
return attribute.chunks
2329
.map((chunk) => {
2430
return chunk.type === 'Text'
2531
? string_literal(chunk.data.replace(regex_double_quotes, '&quot;')) as ESTreeExpression
26-
: x`@escape(${chunk.node}, true)`;
32+
: x`@escape(${chunk.node}, ${is_textarea_value ? 'false' : 'true'})`;
2733
})
2834
.reduce((lhs, rhs) => x`${lhs} + ${rhs}`);
2935
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// @ts-nocheck
2+
// Note: Must import from the `css-tree` browser bundled distribution due to `createRequire` usage if importing from
3+
// `css-tree` Node module directly. This allows the production build of Svelte to work correctly.
4+
import { fork } from '../../../../../node_modules/css-tree/dist/csstree.esm.js';
5+
6+
import * as node from './node';
7+
8+
/**
9+
* Extends `css-tree` for container query support by forking and adding new nodes and at-rule support for `@container`.
10+
*
11+
* The new nodes are located in `./node`.
12+
*/
13+
const cqSyntax = fork({
14+
atrule: { // extend or override at-rule dictionary
15+
container: {
16+
parse: {
17+
prelude() {
18+
return this.createSingleNodeList(
19+
this.ContainerQuery()
20+
);
21+
},
22+
block(isStyleBlock = false) {
23+
return this.Block(isStyleBlock);
24+
}
25+
}
26+
}
27+
},
28+
node
29+
});
30+
31+
export const parse = cqSyntax.parse;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// @ts-nocheck
2+
import { Delim } from 'css-tree/tokenizer';
3+
4+
export const name = 'Comparison';
5+
export const structure = {
6+
value: String
7+
};
8+
9+
export function parse() {
10+
const start = this.tokenStart;
11+
12+
const char1 = this.consume(Delim);
13+
14+
// The first character in the comparison operator must match '<', '=', or '>'.
15+
if (char1 !== '<' && char1 !== '>' && char1 !== '=') {
16+
this.error('Malformed comparison operator');
17+
}
18+
19+
let char2;
20+
21+
if (this.tokenType === Delim) {
22+
char2 = this.consume(Delim);
23+
24+
// The second character in the comparison operator must match '='.
25+
if (char2 !== '=') {
26+
this.error('Malformed comparison operator');
27+
}
28+
}
29+
30+
// If the next token is also 'Delim' then it is malformed.
31+
if (this.tokenType === Delim) {
32+
this.error('Malformed comparison operator');
33+
}
34+
35+
const value = char2 ? `${char1}${char2}` : char1;
36+
37+
return {
38+
type: 'Comparison',
39+
loc: this.getLocation(start, this.tokenStart),
40+
value
41+
};
42+
}
43+
44+
export function generate(node) {
45+
for (let index = 0; index < node.value.length; index++) {
46+
this.token(Delim, node.value.charAt(index));
47+
}
48+
}

0 commit comments

Comments
 (0)