netscape-bookmark-parser 1.0.1 → 1.1.1

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-ja.md CHANGED
@@ -38,6 +38,81 @@ import {
38
38
  } from "jsr:@grakeice/netscape-bookmark-parser";
39
39
  ```
40
40
 
41
+ > **注意:** JSR 版は Node.js/Deno ランタイム版のみを含んでいます。ブラウザサポートが必要な場合は、npm パッケージをご使用ください。
42
+
43
+ ### ブラウザ
44
+
45
+ #### オプション 1: ビルドツールの使用(推奨)
46
+
47
+ **Webpack、Vite、Rollup、Parcel など:**
48
+
49
+ ```typescript
50
+ // ブラウザ環境では、Web最適化版を使用
51
+ import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
52
+
53
+ // 例: アップロードされたブックマークファイルの解析
54
+ function handleFileUpload(event: Event) {
55
+ const file = (event.target as HTMLInputElement).files?.[0];
56
+ if (file) {
57
+ const reader = new FileReader();
58
+ reader.onload = (e) => {
59
+ const htmlContent = e.target?.result as string;
60
+ const bookmarksTree = BookmarksParser.parse(htmlContent);
61
+ console.log(bookmarksTree.toJSON());
62
+ };
63
+ reader.readAsText(file);
64
+ }
65
+ }
66
+ ```
67
+
68
+ #### オプション 2: 直接 ES モジュールインポート
69
+
70
+ ```html
71
+ <script type="module">
72
+ import {
73
+ BookmarksParser,
74
+ BookmarksTree,
75
+ } from "./node_modules/netscape-bookmark-parser/esm/mod_web.js";
76
+
77
+ // ブックマーク処理コードをここに...
78
+ </script>
79
+ ```
80
+
81
+ #### オプション 3: Import Maps を使用した CDN
82
+
83
+ ```html
84
+ <script type="importmap">
85
+ {
86
+ "imports": {
87
+ "netscape-bookmark-parser/web": "https://cdn.jsdelivr.net/npm/netscape-bookmark-parser@1.1.0/esm/mod_web.js"
88
+ }
89
+ }
90
+ </script>
91
+ <script type="module">
92
+ import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
93
+
94
+ // ローカルインポートと同じように動作
95
+ const tree = BookmarksParser.parse(htmlContent);
96
+ </script>
97
+ ```
98
+
99
+ #### オプション 4: CDN を直接インポート
100
+
101
+ ```html
102
+ <script type="module">
103
+ import {
104
+ BookmarksParser,
105
+ BookmarksTree,
106
+ } from "https://cdn.jsdelivr.net/npm/netscape-bookmark-parser@1.1.0/esm/mod_web.js";
107
+
108
+ // import maps なしでの直接 CDN インポート
109
+ </script>
110
+ ```
111
+
112
+ > **ブラウザサポート:** ブラウザ互換性は npm パッケージを通してのみ利用可能です。JSR パッケージは、プラットフォーム固有の依存関係のため、Web 最適化版を含んでいません。
113
+
114
+ > **注意:** Web 最適化版は、ネイティブブラウザ API(DOMParser など)を使用し、Node.js ポリフィルを含まないため、ブラウザ環境でより軽量で高速に動作します。
115
+
41
116
  ## 使用方法
42
117
 
43
118
  ### 基本的な例
@@ -141,6 +216,17 @@ console.log(devFolder.get("GitHub")); // "https://github.com"
141
216
 
142
217
  ## API リファレンス
143
218
 
219
+ ### Web 最適化版
220
+
221
+ > **重要:** ブラウザサポートは npm インストールを通してのみ利用可能です。JSR 版にはブラウザ互換ビルドが含まれていません。
222
+
223
+ ライブラリは、Node.js 依存関係を排除し、ネイティブブラウザ API を使用するブラウザ最適化版を提供しています:
224
+
225
+ ```typescript
226
+ // ブラウザ最適化版をインポート(npm のみ)
227
+ import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
228
+ ```
229
+
144
230
  ### BookmarksParser クラス
145
231
 
146
232
  [`BookmarksParser`](src/BookmarksParser/BookmarksParser.ts)クラスは、HTML ブックマークファイルを解析するための静的メソッドを提供します。
@@ -543,7 +629,31 @@ MIT License - 詳細は[LICENSE](LICENSE)ファイルを参照してください
543
629
 
544
630
  ## 変更履歴
545
631
 
546
- ### v1.0.1(最新)
632
+ ### v1.1.0(最新)
633
+
634
+ - 🌐 **ブラウザサポート**: ブラウザ環境用の Web 最適化版を追加
635
+ - 📦 **デュアルエントリーポイント**: Node.js/Deno 用(`./mod.ts`)とブラウザ用(`./mod_web.ts`)の分離ビルド
636
+ - ⚡ **ネイティブ DOM API**: ブラウザ版はネイティブ DOMParser と DOM API を使用してパフォーマンス向上
637
+ - 🔧 **ビルド最適化**: ブラウザ互換性のためのポリフィル除去を含む強化されたビルドプロセス
638
+ - 📚 **ドキュメント更新**: ブラウザ使用例と API リファレンスを追加
639
+
640
+ ### v1.0.1
547
641
 
548
642
  - ✨ **コア機能**: 完全な HTML ブックマークファイル解析機能
549
- - 🏗️ **BookmarksTree クラス**: Map インターフェースを持つ階層
643
+ - 🏗️ **BookmarksTree クラス**: Map インターフェースを持つ階層構造管理
644
+ - 🔄 **双方向変換**: JSON ↔ HTML ↔ DOM 変換サポート
645
+ - 🧪 **包括的テスト**: エッジケースハンドリングを含む完全なテストカバレッジ
646
+ - 📦 **マルチランタイムサポート**: ネイティブ Deno と Node.js 互換性
647
+ - 🔧 **TypeScript サポート**: 完全な型定義と IntelliSense
648
+ - 🤖 **CI/CD パイプライン**: GitHub Actions による自動テストと公開
649
+ - 📚 **ドキュメント**: 例と API リファレンスを含む包括的な README
650
+ - 🌐 **国際化サポート**: Unicode と多言語ブックマークハンドリング
651
+ - ⚡ **パフォーマンス最適化**: 大規模ブックマークコレクションの効率的解析
652
+ - 🛡️ **エラーハンドリング**: 不正な HTML と無効な URL の適切な処理
653
+
654
+ ### v0.0.1-pre4
655
+
656
+ - 初期のプレリリース版
657
+ - コア機能の概念実証
658
+ - 基本的な解析実装
659
+ - 初期テスト設定
package/README.md CHANGED
@@ -40,6 +40,81 @@ import {
40
40
  } from "jsr:@grakeice/netscape-bookmark-parser";
41
41
  ```
42
42
 
43
+ > **Note:** The JSR version only includes the Node.js/Deno runtime version. For browser support, please use the npm package.
44
+
45
+ ### Browser
46
+
47
+ #### Option 1: Using Build Tools (Recommended)
48
+
49
+ **Webpack, Vite, Rollup, Parcel, etc.:**
50
+
51
+ ```typescript
52
+ // For browser environments, use the web-optimized version
53
+ import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
54
+
55
+ // Example: Parse uploaded bookmark file
56
+ function handleFileUpload(event: Event) {
57
+ const file = (event.target as HTMLInputElement).files?.[0];
58
+ if (file) {
59
+ const reader = new FileReader();
60
+ reader.onload = (e) => {
61
+ const htmlContent = e.target?.result as string;
62
+ const bookmarksTree = BookmarksParser.parse(htmlContent);
63
+ console.log(bookmarksTree.toJSON());
64
+ };
65
+ reader.readAsText(file);
66
+ }
67
+ }
68
+ ```
69
+
70
+ #### Option 2: Direct ES Module Import
71
+
72
+ ```html
73
+ <script type="module">
74
+ import {
75
+ BookmarksParser,
76
+ BookmarksTree,
77
+ } from "./node_modules/netscape-bookmark-parser/esm/mod_web.js";
78
+
79
+ // Your bookmark processing code here...
80
+ </script>
81
+ ```
82
+
83
+ #### Option 3: CDN with Import Maps
84
+
85
+ ```html
86
+ <script type="importmap">
87
+ {
88
+ "imports": {
89
+ "netscape-bookmark-parser/web": "https://cdn.jsdelivr.net/npm/netscape-bookmark-parser@1.1.0/esm/mod_web.js"
90
+ }
91
+ }
92
+ </script>
93
+ <script type="module">
94
+ import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
95
+
96
+ // Works the same as local imports
97
+ const tree = BookmarksParser.parse(htmlContent);
98
+ </script>
99
+ ```
100
+
101
+ #### Option 4: Direct CDN Import
102
+
103
+ ```html
104
+ <script type="module">
105
+ import {
106
+ BookmarksParser,
107
+ BookmarksTree,
108
+ } from "https://cdn.jsdelivr.net/npm/netscape-bookmark-parser@1.1.0/esm/mod_web.js";
109
+
110
+ // Direct CDN import without import maps
111
+ </script>
112
+ ```
113
+
114
+ > **Browser Support:** Browser compatibility is only available through the npm package. The JSR package does not include the web-optimized version due to platform-specific dependencies.
115
+
116
+ > **Note:** The web-optimized version uses native browser APIs (DOMParser, etc.) and does not include Node.js polyfills, making it lighter and faster in browser environments.
117
+
43
118
  ## Usage
44
119
 
45
120
  ### Basic Example
@@ -143,6 +218,17 @@ console.log(devFolder.get("GitHub")); // "https://github.com"
143
218
 
144
219
  ## API Reference
145
220
 
221
+ ### Web-Optimized Version
222
+
223
+ > **Important:** Browser support is only available via npm installation. JSR version does not include browser-compatible builds.
224
+
225
+ The library provides a browser-optimized version that eliminates Node.js dependencies and uses native browser APIs:
226
+
227
+ ```typescript
228
+ // Import browser-optimized version (npm only)
229
+ import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
230
+ ```
231
+
146
232
  ### BookmarksParser Class
147
233
 
148
234
  The [`BookmarksParser`](src/BookmarksParser/BookmarksParser.ts) class provides static methods for parsing HTML bookmark files.
@@ -544,7 +630,15 @@ When reporting issues, please include:
544
630
 
545
631
  ## Changelog
546
632
 
547
- ### v1.0.1 (Latest)
633
+ ### v1.1.0 (Latest)
634
+
635
+ - 🌐 **Browser Support**: Added web-optimized version for browser environments
636
+ - 📦 **Dual Entry Points**: Separate builds for Node.js/Deno (`./mod.ts`) and browsers (`./mod_web.ts`)
637
+ - ⚡ **Native DOM APIs**: Browser version uses native DOMParser and DOM APIs for better performance
638
+ - 🔧 **Build Optimization**: Enhanced build process with polyfill removal for browser compatibility
639
+ - 📚 **Updated Documentation**: Added browser usage examples and API reference
640
+
641
+ ### v1.0.1
548
642
 
549
643
  - ✨ **Core Features**: Complete HTML bookmark file parsing functionality
550
644
  - 🏗️ **BookmarksTree Class**: Hierarchical structure management with Map interface
@@ -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
+ export { BookmarksTree } from "./src/web/BookmarksTree/index.js";
8
+ export { BookmarksParser } from "./src/web/BookmarksParser/index.js";
9
+ //# sourceMappingURL=mod_web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod_web.d.ts","sourceRoot":"","sources":["../src/mod_web.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,qBAAqB,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC"}
package/esm/mod_web.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 grakeice
3
+ *
4
+ * This software is released under the MIT License.
5
+ * https://opensource.org/licenses/MIT
6
+ */
7
+ export { BookmarksTree } from "./src/web/BookmarksTree/index.js";
8
+ export { BookmarksParser } from "./src/web/BookmarksParser/index.js";
@@ -4,7 +4,7 @@
4
4
  * This software is released under the MIT License.
5
5
  * https://opensource.org/licenses/MIT
6
6
  */
7
- import { DOMParser } from "../../deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.js";
7
+ import { DOMParser } from "../deps.js";
8
8
  import { BookmarksTree } from "../BookmarksTree/index.js";
9
9
  export class BookmarksParser {
10
10
  static parse(data) {
@@ -4,7 +4,7 @@
4
4
  * This software is released under the MIT License.
5
5
  * https://opensource.org/licenses/MIT
6
6
  */
7
- import { type HTMLDocument } from "../../deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.js";
7
+ import { type HTMLDocument } from "../deps.js";
8
8
  export declare class BookmarksTree extends Map<string, string | BookmarksTree> {
9
9
  constructor();
10
10
  toJSON(): Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"BookmarksTree.d.ts","sourceRoot":"","sources":["../../../src/src/BookmarksTree/BookmarksTree.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,4DAA4D,CAAC;AAExH,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"}
1
+ {"version":3,"file":"BookmarksTree.d.ts","sourceRoot":"","sources":["../../../src/src/BookmarksTree/BookmarksTree.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAExE,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,CA+CrB;CACD"}
@@ -4,7 +4,7 @@
4
4
  * This software is released under the MIT License.
5
5
  * https://opensource.org/licenses/MIT
6
6
  */
7
- import { DOMParser } from "../../deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.js";
7
+ import { DOMParser } from "../deps.js";
8
8
  export class BookmarksTree extends Map {
9
9
  constructor() {
10
10
  super();
@@ -80,16 +80,24 @@ export class BookmarksTree extends Map {
80
80
  return new DOMParser().parseFromString(this.HTMLText, "text/html");
81
81
  }
82
82
  get HTMLText() {
83
+ const escapeHtml = (text) => {
84
+ return text
85
+ .replace(/&/g, "&amp;")
86
+ .replace(/</g, "&lt;")
87
+ .replace(/>/g, "&gt;")
88
+ .replace(/"/g, "&quot;")
89
+ .replace(/'/g, "&#39;");
90
+ };
83
91
  const createBookmarkList = (tree, indent = "") => {
84
92
  let html = `${indent}<DL><p>\n`;
85
93
  for (const [key, value] of tree.entries()) {
86
94
  if (typeof value === "string") {
87
95
  // ブックマークの場合: <DT><A HREF="url">タイトル</A>
88
- html += `${indent} <DT><A HREF="${value}">${key}</A>\n`;
96
+ html += `${indent} <DT><A HREF="${escapeHtml(value)}">${escapeHtml(key)}</A>\n`;
89
97
  }
90
98
  else if (value instanceof BookmarksTree) {
91
99
  // フォルダの場合: <DT><H3>フォルダ名</H3>
92
- html += `${indent} <DT><H3>${key}</H3>\n`;
100
+ html += `${indent} <DT><H3>${escapeHtml(key)}</H3>\n`;
93
101
  html += createBookmarkList(value, indent + " ");
94
102
  html += `${indent} </DL><p>\n`;
95
103
  }
@@ -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
+ export { DOMParser } from "../deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.js";
8
+ export type { Element, HTMLDocument } from "../deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.js";
9
+ //# sourceMappingURL=deps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../../src/src/deps.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yDAAyD,CAAC;AACpF,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,yDAAyD,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2025 grakeice
3
+ *
4
+ * This software is released under the MIT License.
5
+ * https://opensource.org/licenses/MIT
6
+ */
7
+ export { DOMParser } from "../deps/jsr.io/@b-fuze/deno-dom/0.1.49/deno-dom-wasm.js";
@@ -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 BookmarksParser {
9
+ static parse(data: string): BookmarksTree;
10
+ }
11
+ //# sourceMappingURL=BookmarksParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BookmarksParser.d.ts","sourceRoot":"","sources":["../../../../src/src/web/BookmarksParser/BookmarksParser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,qBAAa,eAAe;IAC3B,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;CAKzC"}
@@ -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.js";
8
+ import { BookmarksTree } from "../BookmarksTree/index.js";
9
+ export class BookmarksParser {
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,8 @@
1
+ /**
2
+ * Copyright (c) 2025 grakeice
3
+ *
4
+ * This software is released under the MIT License.
5
+ * https://opensource.org/licenses/MIT
6
+ */
7
+ export { BookmarksParser } from "./BookmarksParser.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/web/BookmarksParser/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2025 grakeice
3
+ *
4
+ * This software is released under the MIT License.
5
+ * https://opensource.org/licenses/MIT
6
+ */
7
+ export { BookmarksParser } from "./BookmarksParser.js";
@@ -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.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/web/BookmarksTree/BookmarksTree.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAExE,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,CA+CrB;CACD"}
@@ -0,0 +1,121 @@
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.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 escapeHtml = (text) => {
84
+ return text
85
+ .replace(/&/g, "&amp;")
86
+ .replace(/</g, "&lt;")
87
+ .replace(/>/g, "&gt;")
88
+ .replace(/"/g, "&quot;")
89
+ .replace(/'/g, "&#39;");
90
+ };
91
+ const createBookmarkList = (tree, indent = "") => {
92
+ let html = `${indent}<DL><p>\n`;
93
+ for (const [key, value] of tree.entries()) {
94
+ if (typeof value === "string") {
95
+ // ブックマークの場合: <DT><A HREF="url">タイトル</A>
96
+ html += `${indent} <DT><A HREF="${escapeHtml(value)}">${escapeHtml(key)}</A>\n`;
97
+ }
98
+ else if (value instanceof BookmarksTree) {
99
+ // フォルダの場合: <DT><H3>フォルダ名</H3>
100
+ html += `${indent} <DT><H3>${escapeHtml(key)}</H3>\n`;
101
+ html += createBookmarkList(value, indent + " ");
102
+ html += `${indent} </DL><p>\n`;
103
+ }
104
+ }
105
+ if (indent === "") {
106
+ // ルートレベルの場合は閉じタグを追加
107
+ html += `</DL>\n`;
108
+ }
109
+ return html;
110
+ };
111
+ const htmlTemplate = `<!DOCTYPE NETSCAPE-Bookmark-file-1>
112
+ <HTML>
113
+ <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
114
+ <TITLE>Bookmark</TITLE>
115
+ <H1>Bookmark</H1>
116
+ <BODY>
117
+ ${createBookmarkList(this)}</BODY>
118
+ </HTML>`;
119
+ return htmlTemplate;
120
+ }
121
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 grakeice
3
+ *
4
+ * This software is released under the MIT License.
5
+ * https://opensource.org/licenses/MIT
6
+ */
7
+ export { BookmarksTree } from "./BookmarksTree.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/web/BookmarksTree/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2025 grakeice
3
+ *
4
+ * This software is released under the MIT License.
5
+ * https://opensource.org/licenses/MIT
6
+ */
7
+ export { BookmarksTree } from "./BookmarksTree.js";
@@ -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
+ export declare const DOMParser: any;
8
+ export type Element = globalThis.Element;
9
+ export type HTMLDocument = globalThis.HTMLDocument;
10
+ //# sourceMappingURL=deps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../../../src/src/web/deps.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,eAAO,MAAM,SAAS,KAAuB,CAAC;AAC9C,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;AACzC,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC"}
@@ -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
+ // deno-lint-ignore ban-ts-comment
8
+ // @ts-nocheck
9
+ export const DOMParser = globalThis.DOMParser;
package/package.json CHANGED
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "name": "netscape-bookmark-parser",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
+ "keywords": [
5
+ "bookmark",
6
+ "parser",
7
+ "netscape"
8
+ ],
4
9
  "author": "grakeice",
5
10
  "repository": "https://github.com/grakeice/netscape-bookmark-parser",
6
11
  "license": "MIT",
@@ -8,6 +13,9 @@
8
13
  "exports": {
9
14
  ".": {
10
15
  "import": "./esm/mod.js"
16
+ },
17
+ "./web": {
18
+ "import": "./esm/mod_web.js"
11
19
  }
12
20
  },
13
21
  "scripts": {},