netscape-bookmark-parser 1.1.0 → 1.1.2

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
@@ -1,16 +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
-
8
1
  # Netscape Bookmark Parser
9
2
 
10
3
  > **注意:**
11
4
  > この README は AI 生成されたドキュメントです。詳細はほぼ正確ですが、不正確な説明が含まれる可能性があります。
12
5
 
13
- ブラウザのブックマークファイル(HTML 形式)を解析し、構造化データとして操作するための TypeScript/JavaScript ライブラリです。DenoNode.js、**ブラウザ**の全てのランタイムに対応しています。
6
+ ブラウザのブックマークファイル(HTML 形式)を解析し、構造化データとして操作するための TypeScript/JavaScript ライブラリです。DenoNode.js の両方のランタイムに対応しています。
14
7
 
15
8
  ## 機能
16
9
 
@@ -38,13 +31,81 @@ import {
38
31
  } from "jsr:@grakeice/netscape-bookmark-parser";
39
32
  ```
40
33
 
34
+ > **注意:** JSR 版は Node.js/Deno ランタイム版のみを含んでいます。ブラウザサポートが必要な場合は、npm パッケージをご使用ください。
35
+
41
36
  ### ブラウザ
42
37
 
38
+ #### オプション 1: ビルドツールの使用(推奨)
39
+
40
+ **Webpack、Vite、Rollup、Parcel など:**
41
+
43
42
  ```typescript
44
43
  // ブラウザ環境では、Web最適化版を使用
45
44
  import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
45
+
46
+ // 例: アップロードされたブックマークファイルの解析
47
+ function handleFileUpload(event: Event) {
48
+ const file = (event.target as HTMLInputElement).files?.[0];
49
+ if (file) {
50
+ const reader = new FileReader();
51
+ reader.onload = (e) => {
52
+ const htmlContent = e.target?.result as string;
53
+ const bookmarksTree = BookmarksParser.parse(htmlContent);
54
+ console.log(bookmarksTree.toJSON());
55
+ };
56
+ reader.readAsText(file);
57
+ }
58
+ }
59
+ ```
60
+
61
+ #### オプション 2: 直接 ES モジュールインポート
62
+
63
+ ```html
64
+ <script type="module">
65
+ import {
66
+ BookmarksParser,
67
+ BookmarksTree,
68
+ } from "./node_modules/netscape-bookmark-parser/esm/mod_web.js";
69
+
70
+ // ブックマーク処理コードをここに...
71
+ </script>
72
+ ```
73
+
74
+ #### オプション 3: Import Maps を使用した CDN
75
+
76
+ ```html
77
+ <script type="importmap">
78
+ {
79
+ "imports": {
80
+ "netscape-bookmark-parser/web": "https://cdn.jsdelivr.net/npm/netscape-bookmark-parser@1.1.2/esm/mod_web.js"
81
+ }
82
+ }
83
+ </script>
84
+ <script type="module">
85
+ import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
86
+
87
+ // ローカルインポートと同じように動作
88
+ const tree = BookmarksParser.parse(htmlContent);
89
+ </script>
46
90
  ```
47
91
 
92
+ #### オプション 4: CDN を直接インポート
93
+
94
+ ```html
95
+ <script type="module">
96
+ import {
97
+ BookmarksParser,
98
+ BookmarksTree,
99
+ } from "https://cdn.jsdelivr.net/npm/netscape-bookmark-parser@1.1.2/esm/mod_web.js";
100
+
101
+ // import maps なしでの直接 CDN インポート
102
+ </script>
103
+ ```
104
+
105
+ > **ブラウザサポート:** ブラウザ互換性は npm パッケージを通してのみ利用可能です。JSR パッケージは、プラットフォーム固有の依存関係のため、Web 最適化版を含んでいません。
106
+
107
+ > **注意:** Web 最適化版は、ネイティブブラウザ API(DOMParser など)を使用し、Node.js ポリフィルを含まないため、ブラウザ環境でより軽量で高速に動作します。
108
+
48
109
  ## 使用方法
49
110
 
50
111
  ### 基本的な例
@@ -148,6 +209,17 @@ console.log(devFolder.get("GitHub")); // "https://github.com"
148
209
 
149
210
  ## API リファレンス
150
211
 
212
+ ### Web 最適化版
213
+
214
+ > **重要:** ブラウザサポートは npm インストールを通してのみ利用可能です。JSR 版にはブラウザ互換ビルドが含まれていません。
215
+
216
+ ライブラリは、Node.js 依存関係を排除し、ネイティブブラウザ API を使用するブラウザ最適化版を提供しています:
217
+
218
+ ```typescript
219
+ // ブラウザ最適化版をインポート(npm のみ)
220
+ import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
221
+ ```
222
+
151
223
  ### BookmarksParser クラス
152
224
 
153
225
  [`BookmarksParser`](src/BookmarksParser/BookmarksParser.ts)クラスは、HTML ブックマークファイルを解析するための静的メソッドを提供します。
@@ -550,7 +622,20 @@ MIT License - 詳細は[LICENSE](LICENSE)ファイルを参照してください
550
622
 
551
623
  ## 変更履歴
552
624
 
553
- ### v1.1.0(最新)
625
+ ### v1.1.2(最新)
626
+
627
+ - 📝 **ドキュメント強化**: 最新バージョン参照と改善された例を含む包括的な README ドキュメントの更新
628
+ - 🔧 **バージョン一貫性**: 全ドキュメントとコード例でのバージョン番号の同期
629
+ - 📚 **コンテンツ更新**: より明確性のためのインストール手順、使用例、API ドキュメントの改良
630
+
631
+ ### v1.1.1
632
+
633
+ - 🛡️ **セキュリティ強化**: [`BookmarksTree.prototype.HTMLText`](src/BookmarksTree/BookmarksTree.ts) がブックマークのタイトルと URL の HTML エンティティを適切にエスケープするように修正
634
+ - 🔧 **コード一貫性**: Node.js とブラウザ版間で HTML エスケープ動作を統一
635
+ - 📝 **ドキュメント更新**: セキュリティ考慮事項を含む API ドキュメントの強化
636
+ - 🐛 **バグ修正**: マイナーな安定性改善とエッジケース処理
637
+
638
+ ### v1.1.0
554
639
 
555
640
  - 🌐 **ブラウザサポート**: ブラウザ環境用の Web 最適化版を追加
556
641
  - 📦 **デュアルエントリーポイント**: Node.js/Deno 用(`./mod.ts`)とブラウザ用(`./mod_web.ts`)の分離ビルド
@@ -571,3 +656,10 @@ MIT License - 詳細は[LICENSE](LICENSE)ファイルを参照してください
571
656
  - 🌐 **国際化サポート**: Unicode と多言語ブックマークハンドリング
572
657
  - ⚡ **パフォーマンス最適化**: 大規模ブックマークコレクションの効率的解析
573
658
  - 🛡️ **エラーハンドリング**: 不正な HTML と無効な URL の適切な処理
659
+
660
+ ### v0.0.1-pre4
661
+
662
+ - 初期のプレリリース版
663
+ - コア機能の概念実証
664
+ - 基本的な解析実装
665
+ - 初期テスト設定
package/README.md CHANGED
@@ -1,10 +1,3 @@
1
- <!--
2
- Copyright (c) 2025 grakeice
3
-
4
- This software is released under the MIT License.
5
- https://opensource.org/licenses/MIT
6
- -->
7
-
8
1
  # Netscape Bookmark Parser
9
2
 
10
3
  > **Note:**
@@ -40,13 +33,81 @@ import {
40
33
  } from "jsr:@grakeice/netscape-bookmark-parser";
41
34
  ```
42
35
 
36
+ > **Note:** The JSR version only includes the Node.js/Deno runtime version. For browser support, please use the npm package.
37
+
43
38
  ### Browser
44
39
 
40
+ #### Option 1: Using Build Tools (Recommended)
41
+
42
+ **Webpack, Vite, Rollup, Parcel, etc.:**
43
+
45
44
  ```typescript
46
45
  // For browser environments, use the web-optimized version
47
46
  import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
47
+
48
+ // Example: Parse uploaded bookmark file
49
+ function handleFileUpload(event: Event) {
50
+ const file = (event.target as HTMLInputElement).files?.[0];
51
+ if (file) {
52
+ const reader = new FileReader();
53
+ reader.onload = (e) => {
54
+ const htmlContent = e.target?.result as string;
55
+ const bookmarksTree = BookmarksParser.parse(htmlContent);
56
+ console.log(bookmarksTree.toJSON());
57
+ };
58
+ reader.readAsText(file);
59
+ }
60
+ }
61
+ ```
62
+
63
+ #### Option 2: Direct ES Module Import
64
+
65
+ ```html
66
+ <script type="module">
67
+ import {
68
+ BookmarksParser,
69
+ BookmarksTree,
70
+ } from "./node_modules/netscape-bookmark-parser/esm/mod_web.js";
71
+
72
+ // Your bookmark processing code here...
73
+ </script>
48
74
  ```
49
75
 
76
+ #### Option 3: CDN with Import Maps
77
+
78
+ ```html
79
+ <script type="importmap">
80
+ {
81
+ "imports": {
82
+ "netscape-bookmark-parser/web": "https://cdn.jsdelivr.net/npm/netscape-bookmark-parser@1.1.2/esm/mod_web.js"
83
+ }
84
+ }
85
+ </script>
86
+ <script type="module">
87
+ import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
88
+
89
+ // Works the same as local imports
90
+ const tree = BookmarksParser.parse(htmlContent);
91
+ </script>
92
+ ```
93
+
94
+ #### Option 4: Direct CDN Import
95
+
96
+ ```html
97
+ <script type="module">
98
+ import {
99
+ BookmarksParser,
100
+ BookmarksTree,
101
+ } from "https://cdn.jsdelivr.net/npm/netscape-bookmark-parser@1.1.2/esm/mod_web.js";
102
+
103
+ // Direct CDN import without import maps
104
+ </script>
105
+ ```
106
+
107
+ > **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.
108
+
109
+ > **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.
110
+
50
111
  ## Usage
51
112
 
52
113
  ### Basic Example
@@ -152,26 +213,13 @@ console.log(devFolder.get("GitHub")); // "https://github.com"
152
213
 
153
214
  ### Web-Optimized Version
154
215
 
216
+ > **Important:** Browser support is only available via npm installation. JSR version does not include browser-compatible builds.
217
+
155
218
  The library provides a browser-optimized version that eliminates Node.js dependencies and uses native browser APIs:
156
219
 
157
220
  ```typescript
158
- // Import browser-optimized version
221
+ // Import browser-optimized version (npm only)
159
222
  import { BookmarksParser, BookmarksTree } from "netscape-bookmark-parser/web";
160
-
161
- // Works with browser File API
162
- document
163
- .getElementById("fileInput")
164
- .addEventListener("change", async (event) => {
165
- const file = event.target.files[0];
166
- const htmlContent = await file.text();
167
-
168
- const bookmarksTree = BookmarksParser.parse(htmlContent);
169
- console.log(bookmarksTree.toJSON());
170
- });
171
-
172
- // Use native DOMParser for fromDOM method
173
- const dom = new DOMParser().parseFromString(htmlContent, "text/html");
174
- const tree = BookmarksTree.fromDOM(dom);
175
223
  ```
176
224
 
177
225
  ### BookmarksParser Class
@@ -575,7 +623,20 @@ When reporting issues, please include:
575
623
 
576
624
  ## Changelog
577
625
 
578
- ### v1.1.0 (Latest)
626
+ ### v1.1.2 (Latest)
627
+
628
+ - 📝 **Documentation Enhancement**: Updated comprehensive README documentation with latest version references and improved examples
629
+ - 🔧 **Version Consistency**: Synchronized version numbers across all documentation and code examples
630
+ - 📚 **Content Updates**: Refined installation instructions, usage examples, and API documentation for better clarity
631
+
632
+ ### v1.1.1
633
+
634
+ - 🛡️ **Security Enhancement**: [`BookmarksTree.prototype.HTMLText`](src/BookmarksTree/BookmarksTree.ts) now properly escapes HTML entities in bookmark titles and URLs
635
+ - 🔧 **Code Consistency**: Unified HTML escaping behavior between Node.js and browser versions
636
+ - 📝 **Documentation Updates**: Enhanced API documentation with security considerations
637
+ - 🐛 **Bug Fixes**: Minor stability improvements and edge case handling
638
+
639
+ ### v1.1.0
579
640
 
580
641
  - 🌐 **Browser Support**: Added web-optimized version for browser environments
581
642
  - 📦 **Dual Entry Points**: Separate builds for Node.js/Deno (`./mod.ts`) and browsers (`./mod_web.ts`)
@@ -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,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,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"}
@@ -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
  }
@@ -1 +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,CAoCrB;CACD"}
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"}
@@ -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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "netscape-bookmark-parser",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "keywords": [
5
5
  "bookmark",
6
6
  "parser",
@@ -19,6 +19,9 @@
19
19
  }
20
20
  },
21
21
  "scripts": {},
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
22
25
  "dependencies": {
23
26
  "@deno/shim-deno": "~0.18.0"
24
27
  },