I have a firefox extension that opens up a tab with a html file that is located in my data folder. The main.js does this:
function handleClick(state) {
tabs.open("login.html");
}
In main.js I require() a bunch of scripts to run as background scripts. This html file acts as the "login" for the extension. How can this html page have access to the background scripts?
It can't. You'll need to attach a content script to your login page and to send variables to it the standard way using port.
Also, does your code work? Don't you need to require(sdk/self).data to get access to login.html?
Here's an example of what you can do.
main.js
const { data } = require('sdk/self');
function handleClick(state) {
tabs.open({
url: data.url('login.html'),
onOpen: function(tab) {
var worker = tab.attach({
contentScriptFile: data.url('login.js')
});
worker.port.emit('foo', foo);
worker.port.on('bar', handleBar);
}
});
}
function handleBar(bar) {
// do something with bar;
}
login.js
self.port.on('foo', function(foo) {
// do something with foo
});
self.port.emit('bar', bar);
Related
I'm using the raw property to get formatted data from urls into the terminal, like this
$(function() {
var save_state = [];
var terminal = $('#term').terminal(function(command, term) {
term.pause();
url = ...;
$.get(url, function(result) {
term.echo(result, {raw:true}).resume();
});
}, { prompt: '>>', name: 'test', outputLimit: 1000 });
});
I'm wondering, how do I get it so when links in result are clicked, they load their data into the terminal the same way command data is loaded, rather than opening a new browser tab?
Thanks!
If you're using command that include URL or URI (for instance get foo.html or get https://example.com) you can use this:
terminal.on('click', '.terminal-output > div:not(.exception) a', function() {
// if you don't use `true` it will show the command like if you type it
// instead of `get` you can use any command you have that will
// fetch the url and display it on the terminal
terminal.exec('get ' + $(this).attr('href'), true);
return false; // prevent following the link
});
if you have different logic for displaying the urls you may need to dipicate the code from interpreter inside click event handler.
terminal.on('click', '.terminal-output > div:not(.exception) a', function() {
// duplicated code from your interpreter
term.pause();
var url = $(this).attr('href');
$.get(url, function(result) {
term.echo(result, {raw:true}).resume();
});
return false;
});
The magiczoom documentation describes callbacks that will execute at given times, but it's unclear how to use or assign those callbacks.
For example, how would I print a console message onZoomReady?
The closest I've found is a MagicZoom.defaults.onready property, but it's unclear how to set it via javascript (my attempts aren't working as expected).
The callbacks are configured via mzOptions, for example:
var mzOptions = {
onZoomReady: function() { … } }
;
Or:
var mzOptions = {};
mzOptions.onZoomReady = function() { … };
You can do something like this:
MagicZoom.registerCallback('onUpdate',
function() {
console.log('onUpdated', arguments[0], arguments[1], arguments[2]);
});
That will log stuff in the console like this:
onUpdated (id-of-mz-wraper) (html of old element) (html of new element)
Other options that you can use are as per the documentation:
MagicZoom.registerCallback('onZoomReady', function() {
console.log('onReady', arguments[0]);
});
MagicZoom.registerCallback('onZoomIn', function() {
console.log('onZoomIn', arguments[0]);
});
MagicZoom.registerCallback('onZoomOut', function() {
console.log('onZoomOut', arguments[0]);
});
I'm creating a Firefox addon using jetpack (jpm with node.js) to extend the Firefox developer tools to allow editing the current page's html. (I know this feature already exists; just trying to learn the ropes).
What API do I use to access the current page's HTML? I see that there is a Debugger.Source but I'm not sure if this is correct. If so, how do I retrieve this data?
As the first answer suggests, you can get at the html source using a content script injected the page. For example, here's a very simple approach that uses the tabs module to attach a content script into the current page:
const self = require('sdk/self');
const tabs = require('sdk/tabs');
let { ActionButton } = require("sdk/ui/button/action");
let button = ActionButton({
id: "my-button-id",
label: "Get HTML Source",
icon: {
"16": "chrome://mozapps/skin/extensions/extensionGeneric.png",
"32": "chrome://mozapps/skin/extensions/extensionGeneric.png"
},
onClick: (state) => {
let worker = tabs.activeTab.attach({
contentScript: 'self.port.emit("htmlSrc", {head: document.head.outerHTML, body: document.body.outerHTML});'
});
worker.port.on('htmlSrc', (result) => {
worker.destroy(); // clean up
let src = "<html>\n"+ result.head + "\n" + result.body + "\n</html>";
require('sdk/clipboard').set(src, 'text');
});
}
});
Direct access via SDK is impossible, but you can use content scripts to read and modify the page.
Using Kango, I have added an iFrame to a page. This iFrame points to an internal resource. I want this iFrame to be able to communicate with the background script. I would love to actually get the Kango API accessable from the iFrame, but if this is not possible I wonder how I might target this iFrame with a content script.
From your application that is inside the iFrame you can do:
top.window.postMessage({ type: 'EVENT', data: {} }, "*");
Then inside your Kango extension HTML link a JS file that has:
KangoAPI.onReady(function () {
window.addEventListener('message', function (event) {
console.log('host.js -> message', event);
kango.dispatchMessage('MessageToWindow', event);
});
document.body.onload = function () {
try {
document.getElementById('iFrameID').src = 'URL';
} catch (ex) {
throw ex;
}
}
});
Then inside the background.js
kango.addMessageListener('MessageToWindow', function (event) {
console.log('background.js -> MessageToWindow', event);
kango.browser.tabs.getCurrent(function (tab) {
console.log('background.js -> TAB', tab || 'NONE');
console.log('background.js -> TYPE', event.data.data.type || 'NONE');
console.log('background.js -> DATA', event.data.data.data || 'NONE');
tab.dispatchMessage(event.data.data.type, event.data.data.data);
});
});
Lastly, inside the content.js
kango.addMessageListener('EVENT', function(event) {
kango.console.log('got event');
});
Seems like a lot, but this was the only way that I could get it to work. Hope that helps!
I'm using Rails 3.2.16 and require.js ('requirejs-rails' gem).
My app has a module named ExpensesUI (here is a snippet of it):
$(function() {
define('ExpensesUI', ['OperationsUI'], function(operationsUI) {
var expenses = {
operationConsolidatedCheckbox: "#operation_consolidated",
parcelledNoCheckbox: "#operation_parcelled_no",
parcelledYesCheckbox: "#operation_parcelled_yes",
/* more things */
};
}
});
I can use it perfectly in any .js file with:
require(['ExpensesUI'], function(expensesUI) { console.log(expensesUI.parcelledNoCheckbox); });
But when I try the same require call in a .js.erb, I got 'undefined' logged.
It's not possible to use requirejs with *.js.erb files. Just because requirejs get files out of sprockets.
But instead, you can use named modules in *.html.erb views, for instance:
<script>
define('mymodule', function() {
'use strict';
return {
user: <%= #user.to_json.html_safe %>
};
});
</script>