svelte 4.0.0 → 4.0.2
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/README.md +1 -1
- package/compiler.cjs +604 -226
- package/package.json +15 -14
- package/src/compiler/compile/internal_exports.js +1 -1
- package/src/compiler/compile/nodes/Element.js +5 -1
- package/src/compiler/compile/nodes/shared/Context.js +1 -0
- package/src/compiler/compile/render_dom/wrappers/Element/Attribute.js +12 -1
- package/src/compiler/compile/render_dom/wrappers/Element/index.js +12 -4
- package/src/compiler/compile/render_dom/wrappers/RawMustacheTag.js +1 -1
- package/src/runtime/action/public.d.ts +7 -10
- package/src/runtime/internal/Component.js +89 -83
- package/src/runtime/internal/public.d.ts +4 -6
- package/src/runtime/internal/utils.js +36 -1
- package/src/shared/version.js +1 -1
- package/types/index.d.ts +11 -16
- package/types/index.d.ts.map +1 -1
- package/src/compiler/tsconfig.json +0 -15
- package/src/runtime/tsconfig.json +0 -18
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "Cybernetically enhanced web apps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "src/runtime/index.js",
|
|
7
7
|
"main": "src/runtime/index.js",
|
|
8
8
|
"files": [
|
|
9
9
|
"src",
|
|
10
|
+
"!src/**/tsconfig.json",
|
|
10
11
|
"types",
|
|
11
12
|
"compiler.*",
|
|
12
13
|
"register.js",
|
|
@@ -57,7 +58,7 @@
|
|
|
57
58
|
"default": "./src/runtime/store/index.js"
|
|
58
59
|
},
|
|
59
60
|
"./internal/disclose-version": {
|
|
60
|
-
"
|
|
61
|
+
"default": "./src/runtime/internal/disclose-version/index.js"
|
|
61
62
|
},
|
|
62
63
|
"./transition": {
|
|
63
64
|
"types": "./types/index.d.ts",
|
|
@@ -92,8 +93,8 @@
|
|
|
92
93
|
"@ampproject/remapping": "^2.2.1",
|
|
93
94
|
"@jridgewell/sourcemap-codec": "^1.4.15",
|
|
94
95
|
"@jridgewell/trace-mapping": "^0.3.18",
|
|
95
|
-
"acorn": "^8.
|
|
96
|
-
"aria-query": "^5.
|
|
96
|
+
"acorn": "^8.9.0",
|
|
97
|
+
"aria-query": "^5.3.0",
|
|
97
98
|
"axobject-query": "^3.2.1",
|
|
98
99
|
"code-red": "^1.0.3",
|
|
99
100
|
"css-tree": "^2.3.1",
|
|
@@ -104,35 +105,35 @@
|
|
|
104
105
|
"periscopic": "^3.1.0"
|
|
105
106
|
},
|
|
106
107
|
"devDependencies": {
|
|
107
|
-
"@playwright/test": "^1.
|
|
108
|
+
"@playwright/test": "^1.35.1",
|
|
108
109
|
"@rollup/plugin-commonjs": "^24.1.0",
|
|
109
110
|
"@rollup/plugin-json": "^6.0.0",
|
|
110
|
-
"@rollup/plugin-node-resolve": "^15.0
|
|
111
|
+
"@rollup/plugin-node-resolve": "^15.1.0",
|
|
111
112
|
"@sveltejs/eslint-config": "^6.0.4",
|
|
112
113
|
"@types/aria-query": "^5.0.1",
|
|
113
114
|
"@types/estree": "^1.0.1",
|
|
114
|
-
"@types/node": "^14.
|
|
115
|
+
"@types/node": "^14.18.51",
|
|
115
116
|
"agadoo": "^3.0.0",
|
|
116
117
|
"dts-buddy": "^0.1.7",
|
|
117
118
|
"esbuild": "^0.17.19",
|
|
118
|
-
"happy-dom": "^9.
|
|
119
|
-
"jsdom": "^21.1.
|
|
119
|
+
"happy-dom": "^9.20.3",
|
|
120
|
+
"jsdom": "^21.1.2",
|
|
120
121
|
"kleur": "^4.1.5",
|
|
121
|
-
"rollup": "^3.
|
|
122
|
+
"rollup": "^3.25.1",
|
|
122
123
|
"source-map": "^0.7.4",
|
|
123
124
|
"tiny-glob": "^0.2.9",
|
|
124
|
-
"typescript": "^5.
|
|
125
|
-
"vitest": "^0.31.
|
|
125
|
+
"typescript": "^5.1.3",
|
|
126
|
+
"vitest": "^0.31.4"
|
|
126
127
|
},
|
|
127
128
|
"scripts": {
|
|
128
129
|
"format": "prettier . --cache --plugin-search-dir=. --write",
|
|
129
|
-
"check": "
|
|
130
|
+
"check": "tsc --noEmit",
|
|
130
131
|
"test": "vitest run && echo \"manually check that there are no type errors in test/types by opening the files in there\"",
|
|
131
132
|
"build": "rollup -c && pnpm types",
|
|
132
133
|
"generate:version": "node ./scripts/generate-version.js",
|
|
133
134
|
"dev": "rollup -cw",
|
|
134
135
|
"posttest": "agadoo src/internal/index.js",
|
|
135
136
|
"types": "node ./scripts/generate-dts.js",
|
|
136
|
-
"lint": "eslint \"{src,test}/**/*.{ts,js}\" --cache"
|
|
137
|
+
"lint": "prettier . --cache --plugin-search-dir=. --check && eslint \"{src,test}/**/*.{ts,js}\" --cache"
|
|
137
138
|
}
|
|
138
139
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is automatically generated
|
|
2
|
-
export default new Set(["HtmlTag","HtmlTagHydration","ResizeObserverSingleton","SvelteComponent","SvelteComponentDev","SvelteComponentTyped","SvelteElement","action_destroyer","add_attribute","add_classes","add_flush_callback","add_iframe_resize_listener","add_location","add_render_callback","add_styles","add_transform","afterUpdate","append","append_dev","append_empty_stylesheet","append_hydration","append_hydration_dev","append_styles","assign","attr","attr_dev","attribute_to_object","beforeUpdate","bind","binding_callbacks","blank_object","bubble","check_outros","children","claim_comment","claim_component","claim_element","claim_html_tag","claim_space","claim_svg_element","claim_text","clear_loops","comment","component_subscribe","compute_rest_props","compute_slots","construct_svelte_component","construct_svelte_component_dev","contenteditable_truthy_values","createEventDispatcher","create_animation","create_bidirectional_transition","create_component","create_custom_element","create_in_transition","create_out_transition","create_slot","create_ssr_component","current_component","custom_event","dataset_dev","debug","destroy_block","destroy_component","destroy_each","detach","detach_after_dev","detach_before_dev","detach_between_dev","detach_dev","dirty_components","dispatch_dev","each","element","element_is","empty","end_hydrating","ensure_array_like","ensure_array_like_dev","escape","escape_attribute_value","escape_object","exclude_internal_props","fix_and_destroy_block","fix_and_outro_and_destroy_block","fix_position","flush","flush_render_callbacks","getAllContexts","getContext","get_all_dirty_from_scope","get_binding_group_value","get_current_component","get_custom_elements_slots","get_root_for_style","get_slot_changes","get_spread_object","get_spread_update","get_store_value","get_svelte_dataset","globals","group_outros","handle_promise","hasContext","has_prop","head_selector","identity","init","init_binding_group","init_binding_group_dynamic","insert","insert_dev","insert_hydration","insert_hydration_dev","intros","invalid_attribute_name_character","is_client","is_crossorigin","is_empty","is_function","is_promise","is_void","listen","listen_dev","loop","loop_guard","merge_ssr_styles","missing_component","mount_component","noop","not_equal","now","null_to_empty","object_without_properties","onDestroy","onMount","once","outro_and_destroy_block","prevent_default","prop_dev","query_selector_all","raf","resize_observer_border_box","resize_observer_content_box","resize_observer_device_pixel_content_box","run","run_all","safe_not_equal","schedule_update","select_multiple_value","select_option","select_options","select_value","self","setContext","set_attributes","set_current_component","set_custom_element_data","set_custom_element_data_map","set_data","set_data_contenteditable","set_data_contenteditable_dev","set_data_dev","set_data_maybe_contenteditable","set_data_maybe_contenteditable_dev","set_dynamic_element_data","set_input_type","set_input_value","set_now","set_raf","set_store_value","set_style","set_svg_attributes","space","split_css_unit","spread","src_url_equal","start_hydrating","stop_immediate_propagation","stop_propagation","subscribe","svg_element","text","tick","time_ranges_to_array","to_number","toggle_class","transition_in","transition_out","trusted","update_await_block_branch","update_keyed_each","update_slot","update_slot_base","validate_component","validate_dynamic_element","validate_each_keys","validate_slots","validate_store","validate_void_dynamic_element","xlink_attr"]);
|
|
2
|
+
export default new Set(["HtmlTag","HtmlTagHydration","ResizeObserverSingleton","SvelteComponent","SvelteComponentDev","SvelteComponentTyped","SvelteElement","action_destroyer","add_attribute","add_classes","add_flush_callback","add_iframe_resize_listener","add_location","add_render_callback","add_styles","add_transform","afterUpdate","append","append_dev","append_empty_stylesheet","append_hydration","append_hydration_dev","append_styles","assign","attr","attr_dev","attribute_to_object","beforeUpdate","bind","binding_callbacks","blank_object","bubble","check_outros","children","claim_comment","claim_component","claim_element","claim_html_tag","claim_space","claim_svg_element","claim_text","clear_loops","comment","component_subscribe","compute_rest_props","compute_slots","construct_svelte_component","construct_svelte_component_dev","contenteditable_truthy_values","createEventDispatcher","create_animation","create_bidirectional_transition","create_component","create_custom_element","create_in_transition","create_out_transition","create_slot","create_ssr_component","current_component","custom_event","dataset_dev","debug","destroy_block","destroy_component","destroy_each","detach","detach_after_dev","detach_before_dev","detach_between_dev","detach_dev","dirty_components","dispatch_dev","each","element","element_is","empty","end_hydrating","ensure_array_like","ensure_array_like_dev","escape","escape_attribute_value","escape_object","exclude_internal_props","fix_and_destroy_block","fix_and_outro_and_destroy_block","fix_position","flush","flush_render_callbacks","getAllContexts","getContext","get_all_dirty_from_scope","get_binding_group_value","get_current_component","get_custom_elements_slots","get_root_for_style","get_slot_changes","get_spread_object","get_spread_update","get_store_value","get_svelte_dataset","globals","group_outros","handle_promise","hasContext","has_prop","head_selector","identity","init","init_binding_group","init_binding_group_dynamic","insert","insert_dev","insert_hydration","insert_hydration_dev","intros","invalid_attribute_name_character","is_client","is_crossorigin","is_empty","is_function","is_promise","is_void","listen","listen_dev","loop","loop_guard","merge_ssr_styles","missing_component","mount_component","noop","not_equal","now","null_to_empty","object_without_properties","onDestroy","onMount","once","outro_and_destroy_block","prevent_default","prop_dev","query_selector_all","raf","resize_observer_border_box","resize_observer_content_box","resize_observer_device_pixel_content_box","run","run_all","safe_not_equal","schedule_update","select_multiple_value","select_option","select_options","select_value","self","setContext","set_attributes","set_current_component","set_custom_element_data","set_custom_element_data_map","set_data","set_data_contenteditable","set_data_contenteditable_dev","set_data_dev","set_data_maybe_contenteditable","set_data_maybe_contenteditable_dev","set_dynamic_element_data","set_input_type","set_input_value","set_now","set_raf","set_store_value","set_style","set_svg_attributes","space","split_css_unit","spread","src_url_equal","srcset_url_equal","start_hydrating","stop_immediate_propagation","stop_propagation","subscribe","svg_element","text","tick","time_ranges_to_array","to_number","toggle_class","transition_in","transition_out","trusted","update_await_block_branch","update_keyed_each","update_slot","update_slot_base","validate_component","validate_dynamic_element","validate_each_keys","validate_slots","validate_store","validate_void_dynamic_element","xlink_attr"]);
|
|
@@ -694,7 +694,11 @@ export default class Element extends Node {
|
|
|
694
694
|
);
|
|
695
695
|
}
|
|
696
696
|
// no-redundant-roles
|
|
697
|
-
if (
|
|
697
|
+
if (
|
|
698
|
+
current_role === get_implicit_role(this.name, attribute_map) &&
|
|
699
|
+
// <ul role="list"> is ok because CSS list-style:none removes the semantics and this is a way to bring them back
|
|
700
|
+
!['ul', 'ol', 'li'].includes(this.name)
|
|
701
|
+
) {
|
|
698
702
|
component.warn(
|
|
699
703
|
attribute,
|
|
700
704
|
compiler_warnings.a11y_no_redundant_roles(current_role)
|
|
@@ -36,6 +36,7 @@ export function unpack_destructuring({
|
|
|
36
36
|
if (in_rest_element) {
|
|
37
37
|
context_rest_properties.set(node.name, node);
|
|
38
38
|
}
|
|
39
|
+
component.used_names.add(node.name);
|
|
39
40
|
} else if (node.type === 'ArrayPattern') {
|
|
40
41
|
node.elements.forEach((element, i) => {
|
|
41
42
|
if (!element) {
|
|
@@ -64,6 +64,9 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
|
|
|
64
64
|
/** @type {boolean} */
|
|
65
65
|
is_src;
|
|
66
66
|
|
|
67
|
+
/** @type {boolean} */
|
|
68
|
+
is_srcset;
|
|
69
|
+
|
|
67
70
|
/** @type {boolean} */
|
|
68
71
|
is_select_value_attribute;
|
|
69
72
|
|
|
@@ -120,6 +123,9 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
|
|
|
120
123
|
this.is_src =
|
|
121
124
|
this.name === 'src' &&
|
|
122
125
|
(!this.parent.node.namespace || this.parent.node.namespace === namespaces.html);
|
|
126
|
+
this.is_srcset =
|
|
127
|
+
this.name === 'srcset' &&
|
|
128
|
+
(!this.parent.node.namespace || this.parent.node.namespace === namespaces.html);
|
|
123
129
|
this.should_cache = should_cache(this);
|
|
124
130
|
}
|
|
125
131
|
|
|
@@ -164,6 +170,11 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
|
|
|
164
170
|
b`if (!@src_url_equal(${element.var}.src, ${init})) ${method}(${element.var}, "${name}", ${this.last});`
|
|
165
171
|
);
|
|
166
172
|
updater = b`${method}(${element.var}, "${name}", ${should_cache ? this.last : value});`;
|
|
173
|
+
} else if (this.is_srcset) {
|
|
174
|
+
block.chunks.hydrate.push(
|
|
175
|
+
b`if (!@srcset_url_equal(${element.var}, ${init})) ${method}(${element.var}, "${name}", ${this.last});`
|
|
176
|
+
);
|
|
177
|
+
updater = b`${method}(${element.var}, "${name}", ${should_cache ? this.last : value});`;
|
|
167
178
|
} else if (property_name) {
|
|
168
179
|
block.chunks.hydrate.push(b`${element.var}.${property_name} = ${init};`);
|
|
169
180
|
updater = block.renderer.options.dev
|
|
@@ -403,7 +414,7 @@ Object.keys(attribute_lookup).forEach((name) => {
|
|
|
403
414
|
|
|
404
415
|
/** @param {AttributeWrapper} attribute */
|
|
405
416
|
function should_cache(attribute) {
|
|
406
|
-
return attribute.is_src || attribute.node.should_cache();
|
|
417
|
+
return attribute.is_src || attribute.is_srcset || attribute.node.should_cache();
|
|
407
418
|
}
|
|
408
419
|
const regex_contains_checked_or_group = /checked|group/;
|
|
409
420
|
|
|
@@ -233,6 +233,14 @@ export default class ElementWrapper extends Wrapper {
|
|
|
233
233
|
strip_whitespace,
|
|
234
234
|
next_sibling
|
|
235
235
|
);
|
|
236
|
+
|
|
237
|
+
// in the case of `parent_block -> child_dynamic_element_block -> child_dynamic_element`
|
|
238
|
+
// `child_dynamic_element_block.add_intro/outro` is called inside `new ElementWrapper()`
|
|
239
|
+
// but when `is_local === true` it does not bubble to parent_block
|
|
240
|
+
// we manually add transitions back to the parent_block (#8233)
|
|
241
|
+
if (node.intro) block.add_intro(node.intro.is_local);
|
|
242
|
+
if (node.outro) block.add_outro(node.outro.is_local);
|
|
243
|
+
|
|
236
244
|
// the original svelte:element is never used for rendering, because
|
|
237
245
|
// it gets assigned a child_dynamic_element which is used in all rendering logic.
|
|
238
246
|
// so doing all of this on the original svelte:element will just cause double
|
|
@@ -266,10 +274,10 @@ export default class ElementWrapper extends Wrapper {
|
|
|
266
274
|
this.event_handlers = this.node.handlers.map(
|
|
267
275
|
(event_handler) => new EventHandler(event_handler, this)
|
|
268
276
|
);
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
277
|
+
|
|
278
|
+
if (node.intro) block.add_intro(node.intro.is_local);
|
|
279
|
+
if (node.outro) block.add_outro(node.outro.is_local);
|
|
280
|
+
|
|
273
281
|
if (node.animation) {
|
|
274
282
|
block.add_animation();
|
|
275
283
|
}
|
|
@@ -26,7 +26,7 @@ export default class RawMustacheTagWrapper extends Tag {
|
|
|
26
26
|
render(block, parent_node, _parent_nodes) {
|
|
27
27
|
const in_head = is_head(parent_node);
|
|
28
28
|
const can_use_innerhtml = !in_head && parent_node && !this.prev && !this.next;
|
|
29
|
-
if (can_use_innerhtml) {
|
|
29
|
+
if (can_use_innerhtml && !this.renderer.options.hydratable) {
|
|
30
30
|
/** @param {import('estree').Node} content */
|
|
31
31
|
const insert = (content) => b`${parent_node}.innerHTML = ${content};`[0];
|
|
32
32
|
const { init } = this.rename_this_method(block, (content) => insert(content));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Actions can return an object containing the two properties defined in this interface. Both are optional.
|
|
3
3
|
* - update: An action can have a parameter. This method will be called whenever that parameter changes,
|
|
4
|
-
* immediately after Svelte has applied updates to the markup. `ActionReturn` and `ActionReturn<
|
|
5
|
-
* mean that the action accepts no parameters
|
|
4
|
+
* immediately after Svelte has applied updates to the markup. `ActionReturn` and `ActionReturn<undefined>` both
|
|
5
|
+
* mean that the action accepts no parameters.
|
|
6
6
|
* - destroy: Method that is called after the element is unmounted
|
|
7
7
|
*
|
|
8
8
|
* Additionally, you can specify which additional attributes and events the action enables on the applied element.
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
* Docs: https://svelte.dev/docs/svelte-action
|
|
28
28
|
*/
|
|
29
29
|
export interface ActionReturn<
|
|
30
|
-
Parameter =
|
|
30
|
+
Parameter = undefined,
|
|
31
31
|
Attributes extends Record<string, any> = Record<never, any>
|
|
32
32
|
> {
|
|
33
|
-
update?:
|
|
33
|
+
update?: (parameter: Parameter) => void;
|
|
34
34
|
destroy?: () => void;
|
|
35
35
|
/**
|
|
36
36
|
* ### DO NOT USE THIS
|
|
@@ -50,7 +50,7 @@ export interface ActionReturn<
|
|
|
50
50
|
* // ...
|
|
51
51
|
* }
|
|
52
52
|
* ```
|
|
53
|
-
* `Action<HTMLDivElement>` and `Action<HTMLDiveElement,
|
|
53
|
+
* `Action<HTMLDivElement>` and `Action<HTMLDiveElement, undefined>` both signal that the action accepts no parameters.
|
|
54
54
|
*
|
|
55
55
|
* You can return an object with methods `update` and `destroy` from the function and type which additional attributes and events it has.
|
|
56
56
|
* See interface `ActionReturn` for more details.
|
|
@@ -59,13 +59,11 @@ export interface ActionReturn<
|
|
|
59
59
|
*/
|
|
60
60
|
export interface Action<
|
|
61
61
|
Element = HTMLElement,
|
|
62
|
-
Parameter =
|
|
62
|
+
Parameter = undefined,
|
|
63
63
|
Attributes extends Record<string, any> = Record<never, any>
|
|
64
64
|
> {
|
|
65
65
|
<Node extends Element>(
|
|
66
|
-
...args:
|
|
67
|
-
? [node: Node]
|
|
68
|
-
: undefined extends Parameter
|
|
66
|
+
...args: undefined extends Parameter
|
|
69
67
|
? [node: Node, parameter?: Parameter]
|
|
70
68
|
: [node: Node, parameter: Parameter]
|
|
71
69
|
): void | ActionReturn<Parameter, Attributes>;
|
|
@@ -73,4 +71,3 @@ export interface Action<
|
|
|
73
71
|
|
|
74
72
|
// Implementation notes:
|
|
75
73
|
// - undefined extends X instead of X extends undefined makes this work better with both strict and nonstrict mode
|
|
76
|
-
// - [X] extends [never] is needed, X extends never would reduce the whole resulting type to never and not to one of the condition outcomes
|
|
@@ -13,7 +13,9 @@ import {
|
|
|
13
13
|
start_hydrating,
|
|
14
14
|
end_hydrating,
|
|
15
15
|
get_custom_elements_slots,
|
|
16
|
-
insert
|
|
16
|
+
insert,
|
|
17
|
+
element,
|
|
18
|
+
attr
|
|
17
19
|
} from './dom.js';
|
|
18
20
|
import { transition_in } from './transitions.js';
|
|
19
21
|
|
|
@@ -157,23 +159,29 @@ export let SvelteElement;
|
|
|
157
159
|
|
|
158
160
|
if (typeof HTMLElement === 'function') {
|
|
159
161
|
SvelteElement = class extends HTMLElement {
|
|
160
|
-
|
|
161
|
-
$$
|
|
162
|
-
|
|
163
|
-
$$
|
|
164
|
-
|
|
165
|
-
$$
|
|
166
|
-
/**
|
|
167
|
-
$$
|
|
168
|
-
/**
|
|
169
|
-
$$
|
|
170
|
-
/**
|
|
171
|
-
$$
|
|
162
|
+
/** The Svelte component constructor */
|
|
163
|
+
$$ctor;
|
|
164
|
+
/** Slots */
|
|
165
|
+
$$s;
|
|
166
|
+
/** The Svelte component instance */
|
|
167
|
+
$$c;
|
|
168
|
+
/** Whether or not the custom element is connected */
|
|
169
|
+
$$cn = false;
|
|
170
|
+
/** Component props data */
|
|
171
|
+
$$d = {};
|
|
172
|
+
/** `true` if currently in the process of reflecting component props back to attributes */
|
|
173
|
+
$$r = false;
|
|
174
|
+
/** @type {Record<string, CustomElementPropDefinition>} Props definition (name, reflected, type etc) */
|
|
175
|
+
$$p_d = {};
|
|
176
|
+
/** @type {Record<string, Function[]>} Event listeners */
|
|
177
|
+
$$l = {};
|
|
178
|
+
/** @type {Map<Function, Function>} Event listener unsubscribe functions */
|
|
179
|
+
$$l_u = new Map();
|
|
172
180
|
|
|
173
181
|
constructor($$componentCtor, $$slots, use_shadow_dom) {
|
|
174
182
|
super();
|
|
175
|
-
this.$$
|
|
176
|
-
this.$$
|
|
183
|
+
this.$$ctor = $$componentCtor;
|
|
184
|
+
this.$$s = $$slots;
|
|
177
185
|
if (use_shadow_dom) {
|
|
178
186
|
this.attachShadow({ mode: 'open' });
|
|
179
187
|
}
|
|
@@ -183,32 +191,32 @@ if (typeof HTMLElement === 'function') {
|
|
|
183
191
|
// We can't determine upfront if the event is a custom event or not, so we have to
|
|
184
192
|
// listen to both. If someone uses a custom event with the same name as a regular
|
|
185
193
|
// browser event, this fires twice - we can't avoid that.
|
|
186
|
-
this.$$
|
|
187
|
-
this.$$
|
|
188
|
-
if (this.$$
|
|
189
|
-
const unsub = this.$$
|
|
190
|
-
this.$$
|
|
194
|
+
this.$$l[type] = this.$$l[type] || [];
|
|
195
|
+
this.$$l[type].push(listener);
|
|
196
|
+
if (this.$$c) {
|
|
197
|
+
const unsub = this.$$c.$on(type, listener);
|
|
198
|
+
this.$$l_u.set(listener, unsub);
|
|
191
199
|
}
|
|
192
200
|
super.addEventListener(type, listener, options);
|
|
193
201
|
}
|
|
194
202
|
|
|
195
203
|
removeEventListener(type, listener, options) {
|
|
196
204
|
super.removeEventListener(type, listener, options);
|
|
197
|
-
if (this.$$
|
|
198
|
-
const unsub = this.$$
|
|
205
|
+
if (this.$$c) {
|
|
206
|
+
const unsub = this.$$l_u.get(listener);
|
|
199
207
|
if (unsub) {
|
|
200
208
|
unsub();
|
|
201
|
-
this.$$
|
|
209
|
+
this.$$l_u.delete(listener);
|
|
202
210
|
}
|
|
203
211
|
}
|
|
204
212
|
}
|
|
205
213
|
|
|
206
214
|
async connectedCallback() {
|
|
207
|
-
this.$$
|
|
208
|
-
if (!this.$$
|
|
215
|
+
this.$$cn = true;
|
|
216
|
+
if (!this.$$c) {
|
|
209
217
|
// We wait one tick to let possible child slot elements be created/mounted
|
|
210
218
|
await Promise.resolve();
|
|
211
|
-
if (!this.$$
|
|
219
|
+
if (!this.$$cn) {
|
|
212
220
|
return;
|
|
213
221
|
}
|
|
214
222
|
function create_slot(name) {
|
|
@@ -216,9 +224,9 @@ if (typeof HTMLElement === 'function') {
|
|
|
216
224
|
let node;
|
|
217
225
|
const obj = {
|
|
218
226
|
c: function create() {
|
|
219
|
-
node =
|
|
227
|
+
node = element('slot');
|
|
220
228
|
if (name !== 'default') {
|
|
221
|
-
node
|
|
229
|
+
attr(node, 'name', name);
|
|
222
230
|
}
|
|
223
231
|
},
|
|
224
232
|
/**
|
|
@@ -239,74 +247,89 @@ if (typeof HTMLElement === 'function') {
|
|
|
239
247
|
}
|
|
240
248
|
const $$slots = {};
|
|
241
249
|
const existing_slots = get_custom_elements_slots(this);
|
|
242
|
-
for (const name of this.$$
|
|
250
|
+
for (const name of this.$$s) {
|
|
243
251
|
if (name in existing_slots) {
|
|
244
252
|
$$slots[name] = [create_slot(name)];
|
|
245
253
|
}
|
|
246
254
|
}
|
|
247
255
|
for (const attribute of this.attributes) {
|
|
248
256
|
// this.$$data takes precedence over this.attributes
|
|
249
|
-
const name = this.$$
|
|
250
|
-
if (!(name in this.$$
|
|
251
|
-
this.$$
|
|
252
|
-
name,
|
|
253
|
-
attribute.value,
|
|
254
|
-
this.$$props_definition,
|
|
255
|
-
'toProp'
|
|
256
|
-
);
|
|
257
|
+
const name = this.$$g_p(attribute.name);
|
|
258
|
+
if (!(name in this.$$d)) {
|
|
259
|
+
this.$$d[name] = get_custom_element_value(name, attribute.value, this.$$p_d, 'toProp');
|
|
257
260
|
}
|
|
258
261
|
}
|
|
259
|
-
this.$$
|
|
262
|
+
this.$$c = new this.$$ctor({
|
|
260
263
|
target: this.shadowRoot || this,
|
|
261
264
|
props: {
|
|
262
|
-
...this.$$
|
|
265
|
+
...this.$$d,
|
|
263
266
|
$$slots,
|
|
264
267
|
$$scope: {
|
|
265
268
|
ctx: []
|
|
266
269
|
}
|
|
267
270
|
}
|
|
268
271
|
});
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
272
|
+
|
|
273
|
+
// Reflect component props as attributes
|
|
274
|
+
const reflect_attributes = () => {
|
|
275
|
+
this.$$r = true;
|
|
276
|
+
for (const key in this.$$p_d) {
|
|
277
|
+
this.$$d[key] = this.$$c.$$.ctx[this.$$c.$$.props[key]];
|
|
278
|
+
if (this.$$p_d[key].reflect) {
|
|
279
|
+
const attribute_value = get_custom_element_value(
|
|
280
|
+
key,
|
|
281
|
+
this.$$d[key],
|
|
282
|
+
this.$$p_d,
|
|
283
|
+
'toAttribute'
|
|
284
|
+
);
|
|
285
|
+
if (attribute_value == null) {
|
|
286
|
+
this.removeAttribute(key);
|
|
287
|
+
} else {
|
|
288
|
+
this.setAttribute(this.$$p_d[key].attribute || key, attribute_value);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
this.$$r = false;
|
|
293
|
+
};
|
|
294
|
+
this.$$c.$$.after_update.push(reflect_attributes);
|
|
295
|
+
reflect_attributes(); // once initially because after_update is added too late for first render
|
|
296
|
+
|
|
297
|
+
for (const type in this.$$l) {
|
|
298
|
+
for (const listener of this.$$l[type]) {
|
|
299
|
+
const unsub = this.$$c.$on(type, listener);
|
|
300
|
+
this.$$l_u.set(listener, unsub);
|
|
273
301
|
}
|
|
274
302
|
}
|
|
275
|
-
this.$$
|
|
303
|
+
this.$$l = {};
|
|
276
304
|
}
|
|
277
305
|
}
|
|
278
306
|
|
|
279
307
|
// We don't need this when working within Svelte code, but for compatibility of people using this outside of Svelte
|
|
280
308
|
// and setting attributes through setAttribute etc, this is helpful
|
|
281
309
|
attributeChangedCallback(attr, _oldValue, newValue) {
|
|
282
|
-
if (this.$$
|
|
283
|
-
attr = this.$$
|
|
284
|
-
this.$$
|
|
285
|
-
|
|
286
|
-
newValue,
|
|
287
|
-
this.$$props_definition,
|
|
288
|
-
'toProp'
|
|
289
|
-
);
|
|
290
|
-
this.$$component?.$set({ [attr]: this.$$data[attr] });
|
|
310
|
+
if (this.$$r) return;
|
|
311
|
+
attr = this.$$g_p(attr);
|
|
312
|
+
this.$$d[attr] = get_custom_element_value(attr, newValue, this.$$p_d, 'toProp');
|
|
313
|
+
this.$$c?.$set({ [attr]: this.$$d[attr] });
|
|
291
314
|
}
|
|
292
315
|
|
|
293
316
|
disconnectedCallback() {
|
|
294
|
-
this.$$
|
|
317
|
+
this.$$cn = false;
|
|
295
318
|
// In a microtask, because this could be a move within the DOM
|
|
296
319
|
Promise.resolve().then(() => {
|
|
297
|
-
if (!this.$$
|
|
298
|
-
this.$$
|
|
299
|
-
this.$$
|
|
320
|
+
if (!this.$$cn) {
|
|
321
|
+
this.$$c.$destroy();
|
|
322
|
+
this.$$c = undefined;
|
|
300
323
|
}
|
|
301
324
|
});
|
|
302
325
|
}
|
|
303
326
|
|
|
304
|
-
$$
|
|
327
|
+
$$g_p(attribute_name) {
|
|
305
328
|
return (
|
|
306
|
-
Object.keys(this.$$
|
|
329
|
+
Object.keys(this.$$p_d).find(
|
|
307
330
|
(key) =>
|
|
308
|
-
this.$$
|
|
309
|
-
(!this.$$
|
|
331
|
+
this.$$p_d[key].attribute === attribute_name ||
|
|
332
|
+
(!this.$$p_d[key].attribute && key.toLowerCase() === attribute_name)
|
|
310
333
|
) || attribute_name
|
|
311
334
|
);
|
|
312
335
|
}
|
|
@@ -371,7 +394,7 @@ export function create_custom_element(
|
|
|
371
394
|
const Class = class extends SvelteElement {
|
|
372
395
|
constructor() {
|
|
373
396
|
super(Component, slots, use_shadow_dom);
|
|
374
|
-
this.$$
|
|
397
|
+
this.$$p_d = props_definition;
|
|
375
398
|
}
|
|
376
399
|
static get observedAttributes() {
|
|
377
400
|
return Object.keys(props_definition).map((key) =>
|
|
@@ -382,36 +405,19 @@ export function create_custom_element(
|
|
|
382
405
|
Object.keys(props_definition).forEach((prop) => {
|
|
383
406
|
Object.defineProperty(Class.prototype, prop, {
|
|
384
407
|
get() {
|
|
385
|
-
return this.$$
|
|
386
|
-
? this.$$component[prop]
|
|
387
|
-
: this.$$data[prop];
|
|
408
|
+
return this.$$c && prop in this.$$c ? this.$$c[prop] : this.$$d[prop];
|
|
388
409
|
},
|
|
389
410
|
set(value) {
|
|
390
411
|
value = get_custom_element_value(prop, value, props_definition);
|
|
391
|
-
this.$$
|
|
392
|
-
this.$$
|
|
393
|
-
if (props_definition[prop].reflect) {
|
|
394
|
-
this.$$reflecting = true;
|
|
395
|
-
const attribute_value = get_custom_element_value(
|
|
396
|
-
prop,
|
|
397
|
-
value,
|
|
398
|
-
props_definition,
|
|
399
|
-
'toAttribute'
|
|
400
|
-
);
|
|
401
|
-
if (attribute_value == null) {
|
|
402
|
-
this.removeAttribute(prop);
|
|
403
|
-
} else {
|
|
404
|
-
this.setAttribute(props_definition[prop].attribute || prop, attribute_value);
|
|
405
|
-
}
|
|
406
|
-
this.$$reflecting = false;
|
|
407
|
-
}
|
|
412
|
+
this.$$d[prop] = value;
|
|
413
|
+
this.$$c?.$set({ [prop]: value });
|
|
408
414
|
}
|
|
409
415
|
});
|
|
410
416
|
});
|
|
411
417
|
accessors.forEach((accessor) => {
|
|
412
418
|
Object.defineProperty(Class.prototype, accessor, {
|
|
413
419
|
get() {
|
|
414
|
-
return this.$$
|
|
420
|
+
return this.$$c?.[accessor];
|
|
415
421
|
}
|
|
416
422
|
});
|
|
417
423
|
});
|
|
@@ -80,14 +80,12 @@ export interface DispatchOptions {
|
|
|
80
80
|
export interface EventDispatcher<EventMap extends Record<string, any>> {
|
|
81
81
|
// Implementation notes:
|
|
82
82
|
// - undefined extends X instead of X extends undefined makes this work better with both strict and nonstrict mode
|
|
83
|
-
// -
|
|
83
|
+
// - | null | undefined is added for convenience, as they are equivalent for the custom event constructor (both result in a null detail)
|
|
84
84
|
<Type extends keyof EventMap>(
|
|
85
|
-
...args:
|
|
86
|
-
? [type: Type, parameter?: null | undefined, options?: DispatchOptions]
|
|
87
|
-
: null extends EventMap[Type]
|
|
88
|
-
? [type: Type, parameter?: EventMap[Type], options?: DispatchOptions]
|
|
85
|
+
...args: null extends EventMap[Type]
|
|
86
|
+
? [type: Type, parameter?: EventMap[Type] | null | undefined, options?: DispatchOptions]
|
|
89
87
|
: undefined extends EventMap[Type]
|
|
90
|
-
? [type: Type, parameter?: EventMap[Type], options?: DispatchOptions]
|
|
88
|
+
? [type: Type, parameter?: EventMap[Type] | null | undefined, options?: DispatchOptions]
|
|
91
89
|
: [type: Type, parameter: EventMap[Type], options?: DispatchOptions]
|
|
92
90
|
): boolean;
|
|
93
91
|
}
|
|
@@ -68,15 +68,50 @@ export function safe_not_equal(a, b) {
|
|
|
68
68
|
|
|
69
69
|
let src_url_equal_anchor;
|
|
70
70
|
|
|
71
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* @param {string} element_src
|
|
73
|
+
* @param {string} url
|
|
74
|
+
* @returns {boolean}
|
|
75
|
+
*/
|
|
72
76
|
export function src_url_equal(element_src, url) {
|
|
77
|
+
if (element_src === url) return true;
|
|
73
78
|
if (!src_url_equal_anchor) {
|
|
74
79
|
src_url_equal_anchor = document.createElement('a');
|
|
75
80
|
}
|
|
81
|
+
// This is actually faster than doing URL(..).href
|
|
76
82
|
src_url_equal_anchor.href = url;
|
|
77
83
|
return element_src === src_url_equal_anchor.href;
|
|
78
84
|
}
|
|
79
85
|
|
|
86
|
+
/** @param {string} srcset */
|
|
87
|
+
function split_srcset(srcset) {
|
|
88
|
+
return srcset.split(',').map((src) => src.trim().split(' ').filter(Boolean));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {HTMLSourceElement | HTMLImageElement} element_srcset
|
|
93
|
+
* @param {string} srcset
|
|
94
|
+
* @returns {boolean}
|
|
95
|
+
*/
|
|
96
|
+
export function srcset_url_equal(element_srcset, srcset) {
|
|
97
|
+
const element_urls = split_srcset(element_srcset.srcset);
|
|
98
|
+
const urls = split_srcset(srcset);
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
urls.length === element_urls.length &&
|
|
102
|
+
urls.every(
|
|
103
|
+
([url, width], i) =>
|
|
104
|
+
width === element_urls[i][1] &&
|
|
105
|
+
// We need to test both ways because Vite will create an a full URL with
|
|
106
|
+
// `new URL(asset, import.meta.url).href` for the client when `base: './'`, and the
|
|
107
|
+
// relative URLs inside srcset are not automatically resolved to absolute URLs by
|
|
108
|
+
// browsers (in contrast to img.src). This means both SSR and DOM code could
|
|
109
|
+
// contain relative or absolute URLs.
|
|
110
|
+
(src_url_equal(element_urls[i][0], url) || src_url_equal(url, element_urls[i][0]))
|
|
111
|
+
)
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
80
115
|
/** @returns {boolean} */
|
|
81
116
|
export function not_equal(a, b) {
|
|
82
117
|
return a != a ? b == b : a !== b;
|
package/src/shared/version.js
CHANGED