Inject one line of JavaScript from firefox addon - javascript

I am completely new to FF extension creation, and I will be rather specific.
When I run a JS command in, for example, Firefox's built-in sandbox, it works just fine, so I would like to make a FF addon where on click the same JS command would execute. The command basically works in a web page:
javascript:$('.plus').click();
I suppose it doesn't have to work like this:
var Widget = require("widget").Widget;
var tabs = require('tabs');
exports.main = function() {
new Widget({
id: "user-widget-1",
label: "My Mozilla Widget",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(event) {
javascript:$('.plus').click();
}
});
};
Thanks.

$(.plus) is jQuery syntax so you probably want to load jQuery as a content script into your widget. And you want to run your code as a content script as well, e.g.:
var data = require("sdk/self").data;
new Widget({
id: "user-widget-1",
label: "My Mozilla Widget",
contentURL: "http://example.com/foo.html",
contentScriptFile: [data.url("jquery.js"), data.url("myScript.js")]
});
And data/myScript.js would be something like:
$(document).ready(function() {
$('.plus').click()
});
If you don't want the click to happen when the document loads but rather on a specific event happening in your extension, you might want to look into communicating with content scripts. I also recommend reading a general overview of content scripts.

Use Page-Mod to inject content-scripts into a web page, content-script linked in a widget only works in the widget content. Moreover the widget API is deprecated from FF 29, I suggest you to use a Action button instead.

Related

uwp javascript x-ms-webview webkitfullscreenchange event

I am using a x-ms-webview to display an embedded media website, It work great by the problem is I can't handle full screen event when user want to go to full screen.
In iframe i can using webkitfullscreenchange to handle this, but with x-ms-webview seem not work.
Anyone can explaint me why and How to handle full screen event came from media in x-ms-webview?
Thanks
We can interact with the content of the web view by using the InvokeScriptAsync method to invoke or inject script into the web view content, and the ScriptNotify event to get information back from the web view content.
To invoke the onwebkitfullscreenchange event inside the web view content, use the InvokeScriptAsync method.
To enable an external web page to fire the ScriptNotify event when calling window.external.notify, you must include the page's URI in the ApplicationContentUriRules section of the app manifest. (You can do this in Microsoft Visual Studio on the Content URIs tab of the Package.appxmanifest designer.) The URIs in this list must use HTTPS, and may contain subdomain wildcards (for example, https://.microsoft.com) but they cannot contain domain wildcards (for example, https://.com and https://.). The manifest requirement does not apply to content that originates from the app package, uses an ms-local-stream:// URI, or is loaded using NavigateToString.
For more info, refer Interacting with web view content.
For example:
<x-ms-webview id="webview" src="https://www.....com" width="1920" height="1080"></x-ms-webview>
<script src="js/main.js"></script>
The js code:
(function (evt) {
"use strict"
var ViewManagement = Windows.UI.ViewManagement;
var FullScreenSystemOverlayMode = ViewManagement.FullScreenSystemOverlayMode;
var ApplicationView = ViewManagement.ApplicationView;
var view = ApplicationView.getForCurrentView();
var webview = document.getElementById("webview");;
webview.addEventListener("MSWebViewFrameDOMContentLoaded", function () {
var op = webview.invokeScriptAsync("eval", "document.onwebkitfullscreenchange = function (evt) { window.external.notify('123'); }");
op.start();
});
webview.addEventListener("MSWebViewScriptNotify", function (evt) {
if (view.isFullScreen) {
view.exitFullScreenMode();
}
else {
view.tryEnterFullScreenMode();
}
});
})()

How can you replicate a chrome browser_action popup using firefox addon sdk?

I'm porting a chrome extension to firefox. I'm trying to create a button that shows a popup HTML just like chrome. This is what I have so far in the main index.js:
var panels = require("sdk/panel");
var buttons = require("sdk/ui/button/action");
var manifest = require('manifest.json');
var url = function(path) {
return self.data.url('../' + path); //get out of the "data" directory
};
var popupButton = buttons.ActionButton({
id: "show-popup",
label: manifest.browser_action.default_title,
icon: {
"16": url("icon16.png"),
"32": url("icon32.png"),
"64": url("icon64.png")
},
onClick: function(){
//this doesn't work for debugging JS
//tabs.open(url(manifest.browser_action.default_popup));
//reload the content, like chrome, and show the popup
popup.contentURL = 'about:blank';
popup.contentURL = url(manifest.browser_action.default_popup);
popup.show();
}
});
var popup = panels.Panel({
contentURL: url(manifest.browser_action.default_popup),
position: popupButton
//contentScriptFile: ... get from HTML?
});
The buttons shows the HTML, however, the javascript which chrome makes you include via <script type="text/javascript" src="..."></script> tags doesn't appear to have access to self.port. Also, there seems to be no way to debug code in a panel. I've seen it suggested you open the HTML as a tab rather than a panel for debugging, but then it's running in a different environment and neither self nor addon are defined.
Unlike chrome, firefox wants you to give the javascript for the panel separately, using contentScript contentScriptFile as a Panel argument. One idea I had was to extract and remove all the <script> tags from the HTML, then give the remaining HTML to the panel and pass in the scripts separately. However, the panel wants a URL and not HTML. Also, it's starting to feel like too much hackery.
How can I replicate the chrome browser_action functionality in firefox? I would like to be able to use the same files in both chrome and firefox and not have a second build script which processes files depending on the target browser.
Is there a better way to debug a panel, like in chrome with right click and inspect?

Firefox Addon Pagemod not executed for youtube

I am building a small add-on that interacts with the youtube website.
For injecting a custom script inside the page I use the convenient page-mod like so :
var pageMod = require("sdk/page-mod");
pageMod.PageMod({
include: "*",
contentScript: "window.alert('injected');",
contentScriptWhen : 'start',
attachTo: ["existing", "top"],
onAttach: function(worker) {
console.log(worker.tab.url);
}
});
When I navigate through pages, the 'injected' message shows up each time a new page is loaded. But when it comes to youtube I got no result.
My visited urls are in order :
https://www.google.com -> injected
https://www.google.com/?q=youtube -> injected
https://www.youtube.com -> injected
https://www.youtube.com/watch?v=lnUeovQ68Tw -> nothing
https://www.youtube.com/results?search_query=dark+side+of+the+moon -> nothing
and now on I never get an injected message if I stay on Youtube...
I noticed that when changing from video to video the url change but the webpage doesn't seem to reload...
I was able to get the injected message on a youtube video when I manually reload it (cmd+r or f5).
As I searched I found this article on page-mod's attachTo which could have been a solution, but event with the attachTo: ["existing", "top"] line, the result was the same...
Do you have any idea ?
Thanks
While looking in another firefox extension lib I found a solution to my question :
background.js
pageMod.PageMod({
include : youtubeRegex,
contentScriptFile : 'permanent.js',
onAttach : function(worker){
worker.port.on('update', function(){
console.log('update from contentscript');
worker.port.emit('include'); // call the script update
});
},
contentScriptWhen : 'start',
});
permanent.js
// 1st line of the file
self.port.emit("update");
// stuff called once
// ...
// stuff called on each udpate
self.port.on('include', function(){
window.alert('injected');
});
This way I get a injected even in the youtube website.
Hope it will help :)
YouTube changes the content of their site using JS. I am not sure if there are any events fired when youtube changes the location. The only event I know of is popstate, which fires, whenever the user navigates using the back or forward buttons (see https://developer.mozilla.org/en-US/docs/Web/Events/popstate).

addon firefox - open window with specific dimensions

I have made an addon for firefox. I install it but i have two problems.I use windows.open because the panel isn`t suitable for me because if the user want to copy something in it, the panel is disappearing when he leaves it. So i have windows. I have this code:
var widgets = require("sdk/widget");
var windows = require("sdk/windows").browserWindows;
var self = require("sdk/self");
var widget = widgets.Widget({
id: "open window",
label: "test",
contentURL: self.data.url("favicon.ico"),
onClick: function() {
windows.open({
url: "http://www.example.com",
onOpen: function(window) {
}
});
}
});
I don`t know where to put the attributes of width,height,no scroll :/ in order to be displayd as a popup window.
And the second problem is that the button is displayed at the bar of addons.How it is possible to display it at the nav bar next to firebug?
The windows module does not support specifying window features.
You could use the unstable window/utils module and the openDialog function to provides.
Or you could get yourself chrome privileges and re-implement the stuff yourself. The implementation of openDialog is surprisingly pretty straight forward and can be borrowed from easily.
Either way, you'll need to wait for a window to actually fully load (newWindow.addEventListener("load", ...)) before you can safely interact with it. Or get somewhat hackish and listen for the first open event via the windows module.

In XUL, how do I know a browser-tag has finished loading?

I'm developing a firefox extension based on this tutorial which is a FF 2.0 extension (second part of the tutorial is at this url)
The main thing that is important is that it uses
<iframe id="contentview" src="http://www.ibm.com/developerworks/web" flex="2"/>
In the backend code, when clicking the GO button, this happens:
contentview.contentDocument.location.href = urlbox.value;
//Use Firefox XPath to get the raw text of the document
var doctext = contentview.contentDocument.evaluate(
"string(.)", document, null, XPathResult.STRING_TYPE, null).stringValue;
I get an error with the xpath, but that's not my question. The issue I have with FF 3.0 is that the contentDocument value refers to the old site loaded, not to the one loaded by the href-change.
So my question is: how can I create a similar window, but be notified someone when the loaded document is complete, so I can access its DOM?
Updated:
first you need to handle the load event of the window then you add an event listener to the iframe element
window.addEventListener("load",Listen,false);
function Listen()
{
var frame = document.getElementById("contentview");
frame.addEventListener("DOMContentLoaded", DomLoadedEventHandler, true);
}
function DomLoadedEventHandler() {
var frame = document.getElementById("contentview");
alert(frame.contentDocument.location.href);
}
replace "DomLoadedEventHandler" with your event handler name.
I recommend that you take a look at the official site of Mozilla to learn everything about Firefox extensions
http://developer.mozilla.com

Categories