Zarkonnen
Zarkonnen

Reputation: 22478

How to load file from inside Firefox plugin

I'm working on a Firefox plugin which contains a file holding some HTML data. How do I load in this file as a string?

I can do

var contents = Components.utils.import("resource://stuff.html");

but that then tries to execute the XML file as Javascript. I just want its contents!

Upvotes: 10

Views: 6217

Answers (7)

BrunoLM
BrunoLM

Reputation: 100331

Using this function you can read files withing chrome scope.

function Read(file)
{
    var ioService=Components.classes["@mozilla.org/network/io-service;1"]
        .getService(Components.interfaces.nsIIOService);
    var scriptableStream=Components
        .classes["@mozilla.org/scriptableinputstream;1"]
        .getService(Components.interfaces.nsIScriptableInputStream);

    var channel=ioService.newChannel(file,null,null);
    var input=channel.open();
    scriptableStream.init(input);
    var str=scriptableStream.read(input.available());
    scriptableStream.close();
    input.close();
    return str;
}

var contents = Read("chrome://yourplugin/stuff.html");

Example loading CSS content and injecting on a page.

EDIT:

Just to update this because it is kinda handy !

let { Cc, Ci } = require('chrome');
function read(file){
    var ioService = Cc["@mozilla.org/network/io-service;1"]
        .getService(Ci.nsIIOService);
    var scriptableStream = Cc["@mozilla.org/scriptableinputstream;1"]
        .getService(Ci.nsIScriptableInputStream);

    var channel = ioService.newChannel2(file, null, null, null, null, null, null, null);
    var input = channel.open();
    scriptableStream.init(input);
    var str = scriptableStream.read(input.available());

    scriptableStream.close();
    input.close();
    return str;
}

Upvotes: 10

kizzx2
kizzx2

Reputation: 19213

I think you are looking for nsILocalFile.

Upvotes: 0

iammyr
iammyr

Reputation: 271

for me, the solution by BunoLM worked (thanks a million!) but only after using the "resource" protocol while passing the file url to the Read function, as for the reasons explained elsewhere.

I'm adding it here cause it took me a while to figure this out, so hopefully it's going to help some others ;)

Upvotes: 0

Greck
Greck

Reputation: 590

Asynchronous solution using XPCOM that can read from any scheme (chrome://, resource://, http://, ...):

const Cc = Components.classes;
const Ci = Components.interfaces;
const nsIIOService = Cc["@mozilla.org/network/io-service;1"]
                     .getService(Ci.nsIIOService);
function get_url_async(_url, /* function(data) */ _callback_success, /* function(status) */ _callback_fail)
{
    var channel=nsIIOService.newChannel(_url,null,null);
    channel.asyncOpen(
        {
            buffer:null,
            onStartRequest: function(/*in nsIRequest*/ aRequest, /*in nsISupports*/ aContext)
            {
                this.buffer = "";
            },
            onStopRequest: function(/*in nsIRequest*/ aRequest, /*in nsISupports*/ aContext, /*in nsresult*/ aStatusCode)
            {
                if(aStatusCode === Cr.NS_OK)
                    _callback_success(this.buffer);
                else
                    _callback_fail(aStatusCode);
            },
            onDataAvailable: function(/*in nsIRequest*/ aRequest, /*in nsISupports*/ aContext, /*in nsIInputStream*/ aInputStream, /*in unsigned long*/ aOffset, /*in unsigned long*/ aCount)
            {
                var scriptable_in_stream = Cc["@mozilla.org/scriptableinputstream;1"]
                                           .createInstance(Ci.nsIScriptableInputStream);
                scriptable_in_stream.init(aInputStream);
                this.buffer += scriptable_in_stream.read(aCount);
                scriptable_in_stream.close();
            }
        }, 
        /* context */ null
    );
}

Usage:

get_url_async(
    "resource://stuff.html", 
    function success(html)
    {
        // actions with html
    },
    function fail(status)
    {
        dump("Cannot get resource://stuff.html status code:"+status);
    }
);

Upvotes: 3

sumit_batcoder
sumit_batcoder

Reputation: 3379

I think these links would be quite helful... These tell how to implement Json as well as some stuff about the firefox interfaces

http://www.json.org/js.html

https://developer.mozilla.org/en/JSON

Hope it helps :)

Upvotes: 4

racetrack
racetrack

Reputation: 3756

For filesystem interactions in Firefox, use Mozilla XPCOM components. There are some wrappers for I/O XPCOM components such as JSLib and io.js

Using io.js it'd be something like:

var file = DirIO.get("ProfD"); // Will get you profile directory
file.append("extensions"); // extensions subfolder of profile directory
file.append("{1234567E-12D1-4AFD-9480-FD321BEBD20D}"); // subfolder of your extension (that's your extension ID) of extensions directory
// append another subfolder here if your stuff.xml isn't right in extension dir
file.append("stuff.xml");
var fileContents = FileIO.read(file);
var domParser = new DOMParser();
var dom = domParser.parseFromString(fileContents, "text/xml");
// print the name of the root element or error message
dump(dom.documentElement.nodeName == "parsererror" ? "error while parsing" : dom.documentElement.nodeName);

Upvotes: 6

Kranu
Kranu

Reputation: 2567

Components.utils.import is used for Javascript Code Modules.

If you want to use that command, you have to store the data as JSON.

JSON is somewhat similar to XML, in that it's designed for data, but JSON is easily integrated with Javascript code.

Upvotes: 0

Related Questions