Greasemonkey: WebExt:3つのrunAt時間すべてでスクリプトを実行する

作成日 2017年02月27日  ·  6コメント  ·  ソース: greasemonkey/greasemonkey

もちろん、実行時までわからない、ユーザースクリプトの実行方法に関する作業計画を考え出します。 3つすべてのrunAt時間と互換性があります-非常にdocument_start

これまでの私の調査については、 https://github.com/arantius/greasemonkey/tree/8a255bde1aa6312715740fd0157d582a2d6cb183を参照してください

  • 1つのバックグラウンドスクリプトを使用します。 (スクリプトが保存されているストレージ/すべてのAPIにアクセスできるため、実行するスクリプトの内容を知ることができます。)
  • トリガーする何か(何? )を観察します。
  • .. tabs.executeScript()を呼び出して、各ユーザースクリプトを起動します。

これは、3つの実行時間すべてで機能することを確認したイベントがないことを除いて、「機能」します。 webNavigationonBeforeNavigateありますが、これは実際には早すぎます。現在のドキュメントがまだアクティブな場合、ナビゲーションの前に(名前が示すように)起動します。 しかし、次のポイントはonCommittedであり、その時点では開始するには遅すぎます。インラインスクリプトはすでに実行されています。

wontfix

全てのコメント6件

調査するには:

  • 守っwebRequestの代わりにwebNavigation 。 それは私たちに開始時にハンドルを与えますか?
  • すべてのページに対して、document_startに1つのwebextコンテンツスクリプトを挿入します。 どのスクリプトを同期的に実行するかをどういうわけか知ってもらいます。 (非同期の場合、開始時刻を過ぎてしまうためです。)

Re: https

BLOBを(バックグラウンドで)保存し、後でそのURLを(のみ)取得して、そのURLを(同期的に)コンテンツスクリプトに渡すことができるようにしたいのですが、これらのことを行う方法がわかりません。

私は自分ですべての詳細を理解していませんが、バックグラウンドページでblobをIndexedDBに格納し、起動時にURL.createObjectURL()を介してblob URIに変換し、仮想の同期構成APIに渡してからおそらく経由でそれらをロードします

FirefoxのプライベートブラウジングモードでIndexedDBが

それがバックグラウンドスクリプトに影響を与えるとは思いませんか?

これは、 document_startで実行され、次のようなコンテンツスクリプトを使用することで可能になります(すでにロードされているタブでは機能しない可能性があります。そのためにjQueryを使用してください)

// execute `document_start` scripts here...

document.addEventListener("DOMContentLoaded", event => {
    // execute `document_end` scripts here...
});

window.addEventListener("load", event => {
    // execute `document_idle` scripts here...
});

またはこのようなもの:(エラーが発生しやすい可能性があります)

let run = [false, false, false];

document_start();

if (document.readyState === "complete") {
    document_idle();
} else if (document.readyState === "interactive") {
    document_end();
}

document.onreadystatechange = () => {
    switch (document.readyState) {
        case "loading":     break;
        case "interactive": document_end();
        case "complete":    document_idle();
    }
};

function document_start() {
    if (run[0]) return;
    run[0] = true;

    // execute `document_start` scripts here...
}

function document_end() {
    if (!run[0]) document_start();
    if (run[1])  return;
    run[1] = true;

    // execute `document_end` scripts here...
}

function document_idle() {
    if (!run[1]) document_end();
    if (run[2])  return;
    run[2] = true;

    // execute `document_idle` scripts here...
}

もう1つの方法は、3つの別々のコンテンツスクリプトを使用することです。各スクリプトは異なる時間に実行されます。
このため、 manifest.jsonには次のものが含まれています:(おそらく動作することが保証されています(競合状態がある可能性があります))

"content_scripts": [
    {
        "matches": ["<all_urls>"],
        "run_at": "document_start",
        "js": ["document_start_handler.js"]
    },
    {
        "matches": ["<all_urls>"],
        "run_at": "document_end",
        "js": ["document_end_handler.js"]
    },
    {
        "matches": ["<all_urls>"],
        "run_at": "document_idle",
        "js": ["document_idle_handler.js"]
    }
]

エラーが発生しにくい方法であるjQueryを使用することもできますが、これにはすべて広範なテストが必要です(ここでも、 document_startで実行されますが、jQueryにバンドルする必要があります)

function document_start() {
    // execute `document_start` scripts here...
}

function document_end() {
    // execute `document_end` scripts here...
}

function document_idle() {
    // execute `document_idle` scripts here...
}

// Use jQuery to execute all the functions:
document_start();

// `$(document).ready(document_end)` is deprecated since 3.0
$(document_end);

// jQuery used to have a method for this: `$(window).load(document_idle)`
if (document.readyState === "complete") {
    document_idle();
} else {
    $(window).on("load", document_idle);
}

書かれているように、この問題は広すぎます。 私はこれを別々の問題に分割して、より簡単に追跡できるようにしています。

2525、#2526

このページは役に立ちましたか?
0 / 5 - 0 評価