2016-07-25 6 views
1

私はブラウザの拡張機能/アドオンに取り組んでいます。私たちはChromeで作業しているので、Firefoxで動作させようとしています。firefoxアドオンを作成するにはcontentscriptは他のページスクリプトの前にスクリプトを挿入して実行しますか?

私のアドオンはFirefox Developer Edition 49.0a2(2016-07-25)にロードされています。

拡張子はrun_at: document_startに設定されているため、他のページスクリプトを実行する前にスクリプトタグを挿入できるため、ウェブサイトでオブジェクトをグローバルに使用できるようになります。

これはChromeで正常に動作していたようですが、Firefoxではほとんどの場合、他のページリソースが最初に読み込まれるため、少し競合状態にあることが判明しています。

&他のページスクリプトを実行する前にスクリプトを読み込む方法でコンテンツスクリプトを読み込む方法はありますか?

ログを追加すると、何が起こっているのか分かりやすくすることができます。

// inject in-page script 
console.log('STEP 1, this always happens first') 
var scriptTag = document.createElement('script') 
scriptTag.src = chrome.extension.getURL('scripts/inpage.js') 
scriptTag.onload = function() { this.parentNode.removeChild(this) } 
var container = document.head || document.documentElement 
// append as first child 
container.insertBefore(scriptTag, container.children[0]) 

今ファイルscripts/inpage.jsは単に

console.log('STEP 2, this should always run second') 

のように、ログを実行し、私はこのようなスクリプトを使用してページを訪問した場合::

console.log('Step 3, the page itself, should run last') 

この例のコンテンツスクリプトで実際には、ステップ2とステップ3は非決定的な順序で実行されます。

ありがとうございます!

あなたはそれを自分でしようとする勇気があるなら、私は特別なブランチ上の公開リポジトリ内のスクリプトのFirefoxの互換バージョンがあります:外部ソース(<script src>)とhttps://github.com/MetaMask/metamask-plugin/tree/FirefoxCompatibility

+0

これは、現在のページにスクリプトタグを追加する行です。私はログでこれを行うとき、私はこのコードがページスクリプトの前に実行されるのを見ますが、注入されたスクリプト自体は常にページスクリプトの前に実行されるとは限りません。 https://github.com/MetaMask/metamask-plugin/blob/FirefoxCompatibility/app/scripts/contentscript.js#L20 – DanF

答えて

3

アン動的に挿入されたスクリプトがブロックされません。スクリプトの実行は、スクリプトがロードされる保証はありません。拡張機能がChromeで動作していたのは、単なる運があっただけでした。

あなたが本当に休み前にいくつかのスクリプトを実行したい場合は、インラインでそれを実行する必要があります。

var actualCode = ` 
// Content of scripts/inpage.js here 
`; 

var s = document.createElement('script'); 
s.textContent = actualCode; 
(document.head || document.documentElement).appendChild(s); 
s.remove(); 

理想的には、ビルドスクリプトは、scripts/inpage.jsを読んでそれを文字列にシリアライズしactualCodeに入れてしまいます変数。しかし、inpage.jsがほんの数行のコードであれば、上記を使用することができます。

は、絶対に必要でない限り、のコードをWebページに挿入しないでください。その理由は、ページの実行環境が信頼できないためです。 document_startに注入すると、後で(クロージャ内で)使用する関数と(プロトタイプ)メソッドを保存できますが、非常に注意深いコーディングが必要です。

コンテンツスクリプトがビルドスクリプトによって生成されておらず、依然としてスクリプトを別々にしたい場合は、同期XMLHttpRequestを使用してスクリプトをフェッチすることもできます。同期XHRはパフォーマンス上の理由から推奨されていませんので、自己責任で使用してください。同期XHRの使用は低リスクでなければなりませんので、延長コードは、一般的に、あなたの拡張機能にバンドルされています

// Note: do not use synchronous XHR in production! 
var x = new XMLHttpRequest(); 
x.open('GET', chrome.runtime.getURL('scripts/inpage.js'), false); 
x.send(); 
var actualCode = x.responseText; 

var s = document.createElement('script'); 
s.textContent = actualCode; 
(document.head || document.documentElement).appendChild(s); 
s.remove(); 
+0

IRCで、FireFoxがきれいに達成する追加の方法を提供していることを指摘しておきますエクスポートヘルパーを介してAPIをメインページにコンテンツクリップから公開するという私の目標:https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.exportFunction – DanF

+1

@ DanF 'Component.utils.exportFunction'などはまだ利用できません(WebExtensions **では' Components'を使用できません)。 https://bugzil.la/1280482にあるパッチは、グローバルな 'exportFunction'メソッドを使って同じ機能を得ることができます。 –

0

あなたが文書で動作するようにframescriptとDOMWindowCreatedを使用することができますbootstrap.jsベースのアドオンを使用している場合HTML DOM(document.bodyなどの過去の基本)もレンダリングする前に - https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Frame_script_environment#Events - innerHTMLは利用可能ですが、スクリプトは実行されませんでした。 @Robのように、インラインスクリプトを一番上に置くことができます。

関連する問題