@oscarpalmer/abydon 0.23.1 → 0.24.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/abydon.full.mjs +1503 -1030
- package/dist/attribute/index.d.mts +4 -6
- package/dist/attribute/index.mjs +1 -3
- package/dist/attribute/value.d.mts +3 -5
- package/dist/attribute/value.mjs +2 -4
- package/dist/constants.d.mts +42 -38
- package/dist/constants.mjs +12 -7
- package/dist/fragment.d.mts +31 -57
- package/dist/fragment.mjs +83 -108
- package/dist/fragments.d.mts +28 -11
- package/dist/fragments.mjs +60 -33
- package/dist/helpers/dom.d.mts +4 -5
- package/dist/helpers/index.d.mts +8 -10
- package/dist/helpers/index.mjs +4 -2
- package/dist/index.d.mts +5 -47
- package/dist/index.mjs +4 -53
- package/dist/models.d.mts +84 -14
- package/dist/node/event.d.mts +2 -3
- package/dist/node/index.d.mts +3 -5
- package/dist/node/index.mjs +5 -8
- package/dist/node/value.d.mts +3 -5
- package/dist/node/value.mjs +8 -7
- package/dist/parse.d.mts +3 -5
- package/package.json +14 -14
- package/src/attribute/index.ts +9 -5
- package/src/attribute/value.ts +11 -7
- package/src/constants.ts +24 -8
- package/src/fragment.ts +154 -130
- package/src/fragments.ts +94 -45
- package/src/helpers/dom.ts +4 -0
- package/src/helpers/index.ts +12 -7
- package/src/index.ts +3 -67
- package/src/models.ts +97 -9
- package/src/node/event.ts +4 -0
- package/src/node/index.ts +17 -15
- package/src/node/value.ts +12 -10
- package/src/parse.ts +7 -3
package/src/attribute/index.ts
CHANGED
|
@@ -9,23 +9,25 @@ import {
|
|
|
9
9
|
PROPERTY_VALUE,
|
|
10
10
|
} from '../constants';
|
|
11
11
|
import {setComputedValue} from '../helpers';
|
|
12
|
-
import type {
|
|
12
|
+
import type {FragmentState} from '../models';
|
|
13
13
|
import {mapEvent} from '../node/event';
|
|
14
14
|
import {setAttribute} from './value';
|
|
15
15
|
import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
|
|
16
16
|
|
|
17
|
+
// #region Functions
|
|
18
|
+
|
|
17
19
|
function compareAttributes(first: Attr, second: Attr): number {
|
|
18
20
|
return first.name.localeCompare(second.name);
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
function getValue(data:
|
|
23
|
+
function getValue(data: FragmentState, original: string): unknown {
|
|
22
24
|
const matches = EXPRESSION_ABYDON_CONTENT.exec(original);
|
|
23
25
|
|
|
24
26
|
return matches == null ? original : data.values[+matches[1]];
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
export function mapAttributeValue(
|
|
28
|
-
data:
|
|
30
|
+
data: FragmentState,
|
|
29
31
|
element: HTMLElement | SVGElement,
|
|
30
32
|
name: string,
|
|
31
33
|
value: unknown,
|
|
@@ -44,7 +46,7 @@ export function mapAttributeValue(
|
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
export function mapAttributes(
|
|
47
|
-
data:
|
|
49
|
+
data: FragmentState,
|
|
48
50
|
element: HTMLElement | SVGElement,
|
|
49
51
|
ignoreValue: boolean,
|
|
50
52
|
): void {
|
|
@@ -80,7 +82,7 @@ export function mapAttributes(
|
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
function setComputedAttribute(
|
|
83
|
-
data:
|
|
85
|
+
data: FragmentState,
|
|
84
86
|
element: HTMLElement | SVGElement,
|
|
85
87
|
name: string,
|
|
86
88
|
callback: GenericCallback,
|
|
@@ -89,3 +91,5 @@ function setComputedAttribute(
|
|
|
89
91
|
setAttribute(data, element, name, computation);
|
|
90
92
|
});
|
|
91
93
|
}
|
|
94
|
+
|
|
95
|
+
// #endregion
|
package/src/attribute/value.ts
CHANGED
|
@@ -12,7 +12,9 @@ import {
|
|
|
12
12
|
EXPRESSION_ATTRIBUTE_STYLE_VARIABLE,
|
|
13
13
|
VALUE_TRUE,
|
|
14
14
|
} from '../constants';
|
|
15
|
-
import type {
|
|
15
|
+
import type {FragmentState} from '../models';
|
|
16
|
+
|
|
17
|
+
// #region Functions
|
|
16
18
|
|
|
17
19
|
function getStyleValue(value: unknown, unit: string, isVariable: boolean): string | undefined {
|
|
18
20
|
if (removeStyleValue(value, unit, isVariable)) {
|
|
@@ -31,7 +33,7 @@ function removeStyleValue(value: unknown, unit: unknown, isVariable: boolean): b
|
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
export function setAttribute(
|
|
34
|
-
data:
|
|
36
|
+
data: FragmentState,
|
|
35
37
|
element: HTMLElement | SVGElement,
|
|
36
38
|
name: string,
|
|
37
39
|
value: unknown,
|
|
@@ -52,7 +54,7 @@ export function setAttribute(
|
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
function setClassValues(
|
|
55
|
-
data:
|
|
57
|
+
data: FragmentState,
|
|
56
58
|
element: HTMLElement | SVGElement,
|
|
57
59
|
name: string,
|
|
58
60
|
value: unknown,
|
|
@@ -69,7 +71,7 @@ function setClassValues(
|
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
function setStyleValues(
|
|
72
|
-
data:
|
|
74
|
+
data: FragmentState,
|
|
73
75
|
element: HTMLElement | SVGElement,
|
|
74
76
|
name: string,
|
|
75
77
|
value: unknown,
|
|
@@ -88,7 +90,7 @@ function setStyleValues(
|
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
function setValue(
|
|
91
|
-
data:
|
|
93
|
+
data: FragmentState,
|
|
92
94
|
element: HTMLElement | SVGElement,
|
|
93
95
|
name: string,
|
|
94
96
|
value: unknown,
|
|
@@ -98,10 +100,12 @@ function setValue(
|
|
|
98
100
|
});
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
function updateValue(data:
|
|
103
|
+
function updateValue(data: FragmentState, value: unknown, updater: (value: unknown) => void): void {
|
|
102
104
|
if (isReactive(value)) {
|
|
103
|
-
data.mora.
|
|
105
|
+
data.mora.subscriptions.add(value.subscribe(updater));
|
|
104
106
|
} else {
|
|
105
107
|
updater(value);
|
|
106
108
|
}
|
|
107
109
|
}
|
|
110
|
+
|
|
111
|
+
// #endregion
|
package/src/constants.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// #region Variables
|
|
2
|
+
|
|
1
3
|
export const ARRAY_COMPARISON_ADDED = 'added';
|
|
2
4
|
|
|
3
5
|
export const ARRAY_COMPARISON_DISSIMILAR = 'dissimilar';
|
|
@@ -10,12 +12,6 @@ export const ATTRIBUTE_NAME_DELIMITER = '.';
|
|
|
10
12
|
|
|
11
13
|
export const CHANGE_INPUTS = new Set(['checkbox', 'radio']);
|
|
12
14
|
|
|
13
|
-
export const ERROR_FRAGMENT = 'Fragment function must return a Fragment instance';
|
|
14
|
-
|
|
15
|
-
export const ERROR_IDENTIFIER_DUPLICATE = "Duplicate identifier found: '<>'";
|
|
16
|
-
|
|
17
|
-
export const ERROR_IDENTIFIER_TYPE = 'Identifier cannot be null or undefined';
|
|
18
|
-
|
|
19
15
|
export const EVENT_CHANGE = 'change';
|
|
20
16
|
|
|
21
17
|
export const EVENT_INPUT = 'input';
|
|
@@ -63,16 +59,36 @@ export const EXPRESSION_EVENT_PREFIX = /^@/;
|
|
|
63
59
|
|
|
64
60
|
export const EXPRESSION_TEXTAREA_VALUE = /(?:<|<)!--abydon\.(\d+)--(?:>|>)/;
|
|
65
61
|
|
|
66
|
-
export const
|
|
62
|
+
export const MESSAGE_FRAGMENT_VALUE =
|
|
63
|
+
'Fragment template must be a string or a template strings array';
|
|
64
|
+
|
|
65
|
+
export const MESSAGE_FRAGMENTS_FRAGMENT_RESULT =
|
|
66
|
+
'Fragment function must return a Fragment instance';
|
|
67
|
+
|
|
68
|
+
export const MESSAGE_FRAGMENTS_FRAGMENT_TYPE = 'Fragment handler must be a function';
|
|
69
|
+
|
|
70
|
+
export const MESSAGE_FRAGMENTS_IDENTIFIER_RESULT_DUPLICATE = "Duplicate identifier found: '<>'";
|
|
67
71
|
|
|
68
|
-
export const
|
|
72
|
+
export const MESSAGE_FRAGMENTS_IDENTIFIER_RESULT_TYPE = 'Identifier cannot be null or undefined';
|
|
73
|
+
|
|
74
|
+
export const MESSAGE_FRAGMENTS_IDENTIFIER_TYPE = 'Identifier handler must be a function';
|
|
75
|
+
|
|
76
|
+
export const MESSAGE_FRAGMENTS_VALUE = 'Fragments array must be a reactive array';
|
|
77
|
+
|
|
78
|
+
export const NAME_FRAGMENT = 'fragment';
|
|
79
|
+
|
|
80
|
+
export const NAME_FRAGMENTS = 'fragments';
|
|
69
81
|
|
|
70
82
|
export const PROPERTY_IDENTIFIER = 'identifier';
|
|
71
83
|
|
|
72
84
|
export const PROPERTY_VALUE = 'value';
|
|
73
85
|
|
|
86
|
+
export const SYMBOL = Symbol('abydon');
|
|
87
|
+
|
|
74
88
|
export const TEMPLATE_ITEM = '<>';
|
|
75
89
|
|
|
76
90
|
export const VALUE_TRUE = 'true';
|
|
77
91
|
|
|
78
92
|
export const WHITESPACE = /\s+/g;
|
|
93
|
+
|
|
94
|
+
// #endregion
|
package/src/fragment.ts
CHANGED
|
@@ -1,158 +1,174 @@
|
|
|
1
|
-
import {isPlainObject} from '@oscarpalmer/atoms/is';
|
|
1
|
+
import {isNonTemplateStringsArray, isPlainObject} from '@oscarpalmer/atoms/is';
|
|
2
2
|
import {html} from '@oscarpalmer/toretto/html';
|
|
3
|
-
import {NAME_FRAGMENT, PROPERTY_IDENTIFIER} from './constants';
|
|
3
|
+
import {MESSAGE_FRAGMENT_VALUE, NAME_FRAGMENT, PROPERTY_IDENTIFIER, SYMBOL} from './constants';
|
|
4
4
|
import {handleFragments} from './fragments';
|
|
5
5
|
import {isFragments} from './helpers';
|
|
6
6
|
import {removeNodes} from './helpers/dom';
|
|
7
|
-
import type {FragmentConfiguration,
|
|
7
|
+
import type {Fragment, FragmentConfiguration, FragmentState, InternalFragment} from './models';
|
|
8
8
|
import {mapNodes} from './node';
|
|
9
9
|
import {parse} from './parse';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
readonly #data: FragmentData;
|
|
11
|
+
// #region Instances
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
function Fragment(this: any, strings: TemplateStringsArray, expressions: unknown[]) {
|
|
14
|
+
this[SYMBOL] = {
|
|
15
|
+
expressions,
|
|
16
|
+
strings,
|
|
16
17
|
cache: true,
|
|
18
|
+
identifier: undefined,
|
|
19
|
+
items: [],
|
|
20
|
+
mora: {
|
|
21
|
+
subscriptions: new Set(),
|
|
22
|
+
values: new Set(),
|
|
23
|
+
},
|
|
24
|
+
name: NAME_FRAGMENT,
|
|
25
|
+
values: [],
|
|
17
26
|
};
|
|
27
|
+
}
|
|
18
28
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
Fragment.prototype.after = insertFragmentAfter;
|
|
30
|
+
Fragment.prototype.appendTo = appendFragmentTo;
|
|
31
|
+
Fragment.prototype.before = insertFragmentBefore;
|
|
32
|
+
Fragment.prototype.configure = configureFragment;
|
|
33
|
+
Fragment.prototype.get = getFragmentNodes;
|
|
34
|
+
Fragment.prototype.prependTo = prependFragmentTo;
|
|
35
|
+
Fragment.prototype.remove = removeFragment;
|
|
36
|
+
|
|
37
|
+
Object.defineProperties(Fragment.prototype, {
|
|
38
|
+
cache: {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
get: getFragmentCache,
|
|
41
|
+
},
|
|
42
|
+
identifier: {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: getFragmentIdentifier,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// #endregion
|
|
49
|
+
|
|
50
|
+
// #region Functions
|
|
51
|
+
|
|
52
|
+
function appendFragmentTo(this: InternalFragment, element: Element): void {
|
|
53
|
+
element.append(...this.get());
|
|
54
|
+
}
|
|
25
55
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
get identifier(): unknown {
|
|
32
|
-
return this.#configuration.identifier;
|
|
33
|
-
}
|
|
56
|
+
function configureFragment(
|
|
57
|
+
this: InternalFragment,
|
|
58
|
+
configuration: FragmentConfiguration,
|
|
59
|
+
): InternalFragment {
|
|
60
|
+
const state = this[SYMBOL];
|
|
34
61
|
|
|
35
|
-
|
|
36
|
-
Object.defineProperty(this, NAME_FRAGMENT, {
|
|
37
|
-
value: true,
|
|
38
|
-
});
|
|
62
|
+
const actual = isPlainObject(configuration) ? configuration : {};
|
|
39
63
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
strings,
|
|
43
|
-
items: [],
|
|
44
|
-
mora: {
|
|
45
|
-
subscribers: new Set(),
|
|
46
|
-
values: new Set(),
|
|
47
|
-
},
|
|
48
|
-
values: [],
|
|
49
|
-
};
|
|
64
|
+
if (PROPERTY_IDENTIFIER in actual) {
|
|
65
|
+
state.identifier = actual.identifier;
|
|
50
66
|
}
|
|
51
67
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
* @param element Element to insert after
|
|
55
|
-
*/
|
|
56
|
-
after(element: Element): void {
|
|
57
|
-
element.after(...this.get());
|
|
68
|
+
if (typeof actual.cache === 'boolean') {
|
|
69
|
+
state.cache = actual.cache;
|
|
58
70
|
}
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
* @param element Element to append to
|
|
63
|
-
*/
|
|
64
|
-
appendTo(element: Element): void {
|
|
65
|
-
element.append(...this.get());
|
|
66
|
-
}
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
67
74
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Create a _Fragment_ from a template
|
|
77
|
+
*
|
|
78
|
+
* _A Fragment can be used to efficiently render a template that may change over time, only updating the necessary parts of the DOM._
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* const name = signal('World');
|
|
83
|
+
* const fragment = fragment`<p>Hello, ${name}!</p>`; // or `html`<p>Hello, ${name}!</p>`
|
|
84
|
+
* fragment.appendTo(document.body); // Renders '<p>Hello, World!</p>'
|
|
85
|
+
* name.set('Alice'); // Replaces 'World' with 'Alice'
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @returns _Fragment_
|
|
89
|
+
*/
|
|
90
|
+
export function fragment(template: TemplateStringsArray, ...values: unknown[]): Fragment;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Create a _Fragment_ from a simple template
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* const fragment = fragment('<p>Hello, World!</p>'); // or `html`('<p>Hello, World!</p>')
|
|
98
|
+
* fragment.appendTo(document.body); // Renders '<p>Hello, World!</p>'
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @returns _Fragment_
|
|
102
|
+
*/
|
|
103
|
+
export function fragment(template: string): Fragment;
|
|
104
|
+
|
|
105
|
+
export function fragment(template: string | TemplateStringsArray, ...values: unknown[]): Fragment {
|
|
106
|
+
if (typeof template !== 'string' && isNonTemplateStringsArray(template)) {
|
|
107
|
+
throw new TypeError(MESSAGE_FRAGMENT_VALUE);
|
|
74
108
|
}
|
|
75
109
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
* _Returns the Fragment instance for chaining_
|
|
80
|
-
* @param configuration Configuration options
|
|
81
|
-
* @returns _Fragment_
|
|
82
|
-
*/
|
|
83
|
-
configure(configuration: FragmentConfiguration): Fragment {
|
|
84
|
-
const actual = isPlainObject(configuration) ? configuration : {};
|
|
85
|
-
|
|
86
|
-
if (PROPERTY_IDENTIFIER in actual) {
|
|
87
|
-
this.#configuration.identifier = actual.identifier;
|
|
88
|
-
}
|
|
110
|
+
// @ts-expect-error All good, no worries :-)
|
|
111
|
+
return new Fragment(template, values);
|
|
112
|
+
}
|
|
89
113
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
114
|
+
function getFragmentCache(this: InternalFragment): boolean {
|
|
115
|
+
return this[SYMBOL].cache;
|
|
116
|
+
}
|
|
93
117
|
|
|
94
|
-
|
|
95
|
-
|
|
118
|
+
function getFragmentIdentifier(this: InternalFragment): unknown {
|
|
119
|
+
return this[SYMBOL].identifier;
|
|
120
|
+
}
|
|
96
121
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const data = this.#data;
|
|
103
|
-
|
|
104
|
-
if (data.items.length === 0) {
|
|
105
|
-
const parsed = parse(data);
|
|
106
|
-
|
|
107
|
-
const templated = html(parsed, {
|
|
108
|
-
cache: this.#configuration.cache,
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
data.items.splice(
|
|
112
|
-
0,
|
|
113
|
-
data.items.length,
|
|
114
|
-
...templated.map(node => ({
|
|
115
|
-
nodes: [node as ChildNode],
|
|
116
|
-
})),
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
mapNodes(
|
|
120
|
-
data,
|
|
121
|
-
data.items.flatMap(item => item.nodes!),
|
|
122
|
-
);
|
|
123
|
-
}
|
|
122
|
+
function getFragmentNodes(this: InternalFragment): ChildNode[] {
|
|
123
|
+
const state = this[SYMBOL];
|
|
124
|
+
|
|
125
|
+
if (state.items.length === 0) {
|
|
126
|
+
const parsed = parse(state);
|
|
124
127
|
|
|
125
|
-
|
|
126
|
-
|
|
128
|
+
const templated = html(parsed, {
|
|
129
|
+
cache: state.cache,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
state.items.splice(
|
|
133
|
+
0,
|
|
134
|
+
state.items.length,
|
|
135
|
+
...templated.map(node => ({
|
|
136
|
+
nodes: [node as ChildNode],
|
|
137
|
+
})),
|
|
127
138
|
);
|
|
128
|
-
}
|
|
129
139
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
prependTo(element: Element): void {
|
|
135
|
-
element.prepend(...this.get());
|
|
140
|
+
mapNodes(
|
|
141
|
+
state,
|
|
142
|
+
state.items.flatMap(item => item.nodes!),
|
|
143
|
+
);
|
|
136
144
|
}
|
|
137
145
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
return state.items.flatMap(
|
|
147
|
+
item => item.fragments?.flatMap(fragment => fragment.get()) ?? item.nodes!,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function insertFragmentAfter(this: InternalFragment, element: Element): void {
|
|
152
|
+
element.after(...this.get());
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function insertFragmentBefore(this: InternalFragment, element: Element): void {
|
|
156
|
+
element.before(...this.get());
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function prependFragmentTo(this: InternalFragment, element: Element): void {
|
|
160
|
+
element.prepend(...this.get());
|
|
147
161
|
}
|
|
148
162
|
|
|
149
|
-
function removeFragment(
|
|
150
|
-
|
|
163
|
+
function removeFragment(this: InternalFragment): void {
|
|
164
|
+
const state = this[SYMBOL];
|
|
165
|
+
|
|
166
|
+
removeMora(state);
|
|
151
167
|
|
|
152
|
-
let {length} =
|
|
168
|
+
let {length} = state.items;
|
|
153
169
|
|
|
154
170
|
for (let index = 0; index < length; index += 1) {
|
|
155
|
-
const {fragments, nodes} =
|
|
171
|
+
const {fragments, nodes} = state.items[index];
|
|
156
172
|
const fragmentsLength = fragments?.length ?? 0;
|
|
157
173
|
|
|
158
174
|
for (let fragmentIndex = 0; fragmentIndex < fragmentsLength; fragmentIndex += 1) {
|
|
@@ -162,12 +178,12 @@ function removeFragment(data: FragmentData): void {
|
|
|
162
178
|
removeNodes(nodes!);
|
|
163
179
|
}
|
|
164
180
|
|
|
165
|
-
|
|
181
|
+
state.items.length = 0;
|
|
166
182
|
|
|
167
|
-
length =
|
|
183
|
+
length = state.values.length;
|
|
168
184
|
|
|
169
185
|
for (let index = 0; index < length; index += 1) {
|
|
170
|
-
const value =
|
|
186
|
+
const value = state.values[index];
|
|
171
187
|
|
|
172
188
|
if (isFragments(value)) {
|
|
173
189
|
handleFragments(value, true);
|
|
@@ -175,13 +191,21 @@ function removeFragment(data: FragmentData): void {
|
|
|
175
191
|
}
|
|
176
192
|
}
|
|
177
193
|
|
|
178
|
-
function removeMora(
|
|
179
|
-
const
|
|
194
|
+
function removeMora(state: FragmentState): void {
|
|
195
|
+
const subscriptions = [...state.mora.subscriptions];
|
|
180
196
|
|
|
181
|
-
|
|
182
|
-
|
|
197
|
+
state.mora.subscriptions.clear();
|
|
198
|
+
state.mora.values.clear();
|
|
183
199
|
|
|
184
|
-
for (const
|
|
185
|
-
unsubscribe();
|
|
200
|
+
for (const subscription of subscriptions) {
|
|
201
|
+
subscription.unsubscribe();
|
|
186
202
|
}
|
|
187
203
|
}
|
|
204
|
+
|
|
205
|
+
// #endregion
|
|
206
|
+
|
|
207
|
+
// #region Exports
|
|
208
|
+
|
|
209
|
+
export {fragment as html};
|
|
210
|
+
|
|
211
|
+
// #endregion
|