12

私は最初の Safari 拡張機能 (非常に単純なもの) を作成中ですが、いくつかの問題に遭遇しました。拡張機能は、ネイティブ フィード ハンドラをバイパスして http:// URI にリダイレクトしようとする単一の挿入されたスクリプトに要約されます。これまでのところ、私の問題は2つあります。

  1. 「ホワイトリスト」が期待どおりに機能していません。すべてのフィードは「feed://」プロトコルで表示されるため、ホワイトリストに「feed://*/*」としてキャプチャしようとしましたが (ブラックリストには何もありません)、リクエストになってしまいます理解できないループ。「 http://*/*」と「https://*/* 」のブラックリスト値を設定すると、すべてが期待どおりに機能します。
  2. 挿入されたスクリプトから自分の設定にアクセスする方法がわかりません。スクリプトはbeforeloadイベント ハンドラーを作成しsafari.extension.settingsますが、ドキュメントに示されているパスを使用して設定にアクセスできません。

Apple のドキュメントには、スクリプトから設定を使用できないことを示すものは見つかりませんでした。拡張機能は非常に新しい機能であるため、Google でさえ返される関連する結果は限られており、それらのほとんどは公式ドキュメントからのものです。

私は何が欠けていますか?

更新 したがって、境界線がひどいため、ドキュメントが不完全であることを願っていますが、設定について少し学びました。インジェクション スクリプトから、SafariExtensionSettingsオブジェクトが利用できないことが判明しました。インジェクション スクリプトはオブジェクトにしかアクセスできSafariContentExtensionませんが (これはまったく役に立ちません)、まったく同じ方法でエイリアス化されます ( safari.extension.settings)--悪い考えです。インジェクションスクリプトのドキュメントに記載されているように:

重要: 挿入されたスクリプト内から safari.extension を使用する場合、SafariExtension クラスに対処していません。SafariContentExtension クラスに対処しています。

設定にアクセスできるグローバル HTML ファイルと通信するには、メッセージング システムを使用する必要があります。ちょっとおかしな話ですがglobal.html、設定を取得するファイルにメッセージが送信されており、その方法がわかり次第、インジェクション スクリプトにメッセージを送り返します。

ドキュメントが読み込まれる前にすべての作業を行っているため、メッセージを送り返すために見つけたすべてのメソッドは、私が持っていないページ オブジェクトに依存しています。

4

4 に答える 4

6

この時点で他のみんなと同じように、私はまだ学習曲線を上っていますが、この問題をどのように処理したかを次に示します。

クロムがなく、エンド スクリプト (script.js) が 1 つ挿入された単純な拡張機能があります。設定をロードする目的で、単純なグローバル ページ (proxy.html) を追加しました。script.js が挿入されると、getSettingsproxy.html にメッセージが送信されます。proxy.html はsetSettingsメッセージで応答し、script.js は初期化を続行します。

このトピックに関するドキュメントで私が見つけた最も役立つページはMessages and Proxiesです。

proxy.html:

<!doctype html>
<html lang="en">
<head>
  <script type="text/javascript">
    safari.application.addEventListener( "message", function( e ) {
      if( e.name === "getSettings" ) {
        e.target.page.dispatchMessage( "setSettings", {
          sort_keys: safari.extension.settings.getItem( "sort_keys" )
        } );
      }
    }, false );
  </script>
</head>
<body></body>
</html>

script.js:

( function() {
  var settings, init = function() {
    // do extension stuff
  };

  // listen for an incoming setSettings message
  safari.self.addEventListener( "message", function( e ) {
    if( e.name === "setSettings" ) {
      settings = e.message;
      init();
    }
  }, false );

  // ask proxy.html for settings
  safari.self.tab.dispatchMessage( "getSettings" );
}() )
于 2010-06-14T03:56:28.647 に答える
3

編集:最初の投稿の更新で述べたように、挿入されたスクリプトには、グローバル HTML ページと同じ種類のアクセス権がありません。これは私の実用的なソリューションです。挿入されたスクリプトで「foo」を設定することの値を知りたいと想像してください。

挿入されたスクリプト コード:

function getMessage(msgEvent) {

    if (msgEvent.name == "settingValueIs")
        alert("Value for asked setting is: " + msgEvent.message);

}

safari.self.tab.dispatchMessage("getSettingValue", "foo"); // ask for value
safari.self.addEventListener("message", getMessage, false); // wait for reply

グローバル HTML コード:

function respondToMessage(messageEvent) {

    if (messageEvent.name == "getSettingValue") {

           // getItem("foo");
        var value = safari.extension.settings.getItem(messageEvent.message);
        // return value of foo to injected script
           safari.application.activeBrowserWindow.activeTab.page.dispatchMessage("settingValueIs", value);

    } 

}

safari.application.addEventListener("message",respondToMessage,false);

お役に立てれば !


最初の投稿:私はあなたと同じ 2 番目の問題を抱えています。注入されたスクリプトから自分の設定 (または secureSettings) にアクセスできません。私の場合、スクリプトはページの読み込み後に読み込まれますが、それでも使用できませんsafari.extension.settings

それが機能する唯一の方法は、ツールバー/ボタンを使用することです。その要素の背後にある HTML はgetItem期待どおりにsetItem機能します。

私の結論は、何らかの理由で、挿入されたスクリプトは設定にアクセスできないということです (実際には、要素にアクセスすることさえできないようですsafari)。バグまたは意図された機能、それは理解するために残されています。

于 2010-06-12T13:06:06.463 に答える
2

canLoad()数日かかりましたが、メッセージングメソッドを使用して実行可能な解決策を見つけたと思います. インジェクション スクリプトは、次のようにグローバル HTML ページを呼び出して設定を取得します。

settings = safari.self.tab.canLoad( event );

次に、私のグローバル HTML ファイルは、これらの設定を次のように返します。

settings = {
  'setting1': safari.extension.settings.getItem( 'setting1' )
}

msgEvent.message = settings;

それはまだ私が望むよりも少し「ハッキー」です。設定オブジェクト自体を単純に返すことはできないようです。そのため、各設定を手動で取得して新しいオブジェクトをコンパイルする必要があります。理想的ではありませんが、効果があるようです。

于 2010-06-13T21:58:39.913 に答える
1

同じ問題に遭遇しますが、答えは想像以上に簡単です。スクリプトをグローバル html に含めます。

<!DOCTYPE HTML>
<script type="text/javascript" src="cleanup.js"></script>
<script>
…
</script>

その後、ドキュメントに記載されているように設定にアクセスできますsafari.extension.settings.myKey

@Travis に賛成票を投じることもできます。彼の投稿からアイデアを得たからです。

//編集:
実際、何が悪いのかよくわかりません。最初のコマンドとして設定を呼び出すと機能しますが、後で機能しません。さらに、インジェクション後に完全なスクリプトが破損しているようです。それが私の(難しい?)スクリプトだけにある場合は、検証が必要です。

//EDIT2:
設定オブジェクトを取得するために動作するようになりましたdispatchMessage()

あなたのinjected.js

function gotSettings(msgEvent) {
   if (msgEvent.name === "SETTINGS") {
      setts = msgEvent.message;
      alert(setts.mySetting1);
      // run the programm
   }
}

safari.self.addEventListener("message", gotSettings, false);
safari.self.tab.dispatchMessage("getSettings");

そしてglobal.html

switch (event.name) {
case "getSettings":
   // send the settings data
   event.target.page.dispatchMessage("SETTINGS", safari.extension.settings);

このアップルのドキュメントに依存

于 2012-01-22T21:14:23.057 に答える