2

I spent 4 hours trying to find a solution for loading a file into my Firefox Add-on. But, with no success (((.

The code I have:

const {TextDecoder, OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
var decoder = new TextDecoder();
var promise = OS.File.read("C:\\test.txt");
promise = promise.then(function onSuccess(array) {
    alert(decoder.decode(array));
});

It's impossible to force the code above to run (((. What am I doing wrong?

Makyen
  • 31,849
  • 12
  • 86
  • 121
Greccy
  • 23
  • 4
  • Have you tried wrapping `OS.File.read()` in a try/catch and checking if an `OS.File.Error` was thrown? https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/OSFile.jsm/OS.File.Error – Rob M. Sep 05 '16 at 20:44
  • What [kind of Firefox extension](https://developer.mozilla.org/en-US/Add-ons) are you making [ [tag:firefox-webextensions]] ([WebExtensions](https://developer.mozilla.org/en-US/Add-ons/WebExtensions), [[tag:fiirefox-addon-sdk]] [Add-on SDK](https://developer.mozilla.org/en-US/Add-ons/SDK), [ [tag:firefox-addon-restartless]] [Bootstraped](https://developer.mozilla.org/en-US/Add-ons/Bootstrapped_extensions), or [[tag:fiirefox-addon-overlay]] [Overlay/XUL/Legacy](https://developer.mozilla.org/en-US/Add-ons/Overlay_Extensions))? Please [edit] the appropriate tag into your question. – Makyen Sep 05 '16 at 21:09
  • What *exactly* was shown in the [Browser Console](https://developer.mozilla.org/en-US/docs/Tools/Browser_Console) (Ctrl-Shift-J, or Cmd-Shift-J on OSX) when you ran this code? – Makyen Sep 05 '16 at 21:12
  • You do not have a function handling rejection/failure. Add one. [OS.File.read()](https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/OSFile.jsm/OS.File_for_the_main_thread#OS.File.read()) rejects with a [OS.File.Error](https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/OSFile.jsm/OS.File.Error). At a minimum, you should have something like: `promise.then(onSuccess,function(reason){console.log('OSFile rejected reason:',reason);});` – Makyen Sep 05 '16 at 22:52
  • browser console is empty all the time ((( i'm using Overlay/XUL – Greccy Sep 06 '16 at 07:13

1 Answers1

0

The code you have basically works as written. However, that assumes that alert() is defined and there was no error when you tried to read the file. However, alert() will not normally be defined, unless you have defined it somewhere else in your code. What exactly the issue is would likely be determined if you looked in the Browser Console (Ctrl-Shift-J, or Cmd-Shift-J on OSX). Unfortunately, you have not included that information in the question.

Reference information:

Below is a complete Firefox Add-on SDK extension which twice reads and outputs to the console the file at B:\testFile.txt. The output in the console for the example text file included below is:

read-text-file:readTextFile: This is a text file line 1
Line 2
read-text-file:readUtf8File: This is a text file line 1
Line 2

index.js:

var {Cu} = require("chrome");
//Open the Browser Console (Used in testing/developmenti to monitor errors/console)
var utils = require('sdk/window/utils');
activeWin = utils.getMostRecentBrowserWindow();
activeWin.document.getElementById('menu_browserConsole').doCommand();
var buttons     = require('sdk/ui/button/action');
var button = buttons.ActionButton({
    id: "doAction",
    label: "Do Action",
    icon: "./myIcon.png",
    onClick: doAction
});
//Above this line is specific to the Firefox Add-on SDK
//Below this line will also work for Overlay/XUL and bootstrap/restartless add-ons
//const Cu = Components.utils; //Uncomment this line for Overlay/XUL and bootstrap add-ons
const { TextDecoder, OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
function doAction(){
    var fileName = 'B:\\textFile.txt'
    //Read the file and log the contents to the console.
    readTextFile(fileName).then(console.log.bind(null,'readTextFile:'))
                          .catch(Cu.reportError);
    //Do it again, using the somewhat shorter syntax for a utf-8 encoded file
    readUtf8File(fileName).then(console.log.bind(null,'readUtf8File:'))
                          .catch(Cu.reportError);
}
function readTextFile(fileName){
    var decoder = new TextDecoder();
    return OS.File.read(fileName).then(array => decoder.decode(array));
}
function readUtf8File(fileName){
    //Using the somewhat shorter syntax for a utf-8 encoded file
    return OS.File.read(fileName, { encoding: "utf-8" }).then(text => text);
}

package.json:

{
    "title": "Read a text file",
    "name": "read-text-file",
    "version": "0.0.1",
    "description": "Reads a text file in two different ways.",
    "main": "index.js",
    "author": "Makyen",
    "engines": {
        "firefox": ">=38.0a1",
        "fennec": ">=38.0a1"
    },
    "license": "MIT",
    "keywords": [
        "jetpack"
    ]
}

textFile.txt:

This is a text file line 1
Line 2
Makyen
  • 31,849
  • 12
  • 86
  • 121
  • @Greccy, It is strongly discouraged. I have not tried to use it in that manner on the main UI thread. It is possible to use OS.File that way if you use it in a worker thread. The text which [MDN has describing why it should be asynchronous is](https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/OSFile.jsm#F.A.Q.): "One thing that all developers need to remember is that the duration of a File I/O operation is unbounded. [continued] – Makyen Sep 06 '16 at 07:33
  • @Greccy, [continued] Depending on the current load of the kernel, the current disk activity, the current load of the bus, the current rotation speed of the disk, the amount of battery power, etc. operations can take an arbitrary amount of time. We are talking about several seconds to execute operations that look trivial, such as closing a file, or checking when it was last modified. If the operation is called on the main thread, this means that the whole user experience is stuck for several seconds, which is quite bad." – Makyen Sep 06 '16 at 07:33
  • is this code non-xul? because i did with xul with cut-off button only doAction(); my browser became laggy. i cudnt open add-ons tab and nothing was loaded ))) – Greccy Sep 06 '16 at 07:39
  • I'm not sure what you mean by that question. The code is JavaScript (a complete Firefox Add-on SDK based add-on. XUL is similar to HTML in that it describes the organization of elements. Both HTML and XUL work in conjunction with JavaScript. (I just saw your comment that you are using developing an overlay based add-on). You will need to not use some portions of the code. I will edit to make what parts are needed more clear. – Makyen Sep 06 '16 at 07:49
  • @Greccy, You will not use the *package.json* file, which is specific to the Firefox Add-on SDK. You can use everything in the *index.js* file starting with and below the line `const Cu = Components.utils;` (which should be uncommented, or a similar line used elsewhere in your code). The lines above that are specific to the Add-on SDK (these lines open the Browser console and set up the toolbar button, both of which are done somewhat differently in overlay/XUL and bootstrap/restartless add-ons). – Makyen Sep 06 '16 at 08:03
  • @Greccy, Unless you have specifically made it such that it would work, one of the more likely things that was preventing your code from working was the call to `alert()`. That is not a function which would normally be available just by calling it as `alert()`. In general, particularly in an overlay/XUL or bootstrapped add-on, you would need to have some code that set up your being able to do so. – Makyen Sep 06 '16 at 08:14
  • i did my XUL to Firefox Webextensions. But there is other stuff i cant use imports like Components.utils (((. I see Chrome Extensions more easy to develop than FF ((( Alone zip -> xpi -> zip makes me crazy – Greccy Sep 07 '16 at 11:21
  • ok Add-on SDK with help of jpm. FInally done my extensions. Thnx Makyen! – Greccy Sep 07 '16 at 15:02