@kyudaisai/pamphlet-viewer 0.0.0-stage → 0.1.0-alpha.8
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/NOTICE +7 -0
- package/README.md +132 -2
- package/THIRD_PARTY_NOTICES.txt +8 -0
- package/dist/library/assets/pdfium-BJ2Yip8Q.wasm +0 -0
- package/dist/library/assets/pdfium.worker-BKxTY1QJ.js +7 -0
- package/dist/library/pamphlet-viewer.d.ts +87 -0
- package/dist/library/pamphlet-viewer.js +101 -0
- package/licenses/LICENSE.embedpdf.txt +21 -0
- package/licenses/LICENSE.lucide.txt +43 -0
- package/licenses/LICENSE.pdfium.txt +196 -0
- package/licenses/LICENSE.svelte.txt +7 -0
- package/package.json +80 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 九大祭実行委員会 and kurage (@umitsukidev)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) 2026 九大祭実行委員会 and kurage (@umitsukidev)
|
|
2
|
+
|
|
3
|
+
This project is licensed under the MIT License. See LICENSE for the full text.
|
|
4
|
+
|
|
5
|
+
Source code: https://github.com/kyudaisai-committee/pamphlet-viewer
|
|
6
|
+
|
|
7
|
+
Third-party notices: THIRD_PARTY_NOTICES.txt and licenses/.
|
package/README.md
CHANGED
|
@@ -1,3 +1,133 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Pamphlet Viewer
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@embedpdf/pdfium`(EmbedPDF)を使ってPDFを表示する、Svelte 5製のWeb Componentです。ES moduleとして配布し、Svelte以外のHTMLページにも埋め込めます。PDFはHTTP Rangeで必要な範囲を取得します。
|
|
4
|
+
|
|
5
|
+
## HTMLへの埋め込み
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<script type="module">
|
|
9
|
+
import { registerPamphletViewer } from "/assets/pamphlet-viewer.js";
|
|
10
|
+
|
|
11
|
+
registerPamphletViewer();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<pamphlet-viewer
|
|
15
|
+
src="./documents/catalog.pdf"
|
|
16
|
+
page="1"
|
|
17
|
+
layout="auto"
|
|
18
|
+
fit="page"
|
|
19
|
+
style="display: block; width: 100%; height: 70vh; min-height: 22rem"
|
|
20
|
+
></pamphlet-viewer>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`registerPamphletViewer()`は登録済みの要素を再登録しません。ブラウザーでentryを読み込むと自動登録も行われます。ホスト要素に表示領域の高さを指定してください。
|
|
24
|
+
|
|
25
|
+
## 表示言語
|
|
26
|
+
|
|
27
|
+
ツールバーなどの表示言語は、要素の初期化時に`<pamphlet-viewer lang="en">`の`lang`属性、HTML文書の`<html lang="en">`属性の順に選びます。どちらも指定されていない場合は日本語です。要素の`lang`が空文字または空白だけの場合はHTML文書の言語を使います。`ja-JP`や`en-US`など地域付きの値も認識し、大文字小文字を区別しません。未対応の言語値は日本語になります。言語は各ビューアごとに決まり、HTML文書の`lang`属性は変更しません。初期化後に要素の`lang`を変更しても表示言語は切り替わりません。
|
|
28
|
+
|
|
29
|
+
## 属性とプロパティ
|
|
30
|
+
|
|
31
|
+
| 名前 | 初期値 | 説明 |
|
|
32
|
+
| -------- | ------ | ---------------------------------------------- |
|
|
33
|
+
| `src` | 空 | PDFのURL。空でない値を指定すると読み込みます。 |
|
|
34
|
+
| `page` | `1` | 現在ページ。UIとプロパティは1始まりです。 |
|
|
35
|
+
| `layout` | `auto` | `single`、`spread`、`auto`のいずれかです。 |
|
|
36
|
+
| `fit` | `page` | `page`または`width`で表示サイズを合わせます。 |
|
|
37
|
+
|
|
38
|
+
章一覧などの設定は属性ではなく、要素の登録後に`setConfig`メソッドから渡します。
|
|
39
|
+
|
|
40
|
+
`src`の相対URLは、要素の`ownerDocument.baseURI`(`<base>`を含む)を基準に解決します。`getAttribute("src")`は指定された文字列を返し、`element.src`は絶対URLを返します。`element.src = "./catalog.pdf"`と`setAttribute("src", "./catalog.pdf")`は、どちらも読み込む文書を切り替えます。`src`を省略した場合、空属性は自動で追加されません。
|
|
41
|
+
|
|
42
|
+
`layout="auto"`は、サムネイル一覧の幅を除いた紙面表示領域の有効幅が約760px以上なら見開き、それより狭ければ単ページにします。判定はブラウザーウィンドウではなく、ホスト内の紙面表示領域の幅を使います。見開きの先頭ページは表紙として単独で表示し、2ページ目以降を左右に並べます。これはページめくりアニメーションではありません。
|
|
43
|
+
|
|
44
|
+
ページ一覧ボタンでサムネイルを開き、ページを選んで移動できます。サムネイルは一覧全体を一度に描画せず、表示範囲のページを必要に応じて作成します。PDFに埋め込みサムネイルがある場合はそれを優先して使い、ない場合や読み取れない場合はページを縮小描画します。狭いホストでは一覧が表示領域を使い、選択後に本文表示へ戻ります。ズームは10%から800%まで変更でき、拡大中はドラッグで紙面を移動できます。タッチ画面では2本指で拡大縮小できます。CtrlまたはMetaキーを押しながらホイールを操作しても拡大縮小します。通常のホイール操作は紙面をスクロールします。
|
|
45
|
+
|
|
46
|
+
## 章とブックマーク
|
|
47
|
+
|
|
48
|
+
登録済みの要素へ型付き設定オブジェクトを`setConfig`で渡すと、章の一覧を表示して開始ページへ移動できます。`chapters`のページ番号は1始まりです。章の設定順にかかわらずページ順に並び、文書のページ数を外れる項目や不正な項目は表示しません。
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { registerPamphletViewer } from "/assets/pamphlet-viewer.js";
|
|
52
|
+
import type { PamphletViewerConfig, PamphletViewerElement } from "/assets/pamphlet-viewer.js";
|
|
53
|
+
|
|
54
|
+
registerPamphletViewer();
|
|
55
|
+
await customElements.whenDefined("pamphlet-viewer");
|
|
56
|
+
|
|
57
|
+
const viewer = document.querySelector("pamphlet-viewer") as PamphletViewerElement | null;
|
|
58
|
+
const config: PamphletViewerConfig = {
|
|
59
|
+
chapters: [
|
|
60
|
+
{ title: "ご利用案内", page: 1 },
|
|
61
|
+
{ title: "商品一覧", page: 8 },
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
if (viewer) viewer.setConfig(config);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
ブックマークボタンで現在のページを追加・解除でき、保存済みページの一覧から移動できます。ブックマークは文書の解決済みURLごとに`localStorage`へ保存され、同じブラウザーで再度開いたときにも復元します。保存領域を利用できない場合は、その閲覧中はメモリ上で操作できます。
|
|
69
|
+
|
|
70
|
+
全画面ボタンはブラウザーのFullscreen APIを使います。利用できない場合はPopover APIによる画面拡大表示へ切り替え、Popoverに対応しない環境では固定表示を使います。Escapeキーで元の埋め込みサイズへ戻れます。埋め込み時と全画面時でホスト幅に合わせてページ配置を切り替えます。左右矢印またはPageUp/PageDownは、前後移動ボタンにフォーカスがあるときに使えます。
|
|
71
|
+
|
|
72
|
+
## イベント
|
|
73
|
+
|
|
74
|
+
イベントは`bubbles: true`、`composed: true`で発火します。
|
|
75
|
+
|
|
76
|
+
| イベント | `detail` | 発火時点 |
|
|
77
|
+
| -------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
|
|
78
|
+
| `ready` | `undefined` | UIの接続が完了したとき。 |
|
|
79
|
+
| `documentload` | `{ pageCount: number }` | 文書のページ数が分かり、表示準備ができたとき。PDF全体の受信完了を意味しません。 |
|
|
80
|
+
| `pagechange` | `{ page: number; visiblePages: number[] }` | 表示ページが変わり、その描画が完了したとき。同じページのズームやリサイズによる再描画では発火しません。番号は1始まりです。 |
|
|
81
|
+
| `error` | `{ code; message; retryable }` | URL、Range応答、PDF処理、ページ指定などで失敗したとき。 |
|
|
82
|
+
|
|
83
|
+
`error`の`code`は`invalid-source`、`invalid-option`、`load-failed`、`invalid-page`、`render-failed`のいずれかです。`retryable`は再試行操作が利用できるかを示します。
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
const viewer = document.querySelector("pamphlet-viewer");
|
|
87
|
+
|
|
88
|
+
viewer?.addEventListener("documentload", (event) => {
|
|
89
|
+
console.log(`${event.detail.pageCount} pages`);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
viewer?.addEventListener("pagechange", (event) => {
|
|
93
|
+
console.log(event.detail.visiblePages);
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## ページ入力方式の拡張
|
|
98
|
+
|
|
99
|
+
`backend`はHTML属性ではなく要素のプロパティです。`DocumentBackend`は`open(source, signal)`から`PageSource`を返し、`PageSource`は`pageCount`、`getPageSize(pageIndex)`、`renderPage(pageIndex, scale)`、`dispose()`を提供します。`PageVisual`はRGBA pixel bufferまたは`ImageBitmap`です。表示状態とレイアウトはこの契約に依存し、PDFium固有の処理はPDF backendに閉じています。
|
|
100
|
+
|
|
101
|
+
`PamphletViewerElement.backend`へ独自backendを設定し、そのbackendが解釈する値を`src`へ指定できます。現在用意しているbackendはPDFiumのみです。画像URLやページ画像一覧を読むbackendは、同じ契約を使って後から追加できます。
|
|
102
|
+
|
|
103
|
+
`DocumentBackend.open()`へ渡す`source`は、ホスト文書の`baseURI`で解決済みの絶対URLです。ページ内容はCanvasで表示し、PDFテキストの選択・検索・文書構造に基づく読み上げには対応していません。ツールバーのARIAラベルやキーボード操作は、PDF本文のアクセシビリティを提供するものではありません。
|
|
104
|
+
|
|
105
|
+
## PDFとアセットの配信条件
|
|
106
|
+
|
|
107
|
+
PDFサーバーはRange要求に対して正しい`Content-Range`を伴う`206 Partial Content`を返してください。`Accept-Ranges: bytes`だけでは不十分です。Rangeを無視した`200 OK`、`416 Range Not Satisfiable`、不正な`Content-Range`、通信timeoutはエラーになり、PDF全体を取得するfallbackは行いません。初回Range要求がリダイレクトされた場合、検証に成功した応答の最終URLを後続Range要求で再利用します。Rangeを理解し、PDFのbyte位置とvalidatorを一貫させるようCDNや圧縮設定を確認してください。
|
|
108
|
+
|
|
109
|
+
別originのPDFを使う場合は、CORSで`Range`と`If-Range`要求ヘッダーを許可し、`Content-Range`、`ETag`、`Last-Modified`応答ヘッダーを公開してください。`ETag`または`Last-Modified`を使うと、範囲の要求に`If-Range`を付けて同一PDF表現か確認します。
|
|
110
|
+
|
|
111
|
+
HTMLページ、ES module、Worker、WASMを別originから配信する場合、モジュールとWorker/WASMの応答に正しいMIME typeとCORSヘッダーを設定してください。異なるoriginのWorkerはBlob bootstrapからWorker moduleを読み込みます。その構成ではCSPの`worker-src`に`blob:`を許可してください。同一originのWorkerではBlob bootstrapを使いません。
|
|
112
|
+
|
|
113
|
+
## 現在の上限
|
|
114
|
+
|
|
115
|
+
- PDFのbyte位置は32-bitのため、ファイルサイズは4GiB未満です。
|
|
116
|
+
- 読み込みcacheは256KiB単位で保持し、連続する未取得範囲は最大1MiBのRange要求にまとめます。同時要求は最大4件、cacheは最大64MiBで、各要求は30秒でtimeoutします。
|
|
117
|
+
- 1ページの描画出力は最大8,388,608 pixel(約32MiB)です。ズーム倍率は最大800%です。
|
|
118
|
+
|
|
119
|
+
これらの制限を超える文書はエラーになることがあります。大きなPDFへの対応は無制限ではなく、代表的な文書と配信環境でページ数、メモリ、初回表示時間を測定して判断してください。
|
|
120
|
+
|
|
121
|
+
## 開発とビルド
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
pnpm dev
|
|
125
|
+
pnpm build:library
|
|
126
|
+
pnpm verify
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`pnpm build:library`は`dist/library/`に配布用ES module、型定義、PDFium WorkerとWASMを出力します。WorkerとWASMは別ファイルなので、`dist/library/`の構成を保って同じ配信先へ配置してください。ビルド時に外部CDNからWorkerやWASMを取得しません。package exportsは`dist/library/pamphlet-viewer.js`と`dist/library/pamphlet-viewer.d.ts`を指します。`pnpm build`はデモとライブラリの両方をビルドします。
|
|
130
|
+
|
|
131
|
+
## ライセンス
|
|
132
|
+
|
|
133
|
+
このプロジェクトのソースコードは[MIT License](LICENSE)で公開します。[GitHubでソースコードを入手できます](https://github.com/kyudaisai-committee/pamphlet-viewer)。npm配布物には[NOTICE](NOTICE)と第三者ライセンスの表示も含まれます。
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Pamphlet Viewer includes third-party software in its distributable JavaScript
|
|
2
|
+
and WebAssembly files. The corresponding license texts are included in the
|
|
3
|
+
licenses/ directory:
|
|
4
|
+
|
|
5
|
+
- @embedpdf/pdfium (MIT): licenses/LICENSE.embedpdf.txt
|
|
6
|
+
- PDFium WebAssembly (BSD-3-Clause and Apache-2.0): licenses/LICENSE.pdfium.txt
|
|
7
|
+
- @lucide/svelte (ISC and MIT for icons derived from Feather): licenses/LICENSE.lucide.txt
|
|
8
|
+
- Svelte (MIT): licenses/LICENSE.svelte.txt
|
|
Binary file
|