svelte 4.1.2 → 4.2.1

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.
@@ -1,5 +1,6 @@
1
1
  import { is_html, is_svg, is_void } from '../../../shared/utils/names.js';
2
2
  import Node from './shared/Node.js';
3
+ import { walk } from 'estree-walker';
3
4
  import Attribute from './Attribute.js';
4
5
  import Binding from './Binding.js';
5
6
  import EventHandler from './EventHandler.js';
@@ -430,7 +431,7 @@ export default class Element extends Node {
430
431
  }
431
432
  if (this.name === 'textarea') {
432
433
  if (info.children.length > 0) {
433
- const value_attribute = info.attributes.find((node) => node.name === 'value');
434
+ const value_attribute = get_value_attribute(info.attributes);
434
435
  if (value_attribute) {
435
436
  component.error(value_attribute, compiler_errors.textarea_duplicate_value);
436
437
  return;
@@ -449,7 +450,7 @@ export default class Element extends Node {
449
450
  // Special case — treat these the same way:
450
451
  // <option>{foo}</option>
451
452
  // <option value={foo}>{foo}</option>
452
- const value_attribute = info.attributes.find((attribute) => attribute.name === 'value');
453
+ const value_attribute = get_value_attribute(info.attributes);
453
454
  if (!value_attribute) {
454
455
  info.attributes.push({
455
456
  type: 'Attribute',
@@ -875,7 +876,7 @@ export default class Element extends Node {
875
876
  ) {
876
877
  const interactive_handlers = handlers
877
878
  .map((handler) => handler.name)
878
- .filter((handlerName) => a11y_interactive_handlers.has(handlerName));
879
+ .filter((handler_name) => a11y_interactive_handlers.has(handler_name));
879
880
  if (interactive_handlers.length > 0) {
880
881
  component.warn(
881
882
  this,
@@ -1420,3 +1421,30 @@ function within_custom_element(parent) {
1420
1421
  }
1421
1422
  return false;
1422
1423
  }
1424
+
1425
+ /**
1426
+ * @param {any[]} attributes
1427
+ */
1428
+ function get_value_attribute(attributes) {
1429
+ let node_value;
1430
+ attributes.forEach((node) => {
1431
+ if (node.type !== 'Spread' && node.name.toLowerCase() === 'value') {
1432
+ node_value = node;
1433
+ }
1434
+ if (node.type === 'Spread') {
1435
+ walk(/** @type {any} */ (node.expression), {
1436
+ enter(/** @type {import('estree').Node} */ node) {
1437
+ if (node_value) {
1438
+ this.skip();
1439
+ }
1440
+ if (node.type === 'Identifier') {
1441
+ if (/** @type {import('estree').Identifier} */ (node).name.toLowerCase() === 'value') {
1442
+ node_value = node;
1443
+ }
1444
+ }
1445
+ }
1446
+ });
1447
+ }
1448
+ });
1449
+ return node_value;
1450
+ }
@@ -73,8 +73,8 @@ function sort_consts_nodes(consts_nodes, component) {
73
73
  }, [])
74
74
  );
75
75
  if (cycle && cycle.length) {
76
- const nodeList = lookup.get(cycle[0]);
77
- const node = nodeList[0];
76
+ const node_list = lookup.get(cycle[0]);
77
+ const node = node_list[0];
78
78
  component.error(node.node, compiler_errors.cyclical_const_tags(cycle));
79
79
  }
80
80
 
@@ -990,7 +990,8 @@ export default class ElementWrapper extends Wrapper {
990
990
  const static_attributes = [];
991
991
  this.attributes.forEach((attr) => {
992
992
  if (attr instanceof SpreadAttributeWrapper) {
993
- static_attributes.push({ type: 'SpreadElement', argument: attr.node.expression.node });
993
+ const snippet = { type: 'SpreadElement', argument: attr.node.expression.manipulate(block) };
994
+ static_attributes.push(snippet);
994
995
  } else {
995
996
  const name = attr.property_name || attr.name;
996
997
  static_attributes.push(p`${name}: ${attr.get_value(block)}`);
@@ -1240,11 +1241,7 @@ export default class ElementWrapper extends Wrapper {
1240
1241
  }
1241
1242
  if (this.dynamic_style_dependencies.size > 0) {
1242
1243
  maybe_create_style_changed_var();
1243
- // If all dependencies are same as the style attribute dependencies, then we can skip the dirty check
1244
- condition =
1245
- all_deps.size === this.dynamic_style_dependencies.size
1246
- ? style_changed_var
1247
- : x`${style_changed_var} || ${condition}`;
1244
+ condition = x`${condition} || ${style_changed_var}`;
1248
1245
  }
1249
1246
  block.chunks.update.push(b`
1250
1247
  if (${condition}) {
@@ -105,14 +105,19 @@ export default class InlineComponentWrapper extends Wrapper {
105
105
  this.slots.set(name, slot_definition);
106
106
  }
107
107
  warn_if_reactive() {
108
- const { name } = this.node;
109
- const variable = this.renderer.component.var_lookup.get(name);
108
+ let { name } = this.node;
109
+ const top = name.split('.')[0]; // <T.foo/> etc. should check for T instead of "T.foo"
110
+ const variable = this.renderer.component.var_lookup.get(top);
110
111
  if (!variable) {
111
112
  return;
112
113
  }
113
114
  const ignores = extract_ignores_above_node(this.node);
114
115
  this.renderer.component.push_ignores(ignores);
115
- if (variable.reassigned || variable.export_name || variable.is_reactive_dependency) {
116
+ if (
117
+ variable.reassigned ||
118
+ variable.export_name || // or a prop
119
+ variable.mutated
120
+ ) {
116
121
  this.renderer.component.warn(this.node, compiler_warnings.reactive_component(name));
117
122
  }
118
123
  this.renderer.component.pop_ignores();
@@ -94,14 +94,14 @@ export default class WindowWrapper extends Wrapper {
94
94
  bindings.scrollX && bindings.scrollY
95
95
  ? x`"${bindings.scrollX}" in this._state || "${bindings.scrollY}" in this._state`
96
96
  : x`"${bindings.scrollX || bindings.scrollY}" in this._state`;
97
- const scrollX = bindings.scrollX && x`this._state.${bindings.scrollX}`;
98
- const scrollY = bindings.scrollY && x`this._state.${bindings.scrollY}`;
97
+ const scroll_x = bindings.scrollX && x`this._state.${bindings.scrollX}`;
98
+ const scroll_y = bindings.scrollY && x`this._state.${bindings.scrollY}`;
99
99
  renderer.meta_bindings.push(b`
100
100
  if (${condition}) {
101
- @_scrollTo(${scrollX || '@_window.pageXOffset'}, ${scrollY || '@_window.pageYOffset'});
101
+ @_scrollTo(${scroll_x || '@_window.pageXOffset'}, ${scroll_y || '@_window.pageYOffset'});
102
102
  }
103
- ${scrollX && `${scrollX} = @_window.pageXOffset;`}
104
- ${scrollY && `${scrollY} = @_window.pageYOffset;`}
103
+ ${scroll_x && `${scroll_x} = @_window.pageXOffset;`}
104
+ ${scroll_y && `${scroll_y} = @_window.pageYOffset;`}
105
105
  `);
106
106
  block.event_listeners.push(x`
107
107
  @listen(@_window, "${event}", () => {
@@ -132,17 +132,17 @@ export default class WindowWrapper extends Wrapper {
132
132
  // special case... might need to abstract this out if we add more special cases
133
133
  if (bindings.scrollX || bindings.scrollY) {
134
134
  const condition = renderer.dirty([bindings.scrollX, bindings.scrollY].filter(Boolean));
135
- const scrollX = bindings.scrollX
135
+ const scroll_x = bindings.scrollX
136
136
  ? renderer.reference(bindings.scrollX)
137
137
  : x`@_window.pageXOffset`;
138
- const scrollY = bindings.scrollY
138
+ const scroll_y = bindings.scrollY
139
139
  ? renderer.reference(bindings.scrollY)
140
140
  : x`@_window.pageYOffset`;
141
141
  block.chunks.update.push(b`
142
142
  if (${condition} && !${scrolling}) {
143
143
  ${scrolling} = true;
144
144
  @_clearTimeout(${scrolling_timeout});
145
- @_scrollTo(${scrollX}, ${scrollY});
145
+ @_scrollTo(${scroll_x}, ${scroll_y});
146
146
  ${scrolling_timeout} = @_setTimeout(${clear_scrolling}, 100);
147
147
  }
148
148
  `);
@@ -3,8 +3,11 @@ import { is_reserved_keyword } from '../../../utils/reserved_keywords.js';
3
3
  /** @param {import('../../../../interfaces.js').Var} variable */
4
4
  export default function is_dynamic(variable) {
5
5
  if (variable) {
6
- if (variable.mutated || variable.reassigned) return true; // dynamic internal state
7
- if (!variable.module && variable.writable && variable.export_name) return true; // writable props
6
+ // Only variables declared in the instance script tags should be considered dynamic
7
+ const is_declared_in_reactive_context = !variable.module && !variable.global;
8
+
9
+ if (is_declared_in_reactive_context && (variable.mutated || variable.reassigned)) return true; // dynamic internal state
10
+ if (is_declared_in_reactive_context && variable.writable && variable.export_name) return true; // writable props
8
11
  if (is_reserved_keyword(variable.name)) return true;
9
12
  }
10
13
  return false;
@@ -144,9 +144,13 @@ export default function ssr(component, options) {
144
144
  ? b`
145
145
  let $$settled;
146
146
  let $$rendered;
147
+ let #previous_head = $$result.head;
147
148
 
148
149
  do {
149
150
  $$settled = true;
151
+ // $$result.head is mutated by the literal expression
152
+ // need to reset it if we're looping back to prevent duplication
153
+ $$result.head = #previous_head;
150
154
 
151
155
  ${reactive_declarations}
152
156
 
@@ -8,7 +8,7 @@ import * as node from './node/index.js';
8
8
  *
9
9
  * The new nodes are located in `./node`.
10
10
  */
11
- const cqSyntax = fork({
11
+ const cq_syntax = fork({
12
12
  atrule: {
13
13
  // extend or override at-rule dictionary
14
14
  container: {
@@ -16,8 +16,8 @@ const cqSyntax = fork({
16
16
  prelude() {
17
17
  return this.createSingleNodeList(this.ContainerQuery());
18
18
  },
19
- block(isStyleBlock = false) {
20
- return this.Block(isStyleBlock);
19
+ block(is_style_block = false) {
20
+ return this.Block(is_style_block);
21
21
  }
22
22
  }
23
23
  }
@@ -25,4 +25,4 @@ const cqSyntax = fork({
25
25
  node
26
26
  });
27
27
 
28
- export const parse = cqSyntax.parse;
28
+ export const parse = cq_syntax.parse;
@@ -16,7 +16,7 @@ export const structure = {
16
16
  value: ['Identifier', 'Number', 'Comparison', 'Dimension', 'QueryCSSFunction', 'Ratio', null]
17
17
  };
18
18
 
19
- function lookup_non_WS_type_and_value(offset, type, referenceStr) {
19
+ function lookup_non_ws_type_and_value(offset, type, reference_str) {
20
20
  let current_type;
21
21
 
22
22
  do {
@@ -26,7 +26,7 @@ function lookup_non_WS_type_and_value(offset, type, referenceStr) {
26
26
  }
27
27
  } while (current_type !== 0); // NULL -> 0
28
28
 
29
- return current_type === type ? this.lookupValue(offset - 1, referenceStr) : false;
29
+ return current_type === type ? this.lookupValue(offset - 1, reference_str) : false;
30
30
  }
31
31
 
32
32
  export function parse() {
@@ -40,7 +40,7 @@ export function parse() {
40
40
  while (!this.eof && this.tokenType !== RightParenthesis) {
41
41
  switch (this.tokenType) {
42
42
  case Number:
43
- if (lookup_non_WS_type_and_value.call(this, 1, Delim, '/')) {
43
+ if (lookup_non_ws_type_and_value.call(this, 1, Delim, '/')) {
44
44
  child = this.Ratio();
45
45
  } else {
46
46
  child = this.Number();
@@ -26,11 +26,7 @@ function _distance(str1, str2) {
26
26
  str1 = String(str1);
27
27
  str2 = String(str2);
28
28
  const distance = levenshtein(str1, str2);
29
- if (str1.length > str2.length) {
30
- return 1 - distance / str1.length;
31
- } else {
32
- return 1 - distance / str2.length;
33
- }
29
+ return 1 - distance / Math.max(str1.length, str2.length);
34
30
  }
35
31
 
36
32
  // helper functions
@@ -1,6 +1,6 @@
1
1
  /** ----------------------------------------------------------------------
2
2
  This file is automatically generated by `scripts/globals-extractor.js`.
3
- Generated At: 2023-05-24T13:16:20.777Z
3
+ Generated At: 2023-08-11T04:11:50.562Z
4
4
  ---------------------------------------------------------------------- */
5
5
 
6
6
  export default new Set([
@@ -292,7 +292,18 @@ export function apply_preprocessor_sourcemap(filename, svelte_map, preprocessor_
292
292
  toUrl: {
293
293
  enumerable: false,
294
294
  value: function toUrl() {
295
- return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());
295
+ let b64 = '';
296
+ if (typeof window !== 'undefined' && window.btoa) {
297
+ // btoa doesn't support multi-byte characters
298
+ b64 = window.btoa(unescape(encodeURIComponent(this.toString())));
299
+ } else if (typeof Buffer !== 'undefined') {
300
+ b64 = Buffer.from(this.toString(), 'utf8').toString('base64');
301
+ } else {
302
+ throw new Error(
303
+ 'Unsupported environment: `window.btoa` or `Buffer` should be present to use toUrl.'
304
+ );
305
+ }
306
+ return 'data:application/json;charset=utf-8;base64,' + b64;
296
307
  }
297
308
  }
298
309
  });
@@ -84,7 +84,17 @@ function make_dirty(component, i) {
84
84
  component.$$.dirty[(i / 31) | 0] |= 1 << i % 31;
85
85
  }
86
86
 
87
- /** @returns {void} */
87
+ // TODO: Document the other params
88
+ /**
89
+ * @param {SvelteComponent} component
90
+ * @param {import('./public.js').ComponentConstructorOptions} options
91
+ *
92
+ * @param {import('./utils.js')['not_equal']} not_equal Used to compare props and state values.
93
+ * @param {(target: Element | ShadowRoot) => void} [append_styles] Function that appends styles to the DOM when the component is first initialised.
94
+ * This will be the `add_css` function from the compiled component.
95
+ *
96
+ * @returns {void}
97
+ */
88
98
  export function init(
89
99
  component,
90
100
  options,
@@ -92,7 +102,7 @@ export function init(
92
102
  create_fragment,
93
103
  not_equal,
94
104
  props,
95
- append_styles,
105
+ append_styles = null,
96
106
  dirty = [-1]
97
107
  ) {
98
108
  const parent_component = current_component;
@@ -139,8 +149,9 @@ export function init(
139
149
  if (options.target) {
140
150
  if (options.hydrate) {
141
151
  start_hydrating();
152
+ // TODO: what is the correct type here?
153
+ // @ts-expect-error
142
154
  const nodes = children(options.target);
143
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
144
155
  $$.fragment && $$.fragment.l(nodes);
145
156
  nodes.forEach(detach);
146
157
  } else {
@@ -283,7 +294,7 @@ if (typeof HTMLElement === 'function') {
283
294
  'toAttribute'
284
295
  );
285
296
  if (attribute_value == null) {
286
- this.removeAttribute(key);
297
+ this.removeAttribute(this.$$p_d[key].attribute || key);
287
298
  } else {
288
299
  this.setAttribute(this.$$p_d[key].attribute || key, attribute_value);
289
300
  }
@@ -1,5 +1,7 @@
1
- import { ResizeObserverSingleton } from './ResizeObserverSingleton.js';
2
1
  import { contenteditable_truthy_values, has_prop } from './utils.js';
2
+
3
+ import { ResizeObserverSingleton } from './ResizeObserverSingleton.js';
4
+
3
5
  // Track which nodes are claimed during hydration. Unclaimed nodes can then be removed from the DOM
4
6
  // at the end of hydration without touching the remaining nodes.
5
7
  let is_hydrating = false;
@@ -50,14 +52,14 @@ function init_hydrate(target) {
50
52
  let children = /** @type {ArrayLike<NodeEx2>} */ (target.childNodes);
51
53
  // If target is <head>, there may be children without claim_order
52
54
  if (target.nodeName === 'HEAD') {
53
- const myChildren = [];
55
+ const my_children = [];
54
56
  for (let i = 0; i < children.length; i++) {
55
57
  const node = children[i];
56
58
  if (node.claim_order !== undefined) {
57
- myChildren.push(node);
59
+ my_children.push(node);
58
60
  }
59
61
  }
60
- children = myChildren;
62
+ children = my_children;
61
63
  }
62
64
  /*
63
65
  * Reorder claimed children optimally.
@@ -87,15 +89,15 @@ function init_hydrate(target) {
87
89
  // Find the largest subsequence length such that it ends in a value less than our current value
88
90
  // upper_bound returns first greater value, so we subtract one
89
91
  // with fast path for when we are on the current longest subsequence
90
- const seqLen =
92
+ const seq_len =
91
93
  (longest > 0 && children[m[longest]].claim_order <= current
92
94
  ? longest + 1
93
95
  : upper_bound(1, longest, (idx) => children[m[idx]].claim_order, current)) - 1;
94
- p[i] = m[seqLen] + 1;
95
- const newLen = seqLen + 1;
96
+ p[i] = m[seq_len] + 1;
97
+ const new_len = seq_len + 1;
96
98
  // We can guarantee that current is the smallest value. Otherwise, we would have generated a longer sequence.
97
- m[newLen] = i;
98
- longest = Math.max(newLen, longest);
99
+ m[new_len] = i;
100
+ longest = Math.max(new_len, longest);
99
101
  }
100
102
  // The longest increasing subsequence of nodes (initially reversed)
101
103
 
@@ -108,28 +110,28 @@ function init_hydrate(target) {
108
110
  /**
109
111
  * @type {NodeEx2[]}
110
112
  */
111
- const toMove = [];
113
+ const to_move = [];
112
114
  let last = children.length - 1;
113
115
  for (let cur = m[longest] + 1; cur != 0; cur = p[cur - 1]) {
114
116
  lis.push(children[cur - 1]);
115
117
  for (; last >= cur; last--) {
116
- toMove.push(children[last]);
118
+ to_move.push(children[last]);
117
119
  }
118
120
  last--;
119
121
  }
120
122
  for (; last >= 0; last--) {
121
- toMove.push(children[last]);
123
+ to_move.push(children[last]);
122
124
  }
123
125
  lis.reverse();
124
126
  // We sort the nodes being moved to guarantee that their insertion order matches the claim order
125
- toMove.sort((a, b) => a.claim_order - b.claim_order);
127
+ to_move.sort((a, b) => a.claim_order - b.claim_order);
126
128
  // Finally, we move the nodes
127
- for (let i = 0, j = 0; i < toMove.length; i++) {
128
- while (j < lis.length && toMove[i].claim_order >= lis[j].claim_order) {
129
+ for (let i = 0, j = 0; i < to_move.length; i++) {
130
+ while (j < lis.length && to_move[i].claim_order >= lis[j].claim_order) {
129
131
  j++;
130
132
  }
131
133
  const anchor = j < lis.length ? lis[j] : null;
132
- target.insertBefore(toMove[i], anchor);
134
+ target.insertBefore(to_move[i], anchor);
133
135
  }
134
136
  }
135
137
 
@@ -624,26 +626,26 @@ function init_claim_info(nodes) {
624
626
  * @template {ChildNodeEx} R
625
627
  * @param {ChildNodeArray} nodes
626
628
  * @param {(node: ChildNodeEx) => node is R} predicate
627
- * @param {(node: ChildNodeEx) => ChildNodeEx | undefined} processNode
628
- * @param {() => R} createNode
629
- * @param {boolean} dontUpdateLastIndex
629
+ * @param {(node: ChildNodeEx) => ChildNodeEx | undefined} process_node
630
+ * @param {() => R} create_node
631
+ * @param {boolean} dont_update_last_index
630
632
  * @returns {R}
631
633
  */
632
- function claim_node(nodes, predicate, processNode, createNode, dontUpdateLastIndex = false) {
634
+ function claim_node(nodes, predicate, process_node, create_node, dont_update_last_index = false) {
633
635
  // Try to find nodes in an order such that we lengthen the longest increasing subsequence
634
636
  init_claim_info(nodes);
635
- const resultNode = (() => {
637
+ const result_node = (() => {
636
638
  // We first try to find an element after the previous one
637
639
  for (let i = nodes.claim_info.last_index; i < nodes.length; i++) {
638
640
  const node = nodes[i];
639
641
  if (predicate(node)) {
640
- const replacement = processNode(node);
642
+ const replacement = process_node(node);
641
643
  if (replacement === undefined) {
642
644
  nodes.splice(i, 1);
643
645
  } else {
644
646
  nodes[i] = replacement;
645
647
  }
646
- if (!dontUpdateLastIndex) {
648
+ if (!dont_update_last_index) {
647
649
  nodes.claim_info.last_index = i;
648
650
  }
649
651
  return node;
@@ -654,13 +656,13 @@ function claim_node(nodes, predicate, processNode, createNode, dontUpdateLastInd
654
656
  for (let i = nodes.claim_info.last_index - 1; i >= 0; i--) {
655
657
  const node = nodes[i];
656
658
  if (predicate(node)) {
657
- const replacement = processNode(node);
659
+ const replacement = process_node(node);
658
660
  if (replacement === undefined) {
659
661
  nodes.splice(i, 1);
660
662
  } else {
661
663
  nodes[i] = replacement;
662
664
  }
663
- if (!dontUpdateLastIndex) {
665
+ if (!dont_update_last_index) {
664
666
  nodes.claim_info.last_index = i;
665
667
  } else if (replacement === undefined) {
666
668
  // Since we spliced before the last_index, we decrease it
@@ -670,11 +672,11 @@ function claim_node(nodes, predicate, processNode, createNode, dontUpdateLastInd
670
672
  }
671
673
  }
672
674
  // If we can't find any matching node, we create a new one
673
- return createNode();
675
+ return create_node();
674
676
  })();
675
- resultNode.claim_order = nodes.claim_info.total_claimed;
677
+ result_node.claim_order = nodes.claim_info.total_claimed;
676
678
  nodes.claim_info.total_claimed += 1;
677
- return resultNode;
679
+ return result_node;
678
680
  }
679
681
 
680
682
  /**
@@ -736,13 +738,13 @@ export function claim_text(nodes, data) {
736
738
  (node) => node.nodeType === 3,
737
739
  /** @param {Text} node */
738
740
  (node) => {
739
- const dataStr = '' + data;
740
- if (node.data.startsWith(dataStr)) {
741
- if (node.data.length !== dataStr.length) {
742
- return node.splitText(dataStr.length);
741
+ const data_str = '' + data;
742
+ if (node.data.startsWith(data_str)) {
743
+ if (node.data.length !== data_str.length) {
744
+ return node.splitText(data_str.length);
743
745
  }
744
746
  } else {
745
- node.data = dataStr;
747
+ node.data = data_str;
746
748
  }
747
749
  },
748
750
  () => text(data),
@@ -6,5 +6,5 @@
6
6
  * https://svelte.dev/docs/svelte-compiler#svelte-version
7
7
  * @type {string}
8
8
  */
9
- export const VERSION = '4.1.2';
9
+ export const VERSION = '4.2.1';
10
10
  export const PUBLIC_VERSION = '4';