@oscarpalmer/abydon 0.15.0 → 0.17.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 +1443 -0
- package/dist/constants.d.mts +20 -0
- package/dist/constants.mjs +27 -0
- package/dist/fragment-9qTBAvtR.d.mts +82 -0
- package/dist/fragment.d.mts +2 -0
- package/dist/{fragment.js → fragment.mjs} +41 -14
- package/dist/fragments.d.mts +16 -0
- package/dist/{fragments.js → fragments.mjs} +10 -4
- package/dist/helpers/dom.d.mts +6 -0
- package/dist/helpers/{dom.js → dom.mjs} +4 -12
- package/dist/helpers/index.d.mts +9 -0
- package/dist/helpers/index.mjs +23 -0
- package/dist/index.d.mts +21 -0
- package/dist/index.mjs +24 -0
- package/dist/models.d.mts +2 -0
- package/dist/models.mjs +1 -0
- package/dist/node/attribute/index.d.mts +6 -0
- package/dist/node/attribute/index.mjs +41 -0
- package/dist/node/attribute/value.d.mts +6 -0
- package/dist/node/attribute/value.mjs +65 -0
- package/dist/node/event.d.mts +4 -0
- package/dist/node/event.mjs +25 -0
- package/dist/node/index.d.mts +6 -0
- package/dist/node/{index.js → index.mjs} +10 -8
- package/dist/node/value.d.mts +7 -0
- package/dist/node/{value.js → value.mjs} +12 -10
- package/dist/parse.d.mts +6 -0
- package/dist/{parse.js → parse.mjs} +11 -1
- package/package.json +42 -42
- package/src/constants.ts +30 -10
- package/src/fragment.ts +12 -24
- package/src/fragments.ts +3 -5
- package/src/helpers/dom.ts +1 -20
- package/src/helpers/index.ts +18 -15
- package/src/index.ts +14 -10
- package/src/models.ts +10 -1
- package/src/node/attribute/index.ts +22 -21
- package/src/node/attribute/value.ts +47 -37
- package/src/node/event.ts +26 -33
- package/src/node/index.ts +6 -18
- package/src/node/value.ts +15 -46
- package/src/parse.ts +15 -17
- package/dist/abydon.full.js +0 -1274
- package/dist/constants.js +0 -10
- package/dist/helpers/index.js +0 -14
- package/dist/index.js +0 -11
- package/dist/models.js +0 -0
- package/dist/node/attribute/index.js +0 -39
- package/dist/node/attribute/value.js +0 -56
- package/dist/node/event.js +0 -30
- package/types/constants.d.ts +0 -9
- package/types/fragment.d.ts +0 -38
- package/types/fragments.d.ts +0 -13
- package/types/helpers/dom.d.ts +0 -3
- package/types/helpers/index.d.ts +0 -5
- package/types/index.d.ts +0 -9
- package/types/models.d.ts +0 -32
- package/types/node/attribute/index.d.ts +0 -3
- package/types/node/attribute/value.d.ts +0 -3
- package/types/node/event.d.ts +0 -3
- package/types/node/index.d.ts +0 -2
- package/types/node/value.d.ts +0 -3
- package/types/parse.d.ts +0 -2
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/constants.d.ts
|
|
2
|
+
declare const ATTRIBUTE_CLASS_PREFIX_LENGTH = 6;
|
|
3
|
+
declare const EVENT_DEFAULTS: Record<string, string>;
|
|
4
|
+
declare const EXPRESSION_ABYDON_ATTRIBUTE_FULL: RegExp;
|
|
5
|
+
declare const EXPRESSION_ABYDON_ATTRIBUTE_PREFIX: RegExp;
|
|
6
|
+
declare const EXPRESSION_ABYDON_CONTENT: RegExp;
|
|
7
|
+
declare const EXPRESSION_ATTRIBUTE_CLASS: RegExp;
|
|
8
|
+
declare const EXPRESSION_ATTRIBUTE_STYLE_FULL: RegExp;
|
|
9
|
+
declare const EXPRESSION_ATTRIBUTE_STYLE_PREFIX: RegExp;
|
|
10
|
+
declare const EXPRESSION_EVENT_CHANGE_TYPES: RegExp;
|
|
11
|
+
declare const EXPRESSION_EVENT_NAME: RegExp;
|
|
12
|
+
declare const EXPRESSION_EVENT_OPTIONS_ACTIVE: RegExp;
|
|
13
|
+
declare const EXPRESSION_EVENT_OPTIONS_CAPTURE: RegExp;
|
|
14
|
+
declare const EXPRESSION_EVENT_OPTIONS_ONCE: RegExp;
|
|
15
|
+
declare const EXPRESSION_EVENT_PREFIX: RegExp;
|
|
16
|
+
declare const EXPRESSION_PERIOD: RegExp;
|
|
17
|
+
declare const NAME_FRAGMENT = "$fragment";
|
|
18
|
+
declare const NAME_FRAGMENTS = "$fragments";
|
|
19
|
+
//#endregion
|
|
20
|
+
export { ATTRIBUTE_CLASS_PREFIX_LENGTH, EVENT_DEFAULTS, EXPRESSION_ABYDON_ATTRIBUTE_FULL, EXPRESSION_ABYDON_ATTRIBUTE_PREFIX, EXPRESSION_ABYDON_CONTENT, EXPRESSION_ATTRIBUTE_CLASS, EXPRESSION_ATTRIBUTE_STYLE_FULL, EXPRESSION_ATTRIBUTE_STYLE_PREFIX, EXPRESSION_EVENT_CHANGE_TYPES, EXPRESSION_EVENT_NAME, EXPRESSION_EVENT_OPTIONS_ACTIVE, EXPRESSION_EVENT_OPTIONS_CAPTURE, EXPRESSION_EVENT_OPTIONS_ONCE, EXPRESSION_EVENT_PREFIX, EXPRESSION_PERIOD, NAME_FRAGMENT, NAME_FRAGMENTS };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/constants.ts
|
|
2
|
+
const ATTRIBUTE_CLASS_PREFIX_LENGTH = 6;
|
|
3
|
+
const EVENT_DEFAULTS = {
|
|
4
|
+
A: "click",
|
|
5
|
+
BUTTON: "click",
|
|
6
|
+
DETAILS: "toggle",
|
|
7
|
+
FORM: "submit",
|
|
8
|
+
SELECT: "change",
|
|
9
|
+
TEXTAREA: "input"
|
|
10
|
+
};
|
|
11
|
+
const EXPRESSION_ABYDON_ATTRIBUTE_FULL = /(@?\w+)="<!--abydon.(\d+)-->"/g;
|
|
12
|
+
const EXPRESSION_ABYDON_ATTRIBUTE_PREFIX = /^_/;
|
|
13
|
+
const EXPRESSION_ABYDON_CONTENT = /^@?abydon\.(\d+)@?$/;
|
|
14
|
+
const EXPRESSION_ATTRIBUTE_CLASS = /^class\./;
|
|
15
|
+
const EXPRESSION_ATTRIBUTE_STYLE_FULL = /^style\.([\w-]+)(?:\.([\w-]+))?$/;
|
|
16
|
+
const EXPRESSION_ATTRIBUTE_STYLE_PREFIX = /^style\./;
|
|
17
|
+
const EXPRESSION_EVENT_CHANGE_TYPES = /^(checkbox|radio)$/;
|
|
18
|
+
const EXPRESSION_EVENT_NAME = /^@([\w-]+)(?::([a-z:]+))?$/i;
|
|
19
|
+
const EXPRESSION_EVENT_OPTIONS_ACTIVE = /^a(ctive)$/i;
|
|
20
|
+
const EXPRESSION_EVENT_OPTIONS_CAPTURE = /^c(apture)$/i;
|
|
21
|
+
const EXPRESSION_EVENT_OPTIONS_ONCE = /^o(nce)$/i;
|
|
22
|
+
const EXPRESSION_EVENT_PREFIX = /^@/;
|
|
23
|
+
const EXPRESSION_PERIOD = /\./;
|
|
24
|
+
const NAME_FRAGMENT = "$fragment";
|
|
25
|
+
const NAME_FRAGMENTS = "$fragments";
|
|
26
|
+
//#endregion
|
|
27
|
+
export { ATTRIBUTE_CLASS_PREFIX_LENGTH, EVENT_DEFAULTS, EXPRESSION_ABYDON_ATTRIBUTE_FULL, EXPRESSION_ABYDON_ATTRIBUTE_PREFIX, EXPRESSION_ABYDON_CONTENT, EXPRESSION_ATTRIBUTE_CLASS, EXPRESSION_ATTRIBUTE_STYLE_FULL, EXPRESSION_ATTRIBUTE_STYLE_PREFIX, EXPRESSION_EVENT_CHANGE_TYPES, EXPRESSION_EVENT_NAME, EXPRESSION_EVENT_OPTIONS_ACTIVE, EXPRESSION_EVENT_OPTIONS_CAPTURE, EXPRESSION_EVENT_OPTIONS_ONCE, EXPRESSION_EVENT_PREFIX, EXPRESSION_PERIOD, NAME_FRAGMENT, NAME_FRAGMENTS };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Reactive, ReactiveArray, Unsubscribe } from "@oscarpalmer/mora";
|
|
2
|
+
|
|
3
|
+
//#region src/models.d.ts
|
|
4
|
+
type FragmentConfiguration = {
|
|
5
|
+
/**
|
|
6
|
+
* Should the template be cached? _(defaults to `true`)_
|
|
7
|
+
*/
|
|
8
|
+
cache?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Identifier for the fragment
|
|
11
|
+
*
|
|
12
|
+
* _(An identifier can be used to uniquely identify a fragment,
|
|
13
|
+
* which helps prevent re-rendering in certain scenarios)_
|
|
14
|
+
*/
|
|
15
|
+
identifier?: unknown;
|
|
16
|
+
};
|
|
17
|
+
type FragmentData = {
|
|
18
|
+
expressions: unknown[];
|
|
19
|
+
items: FragmentItem[];
|
|
20
|
+
mora: MoraData;
|
|
21
|
+
strings: TemplateStringsArray;
|
|
22
|
+
template?: string;
|
|
23
|
+
values: unknown[];
|
|
24
|
+
};
|
|
25
|
+
type FragmentItem = {
|
|
26
|
+
fragments?: Fragment[];
|
|
27
|
+
nodes?: ChildNode[];
|
|
28
|
+
text?: Text;
|
|
29
|
+
};
|
|
30
|
+
type FragmentsState = {
|
|
31
|
+
array: ReactiveArray<unknown>;
|
|
32
|
+
fragment: (item: unknown) => Fragment;
|
|
33
|
+
identify: (item: unknown) => unknown;
|
|
34
|
+
instances: Record<string, Fragment>;
|
|
35
|
+
mapped: ReactiveArray<Fragment>;
|
|
36
|
+
subscriber: Unsubscribe | undefined;
|
|
37
|
+
};
|
|
38
|
+
type MoraData = {
|
|
39
|
+
subscribers: Set<() => void>;
|
|
40
|
+
values: Set<Reactive<unknown>>;
|
|
41
|
+
};
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/fragment.d.ts
|
|
44
|
+
declare class Fragment {
|
|
45
|
+
#private;
|
|
46
|
+
/**
|
|
47
|
+
* Fragment identifier
|
|
48
|
+
*/
|
|
49
|
+
get identifier(): unknown;
|
|
50
|
+
constructor(strings: TemplateStringsArray, expressions: unknown[]);
|
|
51
|
+
/**
|
|
52
|
+
* Append the fragment to the given element
|
|
53
|
+
* @param element Element to append to
|
|
54
|
+
*/
|
|
55
|
+
appendTo(element: Element): void;
|
|
56
|
+
/**
|
|
57
|
+
* Configure the fragment
|
|
58
|
+
* @param configuration Configuration options
|
|
59
|
+
* @returns Fragment
|
|
60
|
+
*/
|
|
61
|
+
configure(configuration: FragmentConfiguration): Fragment;
|
|
62
|
+
/**
|
|
63
|
+
* Get a list of the fragment's nodes
|
|
64
|
+
* @returns List of nodes
|
|
65
|
+
*/
|
|
66
|
+
get(): ChildNode[];
|
|
67
|
+
/**
|
|
68
|
+
* Set an identifier for the fragment
|
|
69
|
+
*
|
|
70
|
+
* _An identifier can be used to uniquely identify a fragment,
|
|
71
|
+
* which helps prevent re-rendering in certain scenarios._
|
|
72
|
+
* @param identifier Identifier
|
|
73
|
+
* @returns Fragment
|
|
74
|
+
*/
|
|
75
|
+
identify(identifier: unknown): Fragment;
|
|
76
|
+
/**
|
|
77
|
+
* Remove the fragment from the DOM
|
|
78
|
+
*/
|
|
79
|
+
remove(): void;
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { FragmentsState as a, FragmentItem as i, FragmentConfiguration as n, FragmentData as r, Fragment as t };
|
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isFragments } from "./helpers/index.
|
|
3
|
-
import { handleFragments } from "./fragments.
|
|
4
|
-
import { removeNodes } from "./helpers/dom.
|
|
5
|
-
import { mapNodes } from "./node/index.
|
|
1
|
+
import { NAME_FRAGMENT } from "./constants.mjs";
|
|
2
|
+
import { isFragments } from "./helpers/index.mjs";
|
|
3
|
+
import { handleFragments } from "./fragments.mjs";
|
|
4
|
+
import { removeNodes } from "./helpers/dom.mjs";
|
|
5
|
+
import { mapNodes } from "./node/index.mjs";
|
|
6
|
+
import { parse } from "./parse.mjs";
|
|
6
7
|
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
7
8
|
import { html } from "@oscarpalmer/toretto/html";
|
|
9
|
+
//#region src/fragment.ts
|
|
8
10
|
var Fragment = class {
|
|
9
11
|
#data;
|
|
10
12
|
#configuration = {
|
|
11
13
|
identifier: void 0,
|
|
12
|
-
|
|
14
|
+
cache: true
|
|
13
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Fragment identifier
|
|
18
|
+
*/
|
|
14
19
|
get identifier() {
|
|
15
20
|
return this.#configuration.identifier;
|
|
16
21
|
}
|
|
17
22
|
constructor(strings, expressions) {
|
|
18
|
-
Object.defineProperty(this,
|
|
23
|
+
Object.defineProperty(this, NAME_FRAGMENT, { value: true });
|
|
19
24
|
this.#data = {
|
|
20
25
|
expressions,
|
|
21
26
|
strings,
|
|
@@ -27,31 +32,52 @@ var Fragment = class {
|
|
|
27
32
|
values: []
|
|
28
33
|
};
|
|
29
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Append the fragment to the given element
|
|
37
|
+
* @param element Element to append to
|
|
38
|
+
*/
|
|
30
39
|
appendTo(element) {
|
|
31
40
|
element.append(...this.get());
|
|
32
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Configure the fragment
|
|
44
|
+
* @param configuration Configuration options
|
|
45
|
+
* @returns Fragment
|
|
46
|
+
*/
|
|
33
47
|
configure(configuration) {
|
|
34
48
|
const actual = isPlainObject(configuration) ? configuration : {};
|
|
35
|
-
if (
|
|
36
|
-
if (typeof actual.
|
|
49
|
+
if ("identifier" in actual) this.#configuration.identifier = actual.identifier;
|
|
50
|
+
if (typeof actual.cache === "boolean") this.#configuration.cache = actual.cache;
|
|
37
51
|
return this;
|
|
38
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Get a list of the fragment's nodes
|
|
55
|
+
* @returns List of nodes
|
|
56
|
+
*/
|
|
39
57
|
get() {
|
|
40
58
|
const data = this.#data;
|
|
41
59
|
if (data.items.length === 0) {
|
|
42
|
-
const templated = html(parse(data), {
|
|
43
|
-
ignoreCache: this.#configuration.ignoreCache,
|
|
44
|
-
sanitizeBooleanAttributes: false
|
|
45
|
-
});
|
|
60
|
+
const templated = html(parse(data), { cache: this.#configuration.cache });
|
|
46
61
|
data.items.splice(0, data.items.length, ...templated.map((node) => ({ nodes: [node] })));
|
|
47
62
|
mapNodes(data, data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes ?? []));
|
|
48
63
|
}
|
|
49
|
-
return
|
|
64
|
+
return data.items.flatMap((item) => item.fragments?.flatMap((fragment) => fragment.get()) ?? item.nodes ?? []);
|
|
50
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Set an identifier for the fragment
|
|
68
|
+
*
|
|
69
|
+
* _An identifier can be used to uniquely identify a fragment,
|
|
70
|
+
* which helps prevent re-rendering in certain scenarios._
|
|
71
|
+
* @param identifier Identifier
|
|
72
|
+
* @returns Fragment
|
|
73
|
+
*/
|
|
51
74
|
identify(identifier) {
|
|
52
75
|
this.#configuration.identifier = identifier;
|
|
53
76
|
return this;
|
|
54
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Remove the fragment from the DOM
|
|
80
|
+
*/
|
|
55
81
|
remove() {
|
|
56
82
|
removeFragment(this.#data);
|
|
57
83
|
}
|
|
@@ -78,4 +104,5 @@ function removeMora(data) {
|
|
|
78
104
|
data.mora.values.clear();
|
|
79
105
|
for (const unsubscribe of unsubscribers) unsubscribe();
|
|
80
106
|
}
|
|
107
|
+
//#endregion
|
|
81
108
|
export { Fragment };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { a as FragmentsState, t as Fragment } from "./fragment-9qTBAvtR.mjs";
|
|
2
|
+
import { ReactiveArray } from "@oscarpalmer/mora";
|
|
3
|
+
|
|
4
|
+
//#region src/fragments.d.ts
|
|
5
|
+
declare class Fragments {
|
|
6
|
+
#private;
|
|
7
|
+
/**
|
|
8
|
+
* Fragment items
|
|
9
|
+
*/
|
|
10
|
+
get items(): ReactiveArray<Fragment>;
|
|
11
|
+
constructor(items: ReactiveArray<unknown>, identify: (item: unknown) => unknown, fragment: (item: unknown) => Fragment);
|
|
12
|
+
}
|
|
13
|
+
declare function handleFragments(item: Fragments | FragmentsState, remove: boolean): void;
|
|
14
|
+
declare function initializeFragments(state: FragmentsState): void;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { Fragments, handleFragments, initializeFragments };
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { NAME_FRAGMENTS } from "./constants.mjs";
|
|
2
|
+
import { isFragment, isFragments } from "./helpers/index.mjs";
|
|
3
3
|
import { getString } from "@oscarpalmer/atoms/string";
|
|
4
|
+
import { array } from "@oscarpalmer/mora";
|
|
5
|
+
//#region src/fragments.ts
|
|
4
6
|
var Fragments = class {
|
|
5
7
|
#state;
|
|
8
|
+
/**
|
|
9
|
+
* Fragment items
|
|
10
|
+
*/
|
|
6
11
|
get items() {
|
|
7
12
|
return this.#state.mapped;
|
|
8
13
|
}
|
|
9
14
|
constructor(items, identify, fragment) {
|
|
10
|
-
Object.defineProperty(this,
|
|
15
|
+
Object.defineProperty(this, NAME_FRAGMENTS, { value: true });
|
|
11
16
|
this.#state = {
|
|
12
17
|
fragment,
|
|
13
18
|
identify,
|
|
@@ -70,5 +75,6 @@ function updateFragments(state, active) {
|
|
|
70
75
|
state.instances = next;
|
|
71
76
|
active?.clear();
|
|
72
77
|
}
|
|
73
|
-
|
|
78
|
+
const states = /* @__PURE__ */ new WeakMap();
|
|
79
|
+
//#endregion
|
|
74
80
|
export { Fragments, handleFragments, initializeFragments };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region src/helpers/dom.d.ts
|
|
2
|
+
declare function createNodes(value: unknown): ChildNode[];
|
|
3
|
+
declare function removeNodes(nodes: ChildNode[]): void;
|
|
4
|
+
declare function replaceNodes(from: ChildNode[], to: ChildNode[]): void;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { createNodes, removeNodes, replaceNodes };
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { isFragment } from "./index.
|
|
2
|
-
import { removeEvents } from "../node/event.js";
|
|
1
|
+
import { isFragment } from "./index.mjs";
|
|
3
2
|
import { getString } from "@oscarpalmer/atoms/string";
|
|
4
|
-
import { isChildNode
|
|
3
|
+
import { isChildNode } from "@oscarpalmer/toretto/is";
|
|
4
|
+
//#region src/helpers/dom.ts
|
|
5
5
|
function createNodes(value) {
|
|
6
6
|
if (isFragment(value)) return value.get();
|
|
7
7
|
if (isChildNode(value)) return [value];
|
|
8
8
|
return [new Text(getString(value))];
|
|
9
9
|
}
|
|
10
10
|
function removeNodes(nodes) {
|
|
11
|
-
sanitizeNodes(nodes);
|
|
12
11
|
const { length } = nodes;
|
|
13
12
|
for (let index = 0; index < length; index += 1) nodes[index].remove();
|
|
14
13
|
}
|
|
@@ -17,12 +16,5 @@ function replaceNodes(from, to) {
|
|
|
17
16
|
const { length } = from;
|
|
18
17
|
for (let index = 1; index < length; index += 1) from[index].remove();
|
|
19
18
|
}
|
|
20
|
-
|
|
21
|
-
const { length } = nodes;
|
|
22
|
-
for (let index = 0; index < length; index += 1) {
|
|
23
|
-
const node = nodes[index];
|
|
24
|
-
if (isHTMLOrSVGElement(node)) removeEvents(node);
|
|
25
|
-
if (node.hasChildNodes()) sanitizeNodes([...node.childNodes]);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
19
|
+
//#endregion
|
|
28
20
|
export { createNodes, removeNodes, replaceNodes };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { t as Fragment } from "../fragment-9qTBAvtR.mjs";
|
|
2
|
+
import { Fragments } from "../fragments.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/helpers/index.d.ts
|
|
5
|
+
declare function compareArrays(first: unknown[], second: unknown[]): 'added' | 'dissimilar' | 'removed';
|
|
6
|
+
declare function isFragment(value: unknown): value is Fragment;
|
|
7
|
+
declare function isFragments(value: unknown): value is Fragments;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { compareArrays, isFragment, isFragments };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { NAME_FRAGMENT, NAME_FRAGMENTS } from "../constants.mjs";
|
|
2
|
+
//#region src/helpers/index.ts
|
|
3
|
+
function compareArrays(first, second) {
|
|
4
|
+
const firstIsLarger = first.length > second.length;
|
|
5
|
+
const from = firstIsLarger ? first : second;
|
|
6
|
+
const to = firstIsLarger ? second : first;
|
|
7
|
+
if (!from.filter((key) => to.includes(key)).every((key, index) => to[index] === key)) return COMPARISON_DISSIMILAR;
|
|
8
|
+
return firstIsLarger ? COMPARISON_REMOVED : COMPARISON_ADDED;
|
|
9
|
+
}
|
|
10
|
+
function isFragment(value) {
|
|
11
|
+
return isNamed(value, NAME_FRAGMENT);
|
|
12
|
+
}
|
|
13
|
+
function isFragments(value) {
|
|
14
|
+
return isNamed(value, NAME_FRAGMENTS);
|
|
15
|
+
}
|
|
16
|
+
function isNamed(value, name) {
|
|
17
|
+
return typeof value === "object" && value != null && name in value && value[name] === true;
|
|
18
|
+
}
|
|
19
|
+
const COMPARISON_ADDED = "added";
|
|
20
|
+
const COMPARISON_DISSIMILAR = "dissimilar";
|
|
21
|
+
const COMPARISON_REMOVED = "removed";
|
|
22
|
+
//#endregion
|
|
23
|
+
export { compareArrays, isFragment, isFragments };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { t as Fragment } from "./fragment-9qTBAvtR.mjs";
|
|
2
|
+
import { Fragments } from "./fragments.mjs";
|
|
3
|
+
import { ReactiveArray } from "@oscarpalmer/mora";
|
|
4
|
+
export * from "@oscarpalmer/mora";
|
|
5
|
+
|
|
6
|
+
//#region src/index.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Create Fragments from a reactive array
|
|
9
|
+
* @param array Reactive array
|
|
10
|
+
* @param identify Function to identify item
|
|
11
|
+
* @param fragment Function to create fragment from item
|
|
12
|
+
* @returns Fragments
|
|
13
|
+
*/
|
|
14
|
+
declare function fragments<Item>(array: ReactiveArray<Item>, identify: (item: Item) => unknown, fragment: (item: Item) => Fragment): Fragments;
|
|
15
|
+
/**
|
|
16
|
+
* Create Fragment from a template
|
|
17
|
+
* @returns Fragment
|
|
18
|
+
*/
|
|
19
|
+
declare function html(template: TemplateStringsArray, ...values: unknown[]): Fragment;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { type Fragment, type Fragments, fragments, html };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Fragments } from "./fragments.mjs";
|
|
2
|
+
import { Fragment } from "./fragment.mjs";
|
|
3
|
+
import "@oscarpalmer/mora";
|
|
4
|
+
export * from "@oscarpalmer/mora";
|
|
5
|
+
//#region src/index.ts
|
|
6
|
+
/**
|
|
7
|
+
* Create Fragments from a reactive array
|
|
8
|
+
* @param array Reactive array
|
|
9
|
+
* @param identify Function to identify item
|
|
10
|
+
* @param fragment Function to create fragment from item
|
|
11
|
+
* @returns Fragments
|
|
12
|
+
*/
|
|
13
|
+
function fragments(array, identify, fragment) {
|
|
14
|
+
return new Fragments(array, identify, fragment);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create Fragment from a template
|
|
18
|
+
* @returns Fragment
|
|
19
|
+
*/
|
|
20
|
+
function html(template, ...values) {
|
|
21
|
+
return new Fragment(template, values);
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { fragments, html };
|
package/dist/models.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { EXPRESSION_ABYDON_ATTRIBUTE_PREFIX, EXPRESSION_ABYDON_CONTENT, EXPRESSION_EVENT_PREFIX, EXPRESSION_PERIOD } from "../../constants.mjs";
|
|
2
|
+
import { mapEvent } from "../event.mjs";
|
|
3
|
+
import { setAttribute } from "./value.mjs";
|
|
4
|
+
import { computed, isReactive } from "@oscarpalmer/mora";
|
|
5
|
+
//#region src/node/attribute/index.ts
|
|
6
|
+
function getValue(data, original) {
|
|
7
|
+
const matches = EXPRESSION_ABYDON_CONTENT.exec(original ?? "");
|
|
8
|
+
return matches == null ? original : data.values[+matches[1]];
|
|
9
|
+
}
|
|
10
|
+
function mapAttributes(data, element) {
|
|
11
|
+
const attributes = [...element.attributes];
|
|
12
|
+
const { length } = attributes;
|
|
13
|
+
for (let index = 0; index < length; index += 1) {
|
|
14
|
+
const { name, value } = attributes[index];
|
|
15
|
+
const actualName = name.replace(EXPRESSION_ABYDON_ATTRIBUTE_PREFIX, "");
|
|
16
|
+
const actualValue = getValue(data, value);
|
|
17
|
+
if (actualName !== name) element.removeAttribute(name);
|
|
18
|
+
switch (true) {
|
|
19
|
+
case EXPRESSION_EVENT_PREFIX.test(actualName):
|
|
20
|
+
mapEvent(element, actualName, actualValue);
|
|
21
|
+
break;
|
|
22
|
+
case EXPRESSION_PERIOD.test(actualName):
|
|
23
|
+
case typeof actualValue === "function":
|
|
24
|
+
case isReactive(actualValue):
|
|
25
|
+
mapValue(data, element, actualName, actualValue);
|
|
26
|
+
break;
|
|
27
|
+
default: break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function mapValue(data, element, name, value) {
|
|
32
|
+
if (typeof value === "function") setComputedAttribute(data, element, name, value);
|
|
33
|
+
else setAttribute(data, element, name, value);
|
|
34
|
+
}
|
|
35
|
+
function setComputedAttribute(data, element, name, callback) {
|
|
36
|
+
const value = computed(callback);
|
|
37
|
+
data.mora.values.add(value);
|
|
38
|
+
setAttribute(data, element, name, value);
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { mapAttributes };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { r as FragmentData } from "../../fragment-9qTBAvtR.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/node/attribute/value.d.ts
|
|
4
|
+
declare function setAttribute(data: FragmentData, element: HTMLElement | SVGElement, name: string, value: unknown): void;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { setAttribute };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { EXPRESSION_ATTRIBUTE_CLASS, EXPRESSION_ATTRIBUTE_STYLE_FULL, EXPRESSION_ATTRIBUTE_STYLE_PREFIX } from "../../constants.mjs";
|
|
2
|
+
import { isReactive } from "@oscarpalmer/mora";
|
|
3
|
+
import { isBooleanAttribute, setAttribute as setAttribute$1 } from "@oscarpalmer/toretto/attribute";
|
|
4
|
+
//#region src/node/attribute/value.ts
|
|
5
|
+
function getCallback(element, name) {
|
|
6
|
+
if (isBooleanAttribute(name) && name in element) return name === "checked" ? updateChecked : updateProperty;
|
|
7
|
+
return name === "value" ? updateValue : setAttribute$1;
|
|
8
|
+
}
|
|
9
|
+
function setAttribute(data, element, name, value) {
|
|
10
|
+
switch (true) {
|
|
11
|
+
case EXPRESSION_ATTRIBUTE_CLASS.test(name):
|
|
12
|
+
setClasses(data, element, name, value);
|
|
13
|
+
return;
|
|
14
|
+
case EXPRESSION_ATTRIBUTE_STYLE_PREFIX.test(name):
|
|
15
|
+
setStyle(data, element, name, value);
|
|
16
|
+
return;
|
|
17
|
+
default:
|
|
18
|
+
setValue(data, element, name, value);
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function setClasses(data, element, name, value) {
|
|
23
|
+
function update(value) {
|
|
24
|
+
if (value === true) element.classList.add(...classes);
|
|
25
|
+
else element.classList.remove(...classes);
|
|
26
|
+
}
|
|
27
|
+
const classes = name.slice(6).split(".");
|
|
28
|
+
if (isReactive(value)) data.mora.subscribers.add(value.subscribe(update));
|
|
29
|
+
else update(value);
|
|
30
|
+
}
|
|
31
|
+
function setStyle(data, element, name, value) {
|
|
32
|
+
const [, property, unit] = EXPRESSION_ATTRIBUTE_STYLE_FULL.exec(name) ?? [];
|
|
33
|
+
if (property == null) return;
|
|
34
|
+
function update(value) {
|
|
35
|
+
if (value == null || value === false || value === true && unit == null) element.style.removeProperty(property);
|
|
36
|
+
else element.style.setProperty(property, value === true ? unit : String(value));
|
|
37
|
+
}
|
|
38
|
+
if (isReactive(value)) data.mora.subscribers.add(value.subscribe(update));
|
|
39
|
+
else update(value);
|
|
40
|
+
}
|
|
41
|
+
function setValue(data, element, name, value) {
|
|
42
|
+
const callback = getCallback(element, name);
|
|
43
|
+
if (isReactive(value)) data.mora.subscribers.add(value.subscribe((next) => {
|
|
44
|
+
callback(element, name, next);
|
|
45
|
+
}));
|
|
46
|
+
else callback(element, name, value);
|
|
47
|
+
}
|
|
48
|
+
function updateChecked(element, name, value) {
|
|
49
|
+
updateElement("change", "checked", element, name, value, value === true);
|
|
50
|
+
}
|
|
51
|
+
function updateElement(event, property, element, name, value, next) {
|
|
52
|
+
if (!(property in element) || element[property] === next) return;
|
|
53
|
+
setAttribute$1(element, name, value);
|
|
54
|
+
if (element[property] === next) return;
|
|
55
|
+
element[property] = next;
|
|
56
|
+
element.dispatchEvent(new Event(event, { bubbles: true }));
|
|
57
|
+
}
|
|
58
|
+
function updateProperty(element, name, value) {
|
|
59
|
+
setAttribute$1(element, name, value === true);
|
|
60
|
+
}
|
|
61
|
+
function updateValue(element, name, value) {
|
|
62
|
+
updateElement(element instanceof HTMLSelectElement ? "change" : "input", "value", element, name, value, String(value));
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { setAttribute };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { EVENT_DEFAULTS, EXPRESSION_EVENT_CHANGE_TYPES, EXPRESSION_EVENT_NAME, EXPRESSION_EVENT_OPTIONS_ACTIVE, EXPRESSION_EVENT_OPTIONS_CAPTURE, EXPRESSION_EVENT_OPTIONS_ONCE } from "../constants.mjs";
|
|
2
|
+
import { on } from "@oscarpalmer/toretto/event";
|
|
3
|
+
//#region src/node/event.ts
|
|
4
|
+
function getOptions(options) {
|
|
5
|
+
const parts = options.split(":");
|
|
6
|
+
return {
|
|
7
|
+
capture: parts.some((part) => EXPRESSION_EVENT_OPTIONS_CAPTURE.test(part)),
|
|
8
|
+
once: parts.some((part) => EXPRESSION_EVENT_OPTIONS_ONCE.test(part)),
|
|
9
|
+
passive: !parts.some((part) => EXPRESSION_EVENT_OPTIONS_ACTIVE.test(part))
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function getType(element, type) {
|
|
13
|
+
if (type !== "on") return type;
|
|
14
|
+
if (element instanceof HTMLInputElement) {
|
|
15
|
+
if (EXPRESSION_EVENT_CHANGE_TYPES.test(element.type)) return "change";
|
|
16
|
+
return element.type === "submit" ? "submit" : "input";
|
|
17
|
+
}
|
|
18
|
+
return EVENT_DEFAULTS[element.tagName] ?? type;
|
|
19
|
+
}
|
|
20
|
+
function mapEvent(element, name, value) {
|
|
21
|
+
const [, type, options] = EXPRESSION_EVENT_NAME.exec(name) ?? [];
|
|
22
|
+
if (type != null && typeof value === "function") on(element, getType(element, type), value, getOptions(options ?? ""));
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { mapEvent };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { createNodes } from "../helpers/dom.
|
|
5
|
-
import { mapAttributes } from "./attribute/index.
|
|
6
|
-
import { setReactiveValue } from "./value.
|
|
1
|
+
import { EXPRESSION_ABYDON_CONTENT } from "../constants.mjs";
|
|
2
|
+
import { isFragment, isFragments } from "../helpers/index.mjs";
|
|
3
|
+
import { handleFragments } from "../fragments.mjs";
|
|
4
|
+
import { createNodes } from "../helpers/dom.mjs";
|
|
5
|
+
import { mapAttributes } from "./attribute/index.mjs";
|
|
6
|
+
import { setReactiveValue } from "./value.mjs";
|
|
7
7
|
import { computed, isReactive } from "@oscarpalmer/mora";
|
|
8
8
|
import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
|
|
9
|
+
//#region src/node/index.ts
|
|
9
10
|
function mapNode(data, comment) {
|
|
10
|
-
const matches =
|
|
11
|
+
const matches = EXPRESSION_ABYDON_CONTENT.exec(comment.textContent ?? "");
|
|
11
12
|
const value = matches == null ? null : data.values[+matches[1]];
|
|
12
13
|
if (value != null) mapValue(data, comment, value);
|
|
13
14
|
}
|
|
@@ -41,7 +42,7 @@ function mapValue(data, comment, value) {
|
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
function replaceComment(data, comment, value) {
|
|
44
|
-
const item = data.items.find((item
|
|
45
|
+
const item = data.items.find((item) => item.nodes?.includes(comment));
|
|
45
46
|
const nodes = createNodes(value);
|
|
46
47
|
if (item != null) {
|
|
47
48
|
item.fragments = isFragment(value) ? [value] : void 0;
|
|
@@ -54,4 +55,5 @@ function setComputedValue(data, comment, callback) {
|
|
|
54
55
|
data.mora.values.add(value);
|
|
55
56
|
setReactiveValue(data, comment, value);
|
|
56
57
|
}
|
|
58
|
+
//#endregion
|
|
57
59
|
export { mapNodes };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { r as FragmentData } from "../fragment-9qTBAvtR.mjs";
|
|
2
|
+
import { Reactive } from "@oscarpalmer/mora";
|
|
3
|
+
|
|
4
|
+
//#region src/node/value.d.ts
|
|
5
|
+
declare function setReactiveValue(data: FragmentData, comment: Comment, reactive: Reactive<unknown>): void;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { setReactiveValue };
|