Greasemonkey: WebExt: Jalankan skrip pada ketiga waktu yang dijalankan

Dibuat pada 27 Feb 2017  ·  6Komentar  ·  Sumber: greasemonkey/greasemonkey

Munculkan rencana kerja tentang cara mengeksekusi skrip pengguna, tentu saja tidak diketahui sampai waktu berjalan. Kompatibel dengan ketiga runAt kali -- kritis document_start .

Lihat https://github.com/arantius/greasemonkey/tree/8a255bde1aa6312715740fd0157d582a2d6cb183 untuk penelitian saya sejauh ini, di mana pendekatannya adalah:

  • Gunakan satu skrip latar belakang. (Ini akan memiliki akses ke penyimpanan/API apa pun, tempat skrip disimpan, sehingga dapat mengetahui konten skrip yang akan dieksekusi.)
  • Amati sesuatu ( apa? ) untuk memicu ..
  • .. panggil tabs.executeScript() untuk menjalankan setiap skrip pengguna.

Ini "berfungsi" kecuali tidak ada acara yang saya temukan untuk mengamati yang berfungsi untuk ketiga waktu berjalan. Ada webNavigation 's onBeforeNavigate yang sebenarnya terlalu cepat , itu (seperti namanya) menyala sebelum navigasi, ketika dokumen saat ini masih aktif. Tetapi poin selanjutnya adalah onCommitted , dan pada saat itu sudah terlambat untuk memulai, skrip sebaris telah dieksekusi.

wontfix

Semua 6 komentar

Untuk meneliti:

  • Amati webRequest alih-alih webNavigation . Apakah itu memberi kita pegangan pada waktu mulai?
  • Suntikkan satu skrip konten webext, di document_start, untuk setiap halaman. Entah bagaimana mengetahui skrip mana yang harus dieksekusi, secara sinkron. (Karena apa pun async akan mendorong kita melewati waktu mulai.)

Re: https://bugzilla.mozilla.org/show_bug.cgi?id=1332273#c8

Saya ingin dapat menyimpan (di latar belakang) gumpalan, kemudian mendapatkan (hanya) URL-nya dan meneruskan URL itu (secara serempak) ke skrip konten, tetapi saya tahu tidak ada cara untuk melakukan hal-hal itu.

Saya sendiri belum mengerjakan semua detailnya, tetapi saya pikir halaman latar belakang dapat menyimpan gumpalan di IndexedDB, lalu mengonversinya menjadi URI gumpalan melalui URL.createObjectURL() pada waktu startup dan meneruskannya ke API konfigurasi sinkron hipotetis dan kemudian mungkin memuatnya melalui

Bukankah IndexedDB dinonaktifkan dalam mode

Saya tidak berpikir itu memengaruhi skrip latar belakang?

Ini dimungkinkan dengan menggunakan skrip konten yang berjalan pada document_start dan terlihat seperti ini: (mungkin tidak akan berfungsi untuk tab yang sudah dimuat, gunakan jQuery untuk itu)

// execute `document_start` scripts here...

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

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

atau sesuatu seperti ini: (mungkin lebih rawan kesalahan)

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...
}

Cara lain adalah dengan menggunakan tiga skrip konten terpisah, di mana masing-masing skrip berjalan pada waktu yang berbeda.
Untuk ini manifest.json berisi yang berikut: (dijamin mungkin berfungsi (mungkin memiliki kondisi balapan))

"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"]
    }
]

Dimungkinkan juga untuk menggunakan jQuery, yang mungkin merupakan cara yang paling tidak rawan kesalahan, tetapi ini semua membutuhkan pengujian ekstensif: (sekali lagi, berjalan pada document_start tetapi perlu dibundel dengan 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);
}

Seperti yang ditulis, masalah ini terlalu luas. Saya membagi ini menjadi masalah terpisah agar lebih mudah dilacak:

2525, #2526

Apakah halaman ini membantu?
0 / 5 - 0 peringkat