@esportsplus/template 0.17.0 → 0.19.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.
Potentially problematic release.
This version of @esportsplus/template might be problematic. Click here for more details.
- package/build/attributes.js +4 -4
- package/build/constants.d.ts +2 -9
- package/build/constants.js +3 -10
- package/build/event.js +47 -45
- package/build/html/index.d.ts +3 -2106
- package/build/html/index.js +34 -8
- package/build/html/{cache.d.ts → parser.d.ts} +1 -1
- package/build/html/{cache.js → parser.js} +13 -7
- package/build/index.d.ts +1 -1
- package/build/render.js +3 -2
- package/build/slot/cleanup.js +2 -1
- package/build/slot/effect.js +22 -17
- package/build/slot/index.js +4 -9
- package/build/slot/reactive.d.ts +1 -1
- package/build/slot/reactive.js +26 -16
- package/build/slot/render.d.ts +2 -2
- package/build/slot/render.js +24 -45
- package/build/types.d.ts +5 -13
- package/build/utilities/element.d.ts +11 -0
- package/build/utilities/element.js +9 -0
- package/build/utilities/fragment.d.ts +3 -0
- package/build/utilities/fragment.js +11 -0
- package/build/utilities/node.d.ts +9 -0
- package/build/utilities/node.js +10 -0
- package/build/utilities/queue.d.ts +3 -0
- package/build/utilities/queue.js +4 -0
- package/build/utilities/text.d.ts +2 -0
- package/build/utilities/text.js +9 -0
- package/package.json +2 -2
- package/src/attributes.ts +23 -26
- package/src/constants.ts +3 -20
- package/src/event.ts +55 -52
- package/src/html/index.ts +50 -11
- package/src/html/{cache.ts → parser.ts} +15 -7
- package/src/index.ts +1 -1
- package/src/render.ts +3 -3
- package/src/slot/cleanup.ts +3 -4
- package/src/slot/effect.ts +33 -35
- package/src/slot/index.ts +6 -16
- package/src/slot/reactive.ts +33 -23
- package/src/slot/render.ts +28 -59
- package/src/types.ts +6 -19
- package/src/utilities/element.ts +28 -0
- package/src/utilities/fragment.ts +21 -0
- package/src/utilities/node.ts +29 -0
- package/src/utilities/queue.ts +9 -0
- package/src/utilities/text.ts +15 -0
- package/build/html/hydrate.d.ts +0 -3
- package/build/html/hydrate.js +0 -34
- package/build/utilities.d.ts +0 -28
- package/build/utilities.js +0 -37
- package/src/html/hydrate.ts +0 -53
- package/src/utilities.ts +0 -89
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactiveArray } from '@esportsplus/reactivity';
|
|
2
|
-
import { RENDERABLE,
|
|
3
|
-
import { firstChild } from './utilities';
|
|
2
|
+
import { RENDERABLE, RENDERABLE_HTML_REACTIVE_ARRAY } from './constants';
|
|
3
|
+
import { firstChild } from './utilities/node';
|
|
4
4
|
import attributes from './attributes';
|
|
5
5
|
import slot from './slot';
|
|
6
6
|
import html from './html';
|
|
@@ -29,15 +29,11 @@ type EffectResponse<T> = T extends [] ? (Primitive | Renderable)[] : Primitive |
|
|
|
29
29
|
|
|
30
30
|
type Element = HTMLElement & Attributes & Record<PropertyKey, unknown>;
|
|
31
31
|
|
|
32
|
-
type Elements = Element[];
|
|
33
|
-
|
|
34
|
-
type Fragment = (DocumentFragment | Node) & Record<PropertyKey, unknown>;
|
|
35
|
-
|
|
36
32
|
// Copied from '@esportsplus/utilities'
|
|
37
33
|
// - Importing from ^ causes 'cannot be named without a reference to...' error
|
|
38
34
|
type Primitive = bigint | boolean | null | number | string | undefined;
|
|
39
35
|
|
|
40
|
-
type Renderable =
|
|
36
|
+
type Renderable = DocumentFragment | Node | NodeList | Primitive | RenderableReactive | Renderable[];
|
|
41
37
|
|
|
42
38
|
type RenderableReactive = Readonly<{
|
|
43
39
|
[RENDERABLE]: typeof RENDERABLE_HTML_REACTIVE_ARRAY;
|
|
@@ -48,15 +44,7 @@ type RenderableReactive = Readonly<{
|
|
|
48
44
|
) => ReturnType<typeof html>;
|
|
49
45
|
}>;
|
|
50
46
|
|
|
51
|
-
type
|
|
52
|
-
[RENDERABLE]: typeof RENDERABLE_HTML_FRAGMENT;
|
|
53
|
-
fragment: Fragment;
|
|
54
|
-
literals: TemplateStringsArray;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
type RenderableValue<T = unknown> = Attributes | Readonly<Attributes> | Readonly<Attributes[]> | Effect<T> | Fragment | Primitive | RenderableReactive;
|
|
58
|
-
|
|
59
|
-
type RenderableValues = RenderableValue | RenderableValue[];
|
|
47
|
+
type RenderableValue<T = unknown> = Attributes | Readonly<Attributes> | Readonly<Attributes[]> | Effect<T> | Primitive | RenderableReactive;
|
|
60
48
|
|
|
61
49
|
type SlotGroup = {
|
|
62
50
|
head: Element;
|
|
@@ -81,9 +69,8 @@ type Template = {
|
|
|
81
69
|
|
|
82
70
|
export type {
|
|
83
71
|
Attributes,
|
|
84
|
-
Effect, Element,
|
|
85
|
-
|
|
86
|
-
Renderable, RenderableReactive, RenderableTemplate, RenderableValue, RenderableValues,
|
|
72
|
+
Effect, Element,
|
|
73
|
+
Renderable, RenderableReactive, RenderableValue,
|
|
87
74
|
SlotGroup,
|
|
88
75
|
Template
|
|
89
76
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
|
|
2
|
+
prototype = Element.prototype;
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const addEventListener = prototype.addEventListener;
|
|
6
|
+
|
|
7
|
+
const className = getOwnPropertyDescriptor(prototype, 'className')!.set!;
|
|
8
|
+
|
|
9
|
+
const innerHTML = getOwnPropertyDescriptor(prototype, 'innerHTML')!.set!;
|
|
10
|
+
|
|
11
|
+
const firstElementChild = getOwnPropertyDescriptor(prototype, 'firstElementChild')!.get!;
|
|
12
|
+
|
|
13
|
+
const nextElementSibling = getOwnPropertyDescriptor(prototype, 'nextElementSibling')!.get!;
|
|
14
|
+
|
|
15
|
+
const removeAttribute = prototype.removeAttribute;
|
|
16
|
+
|
|
17
|
+
const setAttribute = prototype.setAttribute;
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
addEventListener,
|
|
22
|
+
className,
|
|
23
|
+
innerHTML,
|
|
24
|
+
firstElementChild,
|
|
25
|
+
nextElementSibling,
|
|
26
|
+
removeAttribute,
|
|
27
|
+
setAttribute
|
|
28
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { innerHTML } from './element';
|
|
2
|
+
import { cloneNode } from './node';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
let scratchpad = document.createElement('template');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
const append = DocumentFragment.prototype.append;
|
|
9
|
+
|
|
10
|
+
const fragment = (html: string): DocumentFragment => {
|
|
11
|
+
innerHTML.call(scratchpad, html);
|
|
12
|
+
|
|
13
|
+
let content = scratchpad.content;
|
|
14
|
+
|
|
15
|
+
scratchpad = cloneNode.call(scratchpad) as HTMLTemplateElement;
|
|
16
|
+
|
|
17
|
+
return content;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
export { append, fragment };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
|
|
2
|
+
prototype = Node.prototype;
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const appendChild = prototype.appendChild;
|
|
6
|
+
|
|
7
|
+
const cloneNode = prototype.cloneNode;
|
|
8
|
+
|
|
9
|
+
const firstChild = getOwnPropertyDescriptor(prototype, 'firstChild')!.get!;
|
|
10
|
+
|
|
11
|
+
const lastChild = getOwnPropertyDescriptor(prototype, 'lastChild')!.get!;
|
|
12
|
+
|
|
13
|
+
const nextSibling = getOwnPropertyDescriptor(prototype, 'nextSibling')!.get!;
|
|
14
|
+
|
|
15
|
+
const nodeValue = getOwnPropertyDescriptor(prototype, 'nodeValue')!.set!;
|
|
16
|
+
|
|
17
|
+
const parentElement = getOwnPropertyDescriptor(prototype, 'parentElement')!.get!;
|
|
18
|
+
|
|
19
|
+
const previousSibling = getOwnPropertyDescriptor(prototype, 'previousSibling')!.get!;
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
appendChild,
|
|
24
|
+
cloneNode,
|
|
25
|
+
firstChild,
|
|
26
|
+
lastChild,
|
|
27
|
+
nextSibling, nodeValue,
|
|
28
|
+
parentElement, previousSibling
|
|
29
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { cloneNode, nodeValue } from './node';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
let text = document.createTextNode('');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export default (value: string) => {
|
|
8
|
+
let element = cloneNode.call(text);
|
|
9
|
+
|
|
10
|
+
if (value !== '') {
|
|
11
|
+
nodeValue.call(element, value);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return element;
|
|
15
|
+
};
|
package/build/html/hydrate.d.ts
DELETED
package/build/html/hydrate.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { cloneNode } from '../utilities.js';
|
|
2
|
-
export default ({ fragment, slots }, values) => {
|
|
3
|
-
let clone = cloneNode.call(fragment, true);
|
|
4
|
-
if (slots === null) {
|
|
5
|
-
return clone;
|
|
6
|
-
}
|
|
7
|
-
let node, nodePath, parent, parentPath;
|
|
8
|
-
for (let i = 0, n = slots.length; i < n; i++) {
|
|
9
|
-
let { fn, path, slot } = slots[i], pp = path.parent, pr = path.relative;
|
|
10
|
-
if (pp !== parentPath) {
|
|
11
|
-
if (pp === nodePath) {
|
|
12
|
-
parent = node;
|
|
13
|
-
parentPath = nodePath;
|
|
14
|
-
nodePath = undefined;
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
parent = clone;
|
|
18
|
-
parentPath = pp;
|
|
19
|
-
for (let i = 0, n = pp.length; i < n; i++) {
|
|
20
|
-
parent = pp[i].call(parent);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
if (pr !== nodePath) {
|
|
25
|
-
node = parent;
|
|
26
|
-
nodePath = path.absolute;
|
|
27
|
-
for (let i = 0, n = pr.length; i < n; i++) {
|
|
28
|
-
node = pr[i].call(node);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
fn(node, values[slot]);
|
|
32
|
-
}
|
|
33
|
-
return clone;
|
|
34
|
-
};
|
package/build/utilities.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Element as E } from './types.js';
|
|
2
|
-
declare const append: (...nodes: (Node | string)[]) => void;
|
|
3
|
-
declare const addEventListener: {
|
|
4
|
-
<K extends keyof ElementEventMap>(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
5
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
6
|
-
};
|
|
7
|
-
declare const removeEventListener: {
|
|
8
|
-
<K extends keyof ElementEventMap>(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
9
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
10
|
-
};
|
|
11
|
-
declare const className: (v: any) => void;
|
|
12
|
-
declare const innerHTML: (v: any) => void;
|
|
13
|
-
declare const firstElementChild: () => any;
|
|
14
|
-
declare const nextElementSibling: () => any;
|
|
15
|
-
declare const removeAttribute: (qualifiedName: string) => void;
|
|
16
|
-
declare const setAttribute: (qualifiedName: string, value: string) => void;
|
|
17
|
-
declare const cloneNode: (subtree?: boolean) => Node;
|
|
18
|
-
declare const firstChild: () => any;
|
|
19
|
-
declare const lastChild: () => any;
|
|
20
|
-
declare const nextSibling: () => any;
|
|
21
|
-
declare const nodeValue: (v: any) => void;
|
|
22
|
-
declare const parentElement: () => any;
|
|
23
|
-
declare const previousSibling: () => any;
|
|
24
|
-
declare const fragment: (html: string) => DocumentFragment;
|
|
25
|
-
declare const microtask: import("@esportsplus/tasks/build/factory").Scheduler;
|
|
26
|
-
declare const raf: import("@esportsplus/tasks/build/factory").Scheduler;
|
|
27
|
-
declare const text: (value: string) => E;
|
|
28
|
-
export { addEventListener, append, className, cloneNode, firstChild, firstElementChild, fragment, innerHTML, lastChild, microtask, nextElementSibling, nextSibling, nodeValue, parentElement, previousSibling, raf, removeAttribute, removeEventListener, setAttribute, text };
|
package/build/utilities.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { micro as m, raf as r } from '@esportsplus/tasks';
|
|
2
|
-
let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, prototype, template = document.createElement('template'), t = document.createTextNode('');
|
|
3
|
-
prototype = DocumentFragment.prototype;
|
|
4
|
-
const append = prototype.append;
|
|
5
|
-
prototype = Element.prototype;
|
|
6
|
-
const addEventListener = prototype.addEventListener;
|
|
7
|
-
const removeEventListener = prototype.removeEventListener;
|
|
8
|
-
const className = getOwnPropertyDescriptor(prototype, 'className').set;
|
|
9
|
-
const innerHTML = getOwnPropertyDescriptor(prototype, 'innerHTML').set;
|
|
10
|
-
const firstElementChild = getOwnPropertyDescriptor(prototype, 'firstElementChild').get;
|
|
11
|
-
const nextElementSibling = getOwnPropertyDescriptor(prototype, 'nextElementSibling').get;
|
|
12
|
-
const removeAttribute = prototype.removeAttribute;
|
|
13
|
-
const setAttribute = prototype.setAttribute;
|
|
14
|
-
prototype = Node.prototype;
|
|
15
|
-
const cloneNode = prototype.cloneNode;
|
|
16
|
-
const firstChild = getOwnPropertyDescriptor(prototype, 'firstChild').get;
|
|
17
|
-
const lastChild = getOwnPropertyDescriptor(prototype, 'lastChild').get;
|
|
18
|
-
const nextSibling = getOwnPropertyDescriptor(prototype, 'nextSibling').get;
|
|
19
|
-
const nodeValue = getOwnPropertyDescriptor(prototype, 'nodeValue').set;
|
|
20
|
-
const parentElement = getOwnPropertyDescriptor(prototype, 'parentElement').get;
|
|
21
|
-
const previousSibling = getOwnPropertyDescriptor(prototype, 'previousSibling').get;
|
|
22
|
-
const fragment = (html) => {
|
|
23
|
-
innerHTML.call(template, html);
|
|
24
|
-
let { content } = template;
|
|
25
|
-
template = cloneNode.call(template);
|
|
26
|
-
return content;
|
|
27
|
-
};
|
|
28
|
-
const microtask = m();
|
|
29
|
-
const raf = r();
|
|
30
|
-
const text = (value) => {
|
|
31
|
-
let element = cloneNode.call(t);
|
|
32
|
-
if (value !== '') {
|
|
33
|
-
nodeValue.call(element, value);
|
|
34
|
-
}
|
|
35
|
-
return element;
|
|
36
|
-
};
|
|
37
|
-
export { addEventListener, append, className, cloneNode, firstChild, firstElementChild, fragment, innerHTML, lastChild, microtask, nextElementSibling, nextSibling, nodeValue, parentElement, previousSibling, raf, removeAttribute, removeEventListener, setAttribute, text };
|
package/src/html/hydrate.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { Fragment, RenderableValues, Template } from '~/types';
|
|
2
|
-
import { cloneNode } from '~/utilities';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export default ({ fragment, slots }: Template, values: RenderableValues[]): Fragment => {
|
|
6
|
-
let clone = cloneNode.call(fragment, true);
|
|
7
|
-
|
|
8
|
-
if (slots === null) {
|
|
9
|
-
return clone as Fragment;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
let node,
|
|
13
|
-
nodePath,
|
|
14
|
-
parent,
|
|
15
|
-
parentPath;
|
|
16
|
-
|
|
17
|
-
for (let i = 0, n = slots.length; i < n; i++) {
|
|
18
|
-
let { fn, path, slot } = slots[i],
|
|
19
|
-
pp = path.parent,
|
|
20
|
-
pr = path.relative;
|
|
21
|
-
|
|
22
|
-
if (pp !== parentPath) {
|
|
23
|
-
if (pp === nodePath) {
|
|
24
|
-
parent = node;
|
|
25
|
-
parentPath = nodePath;
|
|
26
|
-
|
|
27
|
-
nodePath = undefined;
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
parent = clone;
|
|
31
|
-
parentPath = pp;
|
|
32
|
-
|
|
33
|
-
for (let i = 0, n = pp.length; i < n; i++) {
|
|
34
|
-
parent = pp[i].call(parent);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (pr !== nodePath) {
|
|
40
|
-
node = parent;
|
|
41
|
-
nodePath = path.absolute;
|
|
42
|
-
|
|
43
|
-
for (let i = 0, n = pr.length; i < n; i++) {
|
|
44
|
-
node = pr[i].call(node);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// @ts-ignore
|
|
49
|
-
fn(node, values[slot]);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return clone as Fragment;
|
|
53
|
-
}
|
package/src/utilities.ts
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { micro as m, raf as r } from '@esportsplus/tasks';
|
|
2
|
-
import { Element as E } from './types';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
|
|
6
|
-
prototype,
|
|
7
|
-
template = document.createElement('template'),
|
|
8
|
-
t = document.createTextNode('');
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
prototype = DocumentFragment.prototype;
|
|
12
|
-
|
|
13
|
-
const append = prototype.append
|
|
14
|
-
|
|
15
|
-
// https://github.com/localvoid/ivi/blob/master/packages/ivi/src/client/core.ts#L38
|
|
16
|
-
prototype = Element.prototype;
|
|
17
|
-
|
|
18
|
-
const addEventListener = prototype.addEventListener;
|
|
19
|
-
|
|
20
|
-
const removeEventListener = prototype.removeEventListener;
|
|
21
|
-
|
|
22
|
-
const className = getOwnPropertyDescriptor(prototype, 'className')!.set!;
|
|
23
|
-
|
|
24
|
-
const innerHTML = getOwnPropertyDescriptor(prototype, 'innerHTML')!.set!;
|
|
25
|
-
|
|
26
|
-
const firstElementChild = getOwnPropertyDescriptor(prototype, 'firstElementChild')!.get!;
|
|
27
|
-
|
|
28
|
-
const nextElementSibling = getOwnPropertyDescriptor(prototype, 'nextElementSibling')!.get!;
|
|
29
|
-
|
|
30
|
-
const removeAttribute = prototype.removeAttribute;
|
|
31
|
-
|
|
32
|
-
const setAttribute = prototype.setAttribute;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
prototype = Node.prototype;
|
|
36
|
-
|
|
37
|
-
const cloneNode = prototype.cloneNode;
|
|
38
|
-
|
|
39
|
-
const firstChild = getOwnPropertyDescriptor(prototype, 'firstChild')!.get!;
|
|
40
|
-
|
|
41
|
-
const lastChild = getOwnPropertyDescriptor(prototype, 'lastChild')!.get!;
|
|
42
|
-
|
|
43
|
-
const nextSibling = getOwnPropertyDescriptor(prototype, 'nextSibling')!.get!;
|
|
44
|
-
|
|
45
|
-
const nodeValue = getOwnPropertyDescriptor(prototype, 'nodeValue')!.set!;
|
|
46
|
-
|
|
47
|
-
const parentElement = getOwnPropertyDescriptor(prototype, 'parentElement')!.get!;
|
|
48
|
-
|
|
49
|
-
const previousSibling = getOwnPropertyDescriptor(prototype, 'previousSibling')!.get!;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const fragment = (html: string) => {
|
|
53
|
-
innerHTML.call(template, html);
|
|
54
|
-
|
|
55
|
-
let { content } = template;
|
|
56
|
-
|
|
57
|
-
template = cloneNode.call(template) as HTMLTemplateElement;
|
|
58
|
-
|
|
59
|
-
return content;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const microtask = m();
|
|
63
|
-
|
|
64
|
-
const raf = r();
|
|
65
|
-
|
|
66
|
-
const text = (value: string) => {
|
|
67
|
-
let element = cloneNode.call(t);
|
|
68
|
-
|
|
69
|
-
if (value !== '') {
|
|
70
|
-
nodeValue.call(element, value);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return element as E;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
export {
|
|
78
|
-
addEventListener, append,
|
|
79
|
-
className, cloneNode,
|
|
80
|
-
firstChild, firstElementChild, fragment,
|
|
81
|
-
innerHTML,
|
|
82
|
-
lastChild,
|
|
83
|
-
microtask,
|
|
84
|
-
nextElementSibling, nextSibling, nodeValue,
|
|
85
|
-
parentElement, previousSibling,
|
|
86
|
-
raf, removeAttribute, removeEventListener,
|
|
87
|
-
setAttribute,
|
|
88
|
-
text
|
|
89
|
-
};
|