Content script from Firefox add-on doesn't write to IndexedDB - javascript

I'm developing Firefox add-on which has some content scripts to save data to IndexedDB. Same code works perfectly fine in Chrome extension, but not in Firefox extension. On Firefox everything works fine until part where data has to be written to database.
index.js
var data = require("sdk/self").data;
var pageMod = require("sdk/page-mod");
var { indexedDB } = require('sdk/indexed-db');
var request = indexedDB.open("myDatabase");
request.onerror = function(event) {
console.log("Failure.");
};
request.onsuccess = function(event) {
console.log("Success.");
};
pageMod.PageMod({
include: "*",
contentScriptWhen: "start",
//contentScriptFile: ["./js/jquery.min.js", "./js/jquery-ui.min.js", "./js/Dexie.min.js", "./js/content-script.js"]
contentScriptFile: [data.url("js/jquery.min.js"), data.url("js/content-script.js"), data.url("js/jquery-ui.min.js"), data.url("js/Dexie.min.js")],
contentStyleFile: [data.url("css/jquery-ui.min.css")]
});
content-script.js // part where it doesn't work in Firefox
function transition(location, time, date) {
var db = new Dexie("myDatabase");
db.version(1).stores({
likes: 'url, date, time'
});
db.open();
db.likes.add({url: location, date: date, time: time}).then (function(){
alert("Informations are added.");
}).catch( function(error) {
alert("There's an error: " + error);
});
}
I checked in Storage Inspector too, nothing is added to database. One more detail: I think that problem may be caused by script loading because I defined at start of content-script.js to load everything when DOM is ready (maybe, but I'm not sure if it's caused by that, I tried "start" , "ready" and "end" in contentScriptWhen parameter).
document.addEventListener("DOMContentLoaded", function(event) {
Everything in content-script.js is inside this event listener.

Dexie will by default use the indexedDB from window or self. In a firefox add-ons are not running in a window so probably Dexie doesn't find it. In Dexie v1.3.6, the indexedDB API can be provided in the constructor.
Try the latest Dexie v1.3.6 and do:
var idb = require('sdk/indexed-db');
var db = new Dexie("myDatabase", {
indexedDB: idb.indexedDB,
IDBKeyRange: idb.IDBKeyRange
});

Related

IndexedDB add entry shows as successful, but doesn't show up in chrome dev tools

I'm trying to write a simple JavaScript application to add an entry to indexedDB from a web form. For some reason, the add request shows as successful, but I can't see anything in the chrome developer window, even if I refresh the database. Here's the javascript that I'm writing.
$(document).ready(function() {
$("#addcsub").click(function(e){
e.preventDefault();
//add the contact
addContact($("#clast").val(), $("#cfirst").val(), $("#cphone").val(), $("#cemail").val());
});
});
document.addEventListener("DOMContentLoaded", function() {
if(!"indexedDB" in window){
return;
}
var openRequest = indexedDB.open("theDatabase",1);
openRequest.onupgradeneeded = function(e) {
var thisDB = e.target.result;
if(!thisDB.objectStoreNames.contains("contacts")) {
var objectStore = thisDB.createObjectStore("contacts", {keyPath:"contactid",autoIncrement: true});
objectStore.createIndex("contactid","contactid",{unique:true});
objectStore.createIndex("lastname","lastname", {unique:false});
objectStore.createIndex("firstname","firstname", {unique:false});
objectStore.createIndex("phone","phone", {unique:false});
objectStore.createIndex("email","email", {unique:false});
}
}
openRequest.onsuccess = function(e) {
db = e.target.result;
}
openRequest.onerror = function(e) {
console.log("Open Request Error");
}
},false);
function addContact(last,first,phone,email){
var transaction = db.transaction(["contacts"],"readwrite");
var store = transaction.objectStore("contacts");
var tc = {
lastname:last,
firstname:first,
phone:phone,
email:email
}
var request = store.add(tc);
request.onerror = function(e){
console.error(request.error);
}
request.onsuccess = function(e){ //this runs when I hit submit
console.log("Add Successful"); //this appears in the console
}
}
Update: I did some poking around and realized that my add transaction is aborting with an error of DOMexception code 22.
Update 2: for some reason, it works on other computers, just not my laptop.
I had issues with the devtools gui with indexedDb. You can try pulling the record through the console and see if it is there, but in the past I've had to close devtools and open it again for it to refresh.

Listen to image load in Add-On SDK

Is it possible to listen to the loading of images (or stylesheets) via the Mozilla Add-On SDK?
Having the user load a new URL can be found via the Page-Mod module, AJAX calls via overriding XMLHttpRequest.prototype.*().
Yet both only listen to loading of entirely new pages, not to the attached images of a page. Also, the image source might be changed for example in Javascript.
(It might be possible to use a http-on-modify-request, as pointed to here, but how can you access the nsIHttpChannel's URL and parameters?)
You can listen to every network request via
var {Cc, Ci} = require("chrome");
var httpRequestObserver = {
observe: function(subject, topic, data) {
if (topic == "http-on-modify-request") {
var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
var myURL = httpChannel.URI.spec;
console.log("url: " + myURL);
}
},
register: function() {
var observerService = Cc["#mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.addObserver(this, "http-on-modify-request", false);
},
unregister: function() {
var observerService = Cc["#mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
observerService.removeObserver(this, "http-on-modify-request");
}
};
httpRequestObserver.register();
exports.onUnload = function(reason) {
httpRequestObserver.unregister();
};
See also Firefox Addon observer http-on-modify-request not working properly.
URI access
The nsIHttpChannel extends nsIChannel, which has a URI Attribute of type nsIURI, which has a spec attribute that contains the whole URL (including schema, parameters, ref, etc).

firefox addon sdk: get page load time

When using this Firefox Addon SDK example:
var tabs = require("sdk/tabs");
tabs.open({
url: "http://www.example.com",
onReady: runScript
});
function runScript(tab) {
tab.attach({
contentScript: "document.body.style.border = '5px solid red';"
});
console.log(tab.title);
}
How can I get the page load time and print it to the console?
(like the app.telemetry Addon does - http://www.apptelemetry.com/de/page-speed-monitor.html)
Just use Navigation Timing API:
window.onload = function(){
setTimeout(function(){
var t = performance.timing;
console.log(t.loadEventEnd - t.responseEnd);
}, 0);
}
Notice that it's a Javascript API so it must run inside a Content Script (ie, it won't work inside your lib/main.js or index.js file).

How to call a content script function from main.js in firefox addon

I am new to Firefox addon development.
I need a way to call a contentscript function from main.js in firefox addon.
I have injected contentscript xyz.js on every opening webpage.
I want to call function abc() present in my contentscript xyz.js from my main.js on click of a button which i have place in navigation toolbar.
Below is my code.
Main.js
..
function addToolbarButton() {
var document = mediator.getMostRecentWindow('navigator:browser').document;
var navBar = document.getElementById('nav-bar');
if (!navBar) {
return;
}
var btn = document.createElement('toolbarbutton');
btn.setAttribute('id', 'mybutton-id');
btn.setAttribute('type', 'button');
btn.setAttribute('class', 'toolbarbutton-1');
btn.setAttribute('image', data.url('icon_16.png'));
btn.setAttribute('orient', 'vertical');
btn.setAttribute('label', 'Test');
btn.addEventListener('click', function() {
tabs.activeTab.attach({
//
abc() //here i want to call the function present in my contentscript
//
});
}, false)
navBar.appendChild(btn);
}
..
xyz.js
..
function abc(){
//here is my code logic
}
..
I came to know that message passing is way to do so but unable to implement in firefox.
Please help me i have got stuckd.
You cannot call the function directly, you need to send a message to the content script. Meaning something like that:
var worker = tabs.activeTab.attach({
...
});
// Some time later
worker.postMessage("doABC");
And in the content script:
self.on("message", function(message) {
if (message == "doABC")
abc();
});
For more information on communicating with content scripts see documentation.
According to documentation it should work this way;
However I have similar question Accessing pre-loaded content script from ActionButton not yet resolved.
// main.js
function handleClick(state) {
var myWorker = tabs.activeTab.attach({
});
myWorker.port.emit("initialize", "Message from the add-on");
}
// content.js
/*BEGIN Listen events coming from Add-on script*/
self.port.on("initialize", function () {
alert('self.port.on("initialize")');
return;
});

self.postMessage and onMessage don't work for a context item

I am trying to develop an addon for Firefox (using the latest version of JetPack) that sends some AJAX data on the click on a context item. However, unfortunately it seems I have hit some problem.
Please see the code below - I have tried to make it as simple as possible to understand.
// file main.js
var contextMenu = require("context-menu");
var data = require("self").data;
exports.main = function(options, callbacks) {
var contextMenuItemContentScriptFiles = [data.url("content.js")];
var menuItemSelection = contextMenu.Item({
label: "This is a test",
contentScriptFile: contextMenuItemContentScriptFiles,
context: contextMenu.SelectionContext(),
onMessage: function (testVar) {
alert(testVar);
}
});
};
// file content.js
self.on("click", function (node, data) {
alert("before posting");
self.postMessage("messagePosted");
alert("after posting");
});
The code alerts "before posting" and "after posting" but it doesn't alert "messagePosted" as I was expecting.
Can you please help me at finding the problem?
Found the problem.
I had to use console.log, not alert from the main script.

Categories

Resources