mancha 0.9.0 → 0.9.4
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/README.md +17 -45
- package/dist/browser.d.ts +6 -5
- package/dist/browser.js +9 -38
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -1
- package/dist/core.d.ts +6 -24
- package/dist/core.js +8 -44
- package/dist/css_gen_basic.d.ts +2 -1
- package/dist/css_gen_basic.js +20 -2
- package/dist/dome.d.ts +26 -24
- package/dist/dome.js +60 -69
- package/dist/index.d.ts +3 -1
- package/dist/index.js +8 -6
- package/dist/interfaces.d.ts +1 -2
- package/dist/mancha.d.ts +3 -0
- package/dist/mancha.js +88 -1
- package/dist/plugins.js +79 -117
- package/dist/safe_browser.d.ts +7 -0
- package/dist/safe_browser.js +19 -0
- package/dist/store.d.ts +7 -9
- package/dist/store.js +39 -19
- package/dist/test_utils.d.ts +2 -0
- package/dist/test_utils.js +14 -0
- package/dist/worker.d.ts +3 -1
- package/dist/worker.js +7 -0
- package/gulpfile.js +1 -1
- package/package.json +8 -9
- package/tsconfig.json +19 -13
- package/tsec_exemptions.json +4 -0
- package/webpack.config.js +6 -4
- package/dist/css_raw_basic.css +0 -1
- package/dist/gulp_plugin.d.ts +0 -15
- package/dist/gulp_plugin.js +0 -68
- package/yarn-error.log +0 -4103
package/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# mancha
|
|
2
2
|
|
|
3
3
|
`mancha` is a simple HTML templating and reactivity library for simple people. It works on the
|
|
4
|
-
browser or the server. It can be used as a command-line tool, imported as a Javascript module
|
|
5
|
-
a plugin for [`Gulp`](https://gulpjs.com).
|
|
4
|
+
browser or the server. It can be used as a command-line tool, or imported as a Javascript module.
|
|
6
5
|
|
|
7
6
|
Here's a small sample of the things that you can do with `mancha`:
|
|
8
7
|
|
|
@@ -16,7 +15,7 @@ Here's a small sample of the things that you can do with `mancha`:
|
|
|
16
15
|
<template is="counter">
|
|
17
16
|
<div>
|
|
18
17
|
<slot></slot>
|
|
19
|
-
<button
|
|
18
|
+
<button :on:click="count = count + 1">Counter: {{ count }}</button>
|
|
20
19
|
</div>
|
|
21
20
|
</template>
|
|
22
21
|
|
|
@@ -48,7 +47,7 @@ None of them have all the key features that make `mancha` unique:
|
|
|
48
47
|
| Feature | mancha | Svelte | React.js | Vue.js | petite-vue | Alpine.js |
|
|
49
48
|
| --------------------- | ------ | ------ | -------- | ------ | ---------- | --------- |
|
|
50
49
|
| Simple to learn | ✔️ | ❌ | ❌ | ❌ | ✔️ | ✔️ |
|
|
51
|
-
| <
|
|
50
|
+
| < 15kb compressed | ✔️ | ❌ | ❌ | ❌ | ✔️ | ❌ |
|
|
52
51
|
| Custom web components | ✔️ | ✔️ | ✔️ | ✔️ | ❌ | ❌ |
|
|
53
52
|
| Client-side rendering | ✔️ | ❌ | ❌ | ✔️ | ✔️ | ✔️ |
|
|
54
53
|
| Server-side rendering | ✔️ | ✔️ | ✔️ | ✔️ | ❌ | ❌ |
|
|
@@ -99,7 +98,7 @@ preprocessing consist of:
|
|
|
99
98
|
</template>
|
|
100
99
|
|
|
101
100
|
<!-- Any node traversed after registration can use the component. -->
|
|
102
|
-
<my-red-button
|
|
101
|
+
<my-red-button :on:click="console.log('clicked')">
|
|
103
102
|
<!-- The contents within will replace the `<slot></slot>` tag. -->
|
|
104
103
|
Click Me
|
|
105
104
|
</my-red-button>
|
|
@@ -119,43 +118,31 @@ element tag or attributes match a specific criteria. Here's the list of attribut
|
|
|
119
118
|
```html
|
|
120
119
|
<div :for="item in ['a', 'b', 'c']">{{ item }}</div>
|
|
121
120
|
```
|
|
122
|
-
-
|
|
121
|
+
- `:text` sets the `textContent` value of a node
|
|
123
122
|
```html
|
|
124
|
-
<div :data="{foo: 'bar'}"
|
|
123
|
+
<div :data="{foo: 'bar'}" :text="foo"></div>
|
|
125
124
|
```
|
|
126
|
-
-
|
|
125
|
+
- `:html` sets the `innerHTML` value of a node
|
|
127
126
|
```html
|
|
128
|
-
<div
|
|
127
|
+
<div :html="<span>Hello World</span>"></div>
|
|
129
128
|
```
|
|
130
129
|
- `:show` toggles `$elem.style.display` to `none`
|
|
131
130
|
```html
|
|
132
131
|
<div :data="{foo: false}" :show="foo"></div>
|
|
133
132
|
```
|
|
134
|
-
- `@watch` executes an expression anytime its dependencies change
|
|
135
|
-
```html
|
|
136
|
-
<div :data="{foo: 'bar'}" @watch="console.log('foo changed:', foo)"></div>
|
|
137
|
-
```
|
|
138
133
|
- `:bind` binds (two-way) a variable to the `value` or `checked` property of the element.
|
|
139
134
|
```html
|
|
140
135
|
<div :data="{name: 'Stranger'}">
|
|
141
136
|
<input type="text" :bind="name" />
|
|
142
137
|
</div>
|
|
143
138
|
```
|
|
144
|
-
-
|
|
145
|
-
```html
|
|
146
|
-
<div :data="{foo: false}">
|
|
147
|
-
<input type="submit" $disabled="foo" />
|
|
148
|
-
</div>
|
|
149
|
-
```
|
|
150
|
-
- `:{attr}` binds (one-way) the node attribute `attr` with the given expression
|
|
139
|
+
- `:on:{event}` adds an event listener for `event` to the node
|
|
151
140
|
```html
|
|
152
|
-
<
|
|
153
|
-
<input type="text" :placeholder="foo" />
|
|
154
|
-
</div>
|
|
141
|
+
<button :on:click="console.log('clicked')"></button>
|
|
155
142
|
```
|
|
156
|
-
-
|
|
143
|
+
- `:{attribute}` sets the corresponding property for `attribute` in the node
|
|
157
144
|
```html
|
|
158
|
-
<
|
|
145
|
+
<a :href="buildUrl()"></a>
|
|
159
146
|
```
|
|
160
147
|
- `{{ value }}` replaces `value` in text nodes
|
|
161
148
|
```html
|
|
@@ -278,28 +265,13 @@ self.addEventListener("fetch", async (event) => {
|
|
|
278
265
|
|
|
279
266
|
To meet the size requirements of popular worker runtimes, the worker version of `mancha` uses
|
|
280
267
|
`htmlparser2` instead of `jsdom` for the underlying HTML and DOM manipulation. This keeps the
|
|
281
|
-
footprint of `mancha` under 100kb.
|
|
268
|
+
footprint of `mancha` and its dependencies under 100kb.
|
|
282
269
|
|
|
283
270
|
For a more complete example, see [examples/wrangler](./examples/wrangler).
|
|
284
271
|
|
|
285
|
-
##
|
|
272
|
+
## Dependencies
|
|
286
273
|
|
|
287
|
-
|
|
274
|
+
The browser bundle contains a single external dependency, [`jexpr`][jexpr]. The unbundled version
|
|
275
|
+
can use `htmlparser2`, which is compatible with web workers, or `jsdom`.
|
|
288
276
|
|
|
289
|
-
|
|
290
|
-
import GulpClient from "gulp";
|
|
291
|
-
import { mancha } from "mancha/dist/gulp";
|
|
292
|
-
import vars from "./vars.json";
|
|
293
|
-
|
|
294
|
-
GulpClient.task("build", function () {
|
|
295
|
-
return (
|
|
296
|
-
GulpClient
|
|
297
|
-
// Inlcude all HTML files, but exclude all partials (ending in .tpl.html).
|
|
298
|
-
.src(["src/**/*.html", "!src/**/*.tpl/html"])
|
|
299
|
-
// Render the HTML content using `mancha`.
|
|
300
|
-
.pipe(mancha(vars))
|
|
301
|
-
// Pipe the output to the destination folder.
|
|
302
|
-
.pipe(GulpClient.dest("public"))
|
|
303
|
-
);
|
|
304
|
-
});
|
|
305
|
-
```
|
|
277
|
+
[jexpr]: https://github.com/justinfagnani/jexpr
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { IRenderer } from "./core.js";
|
|
2
2
|
import { ParserParams, RenderParams } from "./interfaces.js";
|
|
3
|
-
declare class Renderer extends IRenderer {
|
|
3
|
+
export declare class Renderer extends IRenderer {
|
|
4
4
|
protected readonly dirpath: string;
|
|
5
|
-
parseHTML(content: string, params?: ParserParams): DocumentFragment;
|
|
5
|
+
parseHTML(content: string, params?: ParserParams): Document | DocumentFragment;
|
|
6
6
|
serializeHTML(root: Node | DocumentFragment): string;
|
|
7
|
-
preprocessLocal(fpath: string, params?: RenderParams & ParserParams): Promise<DocumentFragment>;
|
|
7
|
+
preprocessLocal(fpath: string, params?: RenderParams & ParserParams): Promise<Document | DocumentFragment>;
|
|
8
|
+
createElement(tag: string, owner?: Document | null): Element;
|
|
9
|
+
textContent(node: Node, content: string): void;
|
|
8
10
|
}
|
|
9
|
-
declare const Mancha: Renderer;
|
|
10
|
-
export default Mancha;
|
|
11
|
+
export declare const Mancha: Renderer;
|
package/dist/browser.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
class Renderer extends IRenderer {
|
|
1
|
+
import { IRenderer } from "./core.js";
|
|
2
|
+
import { dirname } from "./dome.js";
|
|
3
|
+
export class Renderer extends IRenderer {
|
|
5
4
|
dirpath = dirname(self.location.href);
|
|
6
5
|
parseHTML(content, params = { rootDocument: false }) {
|
|
7
6
|
if (params.rootDocument) {
|
|
@@ -20,39 +19,11 @@ class Renderer extends IRenderer {
|
|
|
20
19
|
// In the browser, "local" paths (i.e., relative paths) can still be fetched.
|
|
21
20
|
return this.preprocessRemote(fpath, params);
|
|
22
21
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (self.document?.currentScript?.hasAttribute("init")) {
|
|
29
|
-
const debug = currentScript?.hasAttribute("debug");
|
|
30
|
-
const cachePolicy = currentScript?.getAttribute("cache");
|
|
31
|
-
const targets = currentScript?.getAttribute("target")?.split("+") || ["body"];
|
|
32
|
-
window.addEventListener("load", () => {
|
|
33
|
-
targets.map(async (target) => {
|
|
34
|
-
const fragment = self.document.querySelector(target);
|
|
35
|
-
await Mancha.debug(debug).mount(fragment, { cache: cachePolicy });
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
// If the css attribute is present, inject the specified CSS rules.
|
|
40
|
-
if (self.document?.currentScript?.hasAttribute("css")) {
|
|
41
|
-
const styleNames = currentScript?.getAttribute("css")?.split("+");
|
|
42
|
-
for (const styleName of styleNames) {
|
|
43
|
-
const style = document.createElement("style");
|
|
44
|
-
switch (styleName) {
|
|
45
|
-
case "basic":
|
|
46
|
-
style.textContent = basicCssRules();
|
|
47
|
-
break;
|
|
48
|
-
case "utils":
|
|
49
|
-
style.textContent = utilsCssRules();
|
|
50
|
-
break;
|
|
51
|
-
default:
|
|
52
|
-
console.error(`Unknown style name: "${styleName}"`);
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
self.document.head.appendChild(style);
|
|
22
|
+
createElement(tag, owner) {
|
|
23
|
+
return (owner || document).createElement(tag);
|
|
24
|
+
}
|
|
25
|
+
textContent(node, content) {
|
|
26
|
+
node.textContent = content;
|
|
56
27
|
}
|
|
57
28
|
}
|
|
58
|
-
export
|
|
29
|
+
export const Mancha = new Renderer();
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
package/dist/core.d.ts
CHANGED
|
@@ -1,26 +1,6 @@
|
|
|
1
1
|
import { ParserParams, RenderParams } from "./interfaces.js";
|
|
2
2
|
import { SignalStore } from "./store.js";
|
|
3
3
|
export type EvalListener = (result: any, dependencies: string[]) => any;
|
|
4
|
-
/**
|
|
5
|
-
* Returns the directory name from a given file path.
|
|
6
|
-
* @param fpath - The file path.
|
|
7
|
-
* @returns The directory name.
|
|
8
|
-
*/
|
|
9
|
-
export declare function dirname(fpath: string): string;
|
|
10
|
-
/**
|
|
11
|
-
* Checks if a given file path is a relative path.
|
|
12
|
-
*
|
|
13
|
-
* @param fpath - The file path to check.
|
|
14
|
-
* @returns A boolean indicating whether the file path is relative or not.
|
|
15
|
-
*/
|
|
16
|
-
export declare function isRelativePath(fpath: string): boolean;
|
|
17
|
-
/**
|
|
18
|
-
* Creates an evaluation function based on the provided code and arguments.
|
|
19
|
-
* @param code The code to be evaluated.
|
|
20
|
-
* @param args The arguments to be passed to the evaluation function. Default is an empty array.
|
|
21
|
-
* @returns The evaluation function.
|
|
22
|
-
*/
|
|
23
|
-
export declare function makeEvalFunction(code: string, args?: string[]): Function;
|
|
24
4
|
/**
|
|
25
5
|
* Represents an abstract class for rendering and manipulating HTML content.
|
|
26
6
|
* Extends the `ReactiveProxyStore` class.
|
|
@@ -30,8 +10,10 @@ export declare abstract class IRenderer extends SignalStore {
|
|
|
30
10
|
protected readonly dirpath: string;
|
|
31
11
|
readonly _skipNodes: Set<Node>;
|
|
32
12
|
readonly _customElements: Map<string, Node>;
|
|
33
|
-
abstract parseHTML(content: string, params?: ParserParams): DocumentFragment;
|
|
13
|
+
abstract parseHTML(content: string, params?: ParserParams): Document | DocumentFragment;
|
|
34
14
|
abstract serializeHTML(root: DocumentFragment | Node): string;
|
|
15
|
+
abstract createElement(tag: string, owner?: Document | null): Element;
|
|
16
|
+
abstract textContent(node: Node, tag: string): void;
|
|
35
17
|
/**
|
|
36
18
|
* Sets the debugging flag for the current instance.
|
|
37
19
|
*
|
|
@@ -61,21 +43,21 @@ export declare abstract class IRenderer extends SignalStore {
|
|
|
61
43
|
* @param params - Optional rendering and parsing parameters.
|
|
62
44
|
* @returns A promise that resolves to a DocumentFragment representing the preprocessed content.
|
|
63
45
|
*/
|
|
64
|
-
preprocessString(content: string, params?: RenderParams & ParserParams): Promise<DocumentFragment>;
|
|
46
|
+
preprocessString(content: string, params?: RenderParams & ParserParams): Promise<Document | DocumentFragment>;
|
|
65
47
|
/**
|
|
66
48
|
* Preprocesses a remote file by fetching its content and applying preprocessing steps.
|
|
67
49
|
* @param fpath - The path to the remote file.
|
|
68
50
|
* @param params - Optional parameters for rendering and parsing.
|
|
69
51
|
* @returns A Promise that resolves to a DocumentFragment representing the preprocessed content.
|
|
70
52
|
*/
|
|
71
|
-
preprocessRemote(fpath: string, params?: RenderParams & ParserParams): Promise<DocumentFragment>;
|
|
53
|
+
preprocessRemote(fpath: string, params?: RenderParams & ParserParams): Promise<Document | DocumentFragment>;
|
|
72
54
|
/**
|
|
73
55
|
* Preprocesses a local file by fetching its content and applying preprocessing steps.
|
|
74
56
|
* @param fpath - The path to the local file.
|
|
75
57
|
* @param params - Optional parameters for rendering and parsing.
|
|
76
58
|
* @returns A promise that resolves to the preprocessed document fragment.
|
|
77
59
|
*/
|
|
78
|
-
preprocessLocal(fpath: string, params?: RenderParams & ParserParams): Promise<DocumentFragment>;
|
|
60
|
+
preprocessLocal(fpath: string, params?: RenderParams & ParserParams): Promise<Document | DocumentFragment>;
|
|
79
61
|
/**
|
|
80
62
|
* Creates a deep copy of the current renderer instance.
|
|
81
63
|
* @returns A new instance of the renderer with the same state as the original.
|
package/dist/core.js
CHANGED
|
@@ -1,41 +1,7 @@
|
|
|
1
1
|
import { Iterator } from "./iterator.js";
|
|
2
2
|
import { RendererPlugins } from "./plugins.js";
|
|
3
|
-
import { nodeToString, traverse } from "./dome.js";
|
|
3
|
+
import { dirname, nodeToString, traverse } from "./dome.js";
|
|
4
4
|
import { SignalStore } from "./store.js";
|
|
5
|
-
/**
|
|
6
|
-
* Returns the directory name from a given file path.
|
|
7
|
-
* @param fpath - The file path.
|
|
8
|
-
* @returns The directory name.
|
|
9
|
-
*/
|
|
10
|
-
export function dirname(fpath) {
|
|
11
|
-
if (!fpath.includes("/")) {
|
|
12
|
-
return "";
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
return fpath.split("/").slice(0, -1).join("/");
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Checks if a given file path is a relative path.
|
|
20
|
-
*
|
|
21
|
-
* @param fpath - The file path to check.
|
|
22
|
-
* @returns A boolean indicating whether the file path is relative or not.
|
|
23
|
-
*/
|
|
24
|
-
export function isRelativePath(fpath) {
|
|
25
|
-
return (!fpath.includes("://") &&
|
|
26
|
-
!fpath.startsWith("/") &&
|
|
27
|
-
!fpath.startsWith("#") &&
|
|
28
|
-
!fpath.startsWith("data:"));
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Creates an evaluation function based on the provided code and arguments.
|
|
32
|
-
* @param code The code to be evaluated.
|
|
33
|
-
* @param args The arguments to be passed to the evaluation function. Default is an empty array.
|
|
34
|
-
* @returns The evaluation function.
|
|
35
|
-
*/
|
|
36
|
-
export function makeEvalFunction(code, args = []) {
|
|
37
|
-
return new Function(...args, `with (this) { return (async () => (${code}))(); }`);
|
|
38
|
-
}
|
|
39
5
|
/**
|
|
40
6
|
* Represents an abstract class for rendering and manipulating HTML content.
|
|
41
7
|
* Extends the `ReactiveProxyStore` class.
|
|
@@ -183,24 +149,22 @@ export class IRenderer extends SignalStore {
|
|
|
183
149
|
await RendererPlugins.resolveDataAttribute.call(this, node, params);
|
|
184
150
|
// Resolve the :for attribute in the node.
|
|
185
151
|
await RendererPlugins.resolveForAttribute.call(this, node, params);
|
|
186
|
-
// Resolve the
|
|
152
|
+
// Resolve the :text attribute in the node.
|
|
187
153
|
await RendererPlugins.resolveTextAttributes.call(this, node, params);
|
|
188
|
-
// Resolve the
|
|
154
|
+
// Resolve the :html attribute in the node.
|
|
189
155
|
await RendererPlugins.resolveHtmlAttribute.call(this, node, params);
|
|
190
156
|
// Resolve the :show attribute in the node.
|
|
191
157
|
await RendererPlugins.resolveShowAttribute.call(this, node, params);
|
|
192
|
-
// Resolve the
|
|
193
|
-
await RendererPlugins.
|
|
158
|
+
// Resolve the :class attribute in the node.
|
|
159
|
+
await RendererPlugins.resolveClassAttribute.call(this, node, params);
|
|
194
160
|
// Resolve the :bind attribute in the node.
|
|
195
161
|
await RendererPlugins.resolveBindAttribute.call(this, node, params);
|
|
196
|
-
// Resolve all
|
|
197
|
-
await RendererPlugins.resolvePropAttributes.call(this, node, params);
|
|
198
|
-
// Resolve all :attributes in the node.
|
|
199
|
-
await RendererPlugins.resolveAttrAttributes.call(this, node, params);
|
|
200
|
-
// Resolve all @attributes in the node.
|
|
162
|
+
// Resolve all :on:event attributes in the node.
|
|
201
163
|
await RendererPlugins.resolveEventAttributes.call(this, node, params);
|
|
202
164
|
// Replace all the {{ variables }} in the text.
|
|
203
165
|
await RendererPlugins.resolveTextNodeExpressions.call(this, node, params);
|
|
166
|
+
// Resolve the :{attr} attribute in the node.
|
|
167
|
+
await RendererPlugins.resolveCustomAttribute.call(this, node, params);
|
|
204
168
|
}
|
|
205
169
|
// Return the input node, which should now be fully rendered.
|
|
206
170
|
return root;
|
package/dist/css_gen_basic.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { SafeStyleSheet } from "safevalues";
|
|
2
|
+
export default function rules(): SafeStyleSheet;
|
package/dist/css_gen_basic.js
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { safeStyleSheet } from "safevalues";
|
|
2
2
|
export default function rules() {
|
|
3
|
-
|
|
3
|
+
// Based on https://www.swyx.io/css-100-bytes.
|
|
4
|
+
return safeStyleSheet `
|
|
5
|
+
html {
|
|
6
|
+
max-width: 70ch;
|
|
7
|
+
padding: 2em 1em;
|
|
8
|
+
margin: auto;
|
|
9
|
+
line-height: 1.75;
|
|
10
|
+
font-size: 1.25em;
|
|
11
|
+
font-family: sans-serif;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
h1,h2,h3,h4,h5,h6 {
|
|
15
|
+
margin: 1em 0 0.5em;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
p,ul,ol {
|
|
19
|
+
margin-bottom: 1em;
|
|
20
|
+
color: #1d1d1d;
|
|
21
|
+
}`;
|
|
4
22
|
}
|
package/dist/dome.d.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import { ChildNode as _ChildNode, Element as _Element, Node as _Node, ParentNode as _ParentNode } from "domhandler";
|
|
2
|
-
type __Node = Node | _Node;
|
|
3
|
-
type __ParentNode = ParentNode | _ParentNode;
|
|
4
|
-
type __Element = Element | _Element;
|
|
5
|
-
type __ChildNode = ChildNode | _ChildNode;
|
|
6
1
|
/**
|
|
7
2
|
* Traverses the DOM tree starting from the given root node and yields each child node.
|
|
8
3
|
* Nodes in the `skip` set will be skipped during traversal.
|
|
@@ -12,29 +7,36 @@ type __ChildNode = ChildNode | _ChildNode;
|
|
|
12
7
|
* @returns A generator that yields each child node in the DOM tree.
|
|
13
8
|
*/
|
|
14
9
|
export declare function traverse(root: Node | DocumentFragment | Document, skip?: Set<Node>): Generator<ChildNode>;
|
|
10
|
+
export declare function hasProperty(obj: any, prop: string): boolean;
|
|
11
|
+
export declare function hasFunction(obj: any, func: string): boolean;
|
|
15
12
|
/**
|
|
16
13
|
* Converts from an attribute name to camelCase, e.g. `foo-bar` becomes `fooBar`.
|
|
17
14
|
* @param name attribute name
|
|
18
15
|
* @returns camel-cased attribute name
|
|
19
16
|
*/
|
|
20
17
|
export declare function attributeNameToCamelCase(name: string): string;
|
|
21
|
-
export declare function getAttribute(elem:
|
|
22
|
-
export declare function setAttribute(elem:
|
|
23
|
-
export declare function removeAttribute(elem:
|
|
24
|
-
export declare function cloneAttribute(elemFrom:
|
|
25
|
-
export declare function firstElementChild(elem:
|
|
26
|
-
export declare function replaceWith(original:
|
|
27
|
-
export declare function
|
|
28
|
-
export declare function
|
|
29
|
-
export declare function
|
|
30
|
-
export declare function insertBefore(parent:
|
|
31
|
-
export declare function innerHTML(elem: Element | _Element): string;
|
|
32
|
-
export declare function innerText(elem: Element | _Element): string | null;
|
|
33
|
-
export declare function getTextContent(elem: Element | _Element): string | null;
|
|
34
|
-
export declare function setTextContent(elem: Element | _Element, value: string): void;
|
|
35
|
-
export declare function getNodeValue(node: Node | _Node): string | null;
|
|
36
|
-
export declare function setNodeValue(node: Node | _Node, value: string | null): void;
|
|
37
|
-
export declare function createElement(tagName: string, document: Document | null): Element | _Element;
|
|
18
|
+
export declare function getAttribute(elem: Element | any, name: string): string | null;
|
|
19
|
+
export declare function setAttribute(elem: Element | any, name: string, value: string): void;
|
|
20
|
+
export declare function removeAttribute(elem: Element | any, name: string): void;
|
|
21
|
+
export declare function cloneAttribute(elemFrom: Element | any, elemDest: Element | any, name: string): void;
|
|
22
|
+
export declare function firstElementChild(elem: Element): Element | null;
|
|
23
|
+
export declare function replaceWith(original: ChildNode, ...replacement: Node[]): void;
|
|
24
|
+
export declare function replaceChildren(parent: ParentNode, ...nodes: Node[]): void;
|
|
25
|
+
export declare function appendChild(parent: Node, node: Node): Node;
|
|
26
|
+
export declare function removeChild(parent: ParentNode, node: Node): Node;
|
|
27
|
+
export declare function insertBefore(parent: Node, node: Node, reference: ChildNode | null): Node;
|
|
38
28
|
export declare function ellipsize(str: string | null, maxLength?: number): string;
|
|
39
|
-
export declare function nodeToString(node: Node
|
|
40
|
-
|
|
29
|
+
export declare function nodeToString(node: Node, maxLength?: number): string;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the directory name from a given file path.
|
|
32
|
+
* @param fpath - The file path.
|
|
33
|
+
* @returns The directory name.
|
|
34
|
+
*/
|
|
35
|
+
export declare function dirname(fpath: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Checks if a given file path is a relative path.
|
|
38
|
+
*
|
|
39
|
+
* @param fpath - The file path to check.
|
|
40
|
+
* @returns A boolean indicating whether the file path is relative or not.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isRelativePath(fpath: string): boolean;
|
package/dist/dome.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { safeAttrPrefix } from "safevalues";
|
|
2
|
+
import { safeElement } from "safevalues/dom";
|
|
3
|
+
const SAFE_ATTRS = [
|
|
4
|
+
safeAttrPrefix `:`,
|
|
5
|
+
safeAttrPrefix `style`,
|
|
6
|
+
safeAttrPrefix `class`,
|
|
7
|
+
];
|
|
3
8
|
/**
|
|
4
9
|
* Traverses the DOM tree starting from the given root node and yields each child node.
|
|
5
10
|
* Nodes in the `skip` set will be skipped during traversal.
|
|
@@ -26,7 +31,10 @@ export function* traverse(root, skip = new Set()) {
|
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
33
|
}
|
|
29
|
-
function
|
|
34
|
+
export function hasProperty(obj, prop) {
|
|
35
|
+
return typeof obj?.[prop] !== "undefined";
|
|
36
|
+
}
|
|
37
|
+
export function hasFunction(obj, func) {
|
|
30
38
|
return typeof obj?.[func] === "function";
|
|
31
39
|
}
|
|
32
40
|
/**
|
|
@@ -38,38 +46,39 @@ export function attributeNameToCamelCase(name) {
|
|
|
38
46
|
return name.replace(/-./g, (c) => c[1].toUpperCase());
|
|
39
47
|
}
|
|
40
48
|
export function getAttribute(elem, name) {
|
|
41
|
-
if (elem
|
|
42
|
-
return elem.attribs?.[name];
|
|
49
|
+
if (hasProperty(elem, "attribs"))
|
|
50
|
+
return elem.attribs?.[name] ?? null;
|
|
43
51
|
else
|
|
44
52
|
return elem.getAttribute?.(name);
|
|
45
53
|
}
|
|
46
54
|
export function setAttribute(elem, name, value) {
|
|
47
|
-
if (elem
|
|
55
|
+
if (hasProperty(elem, "attribs"))
|
|
48
56
|
elem.attribs[name] = value;
|
|
49
57
|
else
|
|
50
|
-
|
|
58
|
+
safeElement.setPrefixedAttribute(SAFE_ATTRS, elem, name, value);
|
|
51
59
|
}
|
|
52
60
|
export function removeAttribute(elem, name) {
|
|
53
|
-
if (elem
|
|
61
|
+
if (hasProperty(elem, "attribs"))
|
|
54
62
|
delete elem.attribs[name];
|
|
55
63
|
else
|
|
56
64
|
elem.removeAttribute?.(name);
|
|
57
65
|
}
|
|
58
66
|
export function cloneAttribute(elemFrom, elemDest, name) {
|
|
59
|
-
if (elemFrom
|
|
67
|
+
if (hasProperty(elemFrom, "attribs") && hasProperty(elemDest, "attribs")) {
|
|
60
68
|
elemDest.attribs[name] = elemFrom.attribs[name];
|
|
61
69
|
}
|
|
62
70
|
else {
|
|
63
|
-
const attr = elemFrom?.
|
|
64
|
-
elemDest
|
|
71
|
+
const attr = elemFrom?.getAttribute?.(name);
|
|
72
|
+
setAttribute(elemDest, name, attr || "");
|
|
65
73
|
}
|
|
66
74
|
}
|
|
67
75
|
export function firstElementChild(elem) {
|
|
68
|
-
if (elem
|
|
69
|
-
return elem.
|
|
76
|
+
if (hasProperty(elem, "firstElementChild")) {
|
|
77
|
+
return elem.firstElementChild;
|
|
70
78
|
}
|
|
71
79
|
else {
|
|
72
|
-
|
|
80
|
+
const children = Array.from(elem.children);
|
|
81
|
+
return children.find((child) => child.nodeType === 1);
|
|
73
82
|
}
|
|
74
83
|
}
|
|
75
84
|
export function replaceWith(original, ...replacement) {
|
|
@@ -87,6 +96,15 @@ export function replaceWith(original, ...replacement) {
|
|
|
87
96
|
.concat(Array.from(parent.childNodes).slice(index + 1));
|
|
88
97
|
}
|
|
89
98
|
}
|
|
99
|
+
export function replaceChildren(parent, ...nodes) {
|
|
100
|
+
if (hasFunction(parent, "replaceChildren")) {
|
|
101
|
+
parent.replaceChildren(...nodes);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
parent.childNodes = nodes;
|
|
105
|
+
nodes.forEach((node) => (node.parentNode = parent));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
90
108
|
export function appendChild(parent, node) {
|
|
91
109
|
if (hasFunction(node, "appendChild")) {
|
|
92
110
|
return parent.appendChild(node);
|
|
@@ -102,18 +120,8 @@ export function removeChild(parent, node) {
|
|
|
102
120
|
return parent.removeChild(node);
|
|
103
121
|
}
|
|
104
122
|
else {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return elem;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
export function replaceChildren(parent, ...nodes) {
|
|
111
|
-
if (hasFunction(parent, "replaceChildren")) {
|
|
112
|
-
parent.replaceChildren(...nodes);
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
parent.childNodes = nodes;
|
|
116
|
-
nodes.forEach((node) => (node.parentNode = parent));
|
|
123
|
+
replaceChildren(parent, ...Array.from(parent.childNodes).filter((child) => child !== node));
|
|
124
|
+
return node;
|
|
117
125
|
}
|
|
118
126
|
}
|
|
119
127
|
export function insertBefore(parent, node, reference) {
|
|
@@ -128,48 +136,6 @@ export function insertBefore(parent, node, reference) {
|
|
|
128
136
|
return node;
|
|
129
137
|
}
|
|
130
138
|
}
|
|
131
|
-
export function innerHTML(elem) {
|
|
132
|
-
if (elem instanceof _Element)
|
|
133
|
-
return DomUtils.getInnerHTML(elem);
|
|
134
|
-
else
|
|
135
|
-
return elem.innerHTML;
|
|
136
|
-
}
|
|
137
|
-
export function innerText(elem) {
|
|
138
|
-
if (elem instanceof _Element)
|
|
139
|
-
return DomUtils.innerText(elem);
|
|
140
|
-
else
|
|
141
|
-
return elem.innerText;
|
|
142
|
-
}
|
|
143
|
-
export function getTextContent(elem) {
|
|
144
|
-
if (elem instanceof _Element)
|
|
145
|
-
return DomUtils.textContent(elem);
|
|
146
|
-
else
|
|
147
|
-
return elem.textContent;
|
|
148
|
-
}
|
|
149
|
-
export function setTextContent(elem, value) {
|
|
150
|
-
if (elem instanceof _Element)
|
|
151
|
-
elem.children = [new _Text(value)];
|
|
152
|
-
else
|
|
153
|
-
elem.textContent = value;
|
|
154
|
-
}
|
|
155
|
-
export function getNodeValue(node) {
|
|
156
|
-
if (node instanceof _Node)
|
|
157
|
-
return node.data;
|
|
158
|
-
else
|
|
159
|
-
return node.nodeValue;
|
|
160
|
-
}
|
|
161
|
-
export function setNodeValue(node, value) {
|
|
162
|
-
if (node instanceof _Node)
|
|
163
|
-
node.data = value;
|
|
164
|
-
else
|
|
165
|
-
node.nodeValue = value;
|
|
166
|
-
}
|
|
167
|
-
export function createElement(tagName, document) {
|
|
168
|
-
if (document)
|
|
169
|
-
return document.createElement(tagName);
|
|
170
|
-
else
|
|
171
|
-
return new _Element(tagName, {});
|
|
172
|
-
}
|
|
173
139
|
export function ellipsize(str, maxLength = 0) {
|
|
174
140
|
if (!str)
|
|
175
141
|
return "";
|
|
@@ -179,5 +145,30 @@ export function ellipsize(str, maxLength = 0) {
|
|
|
179
145
|
return str.slice(0, maxLength - 1) + "…";
|
|
180
146
|
}
|
|
181
147
|
export function nodeToString(node, maxLength = 0) {
|
|
182
|
-
return ellipsize(node.outerHTML ||
|
|
148
|
+
return ellipsize(node.outerHTML || node.nodeValue || String(node), maxLength);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Returns the directory name from a given file path.
|
|
152
|
+
* @param fpath - The file path.
|
|
153
|
+
* @returns The directory name.
|
|
154
|
+
*/
|
|
155
|
+
export function dirname(fpath) {
|
|
156
|
+
if (!fpath.includes("/")) {
|
|
157
|
+
return "";
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
return fpath.split("/").slice(0, -1).join("/");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Checks if a given file path is a relative path.
|
|
165
|
+
*
|
|
166
|
+
* @param fpath - The file path to check.
|
|
167
|
+
* @returns A boolean indicating whether the file path is relative or not.
|
|
168
|
+
*/
|
|
169
|
+
export function isRelativePath(fpath) {
|
|
170
|
+
return (!fpath.includes("://") &&
|
|
171
|
+
!fpath.startsWith("/") &&
|
|
172
|
+
!fpath.startsWith("#") &&
|
|
173
|
+
!fpath.startsWith("data:"));
|
|
183
174
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ParserParams, RenderParams } from "./interfaces.js";
|
|
2
2
|
import { IRenderer } from "./core.js";
|
|
3
3
|
export declare class Renderer extends IRenderer {
|
|
4
|
-
parseHTML(content: string, params?: ParserParams): DocumentFragment;
|
|
4
|
+
parseHTML(content: string, params?: ParserParams): Document | DocumentFragment;
|
|
5
5
|
serializeHTML(root: Node | DocumentFragment | Document): string;
|
|
6
|
+
createElement(tag: string, owner?: Document | null): Element;
|
|
7
|
+
textContent(node: Node, content: string): void;
|
|
6
8
|
fetchLocal(fpath: string, params?: RenderParams & ParserParams): Promise<string>;
|
|
7
9
|
}
|
|
8
10
|
export declare const Mancha: Renderer;
|