I would like to build an Firefox extension which after users click it, a web page is dynamically constructed and opened in a new tab.
In "tab" API, I only saw tab.open() open a hyperlink to a remote website. Can I construct a JavaScript variable contains all the HTML contents (Like var page = "blahblah....") and open it? How to do that?
You don't have to dynamically construct it, just put a htm page in your addon and then the link to it will be resource://your addon id/blah.htm. This addon here creates a page: addons.mozilla.org/en-US/firefox/addon/twitch-alarm
You can also create an about:blah url to your page, this shows how to do it without the sdk: github.com/Noitidart/ZooniverseXpert
You don't have to create a html page dynamically but put a html page in your addon and refer it when you open a tab.
tabs.open({
url : self.data.url("js/error.html"),
onReady : function(tab) {
var errorWorker = tab.attach({
contentScriptFile : self.data.url("js/error.js")
});
errorWorker.port.emit("error_page",message);
}
});
Here I am displaying an error page which is stored in my addon and attaching a content script file to dynamically change the contents of html page through message passing between main.js and error page.
Hope it is of some use to you.
Related
I have made an extension for chrome, which opens a specific website when new tab is opened. However it works fine with chrome, but when the same extension (with changes in manifest to make it compatible with edge) is tested on microsoft edge, then on opening a new tab it loads the website, but also loads the url in the website, which I don't want. I want to website to be loaded, but not the URL, as chrome doesn't load the url. I have done something like :
CHROME:
chrome.tabs.onCreated.addListener(
function(tab){
var newTabURL = {url: 'http://www.example.com'};
if(tab.url === "chrome://newtab/")
{
// chrome.tabs.update(newTabURL);
}
console.log(tab.url);
}
);
EDGE:
function handleCreated(tab) {
var newTabURL = {url: 'https://www.example.com'};
browser.tabs.update(newTabURL);
}
browser.tabs.onCreated.addListener(handleCreated);
When a new tab is opened, the url is loaded, but I dont want the url to be shown.
It is against Microsoft's Extension policy that any Extension which tries to override a Net Tab Page it wouldn't be approved into Store and you wont be able to publish it.
Coming to your problem, it is not possible as of now to make the Address Bar blank or not to show any url.
I have an addon that places an ActionButton on the toolbar. When the ActionButton is clicked the code below is run.
The code opens a new tab and provides some html and js, this acts as the addon's UI.
The url of the new tab is:
resource://jid1-qljswfs6someid-at-jetpack/addon-firefox/data/html/view.html
If I copy/paste that url into another new tab manually, the html displays but the js logic is not loaded. Is there a way to do this without clicking the ActionButton? So I could maybe bookmark the addon instead of having the ActionButton take up space.
Code:
Tabs.open({
url: require("sdk/self").data.url('html/view.html'),
onReady: function onReady(tab) {
worker = tab.attach({
contentScriptFile: [
require("sdk/self").data.url.get('lib/lib1.js'),
require("sdk/self").data.url.get('js/lib1.js')
],
onMessage: function(message) {
console.log('stuff done');
}
});
}
});
In order to run it whenever the site from data.url('html/view.html') is loaded you would have to use page-mod instead of manually attaching to the document to the tab.
Your include pattern would be something like data.url('html/view.html') + "*", so it also attaches to the page if there is a hash or a query to the document.
I just completed the YouTube API tutorials on Codecademy and successfully managed to display results relating to a given 'q' value in the console window provided using the following code:
// Helper function to display JavaScript value on HTML page.
function showResponse(response) {
var responseString = JSON.stringify(response, '', 2);
document.getElementById('response').innerHTML += responseString;
}
// Called automatically when JavaScript client library is loaded.
function onClientLoad() {
gapi.client.load('youtube', 'v3', onYouTubeApiLoad);
}
// Called automatically when YouTube API interface is loaded (see line 9).
function onYouTubeApiLoad() {
// This API key is intended for use only in this lesson.
// See http://goo.gl/PdPA1 to get a key for your own applications.
gapi.client.setApiKey('AIzaSyCR5In4DZaTP6IEZQ0r1JceuvluJRzQNLE');
search();
}
function search() {
// Use the JavaScript client library to create a search.list() API call.
var request = gapi.client.youtube.search.list({
part: 'snippet',
q: "Hello",
});
// Send the request to the API server,
// and invoke onSearchRepsonse() with the response.
request.execute(onSearchResponse);
}
// Called automatically with the response of the YouTube API request.
function onSearchResponse(response) {
showResponse(response);
}
and:
<!DOCTYPE html>
<html>
<head>
<script src="search.js" type="text/javascript"></script>
<script src="https://apis.google.com/js/client.js?onload=onClientLoad" type="text/javascript"></script>
</head>
<body>
<pre id="response"></pre>
</body>
</html>
The problem I am having now is that I have taken this code and put it into my own local files with the intention of furthering my understanding and manipulating it work in a way which suits me, however it just returns a blank page. I assume that it works on Codecademy because they use a particular environment and the code used perhaps only works within that environment, I am surprised they wouldn't provide information on what changes would be required to use this outside of their given environment and was hoping someone could shed some light on this? Perhaps I am altogether wrong, if so, any insight would be appreciated.
Browser Console Output:
Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('file://') does not match the recipient window's origin ('null').
I also had the same problem but it was resolved when I used Xampp. What you have to do is install xampp on your machine and then locate its directory. After You will find a folder named "htdocs". Just move your folder containing both js and HTML file into this folder. Now you have to open Xampp Control Panel and click on start button for both - Apache and SQL server. Now open your browser and type in the URL:
http://localhost/"(Your htdocs directory name containing both of your pages)"
After this, click on .html file and you are done.
In my Grails application, a user can click on a g:link which will call my controller to export certain data to a CSV file. This works with no problems.
I then moved that button to a jQuery dialog box and, when the button is clicked, I use
${remoteFunction(action:'export', onSuccess:'closeMe();', id:courseInstance?.id)}
to call the same controller method and close the dialog box. I've confirmed that the method is actually called, and the dialog box closes. The user is not prompted with the CSV dowmload, however. I'm assuming this has something to do with the remoteFunction, but I'm not really sure. Can anyone explain why this might happen, and a potential fix?
Thanks!
With AJAX requests you can't handle to download content as attachment and so it can't trigger the Save As dialog.
There are a couple of workarounds for this:
Use a plain g:link as before and bind the 'closeMe();' function to the 'click' event. The problem is that you have no control on error or success response.
Use an iframe: You can create a temporary invisible iframe and set its location to the URL of the file to download. It also has the backside of not controlling the success/error response.
The code could be the same as in this answer:
<script type="text/javascript">
function downloadURL(url) {
var iframe;
var hiddenIFrameID = 'hiddenDownloader';
iframe = document.getElementById(hiddenIFrameID);
if (iframe === null) {
iframe = document.createElement('iframe');
iframe.id = hiddenIFrameID;
iframe.style.display = 'none';
document.body.appendChild(iframe);
}
iframe.src = url;
}
</script>
And the link
Export
I am trying to get page title on every page using new Firefox add-on builder. How can I do that?
Edit
More info
I want to get page title on every page load event .
It is actually the very first example for the tabs package:
var tabs = require("tabs");
for each (var tab in tabs)
console.log(tab.title);
See tab.title.
Edit: If you need to know the title of each page as it loads rather than capture the current state then you should use the page-mod package:
var pageMod = require("page-mod");
pageMod.PageMod({
include: "*",
contentScriptWhen: "end",
contentScript: 'console.log(document.title);'
});
The documentation has some info on how a content script can communicate with the add-on, e.g. to send it this page title.
If you are only interested in top-level documents then you can still use the tabs package:
var tabs = require("tabs");
tabs.on("ready", function(tab) {
console.log(tab.title);
});
"ready" events won't get fired if the page is served from back-forward cache.
'pageshow' event is the appropriate event to listen to.
var tabs = require("sdk/tabs");
function onOpen(tab) {
tab.on('pageshow', function(tab) {
console.log('title: '+ tab.title);
}
tabs.on('open', onOpen);