mancha 0.5.4 → 0.6.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/browser.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { IRenderer } from "./core";
2
- import { ParserParams, RenderParams } from "./interfaces";
3
- declare class RendererImpl extends IRenderer {
1
+ import { IRenderer } from "./core.js";
2
+ import { ParserParams, RenderParams } from "./interfaces.js";
3
+ declare class Renderer extends IRenderer {
4
4
  protected readonly dirpath: string;
5
5
  parseHTML(content: string, params?: ParserParams): DocumentFragment;
6
6
  serializeHTML(root: Node | DocumentFragment): string;
7
7
  preprocessLocal(fpath: string, params?: RenderParams & ParserParams): Promise<DocumentFragment>;
8
8
  }
9
- declare const Mancha: RendererImpl;
9
+ declare const Mancha: Renderer;
10
10
  export default Mancha;
package/dist/browser.js CHANGED
@@ -1,8 +1,6 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const core_1 = require("./core");
4
- class RendererImpl extends core_1.IRenderer {
5
- dirpath = (0, core_1.dirname)(self.location.href);
1
+ import { dirname, IRenderer } from "./core.js";
2
+ class Renderer extends IRenderer {
3
+ dirpath = dirname(self.location.href);
6
4
  parseHTML(content, params = { root: false }) {
7
5
  if (params.root) {
8
6
  return new DOMParser().parseFromString(content, "text/html");
@@ -21,17 +19,18 @@ class RendererImpl extends core_1.IRenderer {
21
19
  return this.preprocessRemote(fpath, params);
22
20
  }
23
21
  }
24
- const Mancha = new RendererImpl();
22
+ const Mancha = new Renderer();
25
23
  self["Mancha"] = Mancha;
26
24
  const currentScript = self.document?.currentScript;
27
25
  if (self.document?.currentScript?.hasAttribute("init")) {
28
- Mancha.update({ ...currentScript?.dataset });
29
26
  const debug = currentScript?.hasAttribute("debug");
30
27
  const cachePolicy = currentScript?.getAttribute("cache");
31
28
  const targets = currentScript?.getAttribute("target")?.split(",") || ["body"];
32
- targets.map(async (target) => {
33
- const fragment = self.document.querySelector(target);
34
- await Mancha.debug(debug).mount(fragment, { cache: cachePolicy });
29
+ window.addEventListener("load", () => {
30
+ targets.map(async (target) => {
31
+ const fragment = self.document.querySelector(target);
32
+ await Mancha.debug(debug).mount(fragment, { cache: cachePolicy });
33
+ });
35
34
  });
36
35
  }
37
- exports.default = Mancha;
36
+ export default Mancha;
package/dist/cli.js CHANGED
@@ -1,21 +1,24 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- const yargs_1 = require("yargs");
5
- const helpers_1 = require("yargs/helpers");
6
- const index_1 = require("./index");
7
- const fs = require("fs/promises");
8
- const args = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
2
+ import * as fs from "fs/promises";
3
+ import yargs from "yargs";
4
+ import { hideBin } from "yargs/helpers";
5
+ import { Mancha } from "./index.js";
6
+ const args = yargs(hideBin(process.argv))
9
7
  .describe("input", "Input HMTL file to render")
10
8
  .describe("output", "Output file, defaults to stdout")
11
9
  .describe("vars", "JSON-formatted variables")
10
+ .describe("debug", "Print Mancha.js debugging information")
12
11
  .demand(["input"])
13
12
  .parse();
14
- index_1.Mancha.preprocessLocal(args["input"], JSON.parse(args.vars || "{}")).then((result) => {
13
+ Mancha.debug(args.debug);
14
+ new Promise(async (resolve, reject) => {
15
+ await Mancha.update(JSON.parse(args.vars || "{}"));
16
+ const fragment = await Mancha.preprocessLocal(args["input"]);
17
+ await Mancha.renderNode(fragment);
15
18
  if (!args.output || args.output === "-") {
16
- console.log(result + "\n");
19
+ console.log(Mancha.serializeHTML(fragment) + "\n");
17
20
  }
18
21
  else {
19
- return fs.writeFile(args.output, index_1.Mancha.serializeHTML(result));
22
+ await fs.writeFile(args.output, Mancha.serializeHTML(fragment));
20
23
  }
21
24
  });
package/dist/core.d.ts CHANGED
@@ -1,20 +1,17 @@
1
- import { ReactiveProxyStore } from "./reactive";
2
- import { ParserParams, RenderParams } from "./interfaces";
1
+ import { ReactiveProxyStore } from "./reactive.js";
2
+ import { ParserParams, RenderParams } from "./interfaces.js";
3
3
  export type EvalListener = (result: any, dependencies: string[]) => any;
4
4
  export declare function traverse(root: Node | DocumentFragment | Document, skip?: Set<Node>): Generator<ChildNode>;
5
5
  export declare function dirname(fpath: string): string;
6
6
  export declare function isRelativePath(fpath: string): boolean;
7
7
  export declare function makeEvalFunction(code: string, args?: string[]): Function;
8
- export declare function safeEval(context: any, code: string, args?: {
9
- [key: string]: any;
10
- }): Promise<any>;
11
8
  export declare abstract class IRenderer extends ReactiveProxyStore {
12
9
  protected debugging: boolean;
13
10
  protected readonly dirpath: string;
14
11
  protected readonly evalkeys: string[];
15
12
  protected readonly expressionCache: Map<string, Function>;
16
13
  protected readonly evalCallbacks: Map<string, EvalListener[]>;
17
- readonly skipNodes: Set<Node>;
14
+ readonly _skipNodes: Set<Node>;
18
15
  abstract parseHTML(content: string, params?: ParserParams): DocumentFragment;
19
16
  abstract serializeHTML(root: DocumentFragment | Node): string;
20
17
  debug(flag: boolean): this;
@@ -33,6 +30,6 @@ export declare abstract class IRenderer extends ReactiveProxyStore {
33
30
  [key: string]: any;
34
31
  }, callback: EvalListener): Promise<void>;
35
32
  preprocessNode(root: Document | DocumentFragment | Node, params?: RenderParams): Promise<void>;
36
- renderNode(root: Document | DocumentFragment | Node, params?: RenderParams): Promise<void>;
33
+ renderNode(root: Document | DocumentFragment | Node, params?: RenderParams): Promise<Document | DocumentFragment | Node>;
37
34
  mount(root: Document | DocumentFragment | Node, params?: RenderParams): Promise<void>;
38
35
  }
package/dist/core.js CHANGED
@@ -1,10 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.IRenderer = exports.safeEval = exports.makeEvalFunction = exports.isRelativePath = exports.dirname = exports.traverse = void 0;
4
- const reactive_1 = require("./reactive");
5
- const iterator_1 = require("./iterator");
6
- const plugins_1 = require("./plugins");
7
- function* traverse(root, skip = new Set()) {
1
+ import { ReactiveProxyStore } from "./reactive.js";
2
+ import { Iterator } from "./iterator.js";
3
+ import { RendererPlugins } from "./plugins.js";
4
+ export function* traverse(root, skip = new Set()) {
8
5
  const explored = new Set();
9
6
  const frontier = Array.from(root.childNodes).filter((node) => !skip.has(node));
10
7
  // Also yield the root node.
@@ -22,8 +19,7 @@ function* traverse(root, skip = new Set()) {
22
19
  }
23
20
  }
24
21
  }
25
- exports.traverse = traverse;
26
- function dirname(fpath) {
22
+ export function dirname(fpath) {
27
23
  if (!fpath.includes("/")) {
28
24
  return "";
29
25
  }
@@ -31,30 +27,22 @@ function dirname(fpath) {
31
27
  return fpath.split("/").slice(0, -1).join("/");
32
28
  }
33
29
  }
34
- exports.dirname = dirname;
35
- function isRelativePath(fpath) {
30
+ export function isRelativePath(fpath) {
36
31
  return (!fpath.includes("://") &&
37
32
  !fpath.startsWith("/") &&
38
33
  !fpath.startsWith("#") &&
39
34
  !fpath.startsWith("data:"));
40
35
  }
41
- exports.isRelativePath = isRelativePath;
42
- function makeEvalFunction(code, args = []) {
36
+ export function makeEvalFunction(code, args = []) {
43
37
  return new Function(...args, `with (this) { return (async () => (${code}))(); }`);
44
38
  }
45
- exports.makeEvalFunction = makeEvalFunction;
46
- function safeEval(context, code, args = {}) {
47
- const inner = `with (this) { return (async () => (${code}))(); }`;
48
- return new Function(...Object.keys(args), inner).call(context, ...Object.values(args));
49
- }
50
- exports.safeEval = safeEval;
51
- class IRenderer extends reactive_1.ReactiveProxyStore {
39
+ export class IRenderer extends ReactiveProxyStore {
52
40
  debugging = false;
53
41
  dirpath = "";
54
42
  evalkeys = ["$elem", "$event"];
55
43
  expressionCache = new Map();
56
44
  evalCallbacks = new Map();
57
- skipNodes = new Set();
45
+ _skipNodes = new Set();
58
46
  debug(flag) {
59
47
  this.debugging = flag;
60
48
  return this;
@@ -80,8 +68,10 @@ class IRenderer extends reactive_1.ReactiveProxyStore {
80
68
  });
81
69
  }
82
70
  async preprocessRemote(fpath, params) {
83
- const cache = params?.cache || "default";
84
- const content = await fetch(fpath, { cache }).then((res) => res.text());
71
+ const fetchOptions = {};
72
+ if (params?.cache)
73
+ fetchOptions.cache = params.cache;
74
+ const content = await fetch(fpath, fetchOptions).then((res) => res.text());
85
75
  return this.preprocessString(content, {
86
76
  ...params,
87
77
  dirpath: dirname(fpath),
@@ -89,7 +79,8 @@ class IRenderer extends reactive_1.ReactiveProxyStore {
89
79
  });
90
80
  }
91
81
  clone() {
92
- return new this.constructor(Object.fromEntries(this.store.entries()));
82
+ const instance = new this.constructor(Object.fromEntries(this.store.entries()));
83
+ return instance.debug(this.debugging);
93
84
  }
94
85
  log(...args) {
95
86
  if (this.debugging)
@@ -102,16 +93,24 @@ class IRenderer extends reactive_1.ReactiveProxyStore {
102
93
  return this.expressionCache.get(expr);
103
94
  }
104
95
  async eval(expr, args = {}) {
105
- const fn = this.cachedExpressionFunction(expr);
106
- const vals = this.evalkeys.map((key) => args[key]);
107
- if (Object.keys(args).some((key) => !this.evalkeys.includes(key))) {
108
- throw new Error(`Invalid argument key, must be one of: ${this.evalkeys.join(", ")}`);
96
+ if (this.store.has(expr)) {
97
+ // Shortcut: if the expression is just an item from the value store, use that directly.
98
+ const result = this.get(expr);
99
+ return [result, [expr]];
100
+ }
101
+ else {
102
+ // Otherwise, perform the expression evaluation.
103
+ const fn = this.cachedExpressionFunction(expr);
104
+ const vals = this.evalkeys.map((key) => args[key]);
105
+ if (Object.keys(args).some((key) => !this.evalkeys.includes(key))) {
106
+ throw new Error(`Invalid argument key, must be one of: ${this.evalkeys.join(", ")}`);
107
+ }
108
+ const [result, dependencies] = await this.trace(async function () {
109
+ return fn.call(this, ...vals);
110
+ });
111
+ this.log(`eval \`${expr}\` => `, result, `[ ${dependencies.join(", ")} ]`);
112
+ return [result, dependencies];
109
113
  }
110
- const [result, dependencies] = await this.trace(async function () {
111
- return fn.call(this, ...vals);
112
- });
113
- this.log(`eval \`${expr}\` => `, result, `[ ${dependencies.join(", ")} ]`);
114
- return [result, dependencies];
115
114
  }
116
115
  watchExpr(expr, args, callback) {
117
116
  // Early exit: this eval has already been registered, we just need to add our callback.
@@ -140,12 +139,12 @@ class IRenderer extends reactive_1.ReactiveProxyStore {
140
139
  }
141
140
  async preprocessNode(root, params) {
142
141
  params = Object.assign({ dirpath: this.dirpath, maxdepth: 10 }, params);
143
- const promises = new iterator_1.Iterator(traverse(root, this.skipNodes)).map(async (node) => {
142
+ const promises = new Iterator(traverse(root, this._skipNodes)).map(async (node) => {
144
143
  this.log("Preprocessing node:\n", node);
145
144
  // Resolve all the includes in the node.
146
- await plugins_1.RendererPlugins.resolveIncludes.call(this, node, params);
145
+ await RendererPlugins.resolveIncludes.call(this, node, params);
147
146
  // Resolve all the relative paths in the node.
148
- await plugins_1.RendererPlugins.rebaseRelativePaths.call(this, node, params);
147
+ await RendererPlugins.rebaseRelativePaths.call(this, node, params);
149
148
  });
150
149
  // Wait for all the rendering operations to complete.
151
150
  await Promise.all(promises.generator());
@@ -153,29 +152,33 @@ class IRenderer extends reactive_1.ReactiveProxyStore {
153
152
  async renderNode(root, params) {
154
153
  // Iterate over all the nodes and apply appropriate handlers.
155
154
  // Do these steps one at a time to avoid any potential race conditions.
156
- for (const node of traverse(root, this.skipNodes)) {
155
+ for (const node of traverse(root, this._skipNodes)) {
157
156
  this.log("Rendering node:\n", node);
158
157
  // Resolve the :data attribute in the node.
159
- await plugins_1.RendererPlugins.resolveDataAttribute.call(this, node, params);
158
+ await RendererPlugins.resolveDataAttribute.call(this, node, params);
160
159
  // Resolve the :for attribute in the node.
161
- await plugins_1.RendererPlugins.resolveForAttribute.call(this, node, params);
160
+ await RendererPlugins.resolveForAttribute.call(this, node, params);
161
+ // Resolve the $text attribute in the node.
162
+ await RendererPlugins.resolveTextAttributes.call(this, node, params);
162
163
  // Resolve the $html attribute in the node.
163
- await plugins_1.RendererPlugins.resolveHtmlAttribute.call(this, node, params);
164
+ await RendererPlugins.resolveHtmlAttribute.call(this, node, params);
164
165
  // Resolve the :show attribute in the node.
165
- await plugins_1.RendererPlugins.resolveShowAttribute.call(this, node, params);
166
+ await RendererPlugins.resolveShowAttribute.call(this, node, params);
166
167
  // Resolve the @watch attribute in the node.
167
- await plugins_1.RendererPlugins.resolveWatchAttribute.call(this, node, params);
168
+ await RendererPlugins.resolveWatchAttribute.call(this, node, params);
168
169
  // Resolve the :bind attribute in the node.
169
- await plugins_1.RendererPlugins.resolveBindAttribute.call(this, node, params);
170
+ await RendererPlugins.resolveBindAttribute.call(this, node, params);
170
171
  // Resolve all $attributes in the node.
171
- await plugins_1.RendererPlugins.resolvePropAttributes.call(this, node, params);
172
+ await RendererPlugins.resolvePropAttributes.call(this, node, params);
172
173
  // Resolve all :attributes in the node.
173
- await plugins_1.RendererPlugins.resolveAttrAttributes.call(this, node, params);
174
+ await RendererPlugins.resolveAttrAttributes.call(this, node, params);
174
175
  // Resolve all @attributes in the node.
175
- await plugins_1.RendererPlugins.resolveEventAttributes.call(this, node, params);
176
+ await RendererPlugins.resolveEventAttributes.call(this, node, params);
176
177
  // Replace all the {{ variables }} in the text.
177
- await plugins_1.RendererPlugins.resolveTextNodeExpressions.call(this, node, params);
178
+ await RendererPlugins.resolveTextNodeExpressions.call(this, node, params);
178
179
  }
180
+ // Return the input node, which should now be fully rendered.
181
+ return root;
179
182
  }
180
183
  async mount(root, params) {
181
184
  // Preprocess all the elements recursively first.
@@ -184,4 +187,3 @@ class IRenderer extends reactive_1.ReactiveProxyStore {
184
187
  await this.renderNode(root, params);
185
188
  }
186
189
  }
187
- exports.IRenderer = IRenderer;
package/dist/dome.d.ts ADDED
@@ -0,0 +1,27 @@
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
+ /**
7
+ * Converts from an attribute name to camelCase, e.g. `foo-bar` becomes `fooBar`.
8
+ * @param name attribute name
9
+ * @returns camel-cased attribute name
10
+ */
11
+ export declare function attributeNameToCamelCase(name: string): string;
12
+ export declare function getAttribute(elem: __Element, name: string): string | null;
13
+ export declare function setAttribute(elem: __Element, name: string, value: string): void;
14
+ export declare function removeAttribute(elem: __Element, name: string): void;
15
+ export declare function replaceWith(original: __ChildNode, ...replacement: __Node[]): void;
16
+ export declare function appendChild(parent: __Node, node: __Node): __Node;
17
+ export declare function removeChild(parent: __Node, node: __Node): __Node;
18
+ export declare function replaceChildren(parent: __ParentNode, ...nodes: __Node[]): void;
19
+ export declare function insertBefore(parent: __Node, node: __Node, reference: __ChildNode | null): __Node;
20
+ export declare function innerHTML(elem: Element | _Element): string;
21
+ export declare function innerText(elem: Element | _Element): string | null;
22
+ export declare function getTextContent(elem: Element | _Element): string | null;
23
+ export declare function setTextContent(elem: Element | _Element, value: string): void;
24
+ export declare function getNodeValue(node: Node | _Node): string | null;
25
+ export declare function setNodeValue(node: Node | _Node, value: string | null): void;
26
+ export declare function createElement(tagName: string, document: Document | null): Element | _Element;
27
+ export {};
package/dist/dome.js ADDED
@@ -0,0 +1,129 @@
1
+ import { Element as _Element, Node as _Node, Text as _Text, } from "domhandler";
2
+ import { DomUtils } from "htmlparser2";
3
+ function hasFunction(obj, func) {
4
+ return typeof obj?.[func] === "function";
5
+ }
6
+ /**
7
+ * Converts from an attribute name to camelCase, e.g. `foo-bar` becomes `fooBar`.
8
+ * @param name attribute name
9
+ * @returns camel-cased attribute name
10
+ */
11
+ export function attributeNameToCamelCase(name) {
12
+ return name.replace(/-./g, (c) => c[1].toUpperCase());
13
+ }
14
+ export function getAttribute(elem, name) {
15
+ if (elem instanceof _Element)
16
+ return elem.attribs?.[name];
17
+ else
18
+ return elem.getAttribute?.(name);
19
+ }
20
+ export function setAttribute(elem, name, value) {
21
+ if (elem instanceof _Element)
22
+ elem.attribs[name] = value;
23
+ else
24
+ elem.setAttribute?.(name, value);
25
+ }
26
+ export function removeAttribute(elem, name) {
27
+ if (elem instanceof _Element)
28
+ delete elem.attribs[name];
29
+ else
30
+ elem.removeAttribute?.(name);
31
+ }
32
+ export function replaceWith(original, ...replacement) {
33
+ if (hasFunction(original, "replaceWith")) {
34
+ return original.replaceWith(...replacement);
35
+ }
36
+ else {
37
+ const elem = original;
38
+ const parent = elem.parentNode;
39
+ const index = Array.from(parent.childNodes).indexOf(elem);
40
+ replacement.forEach((elem) => (elem.parentNode = parent));
41
+ parent.childNodes = []
42
+ .concat(Array.from(parent.childNodes).slice(0, index))
43
+ .concat(replacement)
44
+ .concat(Array.from(parent.childNodes).slice(index + 1));
45
+ }
46
+ }
47
+ export function appendChild(parent, node) {
48
+ if (hasFunction(node, "appendChild")) {
49
+ return parent.appendChild(node);
50
+ }
51
+ else {
52
+ parent.childNodes.push(node);
53
+ node.parentNode = parent;
54
+ return node;
55
+ }
56
+ }
57
+ export function removeChild(parent, node) {
58
+ if (hasFunction(node, "removeChild")) {
59
+ return parent.removeChild(node);
60
+ }
61
+ else {
62
+ const elem = node;
63
+ parent.childNodes = parent.children.filter((child) => child !== elem);
64
+ return elem;
65
+ }
66
+ }
67
+ export function replaceChildren(parent, ...nodes) {
68
+ if (hasFunction(parent, "replaceChildren")) {
69
+ parent.replaceChildren(...nodes);
70
+ }
71
+ else {
72
+ parent.childNodes = nodes;
73
+ nodes.forEach((node) => (node.parentNode = parent));
74
+ }
75
+ }
76
+ export function insertBefore(parent, node, reference) {
77
+ if (!reference) {
78
+ return appendChild(parent, node);
79
+ }
80
+ else if (hasFunction(parent, "insertBefore")) {
81
+ return parent.insertBefore(node, reference);
82
+ }
83
+ else {
84
+ replaceWith(reference, node, reference);
85
+ return node;
86
+ }
87
+ }
88
+ export function innerHTML(elem) {
89
+ if (elem instanceof _Element)
90
+ return DomUtils.getInnerHTML(elem);
91
+ else
92
+ return elem.innerHTML;
93
+ }
94
+ export function innerText(elem) {
95
+ if (elem instanceof _Element)
96
+ return DomUtils.innerText(elem);
97
+ else
98
+ return elem.innerText;
99
+ }
100
+ export function getTextContent(elem) {
101
+ if (elem instanceof _Element)
102
+ return DomUtils.textContent(elem);
103
+ else
104
+ return elem.textContent;
105
+ }
106
+ export function setTextContent(elem, value) {
107
+ if (elem instanceof _Element)
108
+ elem.children = [new _Text(value)];
109
+ else
110
+ elem.textContent = value;
111
+ }
112
+ export function getNodeValue(node) {
113
+ if (node instanceof _Node)
114
+ return node.data;
115
+ else
116
+ return node.nodeValue;
117
+ }
118
+ export function setNodeValue(node, value) {
119
+ if (node instanceof _Node)
120
+ node.data = value;
121
+ else
122
+ node.nodeValue = value;
123
+ }
124
+ export function createElement(tagName, document) {
125
+ if (document)
126
+ return document.createElement(tagName);
127
+ else
128
+ return new _Element(tagName, {});
129
+ }
@@ -11,5 +11,5 @@ import * as stream from "stream";
11
11
  */
12
12
  declare function mancha(context?: {
13
13
  [key: string]: string;
14
- }, wwwroot?: string): stream.Transform;
14
+ }): stream.Transform;
15
15
  export default mancha;
@@ -1,9 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const path = require("path");
4
- const stream = require("stream");
5
- const through = require("through2");
6
- const index_1 = require("./index");
1
+ import * as path from "path";
2
+ import * as stream from "stream";
3
+ import * as through from "through2";
4
+ import { Renderer } from "./index.js";
7
5
  /**
8
6
  * Main entrypoint to be used in Gulp. Usage:
9
7
  *
@@ -13,8 +11,8 @@ const index_1 = require("./index");
13
11
  * @param context <key, value> pairs of literal string replacements. `key` will become `{{ key }}`
14
12
  * before replacing it with `value` in the processed files.
15
13
  */
16
- function mancha(context = {}, wwwroot = process.cwd()) {
17
- const renderer = new index_1.RendererImpl(context);
14
+ function mancha(context = {}) {
15
+ const renderer = new Renderer(context);
18
16
  return through.obj(function (file, encoding, callback) {
19
17
  const catcher = (err) => {
20
18
  console.log(err);
@@ -67,4 +65,4 @@ function mancha(context = {}, wwwroot = process.cwd()) {
67
65
  }
68
66
  });
69
67
  }
70
- exports.default = mancha;
68
+ export default mancha;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
- import { RendererImpl as WorkerRendererImpl } from "./worker";
2
- import { ParserParams, RenderParams } from "./interfaces";
1
+ import { ParserParams, RenderParams } from "./interfaces.js";
2
+ import { IRenderer } from "./core.js";
3
3
  /** The Node Mancha renderer is just like the worker renderer, but it also uses the filesystem. */
4
- export declare class RendererImpl extends WorkerRendererImpl {
4
+ export declare class Renderer extends IRenderer {
5
+ parseHTML(content: string, params?: ParserParams): DocumentFragment;
6
+ serializeHTML(root: Node | DocumentFragment | Document): string;
5
7
  fetchLocal(fpath: string, params?: RenderParams & ParserParams): Promise<string>;
6
8
  }
7
- export declare const Mancha: RendererImpl;
9
+ export declare const Mancha: Renderer;
package/dist/index.js CHANGED
@@ -1,14 +1,28 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Mancha = exports.RendererImpl = void 0;
4
- const fs = require("fs/promises");
5
- const worker_1 = require("./worker");
1
+ import * as fs from "fs/promises";
2
+ import { JSDOM } from "jsdom";
3
+ import { IRenderer } from "./core.js";
6
4
  /** The Node Mancha renderer is just like the worker renderer, but it also uses the filesystem. */
7
- class RendererImpl extends worker_1.RendererImpl {
5
+ export class Renderer extends IRenderer {
6
+ parseHTML(content, params = { root: false }) {
7
+ const dom = new JSDOM();
8
+ if (params.root) {
9
+ const DOMParser = dom.window.DOMParser;
10
+ return new DOMParser().parseFromString(content, "text/html");
11
+ }
12
+ else {
13
+ const range = dom.window.document.createRange();
14
+ range.selectNodeContents(dom.window.document.body);
15
+ return range.createContextualFragment(content);
16
+ }
17
+ }
18
+ serializeHTML(root) {
19
+ const dom = new JSDOM();
20
+ const XMLSerializer = dom.window.XMLSerializer;
21
+ return new XMLSerializer().serializeToString(root).replace(/\s?xmlns="[^"]+"/gm, "");
22
+ }
8
23
  async fetchLocal(fpath, params) {
9
24
  return fs.readFile(fpath, { encoding: params?.encoding || "utf8" });
10
25
  }
11
26
  }
12
- exports.RendererImpl = RendererImpl;
13
27
  // Export the renderer instance directly.
14
- exports.Mancha = new RendererImpl();
28
+ export const Mancha = new Renderer();
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { IRenderer } from "./core";
2
+ import { IRenderer } from "./core.js";
3
3
  export interface ParserParams {
4
4
  /** Whether the file parsed is a root document, or a document fragment. */
5
5
  root?: boolean;
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
package/dist/iterator.js CHANGED
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Iterator = void 0;
4
- class Iterator {
1
+ export class Iterator {
5
2
  iterable;
6
3
  constructor(iter) {
7
4
  this.iterable = iter;
@@ -45,4 +42,3 @@ class Iterator {
45
42
  return aVal.done === bVal.done;
46
43
  }
47
44
  }
48
- exports.Iterator = Iterator;