Greasemonkey: Jalankan dalam bingkai

Dibuat pada 21 Sep 2017  ·  48Komentar  ·  Sumber: greasemonkey/greasemonkey

Greasemonkey 4 mulai hari ini hanya mendeteksi aktivitas navigasi di tingkat atas, sehingga secara efektif menerapkan @noframes ke setiap skrip.

Komentar yang paling membantu

Halo,
Apakah Anda akan memperbaiki masalah ini? Ini cacat yang cukup lama dan berdampak pada semua skrip berdasarkan struktur iframe ...

Semua 48 komentar

webNavigation.onCommitted tidak 'melihat' pembuatan bingkai awal / rendering halaman, meskipun jika navigasi bingkai di tempat lain selain halaman awalnya maka pendengar akan menangkapnya. Jika opsi menyertakan kunci 'allFrames': true masalahnya _agak_ teratasi. Setiap bingkai di halaman html statis akan memiliki skrip yang disuntikkan, meskipun Anda kemudian memiliki masalah pencocokan Asal/url. Selanjutnya, jika bingkai dibuat menggunakan Javascript, skrip tidak disuntikkan.

Solusi termudah yang dapat saya pikirkan adalah mengganti webNavigation.onCommitted dengan webRequest.onResponseStarted dengan filter {'urls': ['<all_urls>'], 'types': ['main_frame', 'sub_frame']} .

Saya melakukan beberapa pengujian terbatas dan tidak ada perubahan lebih lanjut yang diperlukan. Saya dapat menjalankan skrip di dalam bingkai dan bingkai yang dibuat menggunakan Javascript.

@arantius ada rencana untuk menggabungkan perbaikan dari @Sxderp ?

Ini memengaruhi skenario di mana iframe adalah objek lintas asal sehingga tidak mungkin melakukan modifikasi apa pun tanpa menjalankan GM pada iframe tertentu.

Terima kasih !

Melewatkan ini, akan segera memeriksanya.

Hanya pengamatan selama pengujian skrip lama saya, tidak tahu, apakah itu membantu ...

Diberikan skrip, yang seharusnya berfungsi pada iframe,
sepertinya menjalankan perubahan pada halaman,
tetapi kemudian menyegarkan kembali ke halaman yang tidak dimodifikasi.

Saya hanya bisa melihat kedipan ketika saya menyegarkan halaman dengan sangat cepat.

Hanya pengamatan selama pengujian skrip lama saya, tidak tahu, apakah itu membantu ...

Apakah ini dengan tambalan saya atau dengan versi yang dirilis?

Ugh, saya pikir itu adalah rilis 4.0 ...
SAYA @4.1b3, tetapi untuk pengujian, saya cukup yakin, bahwa saya menginstal ulang versi rilis (sampai sekarang!)

Sama di sini dengan iframe seperti yang dijelaskan Eselce. Dalam beberapa cara itu dijalankan, tetapi kemudian berhenti setelah iframe atau halaman dimuat.

Jika saya menyuntikkan skrip ini, saya hanya mendapatkan 1 dan "self !== top":

console.log('1');
if (self !== top) {
   console.log('self !== top');
   setTimeout(function() {
      console.log('Timeout');
   }, 2000);  
} else {
   console.log('self === top');
}

"Waktu habis" tidak ditampilkan di log, baik semua fungsi maupun ikatan tidak ditampilkan.

Saya menggunakan 4.1b3.

Saya memiliki masalah yang sama menjalankan GM 4.0 di Quantum. Saya menulis contoh dummy yang sangat sederhana dengan dua halaman: main.html dan framed.html , dan skrip GM yang dimuat di setiap halaman dan menampilkan URL halaman yang memuatnya.

Sering kali, saya hanya mendapatkan notifikasi tentang main.html , tetapi dalam sekitar 5% kasus, terutama jika saya menahan F5, saya mungkin juga mendapatkan notifikasi tentang framed.html .

Apakah ada peretasan yang andal memaksa GM 4.0 untuk mengeksekusi di dalam iframe hingga tambalan keluar?

Saya baru tahu bahwa skrip pengguna dieksekusi dengan andal di <embed src="..."> tetapi tidak di <iframe src="..">
Saya menulis skrip pengujian kecil:
https://openuserjs.org/scripts/cuzi/iframe_embed_Test_Greasemonkey_4

Beberapa detail lebih lanjut: Dalam beberapa kasus, skrip saya sepenuhnya dieksekusi dalam bingkai (tetapi tampilan kemudian ditimpa oleh skrip halaman dan sebagainya).
Terkadang, bagian sinkron dari skrip saya berakhir, tetapi bagian asinkron tiba-tiba terganggu oleh aktivitas halaman...
Harapan, itu membantu!

Adakah yang punya info lebih lanjut tentang ini?

Hanya ringkasan singkat dari utas ini (masalah):

  • Lupakan sebagian besar posting, mereka tidak berlaku
  • Mungkin, skrip selalu dieksekusi (tetapi tidak sampai akhir)
  • Sayangnya, halaman di-refresh nanti - tata letak dihitung ulang, eksekusi dibatalkan
  • Ini berlaku sebagian besar (tetapi tidak seluruhnya) pada bagian skrip yang asinkron

Saya tidak terlalu menyukai internal ini, tapi mungkin seseorang...

Sebagai perbaikan sementara, saya telah menukar iframe untuk penyematan ( contoh skrip ), yang berfungsi untuk mendapatkan skrip yang sesuai dengan bingkai yang akan dipicu (kredit ke @cvzi karena mengetahui bahwa <embed src="..."> berfungsi) .

Mungkin perlu dicatat bahwa Violentmonkey dan Tampermonkey berfungsi dengan baik di dalam bingkai yang disematkan. Karena VM adalah open source, mungkin lihat bagaimana mereka melakukannya?

Sayangnya, Violentmonkey dan Tampermonkey masih menggunakan skema penamaan GM_ lama untuk fungsi khusus, jadi skrip belum portabel.

https://github.com/greasemonkey/gm4-polyfill

Tampermonkey => GM.* panggilan, jika tidak disediakan
Violentmonkey => GM.* panggilan
Greasemonkey -3.17 / FF -56.0 => GM.* panggilan
Greasemonkey 4.0+ / FF 57.0+ => GM bawaan.* panggilan

// <strong i="11">@grant</strong>        GM.getValue
// <strong i="12">@grant</strong>        GM.setValue
// <strong i="13">@require</strong>      https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// <strong i="14">@grant</strong>        GM_getValue
// <strong i="15">@grant</strong>        GM_setValue

Apakah perbaikan @Sxderp sudah dimasukkan ke cabang utama? Jika tidak, bagaimana saya bisa memasang garpunya?

Apakah perbaikan @Sxderp sudah dimasukkan ke cabang utama? Jika tidak, bagaimana saya bisa memasang garpunya?

  1. Tidak.
  2. Sayangnya itu salah satu PR saya yang belum saya sinkronkan dengan master dan oleh karena itu belum di-rebase. Jadi cabang itu sendiri tidak memiliki beberapa perubahan saat ini.
  3. Saya juga tidak pernah menerapkan perubahan yang disarankan dalam komentar PR. Sejujurnya, perubahan itu _seharusnya tidak_ diperlukan tetapi karena Mozilla terus-menerus mengacaukannya, perubahan itu diperlukan.
  4. Jika Anda masih ingin menggunakannya (tidak disarankan) maka Anda dapat mengikuti langkah-langkah di bawah ini.

  1. git clone -b use-on-response-started-for-execute --single-branch https://github.com/Sxderp/greasemonkey.git [1]
  2. Jalankan ./package.sh , ini akan membuat file XPI.
  3. Buka about:config di Firefox dan setel xpinstall.signatures.required ke false
  4. Pergi ke about:addons di Firefox, klik roda gigi lalu pilih instal dari file.
  5. Pilih XPI yang dibuat di langkah 2.

[1] Jika versi git Anda tidak mendukung flag -b dan / atau --single-branch (versi git yang lebih lama) maka Anda dapat melakukan git clone https://github.com/Sxderp/greasemonkey.git dan git checkout use-on-response-started-for-execute .

Halo,
Apakah Anda akan memperbaiki masalah ini? Ini cacat yang cukup lama dan berdampak pada semua skrip berdasarkan struktur iframe ...

Sebagai pengingat, bahwa kita memiliki tanggal 13 Maret besok (lihat Firefox 59.0 )...

Saya ingin merujuk ke @Sxderp :

webNavigation.onCommitted tidak 'melihat' pembuatan bingkai awal / rendering halaman, meskipun jika navigasi bingkai di tempat lain selain halaman awalnya maka pendengar akan menangkapnya. Jika opsi menyertakan kunci 'allFrames': true masalahnya agak teratasi. Setiap bingkai di halaman html statis akan memiliki skrip yang disuntikkan, meskipun Anda kemudian memiliki masalah pencocokan Asal/url. Selanjutnya, jika bingkai dibuat menggunakan Javascript, skrip tidak disuntikkan.

Sebenarnya, saya punya bukti, bahwa (di sistem saya) pendengar executeUserscriptOnNavigation dipanggil dengan andal chrome.webNavigation.onCommitted , sehingga chrome.tabs.executeScriptInFrame dipanggil dengan frameId . Mengapa ini tidak menyelesaikan semua masalah kita dengan bingkai? Kita tidak perlu chrome.webRequest.onResponseStarted untuk bereaksi pada iframe! (Atau maksud Anda, itu bereaksi pada acara tersebut, tetapi bingkainya tidak terlihat?) Itu pasti disebut ...

Apakah ada bug yang diketahui dengan chrome.tabs.executeScriptInFrame dan frameId ? Ada masalah bertahun-tahun yang lalu, tetapi sekarang sudah diperbaiki. all_frames tidak disetel, jadi frameId harus valid. Opsi pengaturan matchAboutBlank ke true tampaknya penting (jika tidak executeScript mengembalikan kesalahan <unavailable> ), meskipun saya tidak sepenuhnya memahami itu about:blank barang (di mana itu?)...

Ada ide?

Fitur? Ini adalah fungsionalitas dasar yang hilang sejak awal... Saya harap, saya salah mengartikannya.

@Eselce , ini sudah lama sekali dan saya tidak yakin saya sepenuhnya ingat apa yang saya maksud tetapi saya akan mencobanya. Selanjutnya, ini hanya berlaku jika pemahaman saya tentang pencocokan bingkai GM 3.x benar. Artinya, setiap frame Origin+path dicocokkan secara individual untuk menentukan skrip mana yang perlu dijalankan. BUKAN hanya dokumen induk.

Sekarang, ke masalah. Ketika saya melakukan pengujian awal saya, saya memiliki halaman statis dengan bingkai Asal yang sama dan bingkai jarak jauh. Pada pemuatan halaman awal, saya hanya bisa mengaktifkan onCommitted callback untuk diaktifkan sekali. Itu diaktifkan untuk dokumen utama tetapi tidak menyala untuk salah satu bingkai statis dalam dokumen [1]. Jadi tidak ada skrip yang akan disuntikkan ke dalamnya.

Namun, setelah pemuatan awal, jika saya menyebabkan salah satu bingkai 'menavigasi' di suatu tempat, panggilan balik onCommitted akan dipanggil dan skrip dimasukkan ke dalam bingkai di lokasi baru.

Upaya menggunakan kunci opsi all_frames dilakukan untuk mengatasi masalah di atas. Saat menggunakan kunci menyebabkan skrip disuntikkan ke dalam bingkai pada halaman, ada kekurangan yang jelas karena tidak mencocokkan jalur Asal+bingkai dengan benar dengan tempat skrip seharusnya atau tidak seharusnya dijalankan.

Selain itu, saya juga menyebutkan bahwa menggunakan kunci all_frames tidak akan menyuntikkan skrip ke dalam bingkai yang dibuat oleh Javascript.

[1] Apakah masalah ini masih ada, saya tidak tahu. Jika saya ingat masalah ini tidak ada di FF 52 ESR tetapi ada di 56 (57?) (oleh karena itu regresi). Mungkin sudah diperbaiki.

Saya setuju dengan Anda di hampir semua poin.

Dan Anda benar bahwa setiap bingkai dicocokkan secara terpisah, seolah-olah itu adalah seluruh tab (dengan window miliknya sendiri dan document miliknya sendiri, tertanam dalam sebuah bingkai).

Yah, saya hampir selalu menggunakan struktur menu/frame yang sama, jadi mungkin saya harus menguji yang berbeda.

Ketika Anda mengatakan "itu dipecat", maksud Anda panggilan murni dari pendengar?

Seperti yang saya katakan, saya telah menemukan beberapa contoh dengan executeScript menghasilkan kondisi kesalahan, tetapi pendengar masih dipanggil.

all_frames tidak dapat bekerja, karena salah location (berbeda window , berbeda document ). BTW: Menu hanya menangani url mainframe setiap tab - jika menu salah, itu tidak berarti skrip tidak dipanggil ...

Ketika Anda mengatakan "itu dipecat", maksud Anda panggilan murni dari pendengar?

Dalam pesan tertentu yang saya maksud adalah 'Fungsi yang diteruskan ke onCommitted.addListener dipanggil.'.

Halo,

Saya membaca posting ini dengan seksama tetapi saya tidak mengerti bagaimana menggunakan solusi alternatif Anda pada skrip lokal saya ".user.js". Bagaimana saya bisa menerapkan solusi Anda? Maaf, saya baru.

(Sejak memperbarui Firefox, popup-iframe yang dihasilkan tidak lagi dikenali oleh skrip tambahan, tetapi jika saya membuka popup yang sama di jendela baru, skrip diterapkan.)

Terima kasih sebelumnya atas bantuan Anda

Anda telah menjelaskan dengan tepat apa masalahnya: Ini seperti @noframes diaktifkan. URL konten bingkai tidak mengaktifkan skrip Anda dengan benar. Semoga ini segera diperbaiki (membuka bingkai di jendela ekstra mengganggu) ...

Terima kasih Eselce.
Dan selalu sejak update Firefox, saya wajib di header untuk menyatakan semua scipts '.js' (dengan require) sudah digunakan di situs target. (termasuk jquery)
Dan itu tidak sama.... Ini menciptakan bug atau konflik.
Apakah Anda juga tahu masalah ini?

2945 berisi contoh lain untuk pengamatan, bahwa skrip dimulai dalam bingkai, tetapi ditinggalkan setelah beberapa milidetik.

Saya ragu untuk memberikan URL spesifik yang saya uji karena berada di luar kendali saya, tetapi saya menemukan beberapa perilaku yang konsisten tetapi aneh untuk diteruskan.

Saya memiliki situs yang saya perlukan untuk berinteraksi. Awalnya memuat frameset/frame dengan rows="100%,0" (satu frame untuk mengisi layar) pada domain yang berbeda. Frame ini berisi satu frameset / 3 frame dalam domain frameset/frame perantara.

Beberapa skrip GM bingkai anak 1+3 akan "berkedip" menjadi ada, lalu menghilang setelah siklus awal -- skrip tersebut tidak pernah kembali setelah operasi asinkron apa pun. Itu cocok dengan beberapa perilaku yang dijelaskan di utas ini. Perhatikan bahwa yang "blip" dan perilaku yang dijelaskan di bawah ini berbeda-beda menurut browser / versi GM, tetapi ini tidak acak; polanya aneh tetapi 100% dapat diulang untuk pengaturan apa pun.

  1. Frameset/frame pertama TIDAK AKAN PERNAH muncul. Saya telah mencoba melepaskan dan membangun kembali tag bingkai, baik melalui window.document dan unsafeWindow.document, baik dalam siklus awal dan setelah penundaan, tetapi tidak ada yang akan menyebabkan skrip GM bingkai itu melaporkan apa pun ke console.log. ( @include adalah *, tanpa @exclude atau pemfilteran URL lainnya.)
  2. Beberapa perilaku selanjutnya akan berbeda antara Firefox 52.8 / GM 4.1 dan Firefox 60.0 / GM 4.3, tetapi saya bisa mendapatkan skrip GM frame dalam setiap kasus untuk "blip" menjadi ada apakah @noframes disetel atau tidak. Ini dengan @termasuk *, tidak ada filter URL lainnya. Ini seharusnya tidak pernah blip dengan set @noframes . Saya telah memverifikasi bahwa window.top!==window, yaitu browser mengetahui (atau seharusnya mengetahui) ini dalam bingkai.
  3. Di Firefox 52.8 / GM 4.1, Frameset / 3 frame berikutnya akan SELALU muncul. Di Firefox 60.0 / GM 4.3, mereka tidak "blip" pada beban bingkai awal.
  4. Di Firefox 60.0 / GM 4.3, mengeklik tautan di salah satu dari 3 bingkai yang menavigasi 3 bingkai lainnya (melalui atribut "target" pada tautan jangkar, bukan skrip) akan "berkedip" -- bukan URL baru, tetapi URL lama untuk bingkai yang dinavigasi. (Ini adalah salah satu frame yang gagal pada pemuatan awal pada item #3.)
  5. Inilah bagian yang paling aneh. Di kedua pengaturan browser --- Mengikuti langkah-langkahnya, kami telah membuka halaman awal dengan 2 lapisan bingkai, 4 bingkai total, dan mengklik tautan dalam satu bingkai untuk menavigasi bingkai yang berbeda pada halaman yang sama. Untuk memberi nama itu, frameset tingkat kedua yang awalnya ditampilkan memiliki frame "top.htm", "menu.htm", dan "start,htm". Kami telah mengklik tautan di bingkai "menu.htm" untuk menyebabkan bingkai memegang "start.htm" untuk menavigasi ke "content.htm", dengan perilaku yang serupa tetapi sedikit berbeda per pengaturan browser, yang disebutkan di atas. Sekarang, kita klik link di dalam frame "content.htm", untuk menavigasi di dalam frame yang sama, domain yang sama.

Pada titik ini, skrip untuk "content.htm" tidak hanya akan "blip"... itu juga akan tetap hidup setelah GM.xmlHttpRequest selesai -- peristiwa asinkron. Pada titik ini, "content.htm" tidak ada di tampilan browser, tetapi skripnya akan terus beroperasi.

Jadi menurut saya alasan mengapa skrip GM pada halaman dalam bingkai tidak berfungsi adalah karena skrip sedang dimuat pada pembongkaran halaman alih-alih pemuatan halaman. Menyetel @run-at untuk memulai dokumen dan memasukkan skrip ke dalam acara DOMContentReady dari unsafeWindow.document tidak ada peningkatan. (Menyetelnya di window.document tidak pernah mengaktifkan acara.)

-Ryan

Di Firefox 52.8 / GM 4.1, Frameset / 3 frame berikutnya akan SELALU muncul. Di Firefox 60.0 / GM 4.3, mereka tidak "blip" pada beban bingkai awal.

Dalam transisi ke Firefox 57 Mozilla mengubah _something_. Apa pun itu, itu mengubah (atau merusak) cara Frames dapat dipicu. Ini secara singkat dibicarakan dalam beberapa masalah lain. Akibatnya, skrip tidak akan berjalan pada pemuatan bingkai awal (57+).

Peralihan akhirnya ke userScript atau contentScript API harus menyelesaikan semua ini.

Jadi orang terus berkata, namun Violentmonkey terus mengeksekusi dalam bingkai. VM tidak memisahkan skrip pengguna dengan benar dari konten halaman web (CSP memblokir skrip pengguna, halaman web dapat menulis ulang objek global, dll.), atau saya telah membuang Greasemonkey sejak lama. Mungkin ini adalah masalah terkait, tetapi saya menggunakan mesin skrip pengguna jadi saya tidak perlu menjelajahi chrome Firefox cukup dalam untuk mencari tahu sendiri.

Hmm ini masalah yang sulit, beberapa skrip saya tidak berfungsi lagi karena tidak dapat bekerja dengan iframe. Jadi sepertinya tidak mungkin untuk memperbaikinya, dan kita harus bagaimana Mozilla mengimplementasikan beberapa API? Apakah tidak ada yang bisa kita lakukan sendiri, seperti solusi? Saya hanya perlu melakukan beberapa hal ke halaman di iframe, seringkali bahkan dari domain yang sama.

Solusi saya sendiri untuk saat ini adalah menjalankan Greasemonkey di bingkai atas dan Violentmonkey di bingkai anak. Saya tidak dapat menggunakan Tampermonkey karena memiliki lisensi buatan sendiri yang ambigu, tetapi jika itu bukan masalah bagi Anda, maka itu mungkin atau mungkin tidak berfungsi lebih baik.

Ingatlah bahwa VM memasukkan skrip ke dalam konteks halaman itu sendiri. Ini seperti GM unsafeWindow tanpa setara aman. Salah satu waktu paling berkesan yang saya miliki adalah men-debug skrip di mana konten halaman telah mendefinisikan metode 'toJSON()" pada Array.prototype, menyebabkan JSON.stringify() mengeluarkan JSON yang tidak valid di dalam skrip saya. Saya harus melakukannya menjebak dan memperbaikinya secara defensif seperti yang saya temukan.

Kekhawatiran besar lainnya dengan VM adalah bahwa ia menghormati kebijakan keamanan konten halaman konten, sehingga setiap arahan yang membatasi sumber skrip akan menyebabkan skrip VM tidak pernah dijalankan. Anda dapat melihat ini di konsol browser (tetapi tidak di konsol web). Itu sebabnya saya tidak bisa menjalankan VM sepenuhnya dan menyingkirkan GM saja. Saya belum menemukan anak dengan set CSP, tetapi ketika saya melakukannya, itu akan benar-benar tidak dapat digunakan.

@RyanHanekamp Terima kasih atas tipnya! Mungkin saya akan menggunakan Violentmonkey untuk beberapa skrip.

Apakah Violent juga memiliki sesuatu seperti GM_getValue yang sinkron? Itu masalah bermasalah lain yang memecahkan banyak skrip di Greasemonkey baru. Saya masih sangat mempercayai Greasemonkey, karena berbagai alasan, jadi saya tidak akan meninggalkannya.

Mengenai iframe, saya sudah mencoba menggantinya dengan tag objek, yang tampaknya dapat diakses langsung menggunakan Javascript, seperti:

myObject= document.createElement('object');
myObject.setAttribute('id', 'myObject'); 
document.body.appendChild(myObject);
myObject.setAttribute('src', 'https://example.com');

Kemudian, setelah objek dimuat:
document.querySelector('#myObject').contentDocument.defaultView.document.querySelectorAll('someElementInsideObjectPage')
Setidaknya ini berfungsi untuk saya dalam skrip di mana objek berada di Host yang sama dengan halaman utama. Anda juga dapat mengirim pesan dari dan ke ( ... contentDocument.defaultView.postMessage('hello, object') ) objek.

Saya bukan ahli VM, tetapi saya yakin ini mengimplementasikan setidaknya sebagian besar GM_* API asli. Saya pikir lebih baik mengadaptasi skrip Anda ke asinkron daripada mundur ke platform sinkron dalam jangka panjang. Menurut pemahaman saya, Greasemonkey melakukan ini sebagai peningkatan kinerja dalam kerangka Quantum baru, yang tidak memungkinkan panggilan sinkron antara skrip latar belakang dan konten.

Adapun solusi objek, itu tidak akan menyelesaikan masalah khusus saya, tetapi saya senang orang lain menganggapnya berguna. Selain menyusun CSS/properti/dll dan membuatnya berfungsi dengan bingkai serta iframe, saya harus memfilter objek dalam proses pengambilan karena berpotensi tidak aman. Ada beberapa cara untuk mengatasi semua masalah ini, tetapi VM adalah solusi sementara yang lebih mudah sampai GM akhirnya melakukan apa yang tertulis di kaleng.

Juga, jika Anda memiliki bingkai/iframe asal yang sama, Anda juga dapat mengakses kontennya secara langsung. Bagian yang lebih sulit adalah cross-Origin, itulah sebabnya saya membutuhkan skrip pengguna di dalam bingkai. Ini menyiapkan saluran window.postMessage() untuk berbicara kembali ke jendela induk.

@RyanHanekamp Senang mengetahui bahwa Violent Monkey masih memiliki GM_* yang lama dan sederhana. Saya sangat berharap Greasemonkey menyimpan GM_getValue lama yang sinkron untuk kompatibilitas mundur, selain versi baru. Saya mungkin mencoba menerapkan fungsi asinkron baru dalam skrip baru, tetapi saya bukan seorang programmer dan saya tidak yakin apakah saya bisa membuatnya berfungsi. Dan saya tentu saja tidak dapat memperbaiki penggunaan GM_getValue lama dalam skrip kuno 2000 baris yang saya temukan online...begitu banyak skrip yang rusak sekarang.

Saya mengerti mengapa Violent adalah pilihan yang lebih baik untuk Anda. Mari berharap Anthony atau Sxderp atau orang lain tahu bagaimana menerapkan ini pada akhirnya. Saya benar-benar berharap saya bisa berkontribusi, tapi saya benar-benar awam.

Oh, Anda dapat langsung mengakses konten iframe asal yang sama (tanpa postMessage, dll.)? Saya ingat menghabiskan banyak waktu untuk mencari cara, tetapi sepertinya tidak mungkin. Itu sebabnya saya beralih ke postMessage juga.

Frame dan iframe memiliki properti contentWindow yang setara dengan properti window. Keduanya memiliki properti dokumen untuk mengakses DOM.

Bagian tersulit dari bekerja dengan iframe (pada asal yang sama) adalah mendeteksi ketika kontennya dimuat, karena Anda tidak dapat melakukan squat sampai itu terjadi. onload tidak berfungsi seperti yang terlihat. Firefox menyediakan acara DOMFrameContentLoaded yang diaktifkan untuk SETIAP bingkai yang dimuat, termasuk bingkai cucu/cicit dll, yang dapat Anda cocokkan dengan elemen bingkai/iframe asli dengan properti event.target. Jika Anda mengontrol konten frame/iframe, Anda juga dapat memintanya berbicara kembali ke induk dengan postMessage atau memanggil metode global pada objek window.parent.

Omong-omong... itu solusi potensial untuk masalah ini. Jika ada atau bisa menjadi cara untuk mengkodekan skrip GM untuk secara manual menyuntikkan skrip pengguna ke referensi jendela lintas domain, itu akan membutuhkan lebih banyak pengkodean untuk pembuat skrip pengguna, tetapi itu bisa menyelesaikan pekerjaan. Polanya akan mendengarkan DOMFrameContentLoaded, periksa apakah event.target adalah generasi pertama, dan masukkan skrip secara manual jika demikian. (Dengan asumsi bahwa skrip frame generasi pertama dapat mendengarkan DOMContentLoaded untuk frame generasi kedua, dan dengan demikian mendapatkan rantai yang lengkap.) Tidak akan ada cara untuk mendapatkan perilaku @run-at dom-start, dan mungkin juga ada masalah waktu, tapi kami mungkin bisa mengatasinya untuk sebagian besar kasus penggunaan.

Saya pribadi telah menyerah pada masalah ini yang pernah diselesaikan, dan alih-alih beralih ke pengkodean ekstensi secara langsung. Yang berfungsi dengan baik di semua bingkai!

Perbedaan antara Greasemonkey dan Violentmonkey dalam hal ini tampaknya Violentmonkey dipicu dari skrip konten dengan all_frames disetel ke true, sementara Greasemonkey tidak memiliki skrip konten waktu pemasangan dan sepenuhnya bergantung pada kemampuan skrip latar belakang yang meragukan untuk mengendus ketika bingkai tab telah dinavigasi. (Dan Violentmonkey gagal pada halaman CSP karena untuk sementara menyuntikkan tag SCRIPT daripada menggunakan tabs.executeScript() yang jauh lebih aman.)

Masukkan skrip konten statis dengan all_frames, run_at start, cocokkan semuanya untuk memberi tahu proses latar belakang untuk start / document.DOMContentLoaded / document.Idle untuk memicu skrip pengguna untuk setiap run_at, dan Anda siap melakukannya. Jumlah pekerjaan yang tidak sepele tetapi dapat dikelola untuk membuat masalah ini hilang. Saya akan memperbaikinya sendiri, tetapi saya tidak tertarik untuk melalui dependensi dev Anda dan hanya bisa menghasilkan kode output.

@RyanHanekamp

dan alih-alih beralih ke pengkodean ekstensi secara langsung. Yang berfungsi dengan baik di semua bingkai!

Apakah Anda bersedia membagikan kode ekstensi Anda itu?

Ekstensi saya bukan untuk tujuan umum. Intinya adalah bahwa menggunakan content_script statis dalam manifes dengan all_urls, all_frames akan menjalankan skrip setiap kali bingkai apa pun dimuat atau dinavigasi, dan bahkan dapat mengevaluasi / kode konstruktor Fungsi dengan baik terlepas dari Kebijakan-Keamanan-Konten halaman.

Saya belum menguji dengan bingkai/jendela yang dibuat secara terprogram, tetapi saya akan membayangkan mereka akan berjalan pada pembuatan awal terlepas dari pengaturan run_at, karena bingkai seperti itu pada awalnya dibuat kosong dan kemudian diisi - mesin mungkin hanya akan melihat pembuatan awal. Saya juga tidak menguji data: url, yang mungkin memerlukan pencocokan eksplisit -- Saya tidak yakin apakah all_urls mencakupnya, atau hanya http/https.

Ini mungkin juga tidak harus berupa referensi content_script statis, tetapi tampaknya tidak pasti dari dokumentasi jika skrip konten yang dipanggil secara dinamis dimuat secara otomatis saat halaman dinavigasi. Kesan saya adalah bahwa mereka hanya disuntikkan ke dalam tab/bingkai yang saat ini cocok per pola kecocokan yang disediakan, dan navigasi tidak memicu injeksi ulang. Tapi saya tidak melihat kerugian untuk menggunakan content_script statis untuk tujuan ini.

Greasemonkey jelas tidak dapat menyertakan skrip pengguna sebagai sumber daya statis dalam manifes, dan skrip konten tampaknya tidak memiliki akses langsung ke tabs.executeScript (walaupun saya bukan ahli dalam hal ini karena saya baru beberapa hari masuk), tetapi yang BISA dilakukan oleh skrip konten statis adalah mengirim pesan ke proses latar belakang untuk memberi tahu bahwa frameId telah dinavigasi, dan ke URL apa. Ini akan lebih dapat diandalkan daripada bagaimana saya melihat upaya yang disebutkan di utas ini untuk mengaitkan acara yang tepat di webRequest atau webNavigation. Sinyal dari static content_script menjadi peristiwa yang kita cari untuk memicu pemuat/injektor skrip pengguna Greasemonkey.

Mungkin akan ada penundaan untuk skrip pengguna yang secara ketat HARUS menjalankan_at document_start. Panggilan ke skrip latar belakang tidak sinkron, dan dokumen akan berkembang pada saat skrip pengguna dipanggil. Ini sangat mungkin mengapa Violentmonkey menggunakan tag skrip sementara alih-alih tabs.executeScript, karena injeksi tag skrip dapat dilakukan langsung dari content_script, secara sinkron. Saya akan merasa dipaksa untuk mengatasi ketidakpastian status dokumen untuk run_at document_start menjadi merepotkan, tetapi lebih disukai daripada skrip yang tidak berjalan sama sekali.

Greasemonkey ... BISA [menggunakan skrip konten statis untuk] mengirim pesan ke proses latar belakang untuk memberi tahu bahwa frameId telah dinavigasi, dan ke URL apa ...

Ini adalah apa yang kita digunakan untuk melakukan untuk mendeteksi .user.js navigasi. Sepertinya solusi yang jelas dan bagus: deteksi konten dengan menjalankan skrip konten!

Tetapi ternyata bahkan skrip konten ekstensi dapat dilanggar oleh CSP (#2631 dan http://bugzil.la/1267027 dan http://bugzil.la/1411641).

Saya dapat menjalankan plugin saya sendiri, termasuk konstruktor Function() dari langsung di dalam content_script, di Firefox 60.0.1 dan 52.8.1ESR dengan set CSP berikut:

data bingkai-src :; objek-src 'tidak ada'; script-src 'tidak ada'; style-src data 'tidak aman-inline' :; connect-src 'tidak ada'; media-src 'tidak ada';

2631 telah ditutup, tampaknya karena Firefox memperbaiki bug yang mendasarinya. Bugzilla pertama mengacu pada penyuntikan tag skrip (metode Violentmonkey), bukan content_script itu sendiri. Yang kedua mengacu pada atribut kotak pasir untuk CSP, tidak mengherankan karena memaksa domain untuk tidak pernah berhasil menyelesaikan pencocokan domain bahkan untuk dirinya sendiri. Agak seperti NaN!==NaN.

Ketika ini pertama kali diajukan beberapa bulan yang lalu, kami melakukan hal yang berbeda. Hari ini kami menggunakan webNavigation.onCommitted untuk mendeteksi navigasi, dan dalam pengujian yang saya jalankan sekarang, untuk beberapa alasan saya tidak melihatnya terpicu pada bingkai (ni)).

Halo, apakah ini diselesaikan sekarang?

Saya tidak bisa mendapatkan skrip yang saya buat untuk Tampermonkey diluncurkan pada iframe dengan Greasemonkey.

Kode untuk eksekusi belum diubah di pihak kami. Jadi kecuali Mozilla telah mengubah sesuatu pada akhirnya, ini masih rusak. Namun #2663 harus menyelesaikannya.

Mungkin perlu dicatat bahwa Violentmonkey dan Tampermonkey berfungsi dengan baik di dalam bingkai yang disematkan.

Tampermonkey memiliki masalah dengan iframe di Chrome, setidaknya untuk saya.

Mungkin perlu dicatat bahwa Violentmonkey dan Tampermonkey berfungsi dengan baik di dalam bingkai yang disematkan.

Tampermonkey memiliki masalah dengan iframe di Chrome, setidaknya untuk saya.

Tapi itu berhasil untuk saya di Firefox Violentmonkey. Jadi saya bertanya-tanya bagaimana itu bisa bekerja di sana?

Saya baru saja memperhatikan bahwa skrip yang menggunakan sinkronisasi lama GM_GetValue masih berfungsi dengan baik di Violentmonkey juga. Bagaimana mungkin? Saya pikir Firefox telah memaksa async GM.GetValue? Saya sangat bingung sekarang: mungkin Violentmonkey harus mengorbankan sesuatu yang lain untuk tetap mendukung sinkronisasi dan hal-hal lain?

@Cerberus-tm Perubahan di Firefox berarti bahwa data hanya dapat diminta dari penyimpanan ekstensi atau konteks latar belakang secara asinkron (skrip pengguna sendiri dikirim ke skrip konten secara asinkron). Namun, data dapat diberikan ke skrip pengguna secara serempak, jika setiap skrip konten GM4 diambil sebelumnya dan di-cache dalam skrip konten, data yang disimpan untuk setiap skrip pengguna dimuat di halaman itu.

Cache semacam itu akan memungkinkan skrip konten untuk merespons permintaan data skrip pengguna secara serempak. Menerapkan cache mengalami masalah dengan menjaga konsistensi di berbagai skrip konten, tetapi itu dapat diselesaikan dengan meminta skrip konten mendengarkan semua perubahan pada penyimpanan ekstensi GM4. Selain itu, jika skrip pengguna menyimpan data dalam jumlah besar, maka menyimpannya dalam cache di setiap skrip konten tempat skrip pengguna dijalankan juga meningkatkan memori yang diperlukan untuk setiap skrip konten secara signifikan.

TM dan VM memilih untuk melakukan sesuatu yang mirip dengan di atas agar tidak merusak kompatibilitas dengan API Greasemonkey asli ketika pengelola skrip pengguna tersebut diterapkan untuk Chrome, yang memiliki batasan yang sama wrt. komunikasi asinkron dengan penyimpanan ekstensi, dll. Mengingat bahwa mereka sudah melakukannya untuk Chrome, tidak ada alasan bagi mereka untuk mengubah saat diterapkan untuk Firefox.

Jadi, FF57 cut-over ke WebExtensions memang memaksa penulisan ulang GM, tetapi itu tidak memaksa adopsi API asinkron untuk GM.getValue , GM.setValue , dll. WebExtensions memang menggunakan API berbasis async lebih mudah diterapkan daripada sinkron, tetapi itu tidak mengharuskannya.

Secara pribadi, saya merasa bahwa pilihan, dan pilihan lain untuk melanggar kompatibilitas, sangat disayangkan. Kurangnya kompatibilitas mundur dengan skrip yang berjalan dengan baik di GM3 dan/atau kompatibilitas dengan TM mengakibatkan banyak orang memilih untuk tidak menggunakan GM4. Pengalaman saya adalah lebih dari 30 skrip pengguna yang saya gunakan, semuanya berfungsi dengan baik di GM3, tidak berfungsi dengan GM4 (atau setidaknya tidak berfungsi sebelum ditulis ulang agar kompatibel dengan GM4). Masih ada 28 skrip pengguna yang saya gunakan setiap hari yang berjalan dengan baik di bawah GM3 yang tidak bekerja dengan GM4.

Saya memposting solusi untuk masalah ini di Stack Overflow sebagai jawaban tentang cara Menerapkan Greasemonkey/‌Tampermonkey/‌userscript ke iframe . Pada dasarnya, saya menunggu frame dimuat dan kemudian saya mengoperasikan array window.frames . Saya menggunakan penanda khusus di setiap badan bingkai untuk menunjukkan bahwa saya telah melihat bingkai itu.

Mungkin Greasemonkey dapat mengimplementasikan solusi dengan cara yang sama?

Akan luar biasa jika kita juga memiliki GM.waitFor(css_selector, action_function) seperti waitForKeyElements() , tapi itu

Apakah halaman ini membantu?
0 / 5 - 0 peringkat