ハイライト
このセッションは、Safari 16 の Web 拡張機能の改善に焦点を当てます。最大のトピックはマニフェスト V3 移行のサポートです。Chrome/Firefox 拡張機能があり、すでに MV3 への移行を行っている場合は、Safari の方が適応しやすいでしょう。
主要内容
Safari Web Extensions の問題は通常、最初のバージョンではなく、継続的な互換性です。
拡張機能は Mac、iPhone、iPad に同時に対応する必要があり、Chrome、Firefox、Edge の拡張機能プラットフォームの変更にも対応する必要があります。Manifest V3 では、バックエンド モデルが変更され、スクリプト インジェクション API が変更され、リソースの公開とコンテンツ セキュリティ ポリシーが強化されました。ブラウザ間の違いが多すぎると、メンテナンス コストが急速に増加します。
このセッションの主な情報は次のとおりです。Safari 15.4 はマニフェスト V3 拡張機能をサポートし、Safari 16 は一連の Web 拡張機能 API を完成させ、クロスデバイス同期エクスペリエンスを提供します。既存の Manifest V2 拡張機能は引き続きサポートされます。移行の準備ができている拡張機能は、サービス ワーカーを段階的に採用できます。scripting、declarativeNetRequest、externally_connectableそしてunlimitedStorage。
詳細
マニフェスト V3: バックグラウンド ページがイベント駆動型になる
(01:02) Manifest V3 は、Web Extensions プラットフォームの次のバージョンです。Safari 15.4 以降では、Manifest V3 拡張機能を実行できます。Apple はまた、Safari が引き続き Manifest V2 拡張機能をサポートすると述べました。
Manifest V3 の主な変更点の 1 つは、拡張機能がバックグラウンド ページの代わりにサービス ワーカーを使用できることです。Service Worker はイベント駆動型のページであり、addEventListenerリスナーを登録します。Safari では、背景ページを継続的に使用することもできますが、それらは非永続的である必要があります。
移行するときの最小の最初のステップは、マニフェスト構造を変更することです。
{
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"action": {
"default_icon": {
"16": "Images/icon16.png"
},
"default_title": "defaultTitle"
}
}
キーポイント:
manifest_versionに変更します3、マニフェスト V3 ルールに拡張されました。background.service_workerバックグラウンド スクリプトをポイントし、イベントに基づいてバックグラウンド ロジックを開始させます。actionマニフェスト V2 にマージbrowser_actionそしてpage_action。default_iconそしてdefault_titleツールバーボタンのデフォルト表示の説明を続けます。
スクリプト: スクリプト インジェクションが文字列に記述されなくなりました
(02:03) マニフェスト V3 では、JavaScript を実行してスタイルを挿入する機能が削除されます。tabsAPI が新しいものに移動されましたscripting API。tabs.executeScript は Manifest V3 では利用できず、scripting はマニフェスト V2 と V3 の両方で使用できます。
古い書き方では、コードを文字列に詰め込むことしかできません。
// Manifest version 2
browser.tabs.executeScript(1, {
frameId: 1,
code: "document.body.style.background = 'blue';"
});
キーポイント:
browser.tabs.executeScript古い API です。- 最初のパラメータはタブを指定します。
frameId指定できるフレームは 1 つだけです。code文字列を渡すと、複雑なロジックの保守が困難になります。
新しい書き込みメソッドでは、関数、パラメータ、ターゲット フレームを渡すことができます。
// Manifest version 3
function changeBackgroundColor(color) {
document.body.style.background = color;
};
browser.scripting.executeScript({
target: { tabId: 1, frameIds: [ 1 ] },
func: changeBackgroundColor,
args: [ "blue" ]
});
キーポイント:
changeBackgroundColorこれは通常の関数であり、文字列として記述されることはありません。target.tabIdは必須情報です。tab ID がない場合はエラーが返されます。target.frameIdsでは複数の frame を指定できます。func注入される関数へのポインタ。argsインジェクション関数にパラメータを渡します。
スクリプト ファイルには、複数のスクリプトを一度に挿入することもできます。
// Manifest version 3
browser.scripting.executeScript({
target: { tabId: 1 },
files: [ "file.js", "file2.js" ]
});
キーポイント:
target.tabIdスクリプトを実行するページを指定します。files配列を受け入れ、複雑なロジックを複数のファイルに分割するのに適しています。- これは置き換えます
tabs.executeScript一度に 1 つのファイルのみを指定するという古い制限。
スタイルも同じ API セットに従います。
// Add styling
browser.scripting.insertCSS({
target: { tabId: 1, frameIds: [ 1, 2, 3 ] },
files: [ "file.css", "file2.css" ]
});
// Remove styling
browser.scripting.removeCSS({
target: { tabId: 1, frameIds: [ 1, 2, 3 ] },
files: [ "file.css", "file2.css" ]
});
キーポイント:
insertCSS注入样式文件。removeCSS挿入されたスタイル ファイルを削除します。frameIds複数のフレームを一度に処理できます。filesスタイルの分割を明確に保ちます。
Session の Sea Creator の例は、実際の移行手順を示しています。マニフェストをバージョン 3 に変更し、browser_actionに変更しますaction、 またbrowser.tabs.executeScriptに変更しますbrowser.scripting.executeScript。最初の実行が失敗すると、コンソールにレポートが表示されます。browser.tabs.executeScript is undefined、その理由は、Manifest V3 では古い API が利用できないためです。
web_accessible_resources: リソースは指定されたサイトにのみ公開されます
(04:43)マニフェスト V2 のweb_accessible_resourcesファイル配列を宣言するだけです。問題は、拡張機能にアクセス権がある限り、Web ページがこれらのリソースにアクセスできる可能性があることです。
マニフェスト V3 はリソースと一致するルール バインディングに変更されました。
// Manifest version 3
"web_accessible_resources": [
{
"resources": [ "pie.png" ],
"matches": [ "*://*.apple.com/*" ]
},
{
"resources": [ "cookie.png" ],
"matches": [ "*://*.webkit.org/*" ]
}
]
キーポイント:
resources使用可能にする拡張リソースを指定します。matchesどの Web ページ URL がこれらのリソースにアクセスできるかを示します。pie.pngのみオープンapple.comURL。cookie.png只开放给webkit.orgページ。
コンテンツセキュリティポリシーもオブジェクト形式に変更されます。
// Manifest version 3
"content_security_policy" : { "extension_pages" : "script-src 'unsafe-eval' 'self'" }
キーポイント:
- Manifest V3 はオブジェクトを使用して宣言します
content_security_policy。 extension_pages拡張ページのポリシー キーです。- リモート スクリプト ソースはマニフェスト V3 では許可されなくなりました。
declarativeNetRequest: リクエストの変更を Safari に引き渡す
(10:03)declarativeNetRequestコンテンツ ブロック API です。拡張機能はルールセットを宣言するだけで、Safari はネットワーク要求を傍受して変更する作業を実行します。
ルールセットはマニフェストに記述することができます。
// manifest.json
"permissions": [ "declarativeNetRequest" ],
"declarative_net_request": {
"rule_resources": [
{
"id": "my_ruleset",
"enabled": true,
"path": "rules.json"
}
]
}
キーポイント:
permissions声明はこちらdeclarativeNetRequest権限。declarative_net_request.rule_resourcesルールセットをリストします。idルールセットの識別子です。enabledルールセットを有効にするかどうかを制御します。path実際のルール ファイルを指します。
Safari では、マニフェストで宣言されたルール セットを最大 50 個まで許可できるようになりました。同時に最大 10 個を有効にできます。これにより、複数のフィルタリング モードを備えた拡張機能のより柔軟なルール構成が可能になります。
(11:13) 今年は 2 つの新しい動的更新 API も追加されました。
// Rules that won't persist
browser.declarativeNetRequest.updateSessionRules({ addRules: [ rule ] });
// Rules that will persist
browser.declarativeNetRequest.updateDynamicRules({ addRules: [ rule ] });
キーポイント:
updateSessionRules現在のセッションのルールを追加または削除します。- セッション ルールは、ブラウザー セッションまたは拡張機能の更新をまたいで保持されません。
updateDynamicRules更新ではルールが維持されます。- 動的ルールは、拡張機能の更新全体を公開しなくても、インターセプト ルールを更新できます。
デモのシナリオは具体的です。Sea Creator はまずルールですべての URL の画像をブロックし、その後 updateSessionRules を使って webkit.org/blog-files ページでの画像読み込みを許可します。その結果、WebKit ブログの画像は復元される一方、Wikipedia ページの画像は引き続きブロックされていることがわかります。
externally_connectable: Web ページは拡張機能と通信できます
(14:17)externally_connectableユーザーが拡張機能を有効にしたときに、Web サイトでカスタム動作を作成できるようにします。使用する前に、マニフェストで一致パターンを宣言して、どのページが拡張機能と通信できるかを決定する必要があります。
Apple は 2 つの条件を具体的に述べています: この機能は次の 2 つの条件のみを使用します。browser名前空間。拡張機能がメッセージを送受信できるようにするには、ユーザーは拡張機能にページへのアクセス許可を付与する必要があります。
Web ページ上でメッセージを送信します。
// In the webpage
let extensionID = "com.apple.Sea-Creator.Extension (GJT7Q2TVD9)";
browser.runtime.sendMessage(extensionID, { greeting: "Hello!" },
function(response) {
console.log("Received response from the background page:");
console.log(response.farewell);
});
キーポイント:
extensionIDは拡張機能の bundle identifier と team identifier の組み合わせを使用します。browser.runtime.sendMessage内線番号にメッセージを送信します。- 2 番目のパラメータはメッセージ本文です。
- コールバック関数は、拡張機能から返された応答を処理します。
背景ページを拡張して外部メッセージをリッスンします。
// In the background page
browser.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
console.log("Received message from the sender:");
console.log(message.greeting);
sendResponse({ farewell: "Goodbye!" });
});
キーポイント:
onMessageExternalWeb ページから外部メッセージを受信します。messageWeb ページから渡されるデータです。sender出典を説明します。sendResponseはレスポンスを Web ページへ送り返します。
ブラウザー間で公開する場合、同じ拡張機能が複数のストア ID を持つ可能性があります。Web ページでは、まずユーザーが Safari Web 拡張機能をインストールしていることを確認する必要があります。
// Determining the correct identifier
function determineExtensionID(extensionID) {
return new Promise((resolve) => {
try {
browser.runtime.sendMessage(extensionID, { action: 'determineID' }, function(response) {
if (response)
resolve({ extensionID: extensionID, isInstalled: true, response: response });
else
resolve({ extensionID: extensionID, isInstalled: false });
});
}
});
};
キーポイント:
determineExtensionID単一の候補 ID にプローブ メッセージを送信します。browser.runtime.sendMessage送信determineIDアクション。- 応答があれば返す
isInstalled: true。 - 応答がない場合は返送されます
isInstalled: false。 - Session では複数の ID がある場合に
Promise.allと組み合わせてプローブをブロードキャストし、その結果からインストール済みの拡張機能を見つけることが推奨されています。
拡張側はプローブメッセージに応答する必要があります。
// background.js
browser.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
if (message.action == "determineID") {
sendResponse({ "Installed" });
}
});
キーポイント:
- バックグラウンド スクリプトは外部メッセージをリッスンします。
actionがdetermineIDのメッセージだけを処理します。sendResponseは拡張機能がインストール済みであることを Web ページに伝えます。
unlimitedStorage: ストレージ割り当ては 10 MB ではなくなりました
(17:28)Safari の unlimitedStorage は今では本当に無制限です。拡張機能には 10 MB の割り当てが適用されなくなりました。
有効化方法は短いです。
// manifest.json
"permissions": [ "storage", "unlimitedStorage" ]
キーポイント:
storageは拡張機能のストレージ API を有効にします。unlimitedStorage10 MB のクォータ制限を削除しました。- ユーザーは、拡張機能で使用されているデータをいつでもクリアできます。
- Apple は、ユーザーが積極的にデータを消去できないように、必要なデータのみを保存することをお勧めします。
Safari 16: 拡張されたクロスデバイス同期
(18:19) Safari 16 では、拡張されたクロスデバイス エクスペリエンスが向上しています。ユーザーが 1 つのデバイスで拡張機能を開いた後、他のデバイスの拡張機能の設定でダウンロードを求めるメッセージが表示されます。ダウンロード後、自動的に有効になります。
このエクスペリエンスを機能させるために、Apple は App Store に送信するときに iOS、iPadOS、macOS を一緒にリストすることを推奨しています。同期を設定するには 2 つの方法があります。
1つ目はユニバーサル購入です。ユーザーは一度購入するだけで、プラットフォーム間で同じ拡張機能を使用できます。セットアップ時に、拡張機能が App Store Connect 内の同じアプリ レコードに関連付けられるように、単一のバンドル識別子を使用する必要があります。
2 つ目は、アプリを手動でリンクすることです。Xcode の Info.plist に、iOS アプリ、iOS 拡張機能、macOS アプリ、および macOS 拡張機能に対応するバンドル識別子を追加します。Session のデモンストレーションでは、各ターゲットの設定に対応するプラットフォームのアプリと拡張機能の識別子を入力します。
重要ポイント
1. Manifest V3 移行チェッカーを作る
- 内容: 拡張機能のソースをスキャンし、
tabs.executeScript、browser_action、Manifest V2 のcontent_security_policyなどの移行ポイントを列挙します。 - 実行する価値がある理由: Session での Sea Creator の失敗の原因は次のとおりです。
browser.tabs.executeScript is undefined、そのような問題は構築する前に発見できます。 - 開始方法:
manifest.jsonからmanifest_version、browser_action、page_action、content_security_policyを解析し、スクリプト内のbrowser.tabs.executeScriptをスキャンして、対応するscripting.executeScriptへの変更提案を出します。
2. コンテンツブロック拡張機能にサイト単位のスイッチを追加する
- 内容: サイトがポップアップで画像、スクリプト、またはリクエストを読み込むことをユーザーが一時的に許可できるようにします。
- 実行する価値がある理由:
updateSessionRules「このセッションのためにこの Web サイトを解放する」に適した非永続的なルールを追加できます。 - 開始方法: manifest で
declarativeNetRequestを構成し、デフォルトルールをrules.jsonに配置します。ユーザーが解除をクリックしたときにbrowser.declarativeNetRequest.updateSessionRules({ addRules: [rule] })を呼び出します。
3. Web サイトに「拡張機能がインストール済みかを検出する」入口を提供する
- 内容: Web サイトは、ユーザーがアクセスしたときに Safari Web 拡張機能が存在するかどうかを検出し、存在する場合は拡張機能固有の機能を表示します。
- 実行する価値がある理由:
externally_connectableWeb ページと拡張機能間の通信を可能にし、Web サイトと拡張機能が連携してログイン、保存、注釈、コンテンツ拡張などのプロセスを完了するのに適しています。 - 開始方法: Web ページ側で
browser.runtime.sendMessage(extensionID, { action: 'determineID' })を使ってプローブし、拡張機能のバックグラウンド側でbrowser.runtime.onMessageExternal.addListenerを使って応答します。
4. クロスデバイス拡張機能のリリース前チェックリストを作成する
- 対処方法: iOS、iPadOS、macOS のアプリと拡張機能に、クロスデバイスのダウンロードとアクティベーションに必要な構成があるかどうかを確認します。
- 実行する価値がある理由: Safari 16 はユーザーが有効化した拡張機能を他のデバイスにも引き継ぎます。ただし、App Store と bundle identifier が正しく構成されていることが前提です。
- 開始方法: まず universal purchase を採用します。採用できない場合は、Xcode の Info.plist で app と extension に対応するプラットフォームの bundle identifiers を入力します。
5. ビッグ データ拡張機能を「クリーンな」ストレージ モデルに変更する
- 内容: パスワード管理、Web クリッピング、読書注釈などの拡張機能向けに、ストレージ使用量パネルとクリーンアップボタンを設計します。
- 実行する価値がある理由:
unlimitedStorageは 10 MB のクォータをなくしますが、ユーザーは引き続き拡張機能のデータを消去できます。 - 開始方法: manifest で
"permissions": [ "storage", "unlimitedStorage" ]を宣言し、ストレージ画面には必要なデータだけを残し、キャッシュ、インデックス、ユーザーコンテンツの使用量を表示します。
関連セッション
- Create Safari Web Inspector Extensions — 同じく Web Extensions 標準を基盤にし、その機能を Safari Web Inspector のカスタムツールへ拡張します。
- Safari の Web Push について — Safari のプッシュ API、通知 API、およびサービス ワーカーの標準サポートについて説明します。
- Explore Safari Web Extension improvements — Safari 15 の Web Extensions 改善を紹介しており、このセッションの Manifest V3 移行を理解するための前提になります。
- Safari Web Extensions の紹介 — Safari Web Extensions の基本モデルの紹介と、他のブラウザからの移行の開始点です。
コメント
GitHub Issues · utterances