add button to page with chrome extension - google-chrome

is it possible to add simple button with onclick event to a page with chrome extension?
for instance if I am looking at
google.com
var google = document.getElementById("main");
var button = document.createElement("button");
var text = document.createTextNode("test");
button.appendChild(text);
google.appendChild(button);
I see my button in it?

You can use that code in a content script set to run on specific webpages.
Content scripts are JavaScript files that run in the context of web
pages. By using the standard Document Object Model (DOM), they can
read details of the web pages the browser visits, or make changes to
them.

Related

Background scripts vs Content Scripts

I am trying to develop a chrome extension which saves the url of webpages opened in all tabs and then load them whenever needed. Now I know content scripts, background scripts and popup.js. Content scripts mainly deal with the content of the loaded webpage and they have less chrome api interactions, background scripts are executed in an isolated environment and we can use all chrome api methods, popup.js is simply javascript that runs in context of popup.html.
Now here is my problem, I have a button in popup.html named "save" and on click of that button I want to save all the webpage urls opened in multiple tabs under one window. How can I do that?
Should I write a content or a background script?
Sorry for my noobish question. I am new to chrome api. Any help/suggestions?
Neither content script or background page is needed. You could do that just in popup.js, since popup page actually runs in the same context with extension.
In your popup.js, just call chrome.tabs.query to get tab info, including url (you would need to declare tabs permissions in manifest.json). If you want to specify window id, either use WINDOW_ID_CURRENT or retrieve it through other ways (depends on your logic)
chrome.tabs.query({ windowId: YOUR_WINDOW_ID }, (tabs) => {
tabs.forEach((tab) => console.log(tab.url));
});

Open teamspeak server through extension button

I am working on a Chrome extension project and one of the button of the popup must open my TeamSpeak server on click.
The final HTML code of my button is :
Issue is my button open a new blank page with the address "ts3server://MYSERVER". If I manually copy and paste "ts3server://MYSERVER" in Chrome, it open TeamSpeak software as wished.
This can be achieved by adding (and removing) an invisible iframe.
function openExternalLink(uri) {
var iframe = document.createElement("iframe");
iframe.src = uri;
iframe.style.display = "none"; // Make sure it's hidden
document.body.appendChild(iframe); // This will trigger load => external request
iframe.remove(); // Cleanup
}
You need to create a button and add a click handler that calls this.
No need to disturb existing tabs for that.

How can I open my extension's pop-up with JavaScript?

I am trying to write a JavaScript function that will open my extension like when the extension icon is clicked. I know how to open my extension in a new tab:
var url = "chrome-extension://kelodmiboakdjlbcdfoceeiafckgojel/login.html";
window.open(url);
But I want to open a pop-up in the upper right corner of the browser, like when the extension icon is clicked.
The Chromium dev team has explicitly said they will not enable this functionality. See Feature request: open extension popup bubble programmatically :
The philosophy for browser and page action popups is that they must be triggered by user action. Our suggestion is to use the new html notifications feature...
Desktop notifications can be used progammatically to present the user with a small HTML page much like your popup. It's not a perfect substitution, but it might provide the type of functionality you need.
Chrome team did create a method to open the popup programmatically, but it's only enabled as a private API, and plans to make it generally available have stalled due to security concerns.
So, as of March 2018 as of now, you still can't do it.
Short answer is that you cannot open browserAction programmatically. But you can create a dialog with your content script which emulates your browserAction and display that isntead (programmatically). However you won't be able to access your extension's background page from this popup directly as you can from your popup.html. You will have to pass message instead to your extension.
As mentioned there is no public API for this.
One workaround I have come up with is launching the extension as an iframe inside a content script with a button click. Whereby the background script emits the extension URL to the content script to be set as the iframe's src, something like below.
background.js
browser.runtime.onMessage.addListener((request) => {
if (request.open) {
return new Promise(resolve => {
chrome.browserAction.getPopup({}, (popup) => {
return resolve(popup)
})
})
}
})
content-scipt.js
const i = document.createElement('iframe')
const b = document.createElement('button')
const p = document.getElementById('some-id')
b.innerHTML = 'Open'
b.addEventListener('click', (evt) => {
evt.preventDefault()
chrome.runtime.sendMessage({ open: true }, (response) => {
i.src = response
p.appendChild(i)
})
})
p.appendChild(b)
This opens the extension in the DOM of the page the script is running on. You will also need to add the below to the manifest.
manifest.json
....
"web_accessible_resources": [
"popup.html"
]
....
You could emulate the popup by displaying a fixed html element on the page in the same location the popup would be and style it to look like the popup.
I had the same requirement: When the user clicks on the extension icon a small popup should open. In my case, I was writing an extension which will give updates on selective stocks whenever the icon is clicked. This is how my popup looked.
If you were having the same requirement then please read the answer below.
This is how my manifest.json file looked.
All the heavy lifting was handled by manifest.json file only. There is a section browser_action inside which there is a key called default_popup, just put the name of the HTML file that you want the popup to display.
I wanted my extension to work on all the pages that's why I added the attribute matches under content_scripts. I really didn't need to put the jquery file jquery-3.2.1.js inside the js array but the extension manager was not allowing me to keep that array empty.
Hope this helps, do comment if you have any doubt regarding the answer.

mailto link not working in chrome extension popup

This issue drove me nuts for 2 days. I made a simple chrome extension which calls a server-side program that returns HTML that I then stuff into a div in the popup. It was all fine, except for the simple anchor link containing a "mailto:xxx#yyy.com" href. An email message composition window would not pop up.
Workaround: Add target="_blank" attribute
I would like to know why this is necessary.
It might have something to do with extensions running in separate processors from the browser, and therefore a target attribute is needed so that a new tab/window can be opened... there are some websites that don't work when displayed inside extension popups for this reason, because the extension frame won't navigate to certain pages...
I know this is an old question, but I ran into a similar situation. I had to send an email, but I had to do it with a button instead of a link and had to finagle this:
function sendEmail(){
var mail = 'mailto:xxx#yyy.com?subject=Subject&body=Body';
var newWin = window.open(mail);
setTimeout(function(){newWin.close()}, 100);
}
It's not ideal, because it opens a new window that's visible to the user instead of doing it instantly. In fact, my first attempt was this (which works in an HTML file, but doesn't work in my extension):
function sendEmail(){
var mail = 'mailto:xxx#yyy.com?subject=Subject&body=Body';
window.open(mail).close();
}
Not sure why adding a timer makes it work in this instance as opposed to just doing it like in a regular HTML file, but that worked for me so I thought I'd share.

Chrome browser extensions: How to activate page action for all outgoing links of a certain page?

I would like my page action to be activated for all the outgoing links from a certain page. How might I go about doing that? I've gone over the docs to no avail. Any pointers would be appreciated!
Google Chrome API doesn't have such API, but functionality you want may be implemented using standard Google chrome Extensions API.
You need to implement content script
Your content script should modify DOM of the page you want to handle and override all outgoing links with your custom javascript which will do some stuff and open clicked link.
To modify link href you can do something like this:
function processLink(element, newHref) {
var a = document.createElement("a");
a.href = newHref;
a.textContent = element.textContent;
a.title = element.title;
element.parentNode.replaceChild(a, element);
}
UPDATE 1.
Instead of newHref you can generate something like
a.href = "javascript:processOutgoingLinkClick('" + element.href + "')"
Function processOutgoingLinkClick should contain actual processing of the click.
Just a curiosity, why wont you use the Chrome Extensions Tab Events you can listen for onUpdated onCreated. When a user clicks on a link on the page it will go and fire an event within onUpdated.
So within your background.html, you can do:
chrome.tabs.onUpdated.addListener(function(tabId, info) {
if (info.status === 'loading')
console.log('Loading url ... ' + info.url)
});
Same thing for onCreated. Then while its loading, you can decide what to do with your pageAction.