wyskakujący popup z rozszerzenia

wyskakujący popup z rozszerzenia
M1
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 2 lata
  • Postów:33
0

Cześć, w przeglądarce chrome chciałem użyć wbudowanej opcji jaka jest do wyświetlania powiadomień z wcześniej przygotowanego obiektu notification.
Na przykład coś takiego:

Kopiuj
 var notification = {
   priority: 2,
   type: 'basic',
  iconUrl: 'image.png',
  title: 'tytul',
  message: 'zawartosc'
};

Kopiuj
chrome.notifications.create('id', notification, function() {});

Ale, nie zawsze to działa. Jak przeprowadzam testy to to praktycznie wgl nie działa. A consola nie pokazuje żadnych błędów. Tak jak by się to wykonało. Mam przed tym i za tą funkcją console.log() i w obu przypadkach konsola wyświetla zadany tekst, jednak powiadomienie się nie pokazuje na ekranie.
I moje pytanie czy z poziomu mojego rozszerzenia da się jakoś moje dane wyświetlić na ekran w przeglądarce ale nie używając chrome.notifications.create() czyli stworzyć własny szablon i tylko w odpowiednim miejscu kodu dać go na ekran na widoku nad całym contentem przeglądarki ?

Z góry dziękuję za każdą pomoc

Freja Draco
Freja Draco
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:3394
1
Maciej123321 napisał(a):

I moje pytanie czy z poziomu mojego rozszerzenia da się jakoś moje dane wyświetlić na ekran w przeglądarce ale nie używając chrome.notifications.create() czyli stworzyć własny szablon i tylko w odpowiednim miejscu kodu dać go na ekran na widoku nad całym contentem przeglądarki ?

Kopiuj
/* --- f: m_komunikat --- */
function m_komunikat(komunikat="") {
  var element_okno = document.getElementById("div_komunikat");
  /* --- otwórz okno, jeśli jeszcze nie istnieje --- */
  if (!element_okno) {
    /* --- div komunikatu --- */
    m_komunikat_tresc_okno = document.createElement("DIV");
    m_komunikat_tresc_okno.setAttribute("id", "div_komunikat");
    m_komunikat_tresc_okno.style.position = "fixed";
    m_komunikat_tresc_okno.style.zIndex = "99995";
    m_komunikat_tresc_okno.style.top = "10px";
    m_komunikat_tresc_okno.style.left = "calc(50% - 160px)";
    m_komunikat_tresc_okno.style.width = "300px";
    m_komunikat_tresc_okno.style.backgroundColor = "#ECFADE";
    m_komunikat_tresc_okno.style.border = "1px solid #CFDDC1";
    m_komunikat_tresc_okno.style.textAlign = "right";
    m_komunikat_tresc_okno.style.padding = "10px";
    m_komunikat_tresc_okno.style.fontSize = "14px";
    m_komunikat_tresc_okno.style.fontWeight = "normal";
    m_komunikat_tresc_okno.style.fontFamily = "Tahoma,Arial,Helvetica,sans-serif";
    /* + */  document.body.appendChild(m_komunikat_tresc_okno);
    /* --- /div komunikatu --- */
    
    /* --- div zamykacza --- */
    m_komunikat_tresc_zamykacz = document.createElement("DIV");
    m_komunikat_tresc_zamykacz.setAttribute("id", "div_zamykacz");
    m_komunikat_tresc_zamykacz.style.width = "20px";
    m_komunikat_tresc_zamykacz.style.height = "20px";
    m_komunikat_tresc_zamykacz.style.marginLeft = "auto";
    m_komunikat_tresc_zamykacz.style.marginBottom = "-20px";
    m_komunikat_tresc_zamykacz.style.textAlign = "center";
    m_komunikat_tresc_zamykacz.style.color = "red";
    m_komunikat_tresc_zamykacz.style.fontWeight = "bold";
    m_komunikat_tresc_zamykacz.style.cursor = "default";    
    m_komunikat_tresc_zamykacz.innerHTML ="⨯";
    /* + */  m_komunikat_tresc_okno.appendChild(m_komunikat_tresc_zamykacz);
    /* --- /div zamykacza --- */
    
    /* --- div treści --- */
    m_komunikat_tresc = document.createElement("DIV");
    m_komunikat_tresc.setAttribute("id", "div_tresc");
    m_komunikat_tresc.style.marginLeft  = "20px";
    m_komunikat_tresc.style.marginRight = "20px";
    m_komunikat_tresc.style.textAlign = "center";
    m_komunikat_tresc.innerHTML = "";    
    /* + */  m_komunikat_tresc_okno.appendChild(m_komunikat_tresc);    
    /* --- /div treści --- */    
    
    /* --- obsługa zamykania --- */
    document.addEventListener('click', function(e){
      if (e.srcElement.id=="div_zamykacz") m_komunikat();
    });
    /* --- /obsługa zamykania --- */
  }
  /* --- /otwórz okno, jeśli jeszcze nie istnieje --- */

  
  /* --- treść komunikatu --- */
  if (komunikat!="") {
    var element_komunikat = document.getElementById("div_tresc");
    element_komunikat.innerHTML = komunikat;
  }
  /* --- /treść komunikatu --- */
  
  /* --- kasuj okno --- */
  if (komunikat=="") {
    element_okno.parentNode.removeChild(element_okno);
    delete m_komunikat_tresc_okno;
  }
  /* --- /kasuj okno --- */
}
/* --- /f: m_komunikat --- */

M1
:O Dzięki wielkie, spróbuję to przegryźć i wykonać
ŁF
O matko, ale kupa
M1
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 2 lata
  • Postów:33
0

to działa jak coś, dzięki wielkie za pomoc.
Mam jeszcze pytanie.

Bo w background mam skrypt pracujący i słuchający bazy danych firebase.
Jak nastąpi tam zmiana, mogę wysłać kolejnego chrome.runtime.sendMessage i odebrać go w content script funkcją chrome.runtime.onMessage.addListener ??

Freja Draco
Freja Draco
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:3394
0
Maciej123321 napisał(a):

Jak nastąpi tam zmiana, mogę wysłać kolejnego chrome.runtime.sendMessage i odebrać go w content script funkcją chrome.runtime.onMessage.addListener ??

Tak.
Przesyłana wartość jest obiektem.

Kopiuj
chrome.runtime.onMessage.addListener(
  function(request, sender) {
    if (request.nazwa_pola) var tresc_pola = request.nazwa_pola;
    ...
}

M1
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 2 lata
  • Postów:33
0

No niby dobrze, ale jest coś takiego.
W moim background mam

Kopiuj
chrome.runtime.sendMessage({ command: "tekst", data: { title: "tytul"} }, (response) => {
                            console.log("wyslanie");
                        });

I to się wykonuje, bo w konsoli mam komunikat.
Natomiast zaraz po mam error:
Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
W content script mam:

Kopiuj
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
    if (msg.command == "tekst") {
        m_komunikat("W ife "); //ta funkcja z popupem.
    }
});

Jeżeli chodzi o pozwolenia, bo czytałem że activeTabs należy dodać, ale generalnie nie pomaga to, ktoś wie jak to naprawić ?

Kopiuj
"permissions": [
        "storage",
        "notifications",
        "<all_urls>",
        "activeTab"
    ],

Czyli generalnie nie idzie dalej, nie ma jakiegoś kanału utworzonego. Ktoś wie jak to naprawić ?

Freja Draco
Freja Draco
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:3394
1

Could not establish connection. Receiving end does not exist.

Składnia wysyłania ma postać:

Kopiuj
chrome.tabs.sendMessage(karta_docelowa.id, {nazwa_pola: tresc_pola});

Natomiast ze złapaniem właściwej karty może być cała zabawa. Najprościej jak tworzysz akurat nową kartę:

Kopiuj
chrome.tabs.create({url:"lista_wynikow.htm"}, function(tab) {g_karta_wynikow = tab;}); /* otwórz nową katę */

Możesz też szukać karty po różnych kryteriach. Poniżej funkcja wyszukująca i aktywując karę o określonym adresie, ew. tworząca ją jeśli nie istnieje:

Kopiuj
/* --- f: wyświetl kartę wyników --- */
function karta_wynikow_otworz() {
  var temp_karta_wynikow_url = "chrome-extension://" + chrome.runtime.id +"/lista_wynikow.htm";
  /* */
  chrome.tabs.query({url:temp_karta_wynikow_url}, function(tabs) {
    if (tabs.length==0) {
      /* --- karta: nie znaleziono --- */
      chrome.tabs.create({url:"lista_wynikow.htm"}, function(tab) {g_karta_wynikow = tab;}); /* otwórz nową katę */
      /* --- /karta: nie znaleziono --- */
    } else {
      /* --- karta: znaleziono --- */
      chrome.windows.update(tabs[0].windowId, {focused:true}); /* aktywuj okno istniejącej karty */
      chrome.tabs.update(tabs[0].id, {active:true});           /* aktywuj istniejącą kartę */
      if (g_stan=="aktywny") chrome.tabs.update(tabs[0].id, {url:"lista_wynikow.htm"}); /* przeładuj istniejącą kartę */
      /* --- /karta: znaleziono --- */
    }
  });
}
/* --- f: wyświetl kartę wyników --- */

I jak już masz uchwyt do obiektu karty, powyżej g_karta_wynikow, to możesz jego id: g_karta_wynikow.id wrzucić jako parametr odbiorcy i powinno działać.

Acha. I pamiętaj, że wszystkie te funkcje function(tabs), function(tab) wykonują się asynchronicznie "on callback", więc jeśli w następnej linijce kodu wrzucisz jakieś odwołanie do efektu ich pracy, to możesz się zdziwić, bo mogły się jeszcze nie wykonać.


M1
oj to teraz się nakomplikowało......Czyli contentscript generalnie mi nie złapie chrome.runtime, ma on swoje chrome.tabs ? A jak bym chciał żeby się wyświetliło na wszystkich ?
Freja Draco
Freja Draco
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:3394
0
Maciej123321 napisał(a):

Czyli contentscript generalnie mi nie złapie chrome.runtime, ma on swoje chrome.tabs ? A jak bym chciał żeby się wyświetliło na wszystkich ?

Okna to osobne twory a karty osobne. Okna zawierają katy. Więc chcąc wysłać do wszystkich, trzeba by pewnie przelecieć je wszystkie jak powyżej i do każdego wysłać komunikat. Ale mogę się mylić. Studiuj specyfikację i szukaj :)


M1
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 2 lata
  • Postów:33
0

Coś takiego wykminiłem:

Kopiuj
function doInCurrentTab(tabCallback) {
    chrome.tabs.query({ currentWindow: true, active: true },
        function(tabArray) { tabCallback(tabArray[0]); }
    );
}

I jak sobie ją wywołuję to:

Kopiuj
doInCurrentTab(function(tab) {
     chrome.tabs.sendMessage(tab.id, { tekst: "tekst" });
     console.log(tab.id)
 });

I w konsoli widzę że się wykonuje bo jak latam to kartach to różne ID jest, dla każdej inne. Więc chyba działa.

Tylko jak to jeszcze złapać ? żeby to wiadomo było że ode mnie wstrzyknięcie kodu jest.

Kopiuj
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {

    m_komunikat("W ife "); //ta funkcja z popupem.

});

bo musi chyba coś być żeby skrypt zaskoczył ?

edytowany 2x, ostatnio: cerrato
M1
Bo generalnie, to działa, ale też jakoś topornie. Nie zawsze
Freja Draco
Freja Draco
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:3394
1

Wysyłanie wiadomości z background.js do content.js

Kopiuj
chrome.tabs.sendMessage(karta_docelowa.id, {nazwa: wartość});

Wysyłanie wiadomości z content.js do background.js:

Kopiuj
chrome.runtime.sendMessage({nazwa: wartość});

Odbieranie wiadomości (wszędzie takie samo):

Kopiuj
chrome.runtime.onMessage.addListener(
  function(request, sender) {
    if (request.nazwa) {
      alert(request.nazwa)
    }
  }
);

Nie potrzebujesz sprawdzać źródła pochodzenia wiadomości tak jak przy:
window.postMessage() / window.addEventListener("message",
bo kod odpalony na chrome.runtime wykona ci się tylko w obrębie rozszerzenia, więc nie ma niebezpieczeństwa, że ktoś coś zrobi na cudzym komputerze bez wiedzy tej osoby.
A w ogóle to guglaj, są specyfikacje i działające przykłady:
https://developer.chrome.com/docs/extensions/mv2/messaging/


edytowany 1x, ostatnio: Freja Draco
M1
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 2 lata
  • Postów:33
0

Kurcze to wszystko działa, tylko jest ostatni problem którego przeskoczyć nie mogę.
Ponieważ weryfikuję gzie ma mi popup wyskoczyć w ten sposób:

Kopiuj
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
                        if (tabs[0].id != null) {
                            chrome.tabs.sendMessage(tabs[0].id, { msg: "msg" }, function(response) {

                            });
                        }
                    }); 

Ale jak znajduje się w opcjach lub w chrome://extensions czy nawet na nowej karcie gdzie jest pusta strona startowa (domyślna chromowska) to nie mają te karty żadnego ID.
I kiedy jest potrzeba wyrzucenia popupu wywala się błąd:

Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.

tam content scripta chyba nie ma po prostu.
Wiesz może @Freja Draco czy ktokolwiek jak zabezpieczyć tego ifa aby na tych stronach tego nie wywalać ? bo tabs[0].id jest undefined, na nulla nie reaguje.
Był bym wdzięczny za pomoc

Freja Draco
Freja Draco
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:3394
0

Nie pracowałam nigdy na kartach systemowych. Ale o ile to możliwe, to trzeba to przede wszystkim dodać w manifest.json do sekcji:

Kopiuj
  "permissions": [
    "declarativeContent",
    "storage",
    "tabs",
    "activeTab",
    "<all_urls>"
  ]
Kopiuj
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*", "file:///*/*"],
      "all_frames": true,
      "js": "content.js"
    }

Tzn. powyżej akurat nie ma potrzebnych deklaracji, ale pewnie tam je należy dodać.


M1
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 2 lata
  • Postów:33
0

Dodałem "declarativeContent" do permissions. I przestało błędy wywalać, w content script mam właśnie "matches": ["<all_urls>"] i chyba przez to kartach systemowych takich jak chrome://extensions/ czy nawet jak otworzę pustą to nie mam żadnego url, więc tu już nie działa. Próbowałem dać chrome://*, ale nie ma na to zgody, zresztą w dokumentacji też nie ma czegoś takiego

M1
A dobra, nawet nie - w chrome://extensions/ dalej jest błąd, a na pustej karcie zniknął :/
Freja Draco
Freja Draco
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:3394
0

Szybkie guglanie daje:
https://stackoverflow.com/questions/10196258/does-content-scripts-matches-chrome-extension-work

Does content_scripts matches “chrome-extension:///” work?

No. Only ftp:, file:, http: and https: can be matched by a content script declaration.

If you want to run a script on a tab from your extension, use chrome.extension.getViews in your background script. Even better, design your extension's pages such that they effectively communicate with each other (example).

W ostatnim akapicie są linki:
https://developer.chrome.com/docs/extensions/reference/extension/#method-getViews
https://developer.chrome.com/docs/extensions/mv2/messaging/
https://developer.chrome.com/docs/extensions/mv2/messaging/#external


Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.