feat: Reinitialize frontend with SvelteKit and TypeScript

- Delete old Vite+Svelte frontend
- Initialize new SvelteKit project with TypeScript
- Configure Tailwind CSS v4 + DaisyUI
- Implement JWT authentication with auto-refresh
- Create login page with form validation (Zod)
- Add protected route guards
- Update Docker configuration for single-stage build
- Add E2E tests with Playwright (6/11 passing)
- Fix Svelte 5 reactivity with $state() runes

Known issues:
- 5 E2E tests failing (timing/async issues)
- Token refresh implementation needs debugging
- Validation error display timing
This commit is contained in:
2026-02-17 16:19:59 -05:00
parent 54df6018f5
commit de2d83092e
28274 changed files with 3816354 additions and 90 deletions

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=INodeFilter.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"INodeFilter.cjs","sourceRoot":"","sources":["../../src/tree-walker/INodeFilter.ts"],"names":[],"mappings":""}

View File

@@ -0,0 +1,6 @@
import Node from '../nodes/node/Node.cjs';
type INodeFilter = ((node: Node) => number) | {
acceptNode(node: Node): number;
};
export default INodeFilter;
//# sourceMappingURL=INodeFilter.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"INodeFilter.d.ts","sourceRoot":"","sources":["../../src/tree-walker/INodeFilter.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,uBAAuB,CAAC;AAEzC,KAAK,WAAW,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,GAAG;IAAE,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAA;CAAE,CAAC;AAEjF,eAAe,WAAW,CAAC"}

View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = {
FILTER_ACCEPT: 1,
FILTER_REJECT: 2,
FILTER_SKIP: 3,
SHOW_ALL: -1,
SHOW_ELEMENT: 1,
SHOW_ATTRIBUTE: 2,
SHOW_TEXT: 4,
SHOW_CDATA_SECTION: 8,
SHOW_ENTITY_REFERENCE: 16,
SHOW_ENTITY: 32,
SHOW_PROCESSING_INSTRUCTION: 64,
SHOW_COMMENT: 128,
SHOW_DOCUMENT: 256,
SHOW_DOCUMENT_TYPE: 512,
SHOW_DOCUMENT_FRAGMENT: 1024,
SHOW_NOTATION: 2048
};
//# sourceMappingURL=NodeFilter.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"NodeFilter.cjs","sourceRoot":"","sources":["../../src/tree-walker/NodeFilter.ts"],"names":[],"mappings":";;AAAA,kBAAe;IACd,aAAa,EAAE,CAAC;IAChB,aAAa,EAAE,CAAC;IAChB,WAAW,EAAE,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC;IACZ,YAAY,EAAE,CAAC;IACf,cAAc,EAAE,CAAC;IACjB,SAAS,EAAE,CAAC;IACZ,kBAAkB,EAAE,CAAC;IACrB,qBAAqB,EAAE,EAAE;IACzB,WAAW,EAAE,EAAE;IACf,2BAA2B,EAAE,EAAE;IAC/B,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,GAAG;IAClB,kBAAkB,EAAE,GAAG;IACvB,sBAAsB,EAAE,IAAI;IAC5B,aAAa,EAAE,IAAI;CACnB,CAAC"}

View File

@@ -0,0 +1,20 @@
declare const _default: {
FILTER_ACCEPT: number;
FILTER_REJECT: number;
FILTER_SKIP: number;
SHOW_ALL: number;
SHOW_ELEMENT: number;
SHOW_ATTRIBUTE: number;
SHOW_TEXT: number;
SHOW_CDATA_SECTION: number;
SHOW_ENTITY_REFERENCE: number;
SHOW_ENTITY: number;
SHOW_PROCESSING_INSTRUCTION: number;
SHOW_COMMENT: number;
SHOW_DOCUMENT: number;
SHOW_DOCUMENT_TYPE: number;
SHOW_DOCUMENT_FRAGMENT: number;
SHOW_NOTATION: number;
};
export default _default;
//# sourceMappingURL=NodeFilter.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"NodeFilter.d.ts","sourceRoot":"","sources":["../../src/tree-walker/NodeFilter.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,wBAiBE"}

View File

@@ -0,0 +1,33 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const NodeFilter_js_1 = __importDefault(require("./NodeFilter.cjs"));
exports.default = {
/* ELEMENT_NODE */
1: NodeFilter_js_1.default.SHOW_ELEMENT,
/* ATTRIBUTE_NODE */
2: NodeFilter_js_1.default.SHOW_ATTRIBUTE,
/* TEXT_NODE */
3: NodeFilter_js_1.default.SHOW_TEXT,
/* CDATA_SECTION_NODE */
4: NodeFilter_js_1.default.SHOW_CDATA_SECTION,
/* ENTITY_REFERENCE_NODE */
5: NodeFilter_js_1.default.SHOW_ENTITY_REFERENCE,
/* ENTITY_NODE */
6: NodeFilter_js_1.default.SHOW_PROCESSING_INSTRUCTION,
/* PROCESSING_INSTRUCTION_NODE */
7: NodeFilter_js_1.default.SHOW_PROCESSING_INSTRUCTION,
/* COMMENT_NODE */
8: NodeFilter_js_1.default.SHOW_COMMENT,
/* DOCUMENT_NODE */
9: NodeFilter_js_1.default.SHOW_DOCUMENT,
/* DOCUMENT_TYPE_NODE */
10: NodeFilter_js_1.default.SHOW_DOCUMENT_TYPE,
/* DOCUMENT_FRAGMENT_NODE */
11: NodeFilter_js_1.default.SHOW_DOCUMENT_FRAGMENT,
/* NOTATION_NODE */
12: NodeFilter_js_1.default.SHOW_NOTATION
};
//# sourceMappingURL=NodeFilterMask.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"NodeFilterMask.cjs","sourceRoot":"","sources":["../../src/tree-walker/NodeFilterMask.ts"],"names":[],"mappings":";;;;;AAAA,oEAAyC;AAEzC,kBAAe;IACd,kBAAkB;IAClB,CAAC,EAAE,uBAAU,CAAC,YAAY;IAC1B,oBAAoB;IACpB,CAAC,EAAE,uBAAU,CAAC,cAAc;IAC5B,eAAe;IACf,CAAC,EAAE,uBAAU,CAAC,SAAS;IACvB,wBAAwB;IACxB,CAAC,EAAE,uBAAU,CAAC,kBAAkB;IAChC,2BAA2B;IAC3B,CAAC,EAAE,uBAAU,CAAC,qBAAqB;IACnC,iBAAiB;IACjB,CAAC,EAAE,uBAAU,CAAC,2BAA2B;IACzC,iCAAiC;IACjC,CAAC,EAAE,uBAAU,CAAC,2BAA2B;IACzC,kBAAkB;IAClB,CAAC,EAAE,uBAAU,CAAC,YAAY;IAC1B,mBAAmB;IACnB,CAAC,EAAE,uBAAU,CAAC,aAAa;IAC3B,wBAAwB;IACxB,EAAE,EAAE,uBAAU,CAAC,kBAAkB;IACjC,4BAA4B;IAC5B,EAAE,EAAE,uBAAU,CAAC,sBAAsB;IACrC,mBAAmB;IACnB,EAAE,EAAE,uBAAU,CAAC,aAAa;CAC5B,CAAC"}

View File

@@ -0,0 +1,16 @@
declare const _default: {
1: number;
2: number;
3: number;
4: number;
5: number;
6: number;
7: number;
8: number;
9: number;
10: number;
11: number;
12: number;
};
export default _default;
//# sourceMappingURL=NodeFilterMask.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"NodeFilterMask.d.ts","sourceRoot":"","sources":["../../src/tree-walker/NodeFilterMask.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAEA,wBAyBE"}

View File

@@ -0,0 +1,116 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const TreeWalker_js_1 = __importDefault(require("./TreeWalker.cjs"));
const PropertySymbol = __importStar(require("../PropertySymbol.cjs"));
const NodeFilter_js_1 = __importDefault(require("./NodeFilter.cjs"));
/**
* The NodeIterator object represents the nodes of a document subtree and a position within them.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/NodeIterator
*/
class NodeIterator {
#root = null;
#whatToShow = -1;
#filter = null;
#walker;
#atRoot = true;
/**
* Constructor.
*
* @param root Root.
* @param [whatToShow] What to show.
* @param [filter] Filter.
*/
constructor(root, whatToShow = -1, filter = null) {
this.#root = root;
this.#whatToShow = whatToShow;
this.#filter = filter;
this.#walker = new TreeWalker_js_1.default(root, whatToShow, filter);
}
/**
* Returns root.
*
* @returns Root.
*/
get root() {
return this.#root;
}
/**
* Returns what to show.
*
* @returns What to show.
*/
get whatToShow() {
return this.#whatToShow;
}
/**
* Returns filter.
*
* @returns Filter.
*/
get filter() {
return this.#filter;
}
/**
* Moves the current Node to the next visible node in the document order.
*
* @returns Current node.
*/
nextNode() {
if (this.#atRoot) {
this.#atRoot = false;
if (this.#walker[PropertySymbol.filterNode](this.#root) !== NodeFilter_js_1.default.FILTER_ACCEPT) {
return this.#walker.nextNode();
}
return this.#root;
}
return this.#walker.nextNode();
}
/**
* Moves the current Node to the previous visible node in the document order, and returns the found node. It also moves the current node to this one. If no such node exists, or if it is before that the root node defined at the object construction, returns null and the current node is not changed.
*
* @returns Current node.
*/
previousNode() {
return this.#walker.previousNode();
}
}
exports.default = NodeIterator;
//# sourceMappingURL=NodeIterator.cjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"NodeIterator.cjs","sourceRoot":"","sources":["../../src/tree-walker/NodeIterator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,oEAAyC;AAEzC,qEAAuD;AACvD,oEAAyC;AAEzC;;;;;GAKG;AACH,MAAqB,YAAY;IAChC,KAAK,GAAS,IAAI,CAAC;IACnB,WAAW,GAAG,CAAC,CAAC,CAAC;IACjB,OAAO,GAAgB,IAAI,CAAC;IAC5B,OAAO,CAAa;IACpB,OAAO,GAAG,IAAI,CAAC;IAEf;;;;;;OAMG;IACH,YAAY,IAAU,EAAE,UAAU,GAAG,CAAC,CAAC,EAAE,SAAsB,IAAI;QAClE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,IAAI,uBAAU,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IACzD,CAAC;IAED;;;;OAIG;IACH,IAAW,IAAI;QACd,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,IAAW,UAAU;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,IAAW,MAAM;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACI,QAAQ;QACd,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,uBAAU,CAAC,aAAa,EAAE,CAAC;gBACtF,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YAChC,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC;QACnB,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACI,YAAY;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;IACpC,CAAC;CACD;AAxED,+BAwEC"}

View File

@@ -0,0 +1,50 @@
import INodeFilter from './INodeFilter.cjs';
import Node from '../nodes/node/Node.cjs';
/**
* The NodeIterator object represents the nodes of a document subtree and a position within them.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/NodeIterator
*/
export default class NodeIterator {
#private;
/**
* Constructor.
*
* @param root Root.
* @param [whatToShow] What to show.
* @param [filter] Filter.
*/
constructor(root: Node, whatToShow?: number, filter?: INodeFilter);
/**
* Returns root.
*
* @returns Root.
*/
get root(): Node | null;
/**
* Returns what to show.
*
* @returns What to show.
*/
get whatToShow(): number;
/**
* Returns filter.
*
* @returns Filter.
*/
get filter(): INodeFilter;
/**
* Moves the current Node to the next visible node in the document order.
*
* @returns Current node.
*/
nextNode(): Node;
/**
* Moves the current Node to the previous visible node in the document order, and returns the found node. It also moves the current node to this one. If no such node exists, or if it is before that the root node defined at the object construction, returns null and the current node is not changed.
*
* @returns Current node.
*/
previousNode(): Node;
}
//# sourceMappingURL=NodeIterator.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"NodeIterator.d.ts","sourceRoot":"","sources":["../../src/tree-walker/NodeIterator.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAE3C,OAAO,IAAI,MAAM,uBAAuB,CAAC;AAIzC;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;;IAOhC;;;;;;OAMG;gBACS,IAAI,EAAE,IAAI,EAAE,UAAU,SAAK,EAAE,MAAM,GAAE,WAAkB;IAOnE;;;;OAIG;IACH,IAAW,IAAI,IAAI,IAAI,GAAG,IAAI,CAE7B;IAED;;;;OAIG;IACH,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED;;;;OAIG;IACH,IAAW,MAAM,IAAI,WAAW,CAE/B;IAED;;;;OAIG;IACI,QAAQ,IAAI,IAAI;IAWvB;;;;OAIG;IACI,YAAY,IAAI,IAAI;CAG3B"}

View File

@@ -0,0 +1,296 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Node_js_1 = __importDefault(require("../nodes/node/Node.cjs"));
const PropertySymbol = __importStar(require("../PropertySymbol.cjs"));
const NodeFilterMask_js_1 = __importDefault(require("./NodeFilterMask.cjs"));
const DOMException_js_1 = __importDefault(require("../exception/DOMException.cjs"));
const NodeFilter_js_1 = __importDefault(require("./NodeFilter.cjs"));
var TraverseChildrenTypeEnum;
(function (TraverseChildrenTypeEnum) {
TraverseChildrenTypeEnum["first"] = "first";
TraverseChildrenTypeEnum["last"] = "last";
})(TraverseChildrenTypeEnum || (TraverseChildrenTypeEnum = {}));
var TraverseSiblingsTypeEnum;
(function (TraverseSiblingsTypeEnum) {
TraverseSiblingsTypeEnum["next"] = "next";
TraverseSiblingsTypeEnum["previous"] = "previous";
})(TraverseSiblingsTypeEnum || (TraverseSiblingsTypeEnum = {}));
/**
* The TreeWalker object represents the nodes of a document subtree and a position within them.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker
* @see https://dom.spec.whatwg.org/#interface-treewalker
*/
class TreeWalker {
root = null;
whatToShow = -1;
filter = null;
currentNode = null;
/**
* Constructor.
*
* @param root Root.
* @param [whatToShow] What to show.
* @param [filter] Filter.
*/
constructor(root, whatToShow = -1, filter = null) {
if (!(root instanceof Node_js_1.default)) {
throw new DOMException_js_1.default('Parameter 1 was not of type Node.');
}
this.root = root;
this.whatToShow = whatToShow;
this.filter = filter;
this.currentNode = root;
}
/**
* Moves the current Node to the first visible ancestor node in the document order, and returns the found node. It also moves the current node to this one. If no such node exists, or if it is before that the root node defined at the object construction, returns null and the current node is not changed.
*
* @returns Current node.
*/
parentNode() {
let node = this.currentNode;
while (node !== null && node !== this.root) {
node = node.parentNode;
if (node !== null && this[PropertySymbol.filterNode](node) === NodeFilter_js_1.default.FILTER_ACCEPT) {
this.currentNode = node;
return this.currentNode;
}
}
return null;
}
/**
* Moves the current Node to the first visible child of the current node, and returns the found child. It also moves the current node to this child. If no such child exists, returns null and the current node is not changed.
*
* @returns Current node.
*/
firstChild() {
return this.#traverseChildren(TraverseChildrenTypeEnum.first);
}
/**
* Moves the current Node to the last visible child of the current node, and returns the found child. It also moves the current node to this child. If no such child exists, null is returned and the current node is not changed.
*
* @returns Current node.
*/
lastChild() {
return this.#traverseChildren(TraverseChildrenTypeEnum.last);
}
/**
* Moves the current Node to its next sibling, if any, and returns the found sibling. If there is no such node, null is returned and the current node is not changed.
*
* @returns Current node.
*/
nextSibling() {
return this.#traverseSiblings(TraverseSiblingsTypeEnum.next);
}
/**
* Moves the current Node to its previous sibling, if any, and returns the found sibling. If there is no such node, return null and the current node is not changed.
*
* @returns Current node.
*/
previousSibling() {
return this.#traverseSiblings(TraverseSiblingsTypeEnum.previous);
}
/**
* Moves the current Node to the previous visible node in the document order, and returns the found node. It also moves the current node to this one. If no such node exists, or if it is before that the root node defined at the object construction, returns null and the current node is not changed.
*
* @returns Current node.
*/
previousNode() {
let node = this.currentNode;
while (node !== this.root) {
let sibling = node.previousSibling;
while (sibling !== null) {
let node = sibling;
let result = this[PropertySymbol.filterNode](node);
while (result !== NodeFilter_js_1.default.FILTER_REJECT && node[PropertySymbol.nodeArray].length) {
node = node.lastChild;
result = this[PropertySymbol.filterNode](node);
}
if (result === NodeFilter_js_1.default.FILTER_ACCEPT) {
this.currentNode = node;
return node;
}
sibling = node.previousSibling;
}
if (node === this.root || node.parentNode === null) {
return null;
}
node = node.parentNode;
if (this[PropertySymbol.filterNode](node) === NodeFilter_js_1.default.FILTER_ACCEPT) {
this.currentNode = node;
return node;
}
}
return null;
}
/**
* Moves the current Node to the next visible node in the document order.
*
* @returns Current node.
*/
nextNode() {
let node = this.currentNode;
let result = NodeFilter_js_1.default.FILTER_ACCEPT;
while (true) {
while (result !== NodeFilter_js_1.default.FILTER_REJECT && node[PropertySymbol.nodeArray].length) {
node = node.firstChild;
result = this[PropertySymbol.filterNode](node);
if (result === NodeFilter_js_1.default.FILTER_ACCEPT) {
this.currentNode = node;
return node;
}
}
while (node !== null) {
if (node === this.root) {
return null;
}
const sibling = node.nextSibling;
if (sibling !== null) {
node = sibling;
break;
}
node = node.parentNode;
}
if (node === null) {
return null;
}
result = this[PropertySymbol.filterNode](node);
if (result === NodeFilter_js_1.default.FILTER_ACCEPT) {
this.currentNode = node;
return node;
}
}
}
/**
* Filters a node.
*
* Based on solution:
* https://gist.github.com/shawndumas/1132009.
*
* @param node Node.
* @returns Child nodes.
*/
[PropertySymbol.filterNode](node) {
const mask = NodeFilterMask_js_1.default[node.nodeType];
if (mask && (this.whatToShow & mask) == 0) {
return NodeFilter_js_1.default.FILTER_SKIP;
}
if (typeof this.filter === 'function') {
return this.filter(node);
}
if (this.filter) {
return this.filter.acceptNode(node);
}
return NodeFilter_js_1.default.FILTER_ACCEPT;
}
/**
* Traverses children.
*
* @param type Type.
* @returns Node.
*/
#traverseChildren(type) {
let node = this.currentNode;
node = type === TraverseChildrenTypeEnum.first ? node.firstChild : node.lastChild;
while (node !== null) {
const result = this[PropertySymbol.filterNode](node);
if (result === NodeFilter_js_1.default.FILTER_ACCEPT) {
this.currentNode = node;
return node;
}
if (result === NodeFilter_js_1.default.FILTER_SKIP) {
const child = type === TraverseChildrenTypeEnum.first ? node.firstChild : node.lastChild;
if (child !== null) {
node = child;
continue;
}
}
while (node !== null) {
const sibling = type === TraverseChildrenTypeEnum.first ? node.nextSibling : node.previousSibling;
if (sibling !== null) {
node = sibling;
break;
}
const parent = node.parentNode;
if (parent === null || parent === this.root || parent === this.currentNode) {
return null;
}
node = parent;
}
}
return null;
}
/**
* Traverses siblings.
*
* @param type Type.
* @returns Node.
*/
#traverseSiblings(type) {
let node = this.currentNode;
if (node === this.root) {
return null;
}
while (true) {
let sibling = type === TraverseSiblingsTypeEnum.next ? node.nextSibling : node.previousSibling;
while (sibling !== null) {
const node = sibling;
const result = this[PropertySymbol.filterNode](node);
if (result === NodeFilter_js_1.default.FILTER_ACCEPT) {
this.currentNode = node;
return node;
}
sibling = type === TraverseSiblingsTypeEnum.next ? node.firstChild : node.lastChild;
if (result === NodeFilter_js_1.default.FILTER_REJECT || sibling === null) {
sibling =
type === TraverseSiblingsTypeEnum.next ? node.nextSibling : node.previousSibling;
}
}
node = node.parentNode;
if (node === null || node === this.root) {
return null;
}
if (this[PropertySymbol.filterNode](node) === NodeFilter_js_1.default.FILTER_ACCEPT) {
return null;
}
}
}
}
exports.default = TreeWalker;
//# sourceMappingURL=TreeWalker.cjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,77 @@
import Node from '../nodes/node/Node.cjs';
import * as PropertySymbol from '../PropertySymbol.cjs';
import INodeFilter from './INodeFilter.cjs';
/**
* The TreeWalker object represents the nodes of a document subtree and a position within them.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker
* @see https://dom.spec.whatwg.org/#interface-treewalker
*/
export default class TreeWalker {
#private;
root: Node;
whatToShow: number;
filter: INodeFilter;
currentNode: Node;
/**
* Constructor.
*
* @param root Root.
* @param [whatToShow] What to show.
* @param [filter] Filter.
*/
constructor(root: Node, whatToShow?: number, filter?: INodeFilter);
/**
* Moves the current Node to the first visible ancestor node in the document order, and returns the found node. It also moves the current node to this one. If no such node exists, or if it is before that the root node defined at the object construction, returns null and the current node is not changed.
*
* @returns Current node.
*/
parentNode(): Node;
/**
* Moves the current Node to the first visible child of the current node, and returns the found child. It also moves the current node to this child. If no such child exists, returns null and the current node is not changed.
*
* @returns Current node.
*/
firstChild(): Node;
/**
* Moves the current Node to the last visible child of the current node, and returns the found child. It also moves the current node to this child. If no such child exists, null is returned and the current node is not changed.
*
* @returns Current node.
*/
lastChild(): Node;
/**
* Moves the current Node to its next sibling, if any, and returns the found sibling. If there is no such node, null is returned and the current node is not changed.
*
* @returns Current node.
*/
nextSibling(): Node;
/**
* Moves the current Node to its previous sibling, if any, and returns the found sibling. If there is no such node, return null and the current node is not changed.
*
* @returns Current node.
*/
previousSibling(): Node;
/**
* Moves the current Node to the previous visible node in the document order, and returns the found node. It also moves the current node to this one. If no such node exists, or if it is before that the root node defined at the object construction, returns null and the current node is not changed.
*
* @returns Current node.
*/
previousNode(): Node;
/**
* Moves the current Node to the next visible node in the document order.
*
* @returns Current node.
*/
nextNode(): Node | null;
/**
* Filters a node.
*
* Based on solution:
* https://gist.github.com/shawndumas/1132009.
*
* @param node Node.
* @returns Child nodes.
*/
[PropertySymbol.filterNode](node: Node): number;
}
//# sourceMappingURL=TreeWalker.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TreeWalker.d.ts","sourceRoot":"","sources":["../../src/tree-walker/TreeWalker.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,uBAAuB,CAAC;AACzC,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAe3C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,UAAU;;IACvB,IAAI,EAAE,IAAI,CAAQ;IAClB,UAAU,SAAM;IAChB,MAAM,EAAE,WAAW,CAAQ;IAC3B,WAAW,EAAE,IAAI,CAAQ;IAEhC;;;;;;OAMG;gBACS,IAAI,EAAE,IAAI,EAAE,UAAU,SAAK,EAAE,MAAM,GAAE,WAAkB;IAWnE;;;;OAIG;IACI,UAAU,IAAI,IAAI;IAYzB;;;;OAIG;IACI,UAAU,IAAI,IAAI;IAIzB;;;;OAIG;IACI,SAAS,IAAI,IAAI;IAIxB;;;;OAIG;IACI,WAAW,IAAI,IAAI;IAI1B;;;;OAIG;IACI,eAAe,IAAI,IAAI;IAI9B;;;;OAIG;IACI,YAAY,IAAI,IAAI;IAsC3B;;;;OAIG;IACI,QAAQ,IAAI,IAAI,GAAG,IAAI;IA2C9B;;;;;;;;OAQG;IACI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;CA0GtD"}