1. ようこそ
このラボでは、既存のウェブ アプリケーションに高度な機能を追加します。これは、プログレッシブ ウェブアプリ ワークショップの一連のコンパニオン Codelab の 6 番目です。前の Codelab は、インストールを促して測定するでした。このシリーズには、さらに 2 つの Codelab があります。
学習内容
- File System Access API を使用してユーザーのファイル システムからファイルを開いて保存する
- インストールされた PWA を File Handling API でファイル ハンドラとして登録する
- Multi-Screen Window Placement API を使用してウィンドウを開く適切な画面を選択する
- Screen Wake Lock API を使用して画面がスリープ状態になるのを防ぐ
必要な予備知識
- JavaScript
必要なもの
- 上記の API をサポートするブラウザ。一部の API では、デベロッパー トライアルまたはオリジン トライアルが有効になっているブラウザを使用して完了する必要があります。
2. 準備
まず、この Codelab を完了するために必要なスターター コードをクローンするかダウンロードします。
リポジトリのクローンを作成する場合は、pwa05--empowering-your-pwa
ブランチにいることを確認してください。zip ファイルには、そのブランチのコードも含まれています。
このコードベースには Node.js 14 以降が必要です。コードが用意できたら、コードのフォルダのコマンドラインから npm ci
を実行して、必要なすべての依存関係をインストールします。次に、npm start
を実行して、Codelab の開発用サーバーを起動します。
ソースコードの README.md
ファイルには、すべての配布ファイルの説明が記載されています。また、この Codelab 全体を通して使用する主な既存のファイルは次のとおりです。
キーファイル
js/lib/actions.js
- メニューの基本クラスを提供します
重要なアーキテクチャ上の注意事項
この Codelab では、アプリのメニューにあるさまざまなボタンのアクションを管理する js/lib/action.js
を編集します。初期化されたメニューのコンストラクタ内の任意のプロパティにアクセスできます。これには、メイン テキスト エディタのインスタンスの this.editor
が含まれます。この Codelab で使用する重要なエディタ メソッドは次の 2 つです。
this.editor.setContent(content)
- エディタのコンテンツを指定されたコンテンツ引数に設定しますthis.editor.content()
- エディタの現在のコンテンツを取得します
3. ファイルを管理する
File System Access API のおかげで、ユーザーのパソコンでファイルを開いたり、保存したり、新しいファイルを作成したりできるようになりました。File Handling API と組み合わせることで、ユーザーが PWA でファイルを直接開けるようになり、PWA がユーザーの日常生活にシームレスに統合されたように感じられます。
アプリ内から開く
最初にフックするアクションは、アプリ内からユーザーのファイルシステムにあるファイルを開くことができるようにすることです。js/lib/actions.js
の Actions
クラスの open
メソッドで、次の処理を行うコードを記述します。
- 拡張子が
.md
または.markdown
のtext/markdown
ファイルを受け取るファイル選択ツールを開きます。 - ページのタイトルを開いているファイルの名前に
PWA Edit
を追加して設定します - ファイル ハンドラを
this.handler
に保存する - エディタのコンテンツをファイル内のテキスト コンテンツに設定します。
- ハンドラを
settings-store
IndexedDB データベースのsettings
オブジェクト ストアに保存します。
ポジティブ: クラス コンストラクタは async
関数にできませんが、その中で Promise を呼び出すことはできます。
ファイルを読み込んで、読み込まれたファイルを読み込み間で保存できるようになったので、あと 2 つ行う必要があります。アプリの読み込み時にハンドラを再度設定し、ユーザーがアプリをリセットしたときにハンドラの設定を解除します。
最初の処理を行うには、js/lib/actions.js
の Actions
クラスのコンストラクタで次の操作を行います。
settings-store
データベースを開く- 保存されたハンドラを
settings
オブジェクト ストアから取得する - 保存されたハンドラがある場合は、
this.handler
を取得した値に設定し、ページのタイトルをハンドラのファイル名(+PWA Edit
)に設定します。
アプリの状態をリセットする(CTRL
/CMD
+ Shift
+ R
で実現可能)には、js/lib/actions.js
の Actions
クラスの reset
メソッドを更新して、次の処理を行います。
- ドキュメントのタイトルを
PWA Edit
に設定します - エディタのコンテンツを空の文字列に設定する
this.handler
をnull
に設定する- 保存されたハンドラを
settings
オブジェクト ストアから削除する
ユーザーのファイル システムから開く
アプリからファイルを開けるようになったので、ユーザーがファイルからアプリを開けるようにしましょう。デバイスのファイル ハンドラとして登録すると、ユーザーはファイル システムのどこからでもアプリでファイルを開けるようになります。
ネガティブ : これを機能させるには、デベロッパーまたはオリジン トライアルを有効にする必要がある場合があります。デベロッパー トライアルを有効にする必要がある場合は、通常のブラウザではなく、Chrome Canary のコピーで有効にすることをおすすめします。オリジン トライアルを有効にする必要がある場合は、通常どおり登録し、 タグを
index.html
に追加する必要があります。
まず、manifest.json
で、次の処理を行う file_handlers
エントリを追加します。
- 営業開始:
/
.md
または.markdown
のファイル拡張子を持つtext/markdown
を指定します。
これにより、ユーザーはアプリでファイルを開くことができますが、実際にアプリでファイルが開かれるわけではありません。アプリでファイルを開くには、js/lib/actions.js
の Actions
クラスで次の操作を行います。
- コンストラクタに
window.launchQueue
コンシューマーを追加し、ハンドラがある場合はハンドラを使用してthis.open
を呼び出します。 - オプションの起動ハンドラを受け入れるように
this.open
を更新- 存在し、
FileSystemFileHandle
のインスタンスである場合は、それを関数のファイル ハンドラとして使用します。 - そうでない場合は、ファイル選択ツールを開きます。
- 存在し、
上記の両方を実行したら、PWA をインストールして、ファイル システムからファイルを開いてみてください。
ファイルを保存する
ユーザーが選択できる保存パスは、すでに開いているファイルへの変更の保存と、新しいファイルへの保存の 2 つです。File System Access API を使用して新しいファイルに保存すると、実際に新しいファイルが作成され、ファイル ハンドラが返されます。まず、既存のハンドラから保存してみましょう。
js/lib/actions.js
の Actions
クラスの save
メソッドで、次の操作を行います。
this.handler
からハンドラを取得するか、存在しない場合はデータベースから保存されたハンドラを取得します。- ファイル ハンドラの
FileSystemWritableFileStream
を作成する - エディタのコンテンツをストリームに書き込む
- ストリームを閉じる
ファイルを保存できるようになったら、名前を付けて保存を実装します。これを行うには、js/lib/actions.js
の Actions
クラスの saveAs
メソッドで次の操作を行います。
- 保存ファイル選択ツールを表示し、
Markdown File
として説明して、.md
拡張子のtext/markdown
ファイルを受け入れるようにします。 this.handler
を返されたハンドラに設定する- ハンドラを
settings
オブジェクト ストアに保存する this.save
が完了するまで待ってから、新しく作成したファイルにコンテンツを保存します。
完了したら、save
メソッドに戻り、handler
が存在するかどうかを確認してから書き込みを試み、存在しない場合は this.saveAs
の完了を待ちます。
4. プレビューを表示する
Markdown エディタでは、ユーザーはレンダリングされた出力のプレビューを確認したいと考えています。ウィンドウ管理 API を使用して、ユーザーのプライマリ画面にレンダリングされたコンテンツのプレビューを開きます。
始める前に、js/preview.js
というファイルを作成し、次のコードを追加して、読み込み時にプレビューを表示するようにします。
import { openDB } from 'idb';
import { marked } from 'marked';
window.addEventListener('DOMContentLoaded', async () => {
const preview = document.querySelector('.preview');
const db = await openDB('settings-store');
const content = (await db.get('settings', 'content')) || '';
preview.innerHTML = marked(content);
});
プレビューは次のように動作します。
- ユーザーがプレビュー ボタンをクリックしたときにプレビューが開いていない場合は、プレビューを開く必要があります
- ユーザーがプレビュー ボタンをクリックしてプレビューが開いている場合、プレビューを閉じる必要があります
- ユーザーが PWA を閉じるか更新すると、プレビューが閉じる
これらを順番に処理するため、まず js/lib/actions.js
の Actions
クラスの preview
メソッドを編集して、次の処理を行います。
- Window Management API を使用して利用可能な画面を取得する
- 画面をフィルタしてプライマリ画面を見つける
/preview
のウィンドウを開きます。タイトルはMarkdown preview
で、プライマリ画面の利用可能な幅の半分と利用可能な高さ全体を占め、その画面の利用可能な右半分全体を占めるように配置されます。使用可能なディメンションには、システム メニューバー、ツールバー、ステータス、位置情報など、画面の予約済み領域は含まれません。- 開いているウィンドウを
this.previewWindow
に保存する - メソッドの先頭で、
this.previewWindow
が存在するかどうかを確認し、存在する場合は、ウィンドウ プレビューを開く代わりに、ウィンドウを閉じてthis.previewWindow
を設定解除します。
最後に、js/lib/actions.js
の Actions
クラスのコンストラクタの末尾で、次の操作を行います。
beforeunload
イベント中にthis.previewWindow
を閉じる
5. フォーカス
最後に、ユーザーに集中して執筆できるモードを提供したいと考えています。他のアプリの雑多な情報が表示されないだけでなく、ユーザーの画面がスリープ状態にならないようにすることも、集中モードの目的です。これを行うには、Screen Wake Lock API を使用します。
ウェイクロック ボタンはプレビュー ボタンと同じように機能し、オンとオフの状態を切り替えます。これを行うには、js/lib/actions.js
の Actions
クラスの focus
メソッドで、次の操作を行います。
- ドキュメントに全画面表示要素があるかどうかを確認する
- その場合は、次の手順を行います。
- 全画面表示を終了
this.wakeLock
が存在する場合は、ウェイクロックを解放してthis.wakeLock
をリセットします。
- オンになっていない場合は、次の手順を行います。
- ウェイクロック センチネルをリクエストして
this.wakeLock
に設定します - ドキュメントの本文を全画面表示にするようリクエストします。
- ウェイクロック センチネルをリクエストして
6. 完了
File System Access API と File Handling API を使用してシステムファイルを管理し、PWA をシステムに統合する方法、Window Management API を使用してさまざまな画面でウィンドウを開く方法、Screen Wake Lock API を使用して画面がスリープ状態になるのを防ぐ方法について説明しました。
このシリーズの次の Codelab は、Service Worker の組み込みです。