I am trying to build this chrome extension that only displays the popup when I am on a youtube video page. However, I am having a lot of difficulties doing this and used many approaches.
My latest approach is to use chrome.action.onClicked and check if the URL contains https://youtube.com/watch. Then I would use chrome.action.setPopup to my HTML file. This works on all pages until when I click on the extension while on a youtube video page, then it would just show on every single page.
Here is my background.js:
chrome.action.onClicked.addListener((tab) => {
console.log(tab.tabId);
if (tab.url.includes("https://www.youtube.com/watch") == true) {
chrome.action.setPopup({ tabId: tab.tabId, popup: "/Pages/index.html" });
} else if (tab.url.includes("https://www.youtube.com/watch") == false) {
chrome.action.setPopup({ tabId: tab.tabId, popup: "" });
}
});
I think that it is not working because after setting the popup, that means it does not check the onClicked event anymore (specified here).
Any help would be much appreciated!
It's not tab.tabId but tab.id. You can check for it. And setPopup when onClicked, you have to click the extension twice will the popup show up.
Related
I am creating a chrome extension which embeds an iframe on a website and it works well except when a user clicks on the iframe (or anything inside the iframe) and then tries to use the back button to navigate back to a previous page on the parent/actual site. When you attempt to go back the page just reloads the iframe (even when you press the back button many times, each time it just reloads the iframe). If the user doesn't click on the iframe (just mouseover) everything works as expected. Here is what my chrome extension is doing:
background.js:
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status == 'complete') {
chrome.scripting.executeScript({
target: { tabId: tab.id },
function: createIframe
});
}
});
function createIframe() {
var location = document.getElementById(id of location);
var embed = document.createElement("iframe");
embed.setAttribute('src', link);
location.appendChild(embed.cloneNode(true));
}
Responses to similar problems said the issue was setting the src link using setAttribute and that this method added the iframe loading to the browser history. To fix this they suggest using iframe.contentWindow.location.replace(link);. I tried doing this, but the iframe didn't even load the link content (not sure if replace requires a location to be set already):
embed.setAttribute('id', 'uniqueid');
var frame = document.getElementById('uniqueid');
frame.contentWindow.location.replace(link);
I am new to web development (and chrome extension development) and any help would be greatly appreciated! Thanks in advance.
I'd like to understand how can I make changes to the HTML of popup.html in a Chrome extension that reloads a given URL every x seconds and looks for a certain text in the webpage.
More precisely: the extension's UI has two buttons "Run" and "Stop", respectively running and stopping the reload-and-search function above.
I also wanted to include in the UI a "loading" gif to display when the user clicks on the "Run" button and the extension is searching for the text. The loading gif should disappear either when the user clicks on the "Stop" button (and the extension stops searching) or when the the text is found on the target website.
The loading gif is inside an invisible with id="searching" in popup.html:
<div id="searching" style="display: none;" align="center"><img src="loading.gif" style="width: auto; height: 30%"/></div>
and I tried to reach the desired outcome by adding in app.js two functions that change its attributes, as well as chrome.runtime.onMessage.addListener (in addition to backround.js):
function showSrc() {
document.getElementById('searching').style.display ='block';
}
function hideSrc() {
document.getElementById('searching').style.display ='none';
}
document.querySelector('.button-run').addEventListener('click', () => {chrome.runtime.sendMessage('start'); showSrc();});
document.querySelector('.button-stop').addEventListener('click', () => {chrome.runtime.sendMessage('stop'); hideSrc();});
chrome.runtime.onMessage.addListener(function(message, callback){
if(message === 'stop') {
hideSrc();
} else if(message === 'run') {
showSrc();
}
});
As you can see from app.js, when the user clicks on "Run" or "Stop", the script not only sends the respective messages to background.js for the extension to perform/stop its reload-and-search function, but also changes the attribute of the with id="searching" so that the loading gif is visible/invisible in the UI accordingly by calling showSrc() or hideSrc(), respectively.
However, this works fine only when I stay with the UI open in the tab where I launch the script. If I switch the tab while the extension is running, then the UI (popup.html) closes and when I reopen it by clicking on the extension's icon, loading.gif is gone although the extension is still running.
How can I fix this?
We have a Chrome extension download button on our site.
When you click it, it opens a popup that says 'Add extension', 'Cancel' etc.
http://i.imgur.com/RFuts0E.png
The image shows the popup I'm referring to.
It works fine, except for the cancel button opens a new tab and takes you to the plugins chrome store page.
I have no idea why it does this, or how to just get it to cancel.
The js:
chrome.webstore.install(webStoreURL, () => null, (error, errorCode) => {
window.open(PLUGIN_LINKS.Chrome, '_blank');
});
Any help is much appreciated.
Well, you indiscriminately try to open the Webstore page on "error". In fact, user clicking Cancel is one of many "error" conditions.
You need to analyze the errorCode to filter that out.
chrome.webstore.install(webStoreURL, () => null, (error, errorCode) => {
if (errorCode !== "userCanceled") {
window.open(PLUGIN_LINKS.Chrome, '_blank');
}
});
Note: as is obvious from the error code list, there are many other conditions that make opening the Web Store page useless. You should re-think this logic.
I have the following code to introduce my Chrome Extension.
// detect if this is the first time running
var first_run = false;
if (!localStorage['ran_before']) {
first_run = true;
localStorage['ran_before'] = '1';
}
// if not, start the intro() script
if (first_run) intro();
// intro script
function intro() {
window.open("intro/index.html", '_blank');
}
But sadly, when I click the extension, it doesn't open the popup.html but just opens the intro page.. it needs to keep the popup.html open and I'm sure there is a way to do this. I want to open them both at the same time.
What is the best way to do this?
the method you are using is valid and should work, but you should probably
just use the onInstalled event for consistency:
chrome.runtime.onInstalled.addListener(function(info){
if(info.reason == "install"){
console.log("Installed!");
}else if(info.reason == "update"){
console.log("Updated!");
}
});
It doesn't require new permissions, and will keep your install code clearly separated from the rest of your code.
While Marc Guiselin's answer is excellent, it may be useful to know how to open a tab without closing a popup.
You could open the tab in the background, that way it won't close your popup.
chrome.tabs.create({
url: chrome.runtime.getURL("intro/index.html"),
active: false
});
In general, you should avoid using window.open in extensions and use chrome.tabs and chrome.windows API instead.
I got this problem during development of my own addon, but I get the same with the reddit example, so I'll use that for simplicity.
Using the exact code from the example found here, this is what happens.
Reddit Example
This example add-on creates a panel containing the mobile version of Reddit. When the user clicks on the title of a story in the panel, the add-on opens the linked story in a new tab in the main browser window.
To accomplish this the add-on needs to run a content script in the context of the Reddit page which intercepts mouse clicks on each title link and fetches the link's target URL. The content script then needs to send the URL to the add-on script.
main.js:
var data = require("self").data;
var reddit_panel = require("panel").Panel({
width: 240,
height: 320,
contentURL: "http://www.reddit.com/.mobile?keep_extension=True",
contentScriptFile: [data.url("jquery-1.4.4.min.js"),
data.url("panel.js")]
});
reddit_panel.port.on("click", function(url) {
require("tabs").open(url);
});
require("widget").Widget({
id: "open-reddit-btn",
label: "Reddit",
contentURL: "http://www.reddit.com/static/favicon.ico",
panel: reddit_panel
});
panel.js:
$(window).click(function (event) {
var t = event.target;
// Don't intercept the click if it isn't on a link.
if (t.nodeName != "A")
return;
// Don't intercept the click if it was on one of the links in the header
// or next/previous footer, since those links should load in the panel itself.
if ($(t).parents('#header').length || $(t).parents('.nextprev').length)
return;
// Intercept the click, passing it to the addon, which will load it in a tab.
event.stopPropagation();
event.preventDefault();
self.port.emit('click', t.toString());
});
The icon is displayed in the bar, and clicking it launches the panel. Clicking a link within the panel opens it in a new tab - just as described and expected.
Clicking the "next page" link within the tab successfully fetches the next page, within the panel - as expected.
Clicking a link on the 2nd page does NOT open it in a tab, it opens it WITHIN the panel.
Here's my guess: When the page reloads within the panel, it does not reload the script specified in the contentScriptFile. Does anyone else experience this? And is there a workaround?
I'm using SDK 1.0 and FF 5.0
Question cross-posted on the Addon forum here
Recieved this answer at the Mozilla forum, and will post here as well for future reference.
Perhaps you are seeing Bug 667664 - Panel content scripts don't work after reloading or changing location. I think the workaround is to load the content in an iframe.
Which I believe might be the case, I'll try this during the day and report back.
EDIT: iframe seems to do the trick