Search code examples
javascriptfirefox-addoncode-injectiondom-events

How to organize a two-way communication with the Firefox extension code injection?


There is an extension for Firefox, which makes the injected JS code into the page.

Code for XUL:

window.addEventListener("load", function load(event){
document.addEventListener("TestEvnt", function (e) {
    var info = e.detail;
    if(info.cmd=='account_list') {
        consoleLog('... event account_list');
    }
}, false, true);
document.addEventListener("DOMContentLoaded", function (e) {
  var window = e.originalTarget.defaultView.wrappedJSObject;
  var inject = window.document.createElement('script');
  inject.type = 'text/javascript';
  inject.setAttribute('src','resource://apptab-notify/injscr.js');
  window.document.getElementsByTagName('head')[0].appendChild(inject);
}, false);
},false);

Code injscr.js:

var additionalInfo = {
        "cmd": 'account_list',
        "url": document.location.href
    };
var evt = document.createEvent('CustomEvent');
evt.initCustomEvent('TestEvnt', true, false, additionalInfo);
document.dispatchEvent(evt);

How to provide bi-directional communication, something to listen to code injection events from the extension? Without using Addon-SDK!


Solution

  • In injsrc.js:

    var additionalInfo = {
        "cmd": 'account_list',
        "url": document.location.href
    };
    
    var request = document.createTextNode(JSON.stringify(additionalInfo));
    request.addEventListener("something-response", function(event) {
        console.log('... something-response');
        var info=JSON.parse(event.target.nodeValue);
        $('body').css('background-color', info.color);
    }, false);
    document.head.appendChild(request);
    var event = document.createEvent("HTMLEvents");
    event.initEvent("something-query", true, false);
    request.dispatchEvent(event);
    

    In XUL:

    window.addEventListener('load', function(event) {
       document.addEventListener("something-query", function(event) {
            consoleLog('... something-query');
            var node = event.target;
            if (!node || node.nodeType != Node.TEXT_NODE) return;
            var info = JSON.parse(node.nodeValue);
            var doc = node.ownerDocument;
    
            if (info.cmd == 'account_list') {
                consoleLog('... event account_list');
                var event = doc.createEvent("HTMLEvents");
                event.initEvent("something-response", true, false);
                node.nodeValue = JSON.stringify({
                    'color': '#999'
                });
                node.dispatchEvent(event);
            } else if (info.cmd == 'page_options') {
                consoleLog('page_options');
            }
        }, false, true);
    }, false);
    

    Article helped MDN