michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: 'use strict'; michael@0: michael@0: module.metadata = { michael@0: "stability": "stable" michael@0: }; michael@0: michael@0: const { Cc, Ci } = require('chrome'); michael@0: const { get, set, exists } = Cc['@mozilla.org/process/environment;1']. michael@0: getService(Ci.nsIEnvironment); michael@0: michael@0: exports.env = Proxy.create({ michael@0: // XPCOM does not provides a way to enumerate environment variables, so we michael@0: // just don't support enumeration. michael@0: getPropertyNames: function() [], michael@0: getOwnPropertyNames: function() [], michael@0: enumerate: function() [], michael@0: keys: function() [], michael@0: // We do not support freezing, cause it would make it impossible to set new michael@0: // environment variables. michael@0: fix: function() undefined, michael@0: // We present all environment variables as own properties of this object, michael@0: // so we just delegate this call to `getOwnPropertyDescriptor`. michael@0: getPropertyDescriptor: function(name) this.getOwnPropertyDescriptor(name), michael@0: // If environment variable with this name is defined, we generate proprety michael@0: // descriptor for it, otherwise fall back to `undefined` so that for consumer michael@0: // this property does not exists. michael@0: getOwnPropertyDescriptor: function(name) { michael@0: return !exists(name) ? undefined : { michael@0: value: get(name), michael@0: enumerable: false, // Non-enumerable as we don't support enumeration. michael@0: configurable: true, // Configurable as it may be deleted. michael@0: writable: true // Writable as we do support set. michael@0: } michael@0: }, michael@0: michael@0: // New environment variables can be defined just by defining properties michael@0: // on this object. michael@0: defineProperty: function(name, { value }) set(name, value), michael@0: delete: function(name) { michael@0: set(name, null); michael@0: return true; michael@0: }, michael@0: michael@0: // We present all properties as own, there for we just delegate to `hasOwn`. michael@0: has: function(name) this.hasOwn(name), michael@0: // We do support checks for existence of an environment variable, via `in` michael@0: // operator on this object. michael@0: hasOwn: function(name) exists(name), michael@0: michael@0: // On property get / set we do read / write appropriate environment variables, michael@0: // please note though, that variables with names of standard object properties michael@0: // intentionally (so that this behaves as normal object) can not be michael@0: // read / set. michael@0: get: function(proxy, name) Object.prototype[name] || get(name) || undefined, michael@0: set: function(proxy, name, value) Object.prototype[name] || set(name, value) michael@0: });