I'm Writing a firefox addon that logs the current URL when pressing the addon icon at the toolbar.
When pressing the button, a background script will call the native app. That native app should write the current URL to a txt file. At this point, I'm able to write the text file when hitting the addon button. I'm able to write the contents of a variable created in background.js to a text file. But I can't pass the current URL to the background script.
The addon is based on the example addons from Mozilla:
https://github.com/mdn/webextensions-examples/tree/master/native-messaging
When using var url = window.location.href;I get the URL/Location of the loaded script.
Question: How can I pass the current URL to the background.js, so it will write the URL to a text file?
Below are the scripts:
Code background.js:
var url = window.location.href;
/*
On startup, connect to the "ping_pong" app.
*/
var port = browser.runtime.connectNative("ping_pong");
/*
Listen for messages from the app.
*/
port.onMessage.addListener((response) => {
console.log("Received: " + response);
});
/*
On a click on the browser action, send the app a message.
*/
browser.browserAction.onClicked.addListener(() => {
console.log("Console logger");
port.postMessage(url);
});
Code Manifest.json
{
"description": "ping_pong",
"manifest_version": 2,
"name": "Native messaging start Python",
"version": "1.0",
"icons": {
"48": "icons/message.svg"
},
"browser_specific_settings": {
"gecko": {
"id": "ping_pong#example.org",
"strict_min_version": "50.0"
}
},
"background": {
"scripts": ["background.js"]
},
"browser_action": {
"default_icon": "icons/message.svg"
},
"permissions": ["nativeMessaging"]
Related
I am trying to output all tabs in the current window by creating a firefox extension. It seems to be perfect to me, but still not able to get the output in the log. I am testing it as temporary addon from about:debugging.
I even tried to run the js code under "content_scripts", though it doesn't seem to be changing any content, but should run in the background. none of them works. Just want to know what I am missing
JavaScript
function logTabs(tabs) {
for (let tab of tabs) {
// tab.url requires the `tabs` permission
console.log(tab.url);
}
}
function onError(error) {
console.log(`Error: ${error}`);
}
var querying = browser.tabs.query({{currentWindow: true}});
querying.then(logTabs, onError);
Manifest
{
"manifest_version": 2,
"name": "Tablog",
"version": "1.0",
"description": "Prints the all tabs url in he console",
"icons": {
"48": "icons/icon48.png"
},
"background": {
"scripts": ["tablog.js"]
},
"permissions": [
"<all_urls>",
"tabs",
"activeTab"
]
}
NOTE: THIS IS MY FIRST CHROME EXTENSION AND THIS IS AN EXERCISE TO GET FAMILIAR WITH DEVELOPING EXTENSIONS.
I am making a chrome extension that parses a page. When the user clicks on the extension button, payload.js executes parsing the page, and in the popup they can select an option that will decide how the parsed info will be outputted.
I want that after they select an option, a function inside of payload.js executes and evaluates the option and formats the parsed information accordingly. Finally, it sends a message back to popup.js containing the formatted parsed info and popup.js displays it in a textbox inside of the popup.
I can communicate from payload.js to popup.js just fine, but cant seem to do the reverse.
Here is my code and what I have tried
popup.js
// Inject the payload.js script into the current tab after the popout has loaded
window.addEventListener('load', function (evt) {
chrome.extension.getBackgroundPage().chrome.tabs.executeScript(null, {
file: 'payload.js'
});;
});
// Listen to messages from the payload.js script and write to popout.html
chrome.runtime.onMessage.addListener(function (message) {
document.getElementById('output').textContent = message;
});
document.addEventListener('DOMContentLoaded', function() {
var opt = document.getElementById('generate_type');
opt.addEventListener('click', function() {
chrome.runtime.sendMessage(opt.value); //contains value of selection
});
});
payload.js
console.log("executed");
var parsed_info = [];
parse_info();
function parse_info()
{
//CODE that parses page
}
function generate_html()
{
//CODE that generates html output in var html
chrome.runtime.sendMessage(html);
}
function generate_reddit()
{
//CODE that generates MARKUP for reddit in var reddit
chrome.runtime.sendMessage(reddit);
}
function eval_opt(opt)
{
//evaluate if we should call generate_reddit or generate_html based on opt
}
chrome.runtime.onMessage.addListener(function (message) {
alert(message);
eval_opt(opt);
});
manifest.json
{
"manifest_version": 2,
"name": "Hello World",
"description": "A simple page-scraping extension for Chrome",
"version": "1.0",
"author": "#Gabriel",
"background": {
"scripts": ["popup.js"],
"persistent": true
},
"permissions": [
"tabs",
"http://*/",
"https://*/"
],
"browser_action": {
"default_icon": "logo.png",
"default_popup": "popup.html"
}
}
I want to create my own extension, which automatically downloads files from certain websites and saves it in the default downloads folder. I started with the "your first extension" example that creates a red border around the page. This worked!
Then I tried to use this example, which explains the download function, to download an image from google server and it just won't work. I also added a permission for "downloads" API in the manifest.json, but it does not help. The code breaks and everything after browser.downloads.download is not executed.
I also tried console.log(browser); and console.log(browser.downloads);. The browser object is defined, but browser.downloads is undefined.
Here is the code:
manifest.json:
{
"manifest_version": 2,
"name": "Permission Test",
"version": "1.0",
"description": "Downloads an image",
"applications": {
"gecko": {
"id": "permission#example.com"
}
},
"icons": {
"48": "icons/border-48.png"
},
"permissions": [
"activeTab",
"downloads"
],
"content_scripts": [
{
"matches": ["*://www.google.de/logos/doodles/2018/*"],
"js": ["script.js"]
}
]
}
script.js:
document.body.style.border = "10px solid red";
console.log('Extension started.');
function onStartedDownload(id) {
console.log('Started downloading: ${id}');
}
function onFailed(error) {
console.log('Download failed: ${error}');
}
var downloadUrl = "https://www.google.de/logos/doodles/2018/virginia-woolfs-136th-birthday-5857012284915712.6-l.png";
console.log(browser.downloads);
var downloading = browser.downloads.download({
url: downloadUrl
//filename: 'my-image-again.gif',
conflictAction: 'uniquify'
});
downloading.then(onStartedDownload, onFailed);
console.log('Extension execution finished.');
I am using Firefox 58 and Windows 7.
The downloads API is not available in content scripts, you probably want to move that code to a background page. I would start by reading this page to familiarize yourself with the overall structure of WebExtensions:
https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension
Not sure why I cannot retrieve info about current tab using getCurrent() when I navigate to, say, amazon.com or google.com and hit the browser icon for a browser action. Any hints on what I am missing?
MANIFEST:
{
"name": "testGetCurrentTab",
"version": "1.0",
"description": "",
"manifest_version": 2,
"icons": {
"48": "icons/icon-48.png"
},
"permissions": [
"tabs",
"<all_urls>"
],
"browser_action": {
"default_icon": "icon/icon-32.png"
},
"background": {
"scripts": ["background.js"]
}
}
BACKGROUND:
function displayInfo() {
function onGot(tabInfo) {
console.log('Inside onGot() ...');
console.log(tabInfo);
}
function onError(error) {
console.log(`Error: ${error}`);
}
var gettingCurrent = browser.tabs.getCurrent();
gettingCurrent.then(onGot, onError);
}
browser.browserAction.onClicked.addListener(displayInfo);
Here is the output:
Inside onGot() ... background.js:4:7
undefined background.js:5:7
Firefox Dev Edition 54 (64bit)
https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/getCurrent
You can get the currently active tab in the background.js file as well when doing
browser.tabs.query({active: true, windowId: browser.windows.WINDOW_ID_CURRENT})
.then(tabs => browser.tabs.get(tabs[0].id))
.then(tab => {
console.info(tab);
});
From MDN tabs.getCurrent():
Get a tabs.Tab containing information about the tab that this script is running in.
You can call this function in contexts where there is a browser tab, such as an options page. If you call it from a background script or a popup, it will return undefined.
The browserAction.onClicked event returns the active tab, you do not need another API call.
browser.browserAction.onClicked.addListener(function(tab) {
console.log(tab)
})
See the tab parameter for browserAction.onClicked listener.
I am working on simple Chrome Extension with the aim of opening every link on a page with the class of entry. Currently, I have this....
manifest.json:
{
"manifest_version": 2,
"name": "Hello World",
"description": "A simple Chrome Extension",
"version": "1.0",
"background": {
"scripts": ["openlinks.js"],
"persistent": true
},
"permissions": [
"tabs",
"http://*/",
"https://*/"
],
"browser_action": {
"default_icon": "logo.png"
}
}
openlinks.js:
chrome.browserAction.onClicked.addListener(function(tab) {
var linkArray = ['https://www.google.com', 'http://www.bbc.co.uk']; // your links
for (var i = 0; i < linkArray.length; i++) {
chrome.tabs.create({
url: linkArray[i]
});
}
});
Now I am trying to replace the array of sample links with an array of links from the current tab. Is it just a case of using standard JavaScript or jQuery to achieve this?
Take a look at Chrome Extensions Overview # Architecture, because you'll need both an Event Page and a Content Script to make this happen.
Here's an outline of how I would go about solving this:
Manifest structure (Event Page + activeTab permission).
"background": { "scripts": ["bg.js"], "persistent": false },
"permissions": ["activeTab"],
"browser_action": {},
When the browser action is clicked, the browser grants permission to access the current tab, which we use to inject the script. See Content Scripts # Programmatic Injection.
// bg.js
chrome.browserAction.onClicked.addListener(tab =>
chrome.tabs.executeScript({file: 'content.js'});
});
The content script has permission to access the DOM and use message passing, but is restricted from most of the extension APIs (in particular chrome.tabs).
// content.js
message = {}
message.links = [...document.querySelectorAll(
'div.question-summary a.question-hyperlink')].map(e=>e.href);
chrome.runtime.sendMessage(message);
The background page listens for the message.
// bg.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
request.links.forEach(link => chrome.tabs.create({url: link});
});