Mozilla Daaon: exchange variables between main.js -> MyContent.js -> MyScripts.js - firefox-addon

I' writing a addon that add functionality to a site.
But I need to parse variables between .js
main.js:
pageMod.PageMod({
include: ["*"],
contentScriptWhen: 'end',
contentScriptFile: data.url("MyContent.js"),
contentScriptOptions: {
showOptions: true,
dataUrl: data.url("MyContent.js") // To parse the URL-Path
}
});
MyContent.js:
//to read the URL like resource://.....:
var dataUrl=self.options.dataUrl.substring(0,self.options.dataUrl.lastIndexOf("/")+1)
var script = document.createElement("script");
script.type = "text/javascript";
script.src = dataUrl+"scripts.js";
window.document.head.appendChild(script);
The variable dataUrl exist in MyContent.js but not in MyScripts.js
I need the variable dataUrl in MyScripts.js to know the url for some images saved in the data-folder.
How can I define global variables that can been accessed from all scripts?
with worker can I comunicate between main.js and MyContent.js, but not with MyScripts.js

Related

Chrome Extension Manifest V3 inject\execute local script

I am trying to figure out how to add a script to a page via my simple chrome extension. Currently I have a script, mycoolscript.js which is a local file to my extension and I am using the following code (snippets including manifest) to add it to the current page.
I feel like I am close, the script tag is added to the head tag but when the onload fires I am seeing stating that coolObject is not defined. coolObject is returned from mycoolscript to the window. If I build a page manually or use tampermonkey this works perfectly. Any suggestions on what I might be doing wrong here?
manifest.json
"content_scripts": [
{
"matches": ["<all_urls>"],
"css": ["contentScript.css"],
"js": ["contentScript.js"]
}],
"web_accessible_resources": [
{
"resources": ["mycoolscript.js"],
"matches": ["<all_urls>"]
}
]
contentScript.js
function addMyCoolScript(){
var s = document.createElement('script');
s.src = chrome.runtime.getURL('mycoolscript.js');
(document.head || document.documentElement).appendChild(s);
s.onload = function () {
s.parentNode.removeChild(s);
onScriptLoaded();
};
}
function onScriptLoaded() {
let apikey = "ABC123"
let baseUrl = "example.com"
coolObject.initialize(apikey, {
baseUrl: baseUrl,
});
coolObject.runStartup();
coolObject.openSession();
}

How to inject script locally in firefox add-on

I have published a add-on in mozilla add-on website, it got rejected because of remote scripts.
lib/Main.js:
var data = require("sdk/self").data;
var pageMod = require("sdk/page-mod");
var _workers = [];
pageMod.PageMod({
include: "some url",
contentScriptWhen: "ready",
contentScriptFile: data.url("./inject.js"),
contentStyleFile: data.url("style.css"),
attachTo: 'top'
});
data/inject.js:
var script = document.createElement('script');
script.type = "text/javascript";
script1.src = "https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js";
document.body.appendChild(script);
var script2 = document.createElement('script');
script2.type = "text/javascript";
script2.src = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js";
document.body.appendChild(script2);
var script3 = document.createElement('script');
script3.type = "text/javascript";
script3.src = "resource://addon-id/addon-name/data/popup.js";
document.body.appendChild(script3);
Please help me to insert these scripts to the web content or insert these scripts locally from my addon.
And what is remote script?
All the code you use should be reviewable and immutable, google.com being controlled by a suspicious company, is not trustworthy, and can replace jquery.min.js with password/credit card collector, without Mozilla noticing.
To avoid suspicion, copy files required to your plugin's directory, and use them as:
var data = require("sdk/self").data;
var pageMod = require("sdk/page-mod");
pageMod.PageMod({
include: "*.mozilla.org",
contentScriptFile: [data.url("jquery.min.js"),
data.url("jquery-ui.js"),
data.url("popup.js")]
});
See page-mod manual, it has all needed instructions.

Console logging certain objects don't work when developing a Firefox extension using React

Console logging certain objects, like this.refs or the window object results in a TypeError: cyclic object value error in the terminal.
My code is pretty basic: I'm trying to change the html on a web page (placing a react component in it).
Main.js:
var pageMod = require("sdk/page-mod");
var self = require("sdk/self");
var { MatchPattern } = require("sdk/util/match-pattern");
// Create a page mod
// It will run a script whenever a ".org" URL is loaded
// The script replaces the page contents with a message
pageMod.PageMod({
include: /.*wikipedia.org\/wiki\/.*/,
contentScriptFile: [
self.data.url("react-with-addons.js"),
self.data.url("testing.js"),
],
contentScriptWhen: "ready",
// contentStyleFile: self.data.url("style.css"),
});
testing.js:
var AppContainer = React.createClass({displayName: "AppContainer",
componentDidMount: function() {
console.log(this.refs.myRef);
console.log(window);
},
render: function() {
console.log('rendering');
return (
React.createElement("div", {ref: "myRef"})
);
}
});
React.render(React.createElement(AppContainer, null), document.getElementById('content'));
After running cfx run, the logs in the componentDidMount do not display anything in the browser console, and the cyclic object value displays (tried to log the window object to the console). Why is it having difficulties?

How to parse a XML string in a Firefox addon using Add-on SDK

I am trying to create a FF AddOn that brings some XML data from a website. But I can't find a way to parse my RESPONSE. First I used DOMParser but I get this error:
ReferenceError: DOMParser is not defined.
Someone suggested to use XMLHttpRequest, because the parsing is done automatically but then I get this other error:
Error: An exception occurred. Traceback (most recent call last):
File
"resource://jid0-a23vmnhgidl8wlymvolsst4ca98-at-jetpack/api-utils/lib/cuddlefish.js",
line 208, in require
let module, manifest = this.manifest[base], requirer = this.modules[base]; TypeError: this.manifest is undefined
I really don't know what else to do. I must note that I am using the AddOn Builder to achieve this.
Below the code that doesn't seem to work.
Option 1:
exports.main = function() {
require("widget").Widget({
id: "widgetID1",
label: "My Mozilla Widget",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(event) {
var Request = require("request").Request;
var goblecontent = Request({
url: "http://www.myexperiment.org/search.xml?query=goble",
onComplete: function (response) {
var parser = new DOMParser();
var xml = parser.parseFromString(response.text, "application/xml");
var packs = xml.getElementsByTagName("packs");
console.log(packs);
}
});
goblecontent.get();
}
});
};
Option 2:
exports.main = function() {
require("widget").Widget({
id: "widgetID1",
label: "My Mozilla Widget",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(event) {
var request = new require("xhr").XMLHttpRequest();
request.open("GET", "http://www.myexperiment.org/search.xml?query=goble", false);
request.send(null);
if (request.status === 200) {
console.log(request.responseText);
}
}
});
};
DOMParser constructor isn't defined in the context of SDK modules. You can still get it using chrome authority however:
var {Cc, Ci} = require("chrome");
var parser = Cc["#mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
nsIDOMParser documentation.
That said, your approach with XMLHttpRequest should work as well. You used the new operator incorrectly however, the way you wrote it a new "require object" is being created. This way it should work however:
var {XMLHttpRequest} = require("xhr");
var request = new XMLHttpRequest();
Please consider using an asynchronous XMLHttpRequest object however, use request.onreadystatechange to attach your listener (the xhr module currently doesn't support other types of listeners or addEventListener).
If you use XMLHttpRequest (available via the xhr module) you can easily avoid the use of DOMParser. Bellow I provide an example supposing request is an XMLHttpRequest object which request is successfully completed:
Instead of:
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(request.responseText, "application/xml");
Use:
var xmlDoc = request.responseXML;
An then you can:
var packs = xmlDoc.getElementsByTagName("packs");
console.log(packs);
Or whatever.

Accessing local resources from a content script

Is there a way i can access local resources inside a script?
I need to access data.url('layout.html'), data.url('icon.png') and data.url('style.css') inside the contentScript handler.
exports.main = function() {
require("widget").Widget({
onClick: function() {
tabs.activeTab.attach({
contentScriptFile: [ data.url('jquery.js')],
contentScript:
"setTimeout(function(){ alert('asd');}, 100);",
});
}
});
}
I've ended up using cssUrl = data.url('alert.css'). In main.js i set this up, and in the script running client-side add a script having href=cssUrl.
Use contentScriptOptions to pass it to the content script, like this:
//main.js
contentScriptFile: [ data.url('jquery.js')],
contentScriptOptions: {
cssUrl: data.url('alert.css')
}
// jquery.js
console.log(self.options.cssUrl)

Resources