Search code examples
javascripthtmljqueryiframegoogle-chrome-extension

Content script injecting iframe inside all iframes on web page


I'm trying to create an iframe and inject it into the webpage when the webpage is loaded, But when I try to do that the content script is injecting the iframe inside all the iframes on the webpage, I have used the chrome.runtime.onMessage.addListener to be used to toggle the iframe when the user clicks on the extension icon so I'm sending a message from background script to handle this however I'm sending the message only once from the background script but chrome.runtime.onMessage.addListener is getting fired multiple times I'm not sure why

This is what is happening

This is the content script

var iframeContainer = undefined;
window.onload = function () {
  injectPopup();

  chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.message == "togglePopup") {
      console.log("message arrived");
      var appBody = document.getElementById("app-container");
      if (appBody.style.display == "none") {
        console.log("posting message");
        iframeContainer.contentWindow.postMessage(
          JSON.stringify({
            user: request.user,
            token: request.token,
          }),
          "*",
          []
        );
        appBody.style.display = "block";
      } else {
        appBody.style.display = "none";
      }
    }
  });
};

// window.addEventListener("message", function (e) {
//   if (JSON.parse(e.data)) {
//     const data = JSON.parse(e.data);

//     if (data.message) {
//       if (data.message == "toggleApp") {
//         var appBody = document.getElementById("app-container");
//         appBody.style.display = "none";
//       }
//     }
//   }
// });

function injectPopup() {
  console.log("inject popup");
  iframeContainer = document.createElement("iframe");
  console.log(iframeContainer);
  iframeContainer.allowFullscreen = false;
  iframeContainer.src = chrome.runtime.getURL("/index.html");
  iframeContainer.id = "app-container-iframe";
  const appContainer = document.createElement("div");
  appContainer.id = "app-container";
  appContainer.style.display = "none";
  console.log(appContainer);
  const resizeHandle = document.createElement("div");
  resizeHandle.id = "resize-container-handle";
  resizeHandle.classList.add("ui-resizable-handle");
  resizeHandle.classList.add("ui-resizable-w");

  resizeHandle.innerHTML =
    '<div class="resize-handle-horizontal-bar"></div><div class="resize-handle-horizontal-bar"></div><div class="resize-handle-horizontal-bar"></div>';

  appContainer.appendChild(resizeHandle);
  document.querySelector("body").appendChild(appContainer);
  appContainer.appendChild(iframeContainer);
  $("#app-container").resizable({
    handles: { w: "#resize-container-handle" },
  });
}

This is the background script from which I'm sending the message

var userLoggedIn = {};
const openTabs = [];
const apiUrl = "http://localhost:5000";
var popupOpen = false;
var currentWindow = undefined;

window.onload = () => {
  popupOpen = false;
};

chrome.storage.local.get("token", function (result) {
  userLoggedIn = result.token;

  chrome.browserAction.onClicked.addListener(function (tab) {
    const width = 500;
    const height = 900;
    const left = screen.width / 2 - width / 2;
    const top = screen.height / 2 - height / 2;
    console.log("clicked!");
    if (!userLoggedIn) {
      if (currentWindow == undefined) {
        chrome.windows.create(
          {
            url: "/html/auth.html",
            width: width,
            height: height,
            left: left,
            top: top,
            focused: true,
          },
          (window) => {
            currentWindow = window;
            chrome.windows.onRemoved.addListener(function (id) {
              if (currentWindow.id == id) {
                currentWindow = undefined;
              }
            });
          }
        );
      }
    } else {
      console.log("hi!");
      chrome.windows.getCurrent((w) => {
        chrome.tabs.query(
          {
            active: true,
            currentWindow: true,
          },
          function (tabs) {
            const userData = parseJwt(userLoggedIn);
            console.log("sending message");
            chrome.tabs.sendMessage(tabs[0].id, {
              message: "togglePopup",
              user: userData,
              token: userLoggedIn,
            });
          }
        );
      });
    }
  });

  chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.message === "login") {
      loginUser(request.payload)
        .then(function (res) {
          if (res.ok) {
            return res.json();
          } else {
            sendResponse({
              message: "error",
            });
          }
        })
        .then(function (data) {
          chrome.storage.local.set({ token: data.token }, function (result) {
            chrome.windows.remove(currentWindow.id);
            const userData = parseJwt(data.token);
            userLoggedIn = data.token;
            chrome.tabs.query(
              {
                active: true,
                currentWindow: true,
              },
              function (tabs) {
                chrome.tabs.sendMessage(tabs[0].id, {
                  message: "togglePopup",
                  payload: {
                    user: userData,
                    token: userLoggedIn,
                  },
                });
              }
            );

            sendResponse({ message: "success" });
          });
        })
        .catch(function (err) {
          console.log(err);
        });
      return true;
    } else if (request.message === "register") {
      registerUser(request.payload)
        .then(function (res) {
          if (res.ok) {
            return res.json();
          } else {
            sendResponse({
              message: "error",
            });
          }
        })
        .then(function (data) {
          console.log(data);
          sendResponse({ message: "success" });
        })
        .catch(function (err) {
          console.log(err);
        });
    } else if (request.message === "logout") {
    } else if (request.message === "userStatus") {
    } else if (request.message === "closePopup") {
      const index = getIndexOfTab(sender.tab.id, openTabs);
      openTabs[index].popupOpen = false;
    }
  });
});


Solution

  • chrome.tabs.sendMessage sends the message to all frames of the tab per the documentation.

    You can limit it to the main page via frameId:

    chrome.tabs.sendMessage(tabId, {foo: 'bar'}, {frameId: 0});