diff options
Diffstat (limited to 'tools/addon-sdk-1.3/packages/api-utils/lib/securable-module.js')
-rw-r--r-- | tools/addon-sdk-1.3/packages/api-utils/lib/securable-module.js | 782 |
1 files changed, 0 insertions, 782 deletions
diff --git a/tools/addon-sdk-1.3/packages/api-utils/lib/securable-module.js b/tools/addon-sdk-1.3/packages/api-utils/lib/securable-module.js deleted file mode 100644 index ea4df1a..0000000 --- a/tools/addon-sdk-1.3/packages/api-utils/lib/securable-module.js +++ /dev/null @@ -1,782 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Copyright (c) 2009-2010 the Mozilla Foundation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the Mozilla Foundation nor the names - * of its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ***** END LICENSE BLOCK ***** */ - -"use strict"; - -(function(global) { - const Cc = Components.classes; - const Ci = Components.interfaces; - const Cu = Components.utils; - const Cr = Components.results; - - var exports = {}; - - var ios = Cc['@mozilla.org/network/io-service;1'] - .getService(Ci.nsIIOService); - - var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"] - .createInstance(Ci.nsIPrincipal); - - // Even though manifest.py does some dependency scanning, that - // scan is done as part of an evaluation of what the add-on needs - // for security purposes. The following regexps are used to scan for - // dependencies inside a simplified define() callback: - // define(function(require, exports, module){ var a = require('a'); }); - // and are used at runtime ensure the dependencies needed by - // the define factory function are already evaluated and ready. - // Even though this loader is a sync loader, and could fetch the module - // as the require() call happens, it would differ in behavior as - // compared to the async browser case, which would make sure to execute - // the dependencies first before executing the define() factory function. - // So this dependency scanning and evaluation is kept to match the - // async behavior. - var commentRegExp = /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg; - var cjsRequireRegExp = /require\(["']([\w\!\-_\.\/]+)["']\)/g; - var cjsStandardDeps = ['require', 'exports', 'module']; - - function resolvePrincipal(principal, defaultPrincipal) { - if (principal === undefined) - return defaultPrincipal; - if (principal == "system") - return systemPrincipal; - return principal; - } - - // The base URI to we use when we're given relative URLs, if any. - var baseURI = null; - if (global.window) - baseURI = ios.newURI(global.location.href, null, null); - exports.baseURI = baseURI; - - // The "parent" chrome URI to use if we're loading code that - // needs chrome privileges but may not have a filename that - // matches any of SpiderMonkey's defined system filename prefixes. - // The latter is needed so that wrappers can be automatically - // made for the code. For more information on this, see - // bug 418356: - // - // https://bugzilla.mozilla.org/show_bug.cgi?id=418356 - var parentChromeURIString; - if (baseURI) - // We're being loaded from a chrome-privileged document, so - // use its URL as the parent string. - parentChromeURIString = baseURI.spec; - else - // We're being loaded from a chrome-privileged JS module or - // SecurableModule, so use its filename (which may itself - // contain a reference to a parent). - parentChromeURIString = Components.stack.filename; - - function maybeParentifyFilename(filename) { - var doParentifyFilename = true; - try { - // TODO: Ideally we should just make - // nsIChromeRegistry.wrappersEnabled() available from script - // and use it here. Until that's in the platform, though, - // we'll play it safe and parentify the filename unless - // we're absolutely certain things will be ok if we don't. - var filenameURI = ios.newURI(options.filename, - null, - baseURI); - if (filenameURI.scheme == 'chrome' && - filenameURI.path.indexOf('/content/') == 0) - // Content packages will always have wrappers made for them; - // if automatic wrappers have been disabled for the - // chrome package via a chrome manifest flag, then - // this still works too, to the extent that the - // content package is insecure anyways. - doParentifyFilename = false; - } catch (e) {} - if (doParentifyFilename) - return parentChromeURIString + " -> " + filename; - return filename; - } - - function getRootDir(urlStr) { - // TODO: This feels hacky, and like there will be edge cases. - return urlStr.slice(0, urlStr.lastIndexOf("/") + 1); - } - - exports.SandboxFactory = function SandboxFactory(defaultPrincipal) { - // Unless specified otherwise, use a principal with limited - // privileges. - this._defaultPrincipal = resolvePrincipal(defaultPrincipal, - "http://www.mozilla.org"); - }, - - exports.SandboxFactory.prototype = { - createSandbox: function createSandbox(options) { - var principal = resolvePrincipal(options.principal, - this._defaultPrincipal); - - return { - _sandbox: new Cu.Sandbox(principal, - options.filename ? - { sandboxName: options.filename } : - { } - ), - _principal: principal, - get globalScope() { - return this._sandbox; - }, - defineProperty: function defineProperty(name, value) { - this._sandbox[name] = value; - }, - getProperty: function getProperty(name) { - return this._sandbox[name]; - }, - evaluate: function evaluate(options) { - if (typeof(options) == 'string') - options = {contents: options}; - options = {__proto__: options}; - if (typeof(options.contents) != 'string') - throw new Error('Expected string for options.contents'); - if (options.lineNo === undefined) - options.lineNo = 1; - if (options.jsVersion === undefined) - options.jsVersion = "1.8"; - if (typeof(options.filename) != 'string') - options.filename = '<string>'; - - if (this._principal == systemPrincipal) - options.filename = maybeParentifyFilename(options.filename); - - return Cu.evalInSandbox(options.contents, - this._sandbox, - options.jsVersion, - options.filename, - options.lineNo); - } - }; - } - }; - - exports.Loader = function Loader(options) { - options = {__proto__: options}; - if (options.fs === undefined) { - var rootPaths = options.rootPath || options.rootPaths; - if (rootPaths) { - if (rootPaths.constructor.name != "Array") - rootPaths = [rootPaths]; - var fses = [new exports.LocalFileSystem(path) - for each (path in rootPaths)]; - options.fs = new exports.CompositeFileSystem({ - fses: fses, - metadata: options.metadata, - uriPrefix: options.uriPrefix, - name: options.name - }); - } else - options.fs = new exports.LocalFileSystem(); - } - if (options.sandboxFactory === undefined) - options.sandboxFactory = new exports.SandboxFactory( - options.defaultPrincipal - ); - if ('modules' in options) - throw new Error('options.modules is no longer supported'); - // pathAccessed used to know if a module was accessed/required - // by another module, and in that case, assigning the module value - // via a define callback is not allowed. - if (options.pathAccessed === undefined) - options.pathAccessed = {}; - if (options.globals === undefined) - options.globals = {}; - - this.fs = options.fs; - this.sandboxFactory = options.sandboxFactory; - this.sandboxes = {}; - this.modules = {}; - this.pathAccessed = options.pathAccessed; - this.defineUsed = {}; - this.globals = options.globals; - this.getModuleExports = options.getModuleExports; - this.modifyModuleSandbox = options.modifyModuleSandbox; - this.manifest = options.manifest || {}; - }; - - exports.Loader.prototype = { - _makeApi: function _makeApi(basePath) { - /* - * _makeApi() creates a pair of specialized require()/define() - * functions for use by the code that comes from 'basePath' (which is - * a resource: URI pointing to some module, e.g. main.js). This - * require/define pair knows what main.js is allowed to import, in - * particular it knows what the link-time module search algorithm has - * found for each imported name (so if they require "panel", they'll - * get the one from addon-kit, not from some other package). - * - * When some other module (e.g. panel.js) is loaded, they'll get a - * different require/define pair, specialized for them. - */ - var self = this; - let reqs; - if (basePath && (basePath in self.manifest)) - reqs = self.manifest[basePath].requirements; - - function syncRequire(module) { - if (reqs) { - // if we know about you, you must follow the manifest - if (module in reqs) - return loadMaybeMagicModule(module, reqs[module]); - // if you invoke chrome, you can go off-manifest and search - if ("chrome" in reqs) - return loadMaybeMagicModule(module, null); - throw new Error("Module at "+basePath+" not allowed to require"+"("+module+")"); - } else { - // if we don't know about you, you can do anything you want. - // You're going to have to search for your own modules, though. - return loadMaybeMagicModule(module, null); - } - } - - function loadMaybeMagicModule(moduleName, moduleData) { - /* - * If we get here, we're allowed to import this module, we just have - * to figure out how. - * - * 'moduleName' is the unmodified argument passed to require(), - * so it might be "panel" or "pkg/foo" or even "./bar" for relative - * imports. 'moduleData' is the manifest entry that tells us how - * we're supposed to import this module: usually it's an object with - * a .uri, but for certain "magic" modules it might be empty. If - * it's 'null' then we're supposed to search all known packages for - * it. - */ - - if (self.getModuleExports) { - /* this currently handles 'chrome' */ - let exports = self.getModuleExports(basePath, moduleName); - if (exports) - return exports; - } - if (moduleName == "self") { - /* The 'self' module is magic: when someone requires 'self', the - * module they get is supposed to be specialized for the *package* - * that they live in (so pkg1/foo.js will get 'self' for pkg1, - * while pkg2/bar.js will get a 'self' for pkg2). To accomplish - * this, we don't give them the real self.js module directly: - * instead, we load self.js and invoke its makeSelfModule() - * function, passing in the manifest's moduleData, which will - * include enough information to create the specialized module. - */ - if (!moduleData) { - // we don't know where you live, so we must search for your data - // resource://api-utils-api-utils-tests/test-self.js - // make a prefix of resource://api-utils-api-utils-data/ - let doubleslash = basePath.indexOf("//"); - let prefix = basePath.slice(0, doubleslash+2); - let rest = basePath.slice(doubleslash+2); - let slash = rest.indexOf("/"); - prefix = prefix + rest.slice(0, slash); - prefix = prefix.slice(0, prefix.lastIndexOf("-")) + "-data/"; - moduleData = { "dataURIPrefix": prefix }; - // moduleData also wants mapName and mapSHA256, but they're - // currently unused - } - if (false) // force scanner to copy self-maker.js into the XPI - require("./self-maker"); - let makerModData = {uri: self.fs.resolveModule(null, "self-maker")}; - if (!makerModData.uri) - throw new Error("Unable to find self-maker, from "+basePath); - let selfMod = loadFromModuleData(makerModData, "self-maker"); - // selfMod is not cached - return selfMod.makeSelfModule(moduleData); - } - - if (!moduleData) { - // search - let path = self.fs.resolveModule(basePath, moduleName); - if (!path) - throw new Error('Module "' + moduleName + '" not found'); - moduleData = {uri: path}; - } - - // Track accesses to this module via its normalized path. This lets - // us detect cases where foo.js uses define() with a callback that - // wants to return a new value for the 'foo' module, but something - // inside that callback (probably in some sub-function) references - // 'foo' too early. If this happens, we throw an exception when the - // callback finishes. The code for that is in define() below: search - // for self.pathAccessed . - if (!self.pathAccessed[moduleData.uri]) { - self.pathAccessed[moduleData.uri] = 0; - } - self.pathAccessed[moduleData.uri] += 1; - - if (moduleData.uri in self.modules) { - // already loaded: return from cache - return self.modules[moduleData.uri]; - } - return loadFromModuleData(moduleData, moduleName); // adds to cache - } - - function loadFromModuleData(moduleData, moduleName) { - // moduleName is passed solely for error messages: by this point, - // everything is controlled by moduleData - if (!moduleData.uri) { - throw new Error("loadFromModuleData with null URI, from basePath " - +basePath+" importing ("+moduleName+")"); - } - // any manifest-based permission checks have already been done - let path = moduleData.uri; - - let moduleContents = self.fs.getFile(path); - var sandbox = self.sandboxFactory.createSandbox(moduleContents); - self.sandboxes[path] = sandbox; - for (let name in self.globals) - sandbox.defineProperty(name, self.globals[name]); - var api = self._makeApi(path); - sandbox.defineProperty('require', api.require); - sandbox.defineProperty('define', api.define); - if (self.modifyModuleSandbox) - self.modifyModuleSandbox(sandbox, moduleContents); - /* set up an environment in which module code can use CommonJS - patterns like: - module.exports = newobj; - module.setExports(newobj); - if (module.id == "main") stuff(); - define("async", function() {return newobj}); - */ - sandbox.evaluate("var module = {exports: {}};"); - sandbox.evaluate("module.setExports = function(obj) {module.exports = obj; return obj;};"); - sandbox.evaluate("var exports = module.exports;"); - sandbox.evaluate("module.id = '" + path + "';"); - var preeval_exports = sandbox.getProperty("exports"); - self.modules[path] = sandbox.getProperty("exports"); - sandbox.evaluate(moduleContents); - - // We need to duplicate `exports` as Object.freeze throws an exception - // on objects coming from another sandbox. Bug 677768. - sandbox.evaluate( - "if (typeof module.exports === 'object')\n" + - " module.exports = " + - " Object.prototype.isPrototypeOf(module.exports) ? " + - " Object.freeze(module.exports) : " + - " Object.freeze(Object.create(module.exports));"); - - var posteval_exports = sandbox.getProperty("module").exports; - if (posteval_exports !== preeval_exports) { - /* if they used module.exports= or module.setExports(), get - the new value now. If they used define(), we must be - careful to leave self.modules[path] alone, as it will have - been modified in the asyncMain() callback-handling code, - fired during sandbox.evaluate(). */ - if (self.defineUsed[path]) { - // you can do one or the other, not both - throw new Error("define() was used, so module.exports= and " - + "module.setExports() may not be used: " - + path); - } - self.modules[path] = posteval_exports; - } - return self.modules[path]; - } - - // START support Async module-style require and define calls. - // If the only argument to require is a string, then the module that - // is represented by that string is fetched for the appropriate context. - // - // If the first argument is an array, then it will be treated as an array - // of dependency string names to fetch. An optional function callback can - // be specified to execute when all of those dependencies are available. - function asyncRequire(deps, callback) { - if (typeof deps === "undefined" && typeof callback === "undefined") { - // If we could require() the traceback module here, we could - // probably show the source linenumber. But really that should be - // part of the stack trace. - throw new Error("you must provide a module name when calling require() from "+basePath); - } else if (typeof deps === "string" && !callback) { - // Just return the module wanted via sync require. - return syncRequire(deps); - } else { - asyncMain(null, basePath, null, deps, callback); - return undefined; - } - } - - // The function that handles definitions of modules. Differs from - // require() in that a string for the module should be the first - // argument, and the function to execute after dependencies are loaded - // should return a value to define the module corresponding to the first - // argument's name. - function define (name, deps, callback) { - - // Only allow one call to define per module/file. - if (self.defineUsed[basePath]) { - throw new Error("Only one call to define() allowed per file: " + - basePath); - } else { - self.defineUsed[basePath] = true; - } - - // For anonymous modules, the namePath is the basePath - var namePath = basePath, - exports = {}, exported; - - // Adjust args if an anonymous module - if (typeof name !== 'string') { - callback = deps; - deps = name; - name = null; - } - - // If just a define({}) call (no dependencies), - // adjust args accordingly. - if (!Array.isArray(deps)) { - callback = deps; - deps = null; - } - - // If the callback is not an actual function, it means it already - // has the definition of the module as a literal value. - if (!deps && callback && typeof callback !== 'function') { - self.modules[namePath] = callback; - return; - } - - // Set the exports value now in case other modules need a handle - // on it for cyclical cases. - self.modules[namePath] = exports; - - // Load dependencies and call the module's definition function. - exported = asyncMain(name, namePath, exports, deps, callback); - - // Assign output of function to name, if exports was not - // in play (which asyncMain already figured out). - if (exported !== undefined) { - if (self.pathAccessed[namePath] > 1) { - // Another module already accessed the exported value, - // need to throw to avoid nasty circular dependency weirdness - throw new Error('Module "' + (name || namePath) + '" cannot use ' + - 'return from define to define the module ' + - 'after another module has referenced its ' + - 'exported value.'); - } else { - self.modules[namePath] = exported; - } - } - } - - // The function that handles the main async module work, for both - // require([], function(){}) calls and define calls. - // It makes sure all the dependencies exist before calling the - // callback function. It will return the result of the callback - // function if "exports" is not a dependency. - function asyncMain (name, namePath, exports, deps, callback) { - - if (typeof deps === 'function') { - callback = deps; - deps = null; - } - - if (!deps) { - deps = []; - // The shortened form of the async wrapper for CommonJS modules: - // define(function (require, exports, module) {}); - // require calls could be inside the function, so toString it - // and pull out the dependencies. - - // Remove comments from the callback string, - // look for require calls, and pull them into the dependencies. - // The comment regexp is not very robust, but good enough to - // avoid commented out require calls and to find normal, sync - // require calls in the function. - callback - .toString() - .replace(commentRegExp, "") - .replace(cjsRequireRegExp, function (match, dep) { - deps.push(dep); - }); - // Prepend standard require, exports, and module dependencies - // (and in that *exact* order per spec), but only add as many as - // was asked for via the callback's function argument length. - // In particular, do *not* pass exports if it was not asked for. - // By asking for exports as a dependency the rest of this - // asyncRequire code assumes then that the return value from the - // function should not be used as the exported module value. - deps = cjsStandardDeps.slice(0, callback.length).concat(deps); - } - - var depModules = [], - usesExports = false, - exported; - - // Load all the dependencies, with the "require", "exports" and - // "module" ones getting special handling to match the traditional - // CommonJS sync module expectations. - deps.forEach(function (dep) { - if (dep === "require") { - depModules.push(asyncRequire); - } else if (dep === "module") { - depModules.push({ - id: name - }); - } else if (dep === "exports") { - usesExports = true; - depModules.push(exports); - } else { - depModules.push(syncRequire(dep)); - } - }); - - // Execute the function. - if (callback) { - exported = callback.apply(null, depModules); - } - - if (exported !== undefined) { - if (usesExports) { - throw new Error('Inside "' + namePath + '", cannot use exports ' + - 'and also return a value from a define ' + - 'definition function'); - } else { - return exported; - } - } - return undefined; - }; - - return { - require: asyncRequire, - define: define - }; - // END support for Async module-style - }, - - // This is only really used by unit tests and other - // development-related facilities, allowing access to symbols - // defined in the global scope of a module. - findSandboxForModule: function findSandboxForModule(module) { - var path = this.fs.resolveModule(null, module); - if (!path) - throw new Error('Module "' + module + '" not found'); - if (!(path in this.sandboxes)) - this.require(module); - if (!(path in this.sandboxes)) - throw new Error('Internal error: path not in sandboxes: ' + - path); - return this.sandboxes[path]; - }, - - require: function require(module, callback) { - return (this._makeApi(null).require)(module, callback); - }, - - runScript: function runScript(options, extraOutput) { - if (typeof(options) == 'string') - options = {contents: options}; - options = {__proto__: options}; - var sandbox = this.sandboxFactory.createSandbox(options); - if (extraOutput) - extraOutput.sandbox = sandbox; - for (let name in this.globals) - sandbox.defineProperty(name, this.globals[name]); - var api = this._makeApi(null); - sandbox.defineProperty('require', api.require); - sandbox.defineProperty('define', api.define); - return sandbox.evaluate(options); - } - }; - - // this is more of a resolver than a filesystem, but test-securable-module - // wants to override the getFile() function to avoid using real URIs - exports.CompositeFileSystem = function CompositeFileSystem(options) { - // We sort file systems in alphabetical order of a package name. - this.fses = options.fses.sort(function(a, b) a.root > b.root); - this.uriPrefix = options.uriPrefix; - this.name = options.name; - this.packages = options.metadata || {}; - }; - - function isRelative(path) path.charAt(0) === "." - function isNested(path) ~path.indexOf("/") - function normalizePath(path) path.substr(-3) === ".js" ? path : path + ".js" - function relatifyPath(path) isRelative(path) ? path : "./" + path - function getPackageName(path) path.substr(0, path.indexOf("/")) - function getInPackagePath(path) path.substr(path.indexOf("/") + 1) - function isRelativeTo(path, base) 0 === path.indexOf(base) - function resolveTo(path, base) "." + path.substr(base.length) - - exports.CompositeFileSystem.prototype = { - getPackageURI: function getPackageURI(name) { - let uri = this.uriPrefix + name + "-lib/"; - return ios.newURI(uri, null, null).spec; - }, - resolveModule: function resolveModule(base, path) { - // If it is relative path we don't need to search anything - // as it should be module from the same package. - if (isRelative(path)) { - // If base is not provided then it's a main module with a relative - // path to we use `packageURI` as a base to resolve. - base = base || this.getPackageURI(this.name); - return this.resolveRelative(base, path); - } - - // If path contains only one part then we treat if it as - // require(PCKG/{{(package.json).main}} - if (!isNested(path)) - return this.resolveMain(path) || this.searchModule(path); - - // If path contains more then one part than we try to interpret that - // as `require(PCKG/module)` first and fall back to search. - return this.resolveModuleFromPackage(path) || this.searchModule(path); - - }, - resolveRelative: function resolveRelative(base, path) { - path = normalizePath(path); - let uri = ios.newURI(path, null, ios.newURI(base, null, null)); - - try { - let channel = ios.newChannelFromURI(uri); - channel.open().close(); - } catch (e) { - return null; - } - return uri.spec; - }, - searchModule: function seachModule(path) { - for each (let fs in this.fses) { - let id = fs.resolveModule(null, path); - if (id) - return id; - } - return null; - }, - resolveModuleFromPackage: function resolveModuleFromPackage(path) { - let name = getPackageName(path); - if (name in this.packages) { - let base = this.getPackageURI(name); - return this.resolveRelative(base, getInPackagePath(path)); - } - return null; - }, - resolveMain: function resolveMain(name) { - if (name in this.packages) { - let base = this.getPackageURI(name); - let path = relatifyPath(this.packages[name].main || "main"); - - // We need to make sure to strip out directory from the main if it - // contains "lib" part. Unfortunately if main out of the lib folder - // requiring main module will fail as it will be out of the mapped - // resource URI. - let dirs = this.packages[name].directories; - let lib = relatifyPath(dirs ? dirs.lib || "./lib" : "./lib"); - if (isRelativeTo(path, lib)) - path = resolveTo(path, lib); - - return this.resolveRelative(base, path); - } - return null; - }, - getFile: function getFile(path) { - return loadFile(path); - } - }; - - exports.LocalFileSystem = function LocalFileSystem(root) { - if (root === undefined) { - if (!baseURI) - throw new Error("Need a root path for module filesystem"); - root = baseURI; - } - if (typeof(root) == 'string') - root = ios.newURI(root, null, baseURI); - if (root instanceof Ci.nsIFile) - root = ios.newFileURI(root); - if (!(root instanceof Ci.nsIURI)) - throw new Error('Expected nsIFile, nsIURI, or string for root'); - - this.root = root.spec; - this._rootURI = root; - this._rootURIDir = getRootDir(root.spec); - }; - - exports.LocalFileSystem.prototype = { - resolveModule: function resolveModule(base, path) { - path = normalizePath(path); - - var baseURI; - if (!base || path.charAt(0) != '.') - baseURI = this._rootURI; - else - baseURI = ios.newURI(base, null, null); - - var newURI = ios.newURI(path, null, baseURI); - if (newURI.spec.indexOf(this._rootURIDir) == 0) { - var channel = ios.newChannelFromURI(newURI); - try { - channel.open().close(); - } catch (e if e.result == Cr.NS_ERROR_FILE_NOT_FOUND) { - return null; - } - return newURI.spec; - } - return null; - }, - getFile: function getFile(path) { - return loadFile(path); - } - }; - - function loadFile(path) { - var channel = ios.newChannel(path, null, null); - var iStream = channel.open(); - var ciStream = Cc["@mozilla.org/intl/converter-input-stream;1"]. - createInstance(Ci.nsIConverterInputStream); - var bufLen = 0x8000; - ciStream.init(iStream, "UTF-8", bufLen, - Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); - var chunk = {}; - var data = ""; - while (ciStream.readString(bufLen, chunk) > 0) - data += chunk.value; - ciStream.close(); - iStream.close(); - return {contents: data, filename: path}; - }; - - if (global.window) { - // We're being loaded in a chrome window, or a web page with - // UniversalXPConnect privileges. - global.SecurableModule = exports; - } else if (global.exports) { - // We're being loaded in a SecurableModule. - for (let name in exports) { - global.exports[name] = exports[name]; - } - } else { - // We're being loaded in a JS module. - global.EXPORTED_SYMBOLS = []; - for (let name in exports) { - global.EXPORTED_SYMBOLS.push(name); - global[name] = exports[name]; - } - } - })(this); |