fune/addon-sdk/source/lib/sdk/console/plain-text.js

136 lines
4 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.metadata = {
"stability": "unstable"
};
const { Cc, Ci } = require("chrome");
const self = require("../self");
const traceback = require("./traceback")
const prefs = require("../preferences/service");
const { merge } = require("../util/object");
const { partial } = require("../lang/functional");
const LEVELS = {
"all": Number.MIN_VALUE,
"debug": 20000,
"info": 30000,
"warn": 40000,
"error": 50000,
"off": Number.MAX_VALUE,
};
const DEFAULT_LOG_LEVEL = "error";
const ADDON_LOG_LEVEL_PREF = "extensions." + self.id + ".sdk.console.logLevel";
const SDK_LOG_LEVEL_PREF = "extensions.sdk.console.logLevel";
let logLevel;
function setLogLevel() {
logLevel = prefs.get(ADDON_LOG_LEVEL_PREF, prefs.get(SDK_LOG_LEVEL_PREF,
DEFAULT_LOG_LEVEL));
}
setLogLevel();
let logLevelObserver = {
observe: function(subject, topic, data) {
setLogLevel();
}
};
let branch = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService).
getBranch(null);
branch.addObserver(ADDON_LOG_LEVEL_PREF, logLevelObserver, false);
branch.addObserver(SDK_LOG_LEVEL_PREF, logLevelObserver, false);
function stringify(arg) {
try {
return String(arg);
}
catch(ex) {
return "<toString() error>";
}
}
function stringifyArgs(args) {
return Array.map(args, stringify).join(" ");
}
function message(print, level) {
if (LEVELS[level] < LEVELS[logLevel])
return;
let args = Array.slice(arguments, 2);
print(level + ": " + self.name + ": " + stringifyArgs(args) + "\n", level);
}
function errorMessage(print, e) {
// Some platform exception doesn't have name nor message but
// can be stringified to a meaningfull message
var fullString = ("An exception occurred.\n" +
(e.name ? e.name + ": " : "") +
(e.message ? e.message : e.toString()) + "\n" +
(e.fileName ? traceback.sourceURI(e.fileName) + " " +
e.lineNumber + "\n"
: "") +
traceback.format(e));
message(print, "error", fullString);
}
function traceMessage(print) {
var stack = traceback.get();
stack.splice(-1, 1);
message(print, "info", traceback.format(stack));
}
function PlainTextConsole(print) {
if (!print)
print = dump;
if (print === dump) {
// If we're just using dump(), auto-enable preferences so
// that the developer actually sees the console output.
var prefs = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefBranch);
prefs.setBoolPref("browser.dom.window.dump.enabled", true);
}
merge(this, {
log: partial(message, print, "info"),
info: partial(message, print, "info"),
warn: partial(message, print, "warn"),
error: partial(message, print, "error"),
debug: partial(message, print, "debug"),
exception: partial(errorMessage, print),
trace: partial(traceMessage, print),
dir: function dir() {},
group: function group() {},
groupCollapsed: function groupCollapsed() {},
groupEnd: function groupEnd() {},
time: function time() {},
timeEnd: function timeEnd() {}
});
// We defined the `__exposedProps__` in our console chrome object.
// Although it seems redundant, because we use `createObjectIn` too, in
// worker.js, we are following what `ConsoleAPI` does. See:
// http://mxr.mozilla.org/mozilla-central/source/dom/base/ConsoleAPI.js#132
//
// Meanwhile we're investigating with the platform team if `__exposedProps__`
// are needed, or are just a left-over.
this.__exposedProps__ = Object.keys(this).reduce(function(exposed, prop) {
exposed[prop] = "r";
return exposed;
}, {});
Object.freeze(this);
};
exports.PlainTextConsole = PlainTextConsole;