netscape-bookmark-parser 0.0.1-pre1
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/LICENSE +21 -0
- package/README.md +234 -0
- package/esm/_dnt.polyfills.d.ts +101 -0
- package/esm/_dnt.polyfills.d.ts.map +1 -0
- package/esm/_dnt.polyfills.js +127 -0
- package/esm/_dnt.shims.d.ts +6 -0
- package/esm/_dnt.shims.d.ts.map +1 -0
- package/esm/_dnt.shims.js +61 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/build/deno-wasm/deno-wasm.d.ts +14 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/build/deno-wasm/deno-wasm.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/build/deno-wasm/deno-wasm.js +151 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.d.ts +23 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.js +26 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/api.d.ts +24 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/api.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/api.js +48 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/constructor-lock.d.ts +5 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/constructor-lock.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/constructor-lock.js +4 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/deserialize.d.ts +4 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/deserialize.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/deserialize.js +61 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document-fragment.d.ts +19 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document-fragment.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document-fragment.js +110 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document.d.ts +68 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/document.js +322 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/dom-parser.d.ts +6 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/dom-parser.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/dom-parser.js +46 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/element.d.ts +127 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/element.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/element.js +1068 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/elements/html-template-element.d.ts +29 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/elements/html-template-element.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/elements/html-template-element.js +94 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/html-collection.d.ts +21 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/html-collection.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/html-collection.js +80 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node-list.d.ts +23 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node-list.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node-list.js +159 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node.d.ts +127 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/node.js +629 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/custom-api.d.ts +6 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/custom-api.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/custom-api.js +5 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi-types.d.ts +12 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi-types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi-types.js +2 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi.d.ts +90 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/nwsapi.js +1611 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/selectors.d.ts +16 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/selectors.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/selectors.js +28 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle-types.d.ts +8 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle-types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle-types.js +2 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle.d.ts +7 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/selectors/sizzle.js +2061 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/string-cache.d.ts +3 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/string-cache.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/string-cache.js +10 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils-types.d.ts +13 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils-types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils-types.js +8 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils.d.ts +31 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils.js +239 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/parser.d.ts +5 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/parser.d.ts.map +1 -0
- package/esm/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/parser.js +20 -0
- package/esm/mod.d.ts +10 -0
- package/esm/mod.d.ts.map +1 -0
- package/esm/mod.js +9 -0
- package/esm/package.json +3 -0
- package/esm/src/BookmarksTree/BookmarksTree.d.ts +16 -0
- package/esm/src/BookmarksTree/BookmarksTree.d.ts.map +1 -0
- package/esm/src/BookmarksTree/BookmarksTree.js +113 -0
- package/esm/src/BookmarksTree/index.d.ts +8 -0
- package/esm/src/BookmarksTree/index.d.ts.map +1 -0
- package/esm/src/BookmarksTree/index.js +7 -0
- package/esm/src/Parser/Parser.d.ts +11 -0
- package/esm/src/Parser/Parser.d.ts.map +1 -0
- package/esm/src/Parser/Parser.js +15 -0
- package/esm/src/Parser/index.d.ts +8 -0
- package/esm/src/Parser/index.d.ts.map +1 -0
- package/esm/src/Parser/index.js +7 -0
- package/package.json +20 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string-cache.d.ts","sourceRoot":"","sources":["../../../../../../../../src/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/string-cache.ts"],"names":[],"mappings":"AAGA,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGnD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const upperCasedStringCache = new Map();
|
|
2
|
+
const lowerCasedStringCache = new Map();
|
|
3
|
+
export function getUpperCase(string) {
|
|
4
|
+
return upperCasedStringCache.get(string) ??
|
|
5
|
+
upperCasedStringCache.set(string, string.toUpperCase()).get(string);
|
|
6
|
+
}
|
|
7
|
+
export function getLowerCase(string) {
|
|
8
|
+
return lowerCasedStringCache.get(string) ??
|
|
9
|
+
lowerCasedStringCache.set(string, string.toLowerCase()).get(string);
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Element } from "./element.js";
|
|
2
|
+
import type { Document } from "./document.js";
|
|
3
|
+
import type { DocumentFragment } from "./document-fragment.js";
|
|
4
|
+
/**
|
|
5
|
+
* Ugly solution to circular imports... FIXME: Make this better
|
|
6
|
+
*/
|
|
7
|
+
declare const _default: {
|
|
8
|
+
Element: typeof Element;
|
|
9
|
+
Document: typeof Document;
|
|
10
|
+
DocumentFragment: typeof DocumentFragment;
|
|
11
|
+
};
|
|
12
|
+
export default _default;
|
|
13
|
+
//# sourceMappingURL=utils-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-types.d.ts","sourceRoot":"","sources":["../../../../../../../../src/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;GAEG;;aAEuB,OAAO,OAAO;cACb,OAAO,QAAQ;sBACP,OAAO,gBAAgB;;AAH1D,wBAIE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Node } from "./node.js";
|
|
2
|
+
import type { Element } from "./element.js";
|
|
3
|
+
import type { DocumentFragment } from "./document-fragment.js";
|
|
4
|
+
export declare const upperCaseCharRe: RegExp;
|
|
5
|
+
export declare const lowerCaseCharRe: RegExp;
|
|
6
|
+
/**
|
|
7
|
+
* Convert JS property name to dataset attribute name without
|
|
8
|
+
* validation
|
|
9
|
+
*/
|
|
10
|
+
export declare function getDatasetHtmlAttrName(name: string): `data-${string}`;
|
|
11
|
+
export declare function getDatasetJavascriptName(name: string): string;
|
|
12
|
+
export declare function getElementsByClassName(element: any, classNames: string[], search: Node[]): Node[];
|
|
13
|
+
/**
|
|
14
|
+
* .innerHTML/.outerHTML implementation without recursion to avoid stack
|
|
15
|
+
* overflows
|
|
16
|
+
*/
|
|
17
|
+
export declare function getOuterOrInnerHtml(parentElement: Element, asOuterHtml: boolean): string;
|
|
18
|
+
export declare function getElementAttributesString(element: Element): string;
|
|
19
|
+
export declare function insertBeforeAfter(node: Node, nodes: (Node | string)[], before: boolean): void;
|
|
20
|
+
export declare function isDocumentFragment(node: Node): node is DocumentFragment;
|
|
21
|
+
/**
|
|
22
|
+
* Sets the new parent for the children via _setParent() on all
|
|
23
|
+
* the child nodes and removes them from the DocumentFragment's
|
|
24
|
+
* childNode list.
|
|
25
|
+
*
|
|
26
|
+
* A helper function for appendChild, etc. It should be called
|
|
27
|
+
* _after_ the children are already pushed onto the new parent's
|
|
28
|
+
* childNodes.
|
|
29
|
+
*/
|
|
30
|
+
export declare function moveDocumentFragmentChildren(fragment: DocumentFragment, newParent: Node): void;
|
|
31
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../../../../src/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/dom/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,IAAI,EAAqC,MAAM,WAAW,CAAC;AAI7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,eAAO,MAAM,eAAe,QAAU,CAAC;AACvC,eAAO,MAAM,eAAe,QAAU,CAAC;AACvC;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,MAAM,EAAE,CAWrE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAc7D;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,GAAG,EACZ,UAAU,EAAE,MAAM,EAAE,EACpB,MAAM,EAAE,IAAI,EAAE,GACb,IAAI,EAAE,CAqBR;AAwBD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,OAAO,EACtB,WAAW,EAAE,OAAO,GACnB,MAAM,CAkGR;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,GACf,MAAM,CAiBR;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,CAAC,IAAI,GAAG,MAAM,CAAC,EAAE,EACxB,MAAM,EAAE,OAAO,QA6BhB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,gBAAgB,CA2BvE;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,IAAI,QAUhB"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { Node, nodesAndTextNodes, NodeType } from "./node.js";
|
|
2
|
+
import UtilTypes from "./utils-types.js";
|
|
3
|
+
export const upperCaseCharRe = /[A-Z]/;
|
|
4
|
+
export const lowerCaseCharRe = /[a-z]/;
|
|
5
|
+
/**
|
|
6
|
+
* Convert JS property name to dataset attribute name without
|
|
7
|
+
* validation
|
|
8
|
+
*/
|
|
9
|
+
export function getDatasetHtmlAttrName(name) {
|
|
10
|
+
let attributeName = "data-";
|
|
11
|
+
for (const char of name) {
|
|
12
|
+
if (upperCaseCharRe.test(char)) {
|
|
13
|
+
attributeName += "-" + char.toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
attributeName += char;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return attributeName;
|
|
20
|
+
}
|
|
21
|
+
export function getDatasetJavascriptName(name) {
|
|
22
|
+
let javascriptName = "";
|
|
23
|
+
let prevChar = "";
|
|
24
|
+
for (const char of name.slice("data-".length)) {
|
|
25
|
+
if (prevChar === "-" && lowerCaseCharRe.test(char)) {
|
|
26
|
+
javascriptName += char.toUpperCase();
|
|
27
|
+
prevChar = "";
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
javascriptName += prevChar;
|
|
31
|
+
prevChar = char;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return javascriptName + prevChar;
|
|
35
|
+
}
|
|
36
|
+
export function getElementsByClassName(element, classNames, search) {
|
|
37
|
+
for (const child of element.childNodes) {
|
|
38
|
+
if (child.nodeType === NodeType.ELEMENT_NODE) {
|
|
39
|
+
let matchesCount = 0;
|
|
40
|
+
for (const singleClassName of classNames) {
|
|
41
|
+
if (child.classList.contains(singleClassName)) {
|
|
42
|
+
matchesCount++;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// ensure that all class names are present
|
|
46
|
+
if (matchesCount === classNames.length) {
|
|
47
|
+
search.push(child);
|
|
48
|
+
}
|
|
49
|
+
getElementsByClassName(child, classNames, search);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return search;
|
|
53
|
+
}
|
|
54
|
+
function getOuterHTMLOpeningTag(parentElement) {
|
|
55
|
+
return "<" + parentElement.localName +
|
|
56
|
+
getElementAttributesString(parentElement) + ">";
|
|
57
|
+
}
|
|
58
|
+
const voidElements = new Set([
|
|
59
|
+
"area",
|
|
60
|
+
"base",
|
|
61
|
+
"br",
|
|
62
|
+
"col",
|
|
63
|
+
"embed",
|
|
64
|
+
"hr",
|
|
65
|
+
"img",
|
|
66
|
+
"input",
|
|
67
|
+
"link",
|
|
68
|
+
"meta",
|
|
69
|
+
"param",
|
|
70
|
+
"source",
|
|
71
|
+
"track",
|
|
72
|
+
"wbr",
|
|
73
|
+
]);
|
|
74
|
+
/**
|
|
75
|
+
* .innerHTML/.outerHTML implementation without recursion to avoid stack
|
|
76
|
+
* overflows
|
|
77
|
+
*/
|
|
78
|
+
export function getOuterOrInnerHtml(parentElement, asOuterHtml) {
|
|
79
|
+
let outerHTMLOpeningTag = "";
|
|
80
|
+
let outerHTMLClosingTag = "";
|
|
81
|
+
let innerHTML = "";
|
|
82
|
+
if (asOuterHtml) {
|
|
83
|
+
outerHTMLOpeningTag = getOuterHTMLOpeningTag(parentElement);
|
|
84
|
+
outerHTMLClosingTag = `</${parentElement.localName}>`;
|
|
85
|
+
if (voidElements.has(parentElement.localName)) {
|
|
86
|
+
return outerHTMLOpeningTag;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const initialChildNodes = parentElement.localName === "template"
|
|
90
|
+
? parentElement.content.childNodes
|
|
91
|
+
: parentElement.childNodes;
|
|
92
|
+
const childNodeDepth = [initialChildNodes];
|
|
93
|
+
const indexDepth = [0];
|
|
94
|
+
const closingTagDepth = [outerHTMLClosingTag];
|
|
95
|
+
let depth = 0;
|
|
96
|
+
depthLoop: while (depth > -1) {
|
|
97
|
+
const child = childNodeDepth[depth][indexDepth[depth]];
|
|
98
|
+
if (child) {
|
|
99
|
+
switch (child.nodeType) {
|
|
100
|
+
case NodeType.ELEMENT_NODE: {
|
|
101
|
+
innerHTML += getOuterHTMLOpeningTag(child);
|
|
102
|
+
const childLocalName = child.localName;
|
|
103
|
+
// Void elements don't have a closing tag nor print innerHTML
|
|
104
|
+
if (!voidElements.has(childLocalName)) {
|
|
105
|
+
if (childLocalName === "template") {
|
|
106
|
+
childNodeDepth.push(child.content.childNodes);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
childNodeDepth.push(child.childNodes);
|
|
110
|
+
}
|
|
111
|
+
indexDepth.push(0);
|
|
112
|
+
closingTagDepth.push(`</${childLocalName}>`);
|
|
113
|
+
depth++;
|
|
114
|
+
continue depthLoop;
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case NodeType.COMMENT_NODE:
|
|
119
|
+
innerHTML += `<!--${child.data}-->`;
|
|
120
|
+
break;
|
|
121
|
+
case NodeType.TEXT_NODE:
|
|
122
|
+
// Special handling for rawtext-like elements.
|
|
123
|
+
switch (child.parentNode.localName) {
|
|
124
|
+
case "style":
|
|
125
|
+
case "script":
|
|
126
|
+
case "xmp":
|
|
127
|
+
case "iframe":
|
|
128
|
+
case "noembed":
|
|
129
|
+
case "noframes":
|
|
130
|
+
case "plaintext": {
|
|
131
|
+
innerHTML += child.data;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case "noscript": {
|
|
135
|
+
innerHTML += child.data;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
default: {
|
|
139
|
+
// escaping: https://html.spec.whatwg.org/multipage/parsing.html#escapingString
|
|
140
|
+
innerHTML += child.data
|
|
141
|
+
.replace(/&/g, "&")
|
|
142
|
+
.replace(/\xA0/g, " ")
|
|
143
|
+
.replace(/</g, "<")
|
|
144
|
+
.replace(/>/g, ">");
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
depth--;
|
|
153
|
+
indexDepth.pop();
|
|
154
|
+
childNodeDepth.pop();
|
|
155
|
+
innerHTML += closingTagDepth.pop();
|
|
156
|
+
}
|
|
157
|
+
// Go to next child
|
|
158
|
+
indexDepth[depth]++;
|
|
159
|
+
}
|
|
160
|
+
// If innerHTML is requested then the opening tag should be an empty string
|
|
161
|
+
return outerHTMLOpeningTag + innerHTML;
|
|
162
|
+
}
|
|
163
|
+
export function getElementAttributesString(element) {
|
|
164
|
+
let out = "";
|
|
165
|
+
for (const attribute of element.getAttributeNames()) {
|
|
166
|
+
// attribute names should already all be lower-case
|
|
167
|
+
out += ` ${attribute}`;
|
|
168
|
+
// escaping: https://html.spec.whatwg.org/multipage/parsing.html#escapingString
|
|
169
|
+
out += `="${element.getAttribute(attribute)
|
|
170
|
+
.replace(/&/g, "&")
|
|
171
|
+
.replace(/\xA0/g, " ")
|
|
172
|
+
.replace(/"/g, """)}"`;
|
|
173
|
+
}
|
|
174
|
+
return out;
|
|
175
|
+
}
|
|
176
|
+
export function insertBeforeAfter(node, nodes, before) {
|
|
177
|
+
const parentNode = node.parentNode;
|
|
178
|
+
const mutator = parentNode._getChildNodesMutator();
|
|
179
|
+
// Find the previous/next sibling to `node` that isn't in `nodes` before the
|
|
180
|
+
// nodes in `nodes` are removed from their parents.
|
|
181
|
+
let viablePrevNextSibling = null;
|
|
182
|
+
{
|
|
183
|
+
const difference = before ? -1 : +1;
|
|
184
|
+
for (let i = mutator.indexOf(node) + difference; 0 <= i && i < parentNode.childNodes.length; i += difference) {
|
|
185
|
+
if (!nodes.includes(parentNode.childNodes[i])) {
|
|
186
|
+
viablePrevNextSibling = parentNode.childNodes[i];
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
nodes = nodesAndTextNodes(nodes, parentNode);
|
|
192
|
+
let index;
|
|
193
|
+
if (viablePrevNextSibling) {
|
|
194
|
+
index = mutator.indexOf(viablePrevNextSibling) + (before ? 1 : 0);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
index = before ? 0 : parentNode.childNodes.length;
|
|
198
|
+
}
|
|
199
|
+
mutator.splice(index, 0, ...nodes);
|
|
200
|
+
}
|
|
201
|
+
export function isDocumentFragment(node) {
|
|
202
|
+
let obj = node;
|
|
203
|
+
if (!(obj && typeof obj === "object")) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
while (true) {
|
|
207
|
+
switch (obj.constructor) {
|
|
208
|
+
case UtilTypes.DocumentFragment:
|
|
209
|
+
return true;
|
|
210
|
+
case Node:
|
|
211
|
+
case UtilTypes.Element:
|
|
212
|
+
return false;
|
|
213
|
+
// FIXME: We should probably throw here?
|
|
214
|
+
case Object:
|
|
215
|
+
case null:
|
|
216
|
+
case undefined:
|
|
217
|
+
return false;
|
|
218
|
+
default:
|
|
219
|
+
obj = Reflect.getPrototypeOf(obj);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Sets the new parent for the children via _setParent() on all
|
|
225
|
+
* the child nodes and removes them from the DocumentFragment's
|
|
226
|
+
* childNode list.
|
|
227
|
+
*
|
|
228
|
+
* A helper function for appendChild, etc. It should be called
|
|
229
|
+
* _after_ the children are already pushed onto the new parent's
|
|
230
|
+
* childNodes.
|
|
231
|
+
*/
|
|
232
|
+
export function moveDocumentFragmentChildren(fragment, newParent) {
|
|
233
|
+
const childCount = fragment.childNodes.length;
|
|
234
|
+
for (const child of fragment.childNodes) {
|
|
235
|
+
child._setParent(newParent);
|
|
236
|
+
}
|
|
237
|
+
const mutator = fragment._getChildNodesMutator();
|
|
238
|
+
mutator.splice(0, childCount);
|
|
239
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../../../../../src/deps/jsr.io/@b-fuze/deno-dom/0.1.49/src/parser.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;AACzE,eAAO,IAAI,KAAK,EAAE,MAGjB,CAAC;AAEF,eAAO,IAAI,SAAS,EAAE,MAGrB,CAAC;AAGF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAOtD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser interface
|
|
3
|
+
*/
|
|
4
|
+
import * as dntShim from "../../../../../../_dnt.shims.js";
|
|
5
|
+
export let parse = (_html) => {
|
|
6
|
+
console.error("Error: deno-dom: No parser registered");
|
|
7
|
+
dntShim.Deno.exit(1);
|
|
8
|
+
};
|
|
9
|
+
export let parseFrag = (_html, _contextLocalName) => {
|
|
10
|
+
console.error("Error: deno-dom: No parser registered");
|
|
11
|
+
dntShim.Deno.exit(1);
|
|
12
|
+
};
|
|
13
|
+
const originalParse = parse;
|
|
14
|
+
export function register(func, fragFunc) {
|
|
15
|
+
if (parse !== originalParse) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
parse = func;
|
|
19
|
+
parseFrag = fragFunc;
|
|
20
|
+
}
|
package/esm/mod.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 grakeice
|
|
3
|
+
*
|
|
4
|
+
* This software is released under the MIT License.
|
|
5
|
+
* https://opensource.org/licenses/MIT
|
|
6
|
+
*/
|
|
7
|
+
import "./_dnt.polyfills.js";
|
|
8
|
+
export { BookmarksTree } from "./src/BookmarksTree/index.js";
|
|
9
|
+
export { Parser } from "./src/Parser/index.js";
|
|
10
|
+
//# sourceMappingURL=mod.d.ts.map
|
package/esm/mod.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,qBAAqB,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC"}
|
package/esm/mod.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 grakeice
|
|
3
|
+
*
|
|
4
|
+
* This software is released under the MIT License.
|
|
5
|
+
* https://opensource.org/licenses/MIT
|
|
6
|
+
*/
|
|
7
|
+
import "./_dnt.polyfills.js";
|
|
8
|
+
export { BookmarksTree } from "./src/BookmarksTree/index.js";
|
|
9
|
+
export { Parser } from "./src/Parser/index.js";
|
package/esm/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 grakeice
|
|
3
|
+
*
|
|
4
|
+
* This software is released under the MIT License.
|
|
5
|
+
* https://opensource.org/licenses/MIT
|
|
6
|
+
*/
|
|
7
|
+
import { type HTMLDocument } from "../../deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.js";
|
|
8
|
+
export declare class BookmarksTree extends Map<string, string | BookmarksTree> {
|
|
9
|
+
constructor();
|
|
10
|
+
toJSON(): Record<string, unknown>;
|
|
11
|
+
static fromJSON(json: Record<string, unknown>): BookmarksTree;
|
|
12
|
+
static fromDOM(dom: HTMLDocument): BookmarksTree;
|
|
13
|
+
toDOM(): HTMLDocument;
|
|
14
|
+
get HTMLText(): string;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=BookmarksTree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BookmarksTree.d.ts","sourceRoot":"","sources":["../../../src/src/BookmarksTree/BookmarksTree.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,4DAA4D,CAAC;AAEnH,qBAAa,aAAc,SAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC;;IAKrE,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAcjC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa;IAmB7D,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,GAAG,aAAa;IA8ChD,KAAK,IAAI,YAAY;IAIrB,IAAI,QAAQ,IAAI,MAAM,CAoCrB;CACD"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 grakeice
|
|
3
|
+
*
|
|
4
|
+
* This software is released under the MIT License.
|
|
5
|
+
* https://opensource.org/licenses/MIT
|
|
6
|
+
*/
|
|
7
|
+
import { DOMParser } from "../../deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.js";
|
|
8
|
+
export class BookmarksTree extends Map {
|
|
9
|
+
constructor() {
|
|
10
|
+
super();
|
|
11
|
+
}
|
|
12
|
+
toJSON() {
|
|
13
|
+
const json = {};
|
|
14
|
+
for (const [key, value] of this.entries()) {
|
|
15
|
+
if (typeof value === "string") {
|
|
16
|
+
json[key] = value;
|
|
17
|
+
}
|
|
18
|
+
else if (value instanceof BookmarksTree) {
|
|
19
|
+
json[key] = value.toJSON();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return json;
|
|
23
|
+
}
|
|
24
|
+
static fromJSON(json) {
|
|
25
|
+
const tree = new BookmarksTree();
|
|
26
|
+
if (typeof json === "object" && json !== null) {
|
|
27
|
+
for (const [key, value] of Object.entries(json)) {
|
|
28
|
+
if (typeof value === "string") {
|
|
29
|
+
tree.set(key, value);
|
|
30
|
+
}
|
|
31
|
+
else if (typeof value === "object" && value !== null) {
|
|
32
|
+
tree.set(key, BookmarksTree.fromJSON(value));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return tree;
|
|
37
|
+
}
|
|
38
|
+
static fromDOM(dom) {
|
|
39
|
+
const tree = new BookmarksTree();
|
|
40
|
+
const document = dom;
|
|
41
|
+
const processElement = (element, currentTree) => {
|
|
42
|
+
const children = Array.from(element.children);
|
|
43
|
+
for (let i = 0; i < children.length; i++) {
|
|
44
|
+
const child = children[i];
|
|
45
|
+
if (child.tagName === "DT") {
|
|
46
|
+
const h3 = child.querySelector("h3");
|
|
47
|
+
const link = child.querySelector("a");
|
|
48
|
+
if (h3) {
|
|
49
|
+
// フォルダの場合
|
|
50
|
+
const folderName = h3.textContent?.trim() || "";
|
|
51
|
+
if (folderName) {
|
|
52
|
+
const folderTree = new BookmarksTree();
|
|
53
|
+
currentTree.set(folderName, folderTree);
|
|
54
|
+
processElement(child, folderTree);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else if (link) {
|
|
58
|
+
// リンクの場合
|
|
59
|
+
const href = link.getAttribute("href");
|
|
60
|
+
const title = link.textContent?.trim() || "";
|
|
61
|
+
if (href && title) {
|
|
62
|
+
currentTree.set(title, href);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (child.tagName === "DL") {
|
|
67
|
+
// ネストしたDLタグの場合も処理
|
|
68
|
+
processElement(child, currentTree);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
// HTMLのBODY全体から処理を開始
|
|
73
|
+
const body = document.body;
|
|
74
|
+
if (body) {
|
|
75
|
+
processElement(body, tree);
|
|
76
|
+
}
|
|
77
|
+
return tree;
|
|
78
|
+
}
|
|
79
|
+
toDOM() {
|
|
80
|
+
return new DOMParser().parseFromString(this.HTMLText, "text/html");
|
|
81
|
+
}
|
|
82
|
+
get HTMLText() {
|
|
83
|
+
const createBookmarkList = (tree, indent = "") => {
|
|
84
|
+
let html = `${indent}<DL><p>\n`;
|
|
85
|
+
for (const [key, value] of tree.entries()) {
|
|
86
|
+
if (typeof value === "string") {
|
|
87
|
+
// ブックマークの場合: <DT><A HREF="url">タイトル</A>
|
|
88
|
+
html += `${indent} <DT><A HREF="${value}">${key}</A>\n`;
|
|
89
|
+
}
|
|
90
|
+
else if (value instanceof BookmarksTree) {
|
|
91
|
+
// フォルダの場合: <DT><H3>フォルダ名</H3>
|
|
92
|
+
html += `${indent} <DT><H3>${key}</H3>\n`;
|
|
93
|
+
html += createBookmarkList(value, indent + " ");
|
|
94
|
+
html += `${indent} </DL><p>\n`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (indent === "") {
|
|
98
|
+
// ルートレベルの場合は閉じタグを追加
|
|
99
|
+
html += `</DL>\n`;
|
|
100
|
+
}
|
|
101
|
+
return html;
|
|
102
|
+
};
|
|
103
|
+
const htmlTemplate = `<!DOCTYPE NETSCAPE-Bookmark-file-1>
|
|
104
|
+
<HTML>
|
|
105
|
+
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
|
|
106
|
+
<TITLE>Bookmark</TITLE>
|
|
107
|
+
<H1>Bookmark</H1>
|
|
108
|
+
<BODY>
|
|
109
|
+
${createBookmarkList(this)}</BODY>
|
|
110
|
+
</HTML>`;
|
|
111
|
+
return htmlTemplate;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/BookmarksTree/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 grakeice
|
|
3
|
+
*
|
|
4
|
+
* This software is released under the MIT License.
|
|
5
|
+
* https://opensource.org/licenses/MIT
|
|
6
|
+
*/
|
|
7
|
+
import { BookmarksTree } from "../BookmarksTree/index.js";
|
|
8
|
+
export declare class Parser {
|
|
9
|
+
static parse(data: string): BookmarksTree;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=Parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Parser.d.ts","sourceRoot":"","sources":["../../../src/src/Parser/Parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,qBAAa,MAAM;IAClB,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM;CAKzB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 grakeice
|
|
3
|
+
*
|
|
4
|
+
* This software is released under the MIT License.
|
|
5
|
+
* https://opensource.org/licenses/MIT
|
|
6
|
+
*/
|
|
7
|
+
import { DOMParser } from "../../deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.js";
|
|
8
|
+
import { BookmarksTree } from "../BookmarksTree/index.js";
|
|
9
|
+
export class Parser {
|
|
10
|
+
static parse(data) {
|
|
11
|
+
const dom = new DOMParser().parseFromString(data, "text/html");
|
|
12
|
+
const tree = BookmarksTree.fromDOM(dom);
|
|
13
|
+
return tree;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/Parser/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "netscape-bookmark-parser",
|
|
3
|
+
"version": "0.0.1-pre1",
|
|
4
|
+
"author": "grakeice",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"module": "./esm/mod.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./esm/mod.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"scripts": {},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@deno/shim-deno": "~0.18.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/node": "^20.9.0"
|
|
18
|
+
},
|
|
19
|
+
"_generatedBy": "dnt@dev"
|
|
20
|
+
}
|