✨Feature: Button wstaw link w edytorze ma wyświetlić prompt na wprowadzenie linka

Zrobienie tego feature’a nie było aż takie proste jak mi się wydawało. Problem w tym, że button w edytorze ma swoje własne zdarzenie onclick.

Fajnie byłoby event wywalić i napisać swój totalnie od zera.

Niestety nie da się tego tak prosto zrobić.
Dlaczego? Przecież jest metoda:

target.removeEventListener(type, listener);

Tak, jest. Ale by pozbyć się eventa musimy w parametrze podać event listender. Nie znamy go. Nie mamy jak go pobrać ani odwołać się do niego.

Jest jeszcze sposób w jQuery: unbind () czy też off(), lecz tutaj mamy kolejny problem. Kod js’a uruchomiony czy też wstrzyknięty rozszerzeniem działa w zupełnie innym kontekscie. Nie mamy możliwości odwołania do jQuery podpiętego na wykopie. Tak na prawdę, to nie możemy się odwołać do żadnych obiektów, funkcji jsowych na stronie, bo to nie nasz kontekst. Jedynie możemy się komunikować via DOM.

Wstrzyknięcie żywego kodu jsa też nie zadziała. Manifest v3 nie pozwala na to:

var script = document.createElement('script');
script.textContent = 'alert("test")';
(document.head||document.documentElement).appendChild(script);
script.remove();

Gdybyśmy użyli manifest v2, to dałoby radę, lecz do końca 2022 chrome przestanie wspierać v2 i rozszerzenie przestałoby działać.

Jedynie co można zrobić w tym przypadku, to:

  • w pliku manifest.json podać w web_accessible_resources z jakich resourceów, będziemy korzystać. Tutaj resourcem będzie plik z jsem: remove-event.js. Jeśli nie podamy pliku w web_accessible_resources dostaniemy komunikat:
    Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.
  • teraz można podpiąć plik do strony
var s = document.createElement('script');
s.src = chrome.runtime.getURL('/common/remove-event.js');
s.onload = function() {
  this.remove();
};
(document.head || document.documentElement).appendChild(s);

Wszystko fajnie. Skrypt się podpina i wykonuje.

Tylko czy na prawdę warto coś takiego robić aby pozbyć się eventa? Na pewno nie.
Można pomyśleć nad loadm przeniesieniem obecnych funkcjonalności do podpinania jak wyżej, czyli przez script.

Zamiast ładowania pliku js przez `executeScript`

Dodalibyśmy go przez script

Jak dla mnie rozwiązanie spoko, lecz zrobimy obejście aby trzymać się obecnego mechanizmu w ramach ćwiczeń. Zobaczę ile będzie męki z innymi featureami. Niech sobie obecny event na buttonie żyje jak żył. Dodamy nowego eventa, który się uruchomi zaraz PO obecnym

Kluczem jest (g-ł-u-p-i-e) rozwiązanie z setTimeout(function (), 1);

Głupie a działa zadziwiająco dobrze!

  • po kliknieciu w button pozwalamy odpalić pierwony event:
  • natychmiast pojawia się prompt z miejscem na linka
  • klikamy OK i link wskakuje

Pięknie. Niezbyt to eleganckie rozwiązanie ale działa poprawnie. Trzeba wziąć poprawkę na to, że trochę hackujemy wykop i mniej eleganckie rozwiązania będą się lepiej sprawdzać.

Ostatnia rzecz jaka wymagała zmiany to sposób uruchomienia featurea. Do tej pory miałem założenie: jeden feature na URL. Czyli jak jesteśmy na stronie:
https://www.wykop.pl/wiadomosc-prywatna/konwersacja/…
to na podstawie prostego RegEx’a dopinamy feature:

Ha! Jakże szybko okazało się to błędnym założeniem. Obecnie mamy dwie funkcjonalności, które powinny zostać uruchomione na tej samej stronie. Szybka zmiana:

Dodanie foreach’a:

Działa!

to be continued ヘ( ^o^)ノ\(^_^ )

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *