wyskakujący popup z rozszerzenia

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:

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

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

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 ?

/* --- 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 --- */
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 ??

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.

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

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

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:

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ć ?

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

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

1

Could not establish connection. Receiving end does not exist.

Składnia wysyłania ma postać:

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ę:

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:

/* --- 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ć.

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 :)

0

Coś takiego wykminiłem:

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

I jak sobie ją wywołuję to:

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.

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

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

});

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

1

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

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

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

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

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

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/

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:

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

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:

  "permissions": [
    "declarativeContent",
    "storage",
    "tabs",
    "activeTab",
    "<all_urls>"
  ]
  "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ć.

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

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

1 użytkowników online, w tym zalogowanych: 0, gości: 1