Bagaimana ekstensi web Platipus memudahkan penyesuaian browser Anda dan menghubungkan berbagai hal bersama-sama

Versi terbaru artikel ini tersedia di blog Platipus.

Dahulu kala, ada web di seluruh dunia di mana ekstensi web masih merupakan mainan baru untuk dimainkan dan browser utama yang mendukungnya (yaitu Firefox dan Chrome) tidak keberatan memberi mereka akses yang sangat luas ke internal dan API untuk melakukan hal tersebut. (kurang lebih) apapun yang mereka suka. Idenya adalah bahwa add-on/aplikasi/ekstensi browser ini (garis di antara keduanya masih agak kabur pada saat itu) dapat menjadi cara yang ampuh untuk menjalankan perangkat lunak apa pun di dalam browser (bahkan secara lokal dan tanpa terhubung ke situs web lain). pengguna ingin menjalankannya.

Itu adalah zaman ketika ekstensi kuat muncul yang juga dapat mengubah banyak hal di browser (seperti Vimperator yang sekarang sudah tidak berfungsi yang dapat sepenuhnya mendesain ulang UI browser agar terlihat dan berperilaku seperti vim), dan skrip pengguna adalah cara ampuh yang dapat dimanfaatkan pengguna untuk menjalankan apa pun yang mereka suka di mana pun mereka suka. Saya sering menggunakan skrip khusus Vimperator untuk memetakan urutan kunci mana pun yang saya inginkan ke tindakan khusus apa pun yang saya inginkan — hanya dimodelkan sebagai JavaScript biasa. Dan saya juga sering menggunakan skrip pengguna — skrip tersebut masih ada, tetapi dengan lebih banyak keterbatasan dibandingkan sebelumnya.

Era ekstensi web dan aplikasi Barat yang liar sebagian besar sudah berlalu sekarang. Tidak butuh waktu lama sebelum pelaku kejahatan menyadari bahwa kebebasan yang diberikan pada ekstensi web menjadikannya vektor yang sempurna untuk menjalankan malware/spyware langsung di dalam browser yang, dalam banyak kasus, dapat melewati beberapa lapisan anti-malware. Dan generasi ekstensi web tersebut memiliki masalah lain dengan fragmentasi. Firefox dan Chrome telah mengembangkan API mereka sendiri (seperti XUL dan Aplikasi Chrome Mozilla) yang tidak banyak tumpang tindih. Hal ini membuat tugas mengembangkan ekstensi web yang menargetkan banyak browser menjadi pengalaman yang sangat mahal, dan banyak ekstensi serta aplikasi hanya tersedia untuk browser tertentu.

Alasan untuk keamanan yang lebih baik, pemisahan kepentingan, dan pengurangan fragmentasi mendorong migrasi menuju WebExtension API modern. Sekitar akhir tahun 2017, baik Mozilla dan Google mengakhiri dukungan untuk API sebelumnya di browser masing-masing. Mereka juga menambahkan lebih banyak batasan untuk add-on dan skrip yang tidak disetujui di toko mereka (versi terbaru Firefox hanya mengizinkan Anda memasang ekstensi yang dipublikasikan di toko secara permanen) dan menambahkan lebih banyak batasan dan pemeriksaan dalam proses peninjauan mereka.

API baru ini mempersulit pelaku kejahatan untuk meretas pengguna melalui browser, dan juga sangat mengurangi hambatan yang diperlukan untuk mengembangkan ekstensi lintas-browser. Namun di sisi lain, hal ini juga sangat mengurangi derajat kebebasan yang ditawarkan pada perluasan. Beberapa ekstensi yang memerlukan integrasi mendalam dengan browser (seperti Vimperator dan Tukang Pos) memutuskan untuk bermigrasi ke aplikasi yang berdiri sendiri atau mengabaikan upaya mereka. Dan skrip pengguna telah menjadi fitur yang lebih unik dengan lebih banyak batasan dibandingkan sebelumnya yang ditawarkan oleh ekstensi pihak ketiga seperti Greasemonkey/Tampermonkey. “API skrip pengguna” terbaru dari Firefox adalah alternatif yang menjanjikan untuk menghidupkan kembali kekuatan gelombang sebelumnya, namun sejauh ini hanya didukung oleh Firefox.

Sebagai pengguna yang mahir, meskipun saya memahami semua motivasi yang mengarahkan pengembang browser untuk mengambil keputusan untuk lebih membatasi/melakukan sandbox pada ekstensinya, saya masih merindukan saat-saat ketika kami dapat menyesuaikan browser secara mendalam dan apa yang dapat dilakukan browser sesuai keinginan kami. Saya membangun Platipush selama bertahun-tahun untuk memenuhi kebutuhan saya akan ekstensibilitas dan penyesuaian tanpa akhir di sisi backend, dengan segala sesuatunya disediakan oleh API dan platform yang seragam dan koheren (bagi mereka yang belum mengenalnya, lihat artikel Medium direferensikan di README atau Wiki di halaman GitHub untuk memulai). Saya pikir menerapkan filosofi yang sama pada konteks browser web saya akan menjadi langkah alami berikutnya. Dengan ekstensi web Platipus, saya telah mencoba membangun solusi untuk beberapa kebutuhan yang dihadapi oleh banyak pengguna mahir.

Pertama, kami memiliki beberapa solusi backend untuk menjalankan berbagai hal, dan perangkat rumah pintar untuk melakukan berbagai hal dan menyebarkan informasi. Namun browser web desktop lama sering kali tertinggal dalam kemajuan otomatisasi ini, meskipun banyak orang masih menghabiskan banyak waktu di web melalui perangkat desktop. Sebagian besar solusi front-end untuk otomatisasi cloud/rumah hadir melalui aplikasi seluler. Beberapa solusi untuk otomatisasi menyediakan aplikasi/panel web (dan Platipus juga melakukannya), namun panel web semakin kurang mendapat perhatian di dunia yang semakin berpusat pada seluler.

Dan meskipun solusi Anda menyediakan aplikasi web, ada faktor penting lainnya yang perlu dipertimbangkan: waktu untuk bertindak. Berapa lama waktu yang berlalu antara Anda berpikir "Saya ingin menjalankan tindakan ini di perangkat itu" dan tindakan tersebut benar-benar dijalankan di perangkat itu? Dan ingatlah bahwa, terutama jika menyangkut perangkat pintar, waktu untuk bertindak dengan cara yang “pintar” (seperti Anda menyalakan bola lampu dari jarak jauh) tidak boleh lebih lama dari waktu untuk bertindak dengan cara yang “bodoh”. cara (seperti Anda berdiri dan menekan tombol). Itu adalah dasar Anda.

Saat saya melakukan beberapa pekerjaan di laptop, terkadang saya ingin menjalankan beberapa tindakan di perangkat lain — seperti mengirim tautan ke ponsel, menyalakan lampu atau kipas angin, memutar video yang sedang diputar di laptop di pusat media saya , putar playlist Spotify yang diputar di kamar tidur saya di ruang tamu — atau sebaliknya — dan seterusnya. Tentu saja, untuk beberapa masalah ini ada solusi front-end Platipush/HomeAssistant/OpenHAB/BigCorp Inc., tapi itu biasanya mengharuskan Anda melepaskan laptop untuk mengambil ponsel, atau membuka/beralih ke tab dengan web aplikasi yang disediakan oleh platform Anda, mencari menu/opsi yang tepat, menggulir sedikit, dan kemudian menjalankan tindakan. Asisten suara adalah pilihan lain (dan Platipush “menyediakan integrasi” yang memberi Anda akses ke banyak teknologi suara yang ada), namun berbicara sepanjang hari untuk menjalankan apa pun bukanlah proses tanpa hambatan dan cepat yang diinginkan banyak orang — dan seharusnya tidak menjadi satu-satunya cara. Meminimalkan waktu untuk bertindak bagi saya berarti dapat menjalankan tindakan tersebut dengan cepat (idealnya dalam maksimal tiga klik atau penekanan tombol) dari tab mana pun atau dari toolbar itu sendiri, apa pun tindakannya.

Tentu, ada beberapa ekstensi web untuk mengatasi beberapa masalah tersebut. Tapi itu biasanya melibatkan:

  • Mengandalkan solusi orang lain untuk masalah Anda, dan solusi tersebut belum tentu yang paling optimal untuk kasus penggunaan Anda.
  • Mencemari browser Anda dengan banyak ekstensi untuk menjalankan berbagai jenis tindakan. Mengirim tautan ke perangkat lain mungkin melibatkan pemasangan ekstensi Pushbullet/Gabung, memutar media di Kodi ekstensi lain, memutar media di Chromecast ekstensi lain, menyimpan tautan ke Instapaper/Evernote/Pocket atau ekstensi lainnya, berbagi di Twitter/Facebook dan lebih banyak lagi ekstensi, mengontrol hub rumah pintar Anda dengan ekstensi lain… dan daftarnya terus berlanjut, hingga bilah alat browser Anda penuh dengan ikon, dan Anda bahkan tidak dapat mengingat apa yang dilakukan beberapa ikon tersebut — menggagalkan seluruh tujuan mengoptimalkan waktu untuk bertindak dari konteks browser web.
  • Dan, tentu saja, memasang terlalu banyak ekstensi akan meningkatkan potensi serangan terhadap browser Anda — dan itulah masalah yang seharusnya diselesaikan oleh WebExtensions API.

Saya pertama kali memulai perjalanan ini dengan membangun ekstensi web sederhana yang dapat saya gunakan untuk dengan cepat men-debug perintah Platypush yang dijalankan pada RaspberryPis lain dan perangkat pintar di sekitar rumah saya melalui web API/websocket/MQTT. Kemudian, saya menyadari bahwa saya dapat menggunakan solusi yang sama untuk menyelesaikan masalah saya dalam mengoptimalkan waktu untuk bertindak - yaitu masalah “Saya ingin menyalakan lampu sekarang juga tanpa harus memegang ponsel atau berpindah tab atau berdiri, saat saya sedang mengerjakan artikel Medium saya di laptop.” Artinya, baik dari toolbar itu sendiri (sebaiknya dengan semua tindakan yang dikelompokkan dalam tombol ekstensi dan UI yang sama) atau melalui menu konteks klik kanan, seperti tindakan browser asli. Kemampuan untuk menjalankan tindakan Platipus apa pun dari browser saya di perangkat jarak jauh berarti saya dapat mengontrol perangkat apa pun atau API jarak jauh dari antarmuka yang sama, selama ada plugin Platipus untuk berinteraksi dengan perangkat/API tersebut.

Namun target itu belum cukup bagi saya. Tidak semua tindakan yang ingin saya jalankan dengan cepat dari lokasi mana pun di browser dapat diterjemahkan ke tindakan atom Platipus. Prosedur jarak jauh Platipus pasti dapat membantu menjalankan logika yang lebih kompleks di backend, namun saya ingin ekstensi tersebut juga mencakup kasus penggunaan saya yang memerlukan interaksi dengan konteks browser — hal-hal seperti “putar video ini di Chromecast saya (ya, meskipun saya' saya di Firefox)”, “terjemahkan halaman ini dan pastikan hasilnya tidak terlihat seperti situs web tahun 1997 (ya, meskipun saya menggunakan Firefox)”, “unduh tautan Magnet ini langsung di NAS saya”, dan sebagainya pada. Hingga kait peristiwa khusus yang dapat bereaksi terhadap peristiwa Platipus yang dipicu oleh perangkat lain dengan logika khusus yang berjalan di browser — hal-hal seperti “sinkronkan papan klip di laptop jika perangkat Platipush lain mengirimkan ClipboardEvent”, “kirim pemberitahuan ke browser dengan teks yang diucapkan saat plugin Asisten Google memicu ResponseEvent”, atau saat sensor melampaui ambang batas tertentu, dan seterusnya.

Saya ingin kemampuan untuk mendefinisikan semua tindakan ini melalui API asli JavaScript yang serupa dengan yang disediakan oleh Greasemonkey/Tampermonkey. Namun meskipun sebagian besar skrip pengguna yang disediakan oleh ekstensi tersebut hanya berjalan dalam konteks halaman web, saya ingin memisahkan cuplikan skrip saya dari halaman web dan membangun API yang menyediakan akses ke konteks browser, ke tindakan Platipus yang tersedia. di perangkat jarak jauh lainnya, untuk menjalankan kode latar belakang sebagai respons terhadap peristiwa khusus, dan untuk menyinkronkan konfigurasi dengan mudah di seluruh perangkat. Jadi mari kita lihat sekilas ekstensinya untuk melihat apa yang dapat Anda lakukan dengannya.

Instalasi dan Penggunaan

Pertama, Anda memerlukan layanan Platipus yang berjalan di suatu tempat. Jika Anda belum pernah mencobanya, lihat tautan mana pun di bagian sebelumnya untuk memulai (Saya telah memastikan bahwa menginstal, mengonfigurasi, dan memulai lingkungan dasar tidak memakan waktu lebih dari lima menit, saya berjanji : ) ). Selain itu, pastikan Anda mengaktifkan backend HTTP di config.yaml, karena server web adalah saluran yang digunakan oleh ekstensi untuk berkomunikasi dengan server. Setelah Anda menjalankan instance Platipus, mis. RaspberryPi, server lain atau laptop Anda, dapatkan ekstensi web:

Anda juga dapat membuat ekstensi dari sumber. Pertama, pastikan Anda sudah menginstal npm, lalu clone reponya:

git clone https://github.com/BlackLight/platypush-webext

Instal dependensi dan buat ekstensi:

npm install
npm run build

Di akhir proses, Anda akan memiliki folder dist dengan file manifest.json.

  • Di Chrome (atau browser berbasis Chromium apa pun), buka Extensions -› Load Unpacked dan pilih folder dist.
  • Di Firefox, buka about:debugging -› Firefox ini -› Muat Pengaya Sementara dan pilih file manifest.json.

Perhatikan bahwa versi terbaru Firefox "hanya mendukung" ekstensi yang belum dibongkar (yaitu ekstensi apa pun yang tidak dimuat di situs web pengaya Firefox) hingga about:debugging. Artinya, ekstensi sementara apa pun akan hilang saat browser dimulai ulang — namun, memulihkan konfigurasi ekstensi Platipus saat diinstal ulang merupakan proses yang sangat cepat.

Setelah dipasang di browser, ikon ekstensi akan muncul di toolbar.

Klik tautan yang tersedia untuk membuka tab konfigurasi ekstensi dan menambahkan perangkat Platipus Anda dalam konfigurasi.

Setelah perangkat ditambahkan, klik namanya dari menu dan pilih Jalankan Tindakan.

Tab run hadir dengan dua mode: mode permintaan dan skrip. Dalam mode permintaan, Anda dapat menjalankan tindakan secara langsung pada perangkat Platipus jarak jauh melalui antarmuka dinamis. Anda memiliki formulir dengan menu pelengkapan otomatis yang menampilkan semua tindakan yang tersedia di perangkat Anda, dan setelah dipilih, formulir sudah diisi sebelumnya dengan semua argumen yang tersedia untuk tindakan tersebut, nilai defaultnya, dan deskripsinya. Antarmuka ini sangat mirip dengan tab eksekusi yang disediakan oleh panel web Platipus, dan membuatnya sangat mudah untuk menguji dan menjalankan perintah dengan cepat di host lain.

Anda dapat menggunakan antarmuka ini untuk menjalankan tindakan apa pun pada perangkat jarak jauh apa pun asalkan ada plugin yang diinstal dan dikonfigurasi untuk itu — manajemen sistem file, kontrol pusat media, asisten suara, kamera, sakelar, mendapatkan data dari sensor, mengelola layanan cloud, Anda sebutkan saja. Anda juga dapat menjalankan prosedur yang disimpan di perangkat jarak jauh — nama tindakannya dimulai dengan procedure — dan Anda juga dapat meneruskan URL di tab aktif ke tindakan sebagai argumen dengan menggunakan variabel khusus $URL$ sebagai nilai tindakan. Misalnya, Anda dapat menggunakannya untuk membuat tindakan yang mengirimkan URL saat ini ke perangkat seluler Anda melalui pushbullet.send_note, dengan body dan url disetel ke $URL$. Setelah Anda puas dengan tindakan Anda, Anda dapat menyimpannya sehingga tersedia dari toolbar dan menu konteks browser.

Jika Anda hanya memerlukan cara untuk menjalankan tindakan Platipus dari jarak jauh dari browser Anda, inilah yang sebenarnya Anda perlukan. Tindakan tersebut sekarang akan tersedia dari toolbar ekstensi:

Dan dari menu konteks:

Anda dapat dengan mudah men-debug/mengedit tindakan tersimpan dari tab Tindakan Tersimpan di halaman konfigurasi ekstensi.

Cara lain (dan paling ampuh) untuk menentukan tindakan kustom adalah melalui skrip. Skrip dapat digunakan untuk merekatkan API Platipus (atau API lainnya) dan API browser.

Pilih Script dari pemilih di bagian atas tab Jalankan Tindakan. Anda akan disajikan dengan editor JavaScript dengan templat skrip yang sudah dimuat sebelumnya:

Halaman ini juga menyediakan link ke Intinya yang menunjukkan contoh untuk semua bagian API yang tersedia. Singkatnya, ini adalah bagian terpenting yang dapat Anda gunakan untuk membuat skrip pengguna Anda:

  • args menyertakan informasi konteks yang relevan untuk skrip Anda, seperti target Platipus host, elemen tabId, dan target, jika tindakan dipanggil dari menu konteks pada halaman.
  • app memperlihatkan API yang tersedia untuk skrip.

Diantara metode yang dipaparkan oleh app:

  • app.getURL mengembalikan URL di tab aktif.
  • app.setURL mengubah URL yang ditampilkan di tab aktif, sedangkan app.openTab membuka URL di tab baru.
  • app.notify(message, title) menampilkan notifikasi browser.
  • app.run menjalankan tindakan pada perangkat Platipus jarak jauh.

Misalnya, ini adalah tindakan yang mungkin dilakukan untuk mentransmisikan video YouTube ke perangkat Chromecast default:

  • app.axios.[get|post|put|delete|patch|head|options]: API juga mengekspos API Axios untuk melakukan panggilan AJAX khusus ke titik akhir jarak jauh. Misalnya, jika Anda ingin menyimpan URL saat ini ke akun Instapaper Anda:
  • app.getDOM mengembalikan DOM/konten halaman saat ini (sebagai elemen Node), sedangkan app.setDOM menggantikan DOM/konten halaman (diberikan sebagai string). Misalnya, Anda dapat menggabungkan DOM API yang disediakan dengan Platipush Translate plugin untuk menerjemahkan halaman web dengan cepat:
  • API ekstensi juga menampilkan Mercury Reader API untuk menyederhanakan/menyaring konten halaman web. Anda dapat menggabungkan elemen-elemen yang terlihat sejauh ini ke dalam skrip yang menyederhanakan konten halaman web agar lebih mudah dibaca atau membuatnya lebih ramah printer:
  • Terakhir, Anda dapat mengakses elemen target jika Anda menjalankan tindakan melalui menu konteks (misalnya, klik kanan pada item di halaman). Karena keterbatasan WebExtensions API (yang hanya dapat meneruskan objek yang dapat diserialisasikan JSON), elemen target diteruskan pada args sebagai string, namun Anda dapat dengan mudah mengonversinya menjadi objek DOM (dan Anda dapat mengonversi HTML apa pun ke DOM) melalui metode app.HTML2DOM. Misalnya, Anda dapat memperluas skrip pengguna YouTube ke Chromecast awal untuk mentransmisikan item audio atau video apa pun yang ada di laman:

Dengan blok dasar ini, Anda seharusnya dapat membuat tindakan browser khusus apa pun yang Anda inginkan. Beberapa contoh:

  • Konversikan halaman web saat ini ke PDF melalui plugin penyederhanaan halaman web Platipush dan kirimkan ke Kindle Anda sebagai lampiran melalui plugin Platipush GMail.
  • Kirim email ke seseorang yang berisi teks yang dipilih pada halaman.
  • Terjemahkan dengan cepat beberapa teks yang dipilih pada halaman.
  • Bagikan tautan saat ini ke Twitter/Facebook/LinkedIn (dan buang semua ekstensi berbagi-ke-sosial lainnya).
  • Unduh tautan magnet/torrent pada halaman langsung ke NAS Anda.

Pencadangan dan Pemulihan Konfigurasi

Terakhir, Anda dapat dengan mudah mengedit, mencadangkan, dan memulihkan konfigurasi ekstensi melalui tab Konfigurasi. Konfigurasi dapat dimuat/disalin ke file, dipulihkan dari/dicadangkan dari jarak jauh ke perangkat Platipus (lihat ma', tanpa cloud!), atau dimuat dari URL.

Pekerjaan Sedang Berlangsung

Ekstensi ini masih dalam pengembangan, dan saya terbuka untuk saran, tiket, dan permintaan penarikan di halaman GitHub. Dua fitur, khususnya, adalah yang berikutnya dalam peta jalan saya:

Integrasi dengan protokol soket web Platipus

Hal ini akan memungkinkan banyak fitur menarik, seperti memeriksa status kesehatan perangkat jarak jauh, mentransfer potongan data yang lebih besar (seperti aliran audio/video dari perangkat jarak jauh) dan, yang terpenting, menyiapkan event hooks — skrip yang berjalan secara otomatis ketika perangkat Platipus memicu peristiwa seperti mis. respons asisten suara diproses, status media diubah, pemandangan lampu diubah, data sensor baru diterima, dll.

Dukungan untuk perpustakaan pihak ketiga melalui API

Saat ini, API skrip mengekspos pustaka parser axios dan mercury, tetapi saya yakin demi fleksibilitas, pustaka eksternal dapat diimpor ke skrip pengguna melalui sesuatu yang sederhana seperti:

const jquery = app.loadScript('https://some.cdn/jquery.min.js');

Pada akhirnya, jika proyek ini mendapat daya tarik yang cukup, saya ingin membuat repositori di mana pengguna dapat membagikan kreasi mereka — selama kita semua ingat bahwa dengan kekuatan yang besar, ada pula tanggung jawab yang besar :)

Kesimpulan

Saya memahami masalah keamanan dan keseragaman yang menyebabkan penerapan WebExtensions API. Namun saya juga memahami mengapa banyak ekstensi yang dulunya mengandalkan integrasi lebih dalam dengan browser menolak untuk berkompromi dengan API baru dan untuk sementara dihentikan.

Saya sendiri kesulitan mengembangkan ekstensi ini dengan API baru, karena API WebExtensions saat ini membuat banyak kotak pasir dan hanya membuat potongan informasi dapat diakses dalam konteks tertentu (seperti skrip latar belakang, skrip konten, atau konteks popup), dan hal ini memaksa pengembang yang membutuhkan informasi dan fitur untuk diakses oleh berbagai bagian aplikasi mereka untuk menyiapkan sistem pesan yang kompleks untuk meneruskan data. Ini juga memberikan batasan keras pada potongan kode apa yang dapat dieksekusi di mana (semoga berhasil lolos dengan evalin kode Anda). Dengan ekstensi web Platipus, saya telah mencoba mengisi kekosongan yang ditinggalkan oleh penghentian API ekstensi/aplikasi/add-on sebelumnya dan menyediakan lapisan bagi pengguna yang mahir untuk menyesuaikan secara mendalam perilaku browser mereka. Saya juga ingin membangun sebuah ekstensi yang dapat memberi saya akses mudah, dari UI yang sama dan tombol yang sama, ke dunia perangkat pintar yang semakin terfragmentasi di sekitar saya. Dan saya juga bosan melihat ruang di toolbar saya habis oleh banyak ikon ekstensi yang hanya dapat melakukan satu tugas tertentu!