@oscarpalmer/abydon 0.10.0 → 0.12.0

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/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/index.ts
2
+ import"@oscarpalmer/sentinel";
2
3
  import {html} from "./html";
3
4
  export {
4
5
  html
@@ -15,20 +15,25 @@ function mapAttributes(data, element) {
15
15
  if (name.startsWith("@")) {
16
16
  mapEvent(element, name, actual);
17
17
  } else if (name.includes(".") || typeof value2 === "function" || isReactive(actual)) {
18
- mapValue(element, name, actual);
18
+ mapValue(data, element, name, actual);
19
19
  }
20
20
  }
21
21
  }
22
- function mapValue(element, name, value2) {
22
+ function mapValue(data, element, name, value2) {
23
23
  switch (true) {
24
24
  case typeof value2 === "function":
25
- setAttribute(element, name, computed(value2));
25
+ setComputedAttribute(data, element, name, value2);
26
26
  break;
27
27
  default:
28
- setAttribute(element, name, value2);
28
+ setAttribute(data, element, name, value2);
29
29
  break;
30
30
  }
31
31
  }
32
+ function setComputedAttribute(data, element, name, callback) {
33
+ const value2 = computed(callback);
34
+ data.sentinel.values.add(value2);
35
+ setAttribute(data, element, name, value2);
36
+ }
32
37
  var commentExpression = /^<!--abydon\.(\d+)-->$/;
33
38
  export {
34
39
  mapAttributes
@@ -5,21 +5,21 @@ import {
5
5
  isBooleanAttribute,
6
6
  setAttribute as setAttr
7
7
  } from "@oscarpalmer/toretto/attribute";
8
- function setAttribute(element, name, value) {
8
+ function setAttribute(data, element, name, value) {
9
9
  element.removeAttribute(name);
10
10
  switch (true) {
11
11
  case classExpression.test(name):
12
- setClasses(element, name, value);
12
+ setClasses(data, element, name, value);
13
13
  return;
14
14
  case stylePrefixExpression.test(name):
15
- setStyle(element, name, value);
15
+ setStyle(data, element, name, value);
16
16
  return;
17
17
  default:
18
- setValue(element, name, value);
18
+ setValue(data, element, name, value);
19
19
  break;
20
20
  }
21
21
  }
22
- function setClasses(element, name, value) {
22
+ function setClasses(data, element, name, value) {
23
23
  function update(value2) {
24
24
  if (value2 === true) {
25
25
  element.classList.add(...classes);
@@ -29,14 +29,14 @@ function setClasses(element, name, value) {
29
29
  }
30
30
  const classes = name.slice(6).split(".");
31
31
  if (isReactive(value)) {
32
- effect(() => {
32
+ data.sentinel.effects.add(effect(() => {
33
33
  update(value.get());
34
- });
34
+ }));
35
35
  } else {
36
36
  update(value);
37
37
  }
38
38
  }
39
- function setStyle(element, name, value) {
39
+ function setStyle(data, element, name, value) {
40
40
  function update(value2) {
41
41
  if (value2 == null || value2 === false || value2 === true && unit == null) {
42
42
  element.style.removeProperty(property);
@@ -47,20 +47,20 @@ function setStyle(element, name, value) {
47
47
  const [, property, unit] = styleFullExpression.exec(name) ?? [];
48
48
  if (property != null) {
49
49
  if (isReactive(value)) {
50
- effect(() => {
50
+ data.sentinel.effects.add(effect(() => {
51
51
  update(value.get());
52
- });
52
+ }));
53
53
  } else {
54
54
  update(value);
55
55
  }
56
56
  }
57
57
  }
58
- function setValue(element, name, value) {
58
+ function setValue(data, element, name, value) {
59
59
  const callback = isBooleanAttribute(name) && name in element ? name === "selected" ? updateSelected : updateProperty : setAttr;
60
60
  if (isReactive(value)) {
61
- effect(() => {
61
+ data.sentinel.effects.add(effect(() => {
62
62
  callback(element, name, value.get());
63
- });
63
+ }));
64
64
  } else {
65
65
  callback(element, name, value);
66
66
  }
@@ -26,13 +26,12 @@ function mapEvent(element, name, value) {
26
26
  }
27
27
  }
28
28
  function removeEvents(element) {
29
- if (controllers.has(element)) {
30
- controllers.get(element)?.abort();
31
- controllers.delete(element);
32
- }
29
+ controllers.get(element)?.abort(reason);
30
+ controllers.delete(element);
33
31
  }
34
32
  var controllers = new WeakMap;
35
33
  var eventNamePattern = /^@([\w-]+)(?::([a-z:]+))?$/i;
34
+ var reason = "Event removed as element was removed from document by Abydon";
36
35
  export {
37
36
  removeEvents,
38
37
  mapEvent
@@ -1,9 +1,9 @@
1
1
  // src/node/index.ts
2
2
  import {computed, isReactive} from "@oscarpalmer/sentinel";
3
- import {isFragment, isProperElement} from "../helpers";
3
+ import {isFragment, isHTMLOrSVGElement} from "../helpers";
4
4
  import {createNodes} from "../helpers/dom";
5
5
  import {mapAttributes} from "./attribute";
6
- import {setReactiveNode} from "./value";
6
+ import {setReactiveValue} from "./value";
7
7
  function mapNode(data, comment) {
8
8
  const matches = commentExpression.exec(comment.textContent ?? "");
9
9
  const value2 = matches == null ? null : data.values[+matches[1]];
@@ -19,7 +19,7 @@ function mapNodes(data, nodes) {
19
19
  mapNode(data, node);
20
20
  continue;
21
21
  }
22
- if (isProperElement(node)) {
22
+ if (isHTMLOrSVGElement(node)) {
23
23
  mapAttributes(data, node);
24
24
  }
25
25
  if (node.hasChildNodes()) {
@@ -30,10 +30,10 @@ function mapNodes(data, nodes) {
30
30
  function mapValue(data, comment, value2) {
31
31
  switch (true) {
32
32
  case typeof value2 === "function":
33
- setReactiveNode(data, comment, computed(value2));
33
+ setComputedValue(data, comment, value2);
34
34
  break;
35
35
  case isReactive(value2):
36
- setReactiveNode(data, comment, value2);
36
+ setReactiveValue(data, comment, value2);
37
37
  break;
38
38
  default:
39
39
  replaceComment(data, comment, value2);
@@ -49,6 +49,11 @@ function replaceComment(data, comment, value2) {
49
49
  }
50
50
  comment.replaceWith(...nodes);
51
51
  }
52
+ function setComputedValue(data, comment, callback) {
53
+ const value2 = computed(callback);
54
+ data.sentinel.values.add(value2);
55
+ setReactiveValue(data, comment, value2);
56
+ }
52
57
  var commentExpression = /^abydon\.(\d+)$/;
53
58
  export {
54
59
  mapNodes
@@ -2,7 +2,7 @@
2
2
  import {isNullableOrWhitespace} from "@oscarpalmer/atoms/is";
3
3
  import {getString} from "@oscarpalmer/atoms/string";
4
4
  import {effect} from "@oscarpalmer/sentinel";
5
- import {compareArrays, isFragment, isProperNode} from "../helpers";
5
+ import {compareArrays, isChildNode, isFragment} from "../helpers";
6
6
  import {createNodes, replaceNodes} from "../helpers/dom";
7
7
  function removeFragments(fragments) {
8
8
  if (fragments != null) {
@@ -76,12 +76,12 @@ function setNodes(fragments, nodes, comment, text, next) {
76
76
  removeFragments(fragments);
77
77
  return next;
78
78
  }
79
- function setReactiveNode(data, comment, reactive) {
79
+ function setReactiveValue(data, comment, reactive) {
80
80
  const item = data.items.find((item2) => item2.nodes.includes(comment));
81
81
  const text = new Text;
82
82
  let fragments;
83
83
  let nodes;
84
- effect(() => {
84
+ data.sentinel.effects.add(effect(() => {
85
85
  const value = reactive.get();
86
86
  if (Array.isArray(value)) {
87
87
  const result = setArray(fragments, nodes, comment, text, value);
@@ -90,7 +90,7 @@ function setReactiveNode(data, comment, reactive) {
90
90
  } else {
91
91
  const valueIsFragment = isFragment(value);
92
92
  fragments = valueIsFragment ? [value] : undefined;
93
- if (valueIsFragment || isProperNode(value)) {
93
+ if (valueIsFragment || isChildNode(value)) {
94
94
  nodes = setNodes(fragments, nodes, comment, text, createNodes(value));
95
95
  } else {
96
96
  nodes = setText(fragments, nodes, comment, text, value);
@@ -100,7 +100,7 @@ function setReactiveNode(data, comment, reactive) {
100
100
  item.fragments = fragments;
101
101
  item.nodes = [...nodes ?? [comment]];
102
102
  }
103
- });
103
+ }));
104
104
  }
105
105
  function setText(fragments, nodes, comment, text, value) {
106
106
  const isNullable = isNullableOrWhitespace(value);
@@ -119,5 +119,5 @@ function setText(fragments, nodes, comment, text, value) {
119
119
  return result ? [text] : undefined;
120
120
  }
121
121
  export {
122
- setReactiveNode
122
+ setReactiveValue
123
123
  };
package/package.json CHANGED
@@ -47,5 +47,5 @@
47
47
  },
48
48
  "type": "module",
49
49
  "types": "types/index.d.ts",
50
- "version": "0.10.0"
50
+ "version": "0.12.0"
51
51
  }
package/src/fragment.ts CHANGED
@@ -1,6 +1,7 @@
1
+ import type {Key} from '@oscarpalmer/atoms/models';
1
2
  import {html} from '@oscarpalmer/toretto/html';
2
3
  import {parse} from './html';
3
- import type {FragmentData, ProperNode} from './models';
4
+ import type {FragmentData} from './models';
4
5
  import {mapNodes} from './node';
5
6
  import {removeNodes} from './helpers/dom';
6
7
 
@@ -8,11 +9,19 @@ export class Fragment {
8
9
  private readonly $fragment = true;
9
10
  private readonly data: FragmentData;
10
11
 
12
+ get identifier(): Key | undefined {
13
+ return this.data.identifier;
14
+ }
15
+
11
16
  constructor(strings: TemplateStringsArray, expressions: unknown[]) {
12
17
  this.data = {
13
18
  expressions,
14
19
  strings,
15
20
  items: [],
21
+ sentinel: {
22
+ effects: new Set(),
23
+ values: new Set(),
24
+ },
16
25
  values: [],
17
26
  };
18
27
  }
@@ -27,7 +36,7 @@ export class Fragment {
27
36
  /**
28
37
  * Gets a list of the fragment's nodes
29
38
  */
30
- get(): ProperNode[] {
39
+ get(): ChildNode[] {
31
40
  if (this.data.items.length === 0) {
32
41
  const parsed = parse(this.data);
33
42
 
@@ -39,35 +48,68 @@ export class Fragment {
39
48
  0,
40
49
  this.data.items.length,
41
50
  ...templated.map(node => ({
42
- nodes: [node as ProperNode],
51
+ nodes: [node as ChildNode],
43
52
  })),
44
53
  );
45
54
 
46
55
  mapNodes(
47
56
  this.data,
48
- this.data.items.flatMap(item => item.fragment?.get() ?? item.nodes),
57
+ this.data.items.flatMap(
58
+ item =>
59
+ item.fragments?.flatMap(fragment => fragment.get()) ?? item.nodes,
60
+ ),
49
61
  );
50
62
  }
51
63
 
52
64
  return [
53
- ...this.data.items.flatMap(item => item.fragment?.get() ?? item.nodes),
65
+ ...this.data.items.flatMap(
66
+ item =>
67
+ item.fragments?.flatMap(fragment => fragment.get()) ?? item.nodes,
68
+ ),
54
69
  ];
55
70
  }
56
71
 
72
+ identify(identifier: Key): Fragment {
73
+ this.data.identifier = identifier;
74
+
75
+ return this;
76
+ }
77
+
57
78
  /**
58
79
  * Removes the fragment from the DOM
59
80
  */
60
81
  remove(): void {
61
- const {length} = this.data.items;
82
+ removeFragment(this.data);
83
+ }
84
+ }
62
85
 
63
- for (let index = 0; index < length; index += 1) {
64
- const {fragment, nodes} = this.data.items[index];
86
+ function removeFragment(data: FragmentData): void {
87
+ removeSentinels(data);
65
88
 
66
- fragment?.remove();
89
+ const {length} = data.items;
67
90
 
68
- removeNodes(nodes);
91
+ for (let index = 0; index < length; index += 1) {
92
+ const {fragments, nodes} = data.items[index];
93
+ const {length} = fragments ?? [];
94
+
95
+ for (let index = 0; index < length; index += 1) {
96
+ fragments?.[index]?.remove();
69
97
  }
70
98
 
71
- this.data.items.splice(0, length);
99
+ removeNodes(nodes);
100
+ }
101
+
102
+ data.items.splice(0, length);
103
+ }
104
+
105
+ function removeSentinels(data: FragmentData): void {
106
+ const sentinels = [...data.sentinel.effects, ...data.sentinel.values];
107
+ const {length} = sentinels;
108
+
109
+ for (let index = 0; index < length; index += 1) {
110
+ sentinels[index].stop();
72
111
  }
112
+
113
+ data.sentinel.effects.clear();
114
+ data.sentinel.values.clear();
73
115
  }
@@ -1,21 +1,20 @@
1
1
  import {getString} from '@oscarpalmer/atoms/string';
2
- import type {ProperNode} from '../models';
3
- import {isFragment, isProperElement, isProperNode} from './index';
2
+ import {isChildNode, isFragment, isHTMLOrSVGElement} from './index';
4
3
  import {removeEvents} from '../node/event';
5
4
 
6
- export function createNodes(value: unknown): ProperNode[] {
5
+ export function createNodes(value: unknown): ChildNode[] {
7
6
  if (isFragment(value)) {
8
- return value.get() as ProperNode[];
7
+ return value.get() as ChildNode[];
9
8
  }
10
9
 
11
- if (isProperNode(value)) {
10
+ if (isChildNode(value)) {
12
11
  return [value];
13
12
  }
14
13
 
15
14
  return [new Text(getString(value))];
16
15
  }
17
16
 
18
- export function removeNodes(nodes: ProperNode[]): void {
17
+ export function removeNodes(nodes: ChildNode[]): void {
19
18
  sanitiseNodes(nodes);
20
19
 
21
20
  const {length} = nodes;
@@ -25,30 +24,28 @@ export function removeNodes(nodes: ProperNode[]): void {
25
24
  }
26
25
  }
27
26
 
28
- export function replaceNodes(from: ProperNode[], to: ProperNode[]): void {
27
+ export function replaceNodes(from: ChildNode[], to: ChildNode[]): void {
28
+ from[0]?.replaceWith(...to);
29
+
29
30
  const {length} = from;
30
31
 
31
- for (let index = 0; index < length; index += 1) {
32
- if (index === 0) {
33
- from[index].replaceWith(...to);
34
- } else {
35
- from[index].remove();
36
- }
32
+ for (let index = 1; index < length; index += 1) {
33
+ from[index].remove();
37
34
  }
38
35
  }
39
36
 
40
- function sanitiseNodes(nodes: ProperNode[]): void {
37
+ function sanitiseNodes(nodes: ChildNode[]): void {
41
38
  const {length} = nodes;
42
39
 
43
40
  for (let index = 0; index < length; index += 1) {
44
41
  const node = nodes[index];
45
42
 
46
- if (isProperElement(node)) {
43
+ if (isHTMLOrSVGElement(node)) {
47
44
  removeEvents(node);
48
45
  }
49
46
 
50
47
  if (node.hasChildNodes()) {
51
- sanitiseNodes([...node.childNodes] as ProperNode[]);
48
+ sanitiseNodes([...node.childNodes] as ChildNode[]);
52
49
  }
53
50
  }
54
51
  }
@@ -1,5 +1,28 @@
1
1
  import type {Fragment} from '../fragment';
2
- import type {ProperElement, ProperNode} from '../models';
2
+ import type {HTMLOrSVGElement} from '../models';
3
+
4
+ export function compareArrays(
5
+ first: unknown[],
6
+ second: unknown[],
7
+ ): 'added' | 'dissimilar' | 'removed' {
8
+ const firstIsLarger = first.length > second.length;
9
+ const from = firstIsLarger ? first : second;
10
+ const to = firstIsLarger ? second : first;
11
+
12
+ if (
13
+ !from
14
+ .filter(key => to.includes(key))
15
+ .every((key, index) => to[index] === key)
16
+ ) {
17
+ return 'dissimilar';
18
+ }
19
+
20
+ return firstIsLarger ? 'removed' : 'added';
21
+ }
22
+
23
+ export function isChildNode(value: unknown): value is ChildNode {
24
+ return value instanceof CharacterData || value instanceof Element;
25
+ }
3
26
 
4
27
  export function isFragment(value: unknown): value is Fragment {
5
28
  return (
@@ -10,10 +33,6 @@ export function isFragment(value: unknown): value is Fragment {
10
33
  );
11
34
  }
12
35
 
13
- export function isProperElement(value: unknown): value is ProperElement {
36
+ export function isHTMLOrSVGElement(value: unknown): value is HTMLOrSVGElement {
14
37
  return value instanceof HTMLElement || value instanceof SVGElement;
15
38
  }
16
-
17
- export function isProperNode(value: unknown): value is ProperNode {
18
- return value instanceof CharacterData || value instanceof Element;
19
- }
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
+ import '@oscarpalmer/sentinel';
1
2
  export type {Fragment} from './fragment';
2
3
  export {html} from './html';
package/src/models.ts CHANGED
@@ -1,17 +1,24 @@
1
+ import type {Key} from '@oscarpalmer/atoms/models';
2
+ import type {Effect, Reactive} from '@oscarpalmer/sentinel';
1
3
  import type {Fragment} from './fragment';
2
4
 
3
5
  export type FragmentData = {
4
6
  expressions: unknown[];
7
+ identifier?: Key;
5
8
  items: FragmentItem[];
9
+ sentinel: FragmentDataSentinel;
6
10
  strings: TemplateStringsArray;
7
11
  values: unknown[];
8
12
  };
9
13
 
10
- export type FragmentItem = {
11
- fragment?: Fragment;
12
- nodes: ProperNode[];
14
+ type FragmentDataSentinel = {
15
+ effects: Set<Effect>;
16
+ values: Set<Reactive>;
13
17
  };
14
18
 
15
- export type ProperElement = HTMLElement | SVGElement;
19
+ export type FragmentItem = {
20
+ fragments?: Fragment[];
21
+ nodes: ChildNode[];
22
+ };
16
23
 
17
- export type ProperNode = CharacterData | Element;
24
+ export type HTMLOrSVGElement = HTMLElement | SVGElement;
@@ -1,6 +1,6 @@
1
1
  import type {GenericCallback} from '@oscarpalmer/atoms/models';
2
2
  import {computed, isReactive} from '@oscarpalmer/sentinel';
3
- import type {FragmentData, ProperElement} from '../../models';
3
+ import type {FragmentData, HTMLOrSVGElement} from '../../models';
4
4
  import {mapEvent} from '../event';
5
5
  import {setAttribute} from './value';
6
6
 
@@ -14,7 +14,7 @@ function getValue(data: FragmentData, original: string): unknown {
14
14
 
15
15
  export function mapAttributes(
16
16
  data: FragmentData,
17
- element: ProperElement,
17
+ element: HTMLOrSVGElement,
18
18
  ): void {
19
19
  const attributes = [...element.attributes];
20
20
  const {length} = attributes;
@@ -31,19 +31,37 @@ export function mapAttributes(
31
31
  typeof value === 'function' ||
32
32
  isReactive(actual)
33
33
  ) {
34
- mapValue(element, name, actual);
34
+ mapValue(data, element, name, actual);
35
35
  }
36
36
  }
37
37
  }
38
38
 
39
- function mapValue(element: ProperElement, name: string, value: unknown): void {
39
+ function mapValue(
40
+ data: FragmentData,
41
+ element: HTMLOrSVGElement,
42
+ name: string,
43
+ value: unknown,
44
+ ): void {
40
45
  switch (true) {
41
46
  case typeof value === 'function':
42
- setAttribute(element, name, computed(value as GenericCallback));
47
+ setComputedAttribute(data, element, name, value as GenericCallback);
43
48
  break;
44
49
 
45
50
  default:
46
- setAttribute(element, name, value);
51
+ setAttribute(data, element, name, value);
47
52
  break;
48
53
  }
49
54
  }
55
+
56
+ function setComputedAttribute(
57
+ data: FragmentData,
58
+ element: HTMLOrSVGElement,
59
+ name: string,
60
+ callback: GenericCallback,
61
+ ): void {
62
+ const value = computed(callback);
63
+
64
+ data.sentinel.values.add(value);
65
+
66
+ setAttribute(data, element, name, value);
67
+ }
@@ -5,14 +5,15 @@ import {
5
5
  isBooleanAttribute,
6
6
  setAttribute as setAttr,
7
7
  } from '@oscarpalmer/toretto/attribute';
8
- import type {ProperElement} from '../../models';
8
+ import type {FragmentData, HTMLOrSVGElement} from '../../models';
9
9
 
10
10
  const classExpression = /^class\./;
11
11
  const styleFullExpression = /^style\.([\w-]+)(?:\.([\w-]+))?$/;
12
12
  const stylePrefixExpression = /^style\./;
13
13
 
14
14
  export function setAttribute(
15
- element: ProperElement,
15
+ data: FragmentData,
16
+ element: HTMLOrSVGElement,
16
17
  name: string,
17
18
  value: unknown,
18
19
  ): void {
@@ -20,21 +21,22 @@ export function setAttribute(
20
21
 
21
22
  switch (true) {
22
23
  case classExpression.test(name):
23
- setClasses(element, name, value);
24
+ setClasses(data, element, name, value);
24
25
  return;
25
26
 
26
27
  case stylePrefixExpression.test(name):
27
- setStyle(element, name, value);
28
+ setStyle(data, element, name, value);
28
29
  return;
29
30
 
30
31
  default:
31
- setValue(element, name, value);
32
+ setValue(data, element, name, value);
32
33
  break;
33
34
  }
34
35
  }
35
36
 
36
37
  function setClasses(
37
- element: ProperElement,
38
+ data: FragmentData,
39
+ element: HTMLOrSVGElement,
38
40
  name: string,
39
41
  value: unknown,
40
42
  ): void {
@@ -49,15 +51,22 @@ function setClasses(
49
51
  const classes = name.slice(6).split('.');
50
52
 
51
53
  if (isReactive(value)) {
52
- effect(() => {
53
- update(value.get());
54
- });
54
+ data.sentinel.effects.add(
55
+ effect(() => {
56
+ update(value.get());
57
+ }),
58
+ );
55
59
  } else {
56
60
  update(value);
57
61
  }
58
62
  }
59
63
 
60
- function setStyle(element: ProperElement, name: string, value: unknown): void {
64
+ function setStyle(
65
+ data: FragmentData,
66
+ element: HTMLOrSVGElement,
67
+ name: string,
68
+ value: unknown,
69
+ ): void {
61
70
  function update(value: unknown): void {
62
71
  if (value == null || value === false || (value === true && unit == null)) {
63
72
  element.style.removeProperty(property);
@@ -73,16 +82,23 @@ function setStyle(element: ProperElement, name: string, value: unknown): void {
73
82
 
74
83
  if (property != null) {
75
84
  if (isReactive(value)) {
76
- effect(() => {
77
- update(value.get());
78
- });
85
+ data.sentinel.effects.add(
86
+ effect(() => {
87
+ update(value.get());
88
+ }),
89
+ );
79
90
  } else {
80
91
  update(value);
81
92
  }
82
93
  }
83
94
  }
84
95
 
85
- function setValue(element: ProperElement, name: string, value: unknown): void {
96
+ function setValue(
97
+ data: FragmentData,
98
+ element: HTMLOrSVGElement,
99
+ name: string,
100
+ value: unknown,
101
+ ): void {
86
102
  const callback =
87
103
  isBooleanAttribute(name) && name in element
88
104
  ? name === 'selected'
@@ -91,9 +107,11 @@ function setValue(element: ProperElement, name: string, value: unknown): void {
91
107
  : setAttr;
92
108
 
93
109
  if (isReactive(value)) {
94
- effect(() => {
95
- callback(element, name, value.get());
96
- });
110
+ data.sentinel.effects.add(
111
+ effect(() => {
112
+ callback(element, name, value.get());
113
+ }),
114
+ );
97
115
  } else {
98
116
  callback(element, name, value);
99
117
  }
@@ -106,7 +124,7 @@ function triggerSelectChange(select: HTMLSelectElement): void {
106
124
  }
107
125
 
108
126
  function updateProperty(
109
- element: ProperElement,
127
+ element: HTMLOrSVGElement,
110
128
  name: string,
111
129
  value: unknown,
112
130
  ): void {
@@ -114,7 +132,7 @@ function updateProperty(
114
132
  }
115
133
 
116
134
  function updateSelected(
117
- element: ProperElement,
135
+ element: HTMLOrSVGElement,
118
136
  name: string,
119
137
  value: unknown,
120
138
  ): void {