diff options
-rwxr-xr-x | common/bootstrap.js | 18 | ||||
-rw-r--r-- | common/components/commandline-handler.js | 12 | ||||
-rw-r--r-- | common/components/protocols.js | 18 | ||||
-rw-r--r-- | common/modules/base.jsm | 67 | ||||
-rw-r--r-- | common/modules/bookmarkcache.jsm | 8 | ||||
-rw-r--r-- | common/modules/highlight.jsm | 8 | ||||
-rw-r--r-- | common/modules/overlay.jsm | 4 | ||||
-rw-r--r-- | common/modules/prefs.jsm | 2 | ||||
-rw-r--r-- | common/modules/sanitizer.jsm | 6 | ||||
-rw-r--r-- | common/modules/services.jsm | 2 | ||||
-rw-r--r-- | common/modules/storage.jsm | 14 | ||||
-rw-r--r-- | common/modules/styles.jsm | 8 | ||||
-rw-r--r-- | common/modules/template.jsm | 2 | ||||
-rw-r--r-- | common/modules/util.jsm | 31 |
14 files changed, 122 insertions, 78 deletions
diff --git a/common/bootstrap.js b/common/bootstrap.js index 011edd14..68954ad9 100755 --- a/common/bootstrap.js +++ b/common/bootstrap.js @@ -16,7 +16,7 @@ const resourceProto = Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler); const categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager); const manager = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); -const storage = Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication); +const storage = Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication).storage; function httpGet(url) { let xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest); @@ -41,6 +41,7 @@ let addon = null; let basePath = null; let components = {}; let getURI = null; +var JSMLoader = storage.get("dactyl.JSMLoader", { get load() Cu.import }); function startup(data, reason) { dump("dactyl: bootstrap: startup " + reasonToString(reason) + "\n"); @@ -87,12 +88,12 @@ FactoryProxy.prototype = { }, unregister: function () { dump("dactyl: bootstrap: unregister: " + this.classID + " " + this.contractID + "\n"); - manager.unregisterFactory(this.classID, - this); + manager.unregisterFactory(this.classID, this); }, get module() { Object.defineProperty(this, "module", { value: {}, enumerable: true }); - Cu.import(this.url, this.module); + JSMLoader.load(this.url, this.module); + JSMLoader.registerGlobal(this.url, this.module.NSGetFactory); return this.module; }, createInstance: function (iids) { @@ -138,7 +139,6 @@ function init() { break; case "contract": components[fields[2]].contractID = fields[1]; - components[fields[2]].register(); break; case "resource": @@ -146,11 +146,13 @@ function init() { } } - Cc["@dactyl.googlecode.com/base/xpc-interface-shim"].createInstance() - Services.obs.notifyObservers(null, "dactyl-rehash", null); - Cu.import("resource://dactyl/base.jsm"); + JSMLoader.load("resource://dactyl/base.jsm", global); + + for each (let component in components) + component.register(); + require(global, "prefs"); require(global, "services"); diff --git a/common/components/commandline-handler.js b/common/components/commandline-handler.js index 3083af0f..cee31646 100644 --- a/common/components/commandline-handler.js +++ b/common/components/commandline-handler.js @@ -4,14 +4,14 @@ // given in the LICENSE.txt file included with this file. "use strict"; -const Ci = Components.interfaces, Cc = Components.classes; +var Ci = Components.interfaces, Cc = Components.classes; Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -const prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService) +var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService) .getBranch("extensions.dactyl."); -const appName = prefs.getComplexValue("appName", Ci.nsISupportsString).data; -const name = prefs.getComplexValue("name", Ci.nsISupportsString).data; +var appName = prefs.getComplexValue("appName", Ci.nsISupportsString).data; +var name = prefs.getComplexValue("name", Ci.nsISupportsString).data; function CommandLineHandler() { this.wrappedJSObject = this; @@ -45,9 +45,9 @@ CommandLineHandler.prototype = { }; if (XPCOMUtils.generateNSGetFactory) - const NSGetFactory = XPCOMUtils.generateNSGetFactory([CommandLineHandler]); + var NSGetFactory = XPCOMUtils.generateNSGetFactory([CommandLineHandler]); else - const NSGetModule = XPCOMUtils.generateNSGetModule([CommandLineHandler]); + var NSGetModule = XPCOMUtils.generateNSGetModule([CommandLineHandler]); var EXPORTED_SYMBOLS = ["NSGetFactory"]; // vim: set fdm=marker sw=4 ts=4 et: diff --git a/common/components/protocols.js b/common/components/protocols.js index 8b8069a5..ba89090b 100644 --- a/common/components/protocols.js +++ b/common/components/protocols.js @@ -12,16 +12,16 @@ * By Kris Maglione, ideas from Ed Anuff's nsChromeExtensionHandler. */ -const NAME = "protocols"; -const global = this; -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; +var NAME = "protocols"; +var global = this; +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cu = Components.utils; Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -const ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); -const systemPrincipal = Cc["@mozilla.org/systemprincipal;1"].getService(Ci.nsIPrincipal); +var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); +var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"].getService(Ci.nsIPrincipal); function dataURL(type, data) "data:" + (type || "application/xml;encoding=UTF-8") + "," + escape(data); function makeChannel(url, orig) { @@ -204,9 +204,9 @@ Shim.prototype = { }; if (XPCOMUtils.generateNSGetFactory) - const NSGetFactory = XPCOMUtils.generateNSGetFactory([AboutHandler, ChromeData, Dactyl, Shim]); + var NSGetFactory = XPCOMUtils.generateNSGetFactory([AboutHandler, ChromeData, Dactyl, Shim]); else - const NSGetModule = XPCOMUtils.generateNSGetModule([AboutHandler, ChromeData, Dactyl, Shim]); + var NSGetModule = XPCOMUtils.generateNSGetModule([AboutHandler, ChromeData, Dactyl, Shim]); var EXPORTED_SYMBOLS = ["NSGetFactory"]; // vim: set fdm=marker sw=4 ts=4 et: diff --git a/common/modules/base.jsm b/common/modules/base.jsm index 7d393be2..6f3a27db 100644 --- a/common/modules/base.jsm +++ b/common/modules/base.jsm @@ -4,10 +4,49 @@ // given in the LICENSE.txt file included with this file. "use strict"; -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; +if (!JSMLoader) + var JSMLoader = { + builtin: Components.utils.Sandbox(this), + globals: {}, + stale: {}, + load: function load(url, target) { + dump("dactyl: load: " + url + "\n"); + if (this.stale[url]) { + delete this.stale[url]; + dump("dactyl: load stale\n"); + + let global = this.globals[url]; + for each (let prop in Object.getOwnPropertyNames(global)) + try { + if (!set.has(this.builtin, prop) && global[prop] != this && global[prop] != set) + delete global[prop] + } + catch (e) {} + + Components.classes["@mozilla.org/moz/jssubscript-loader;1"] + .getService(Components.interfaces.mozIJSSubScriptLoader) + .loadSubScript(url, this.globals[url]); + dump("dactyl: load reloaded: " + url + "\n"); + } + Components.utils.import(url, target); + }, + purge: function purge() { + for (let [url, global] in Iterator(this.globals)) + this.stale[url] = true; + }, + registerGlobal: function registerGlobal(uri, obj) { + if (Cu.getGlobalForObject) + this.globals[uri] = Cu.getGlobalForObject(obj); + } + }; + +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cr = Components.results; +var Cu = Components.utils; + +Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication) + .storage.set("dactyl.JSMLoader", JSMLoader); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); try { @@ -98,7 +137,8 @@ let loaded = {}; let currentModule; function defineModule(name, params) { let module = Cu.getGlobalForObject ? Cu.getGlobalForObject(params) : params.__parent__; - defineModule.globals.push(module); + JSMLoader.registerGlobal(Components.stack.caller.filename, module); + module.NAME = name; module.EXPORTED_SYMBOLS = params.exports || []; defineModule.loadLog.push("defineModule " + name); @@ -115,7 +155,6 @@ function defineModule(name, params) { currentModule = module; } -defineModule.globals = []; defineModule.loadLog = []; Object.defineProperty(defineModule.loadLog, "push", { value: function (val) { defineModule.dump(val + "\n"); this[this.length] = val; } @@ -162,7 +201,7 @@ function endModule() { function require(obj, name, from) { try { defineModule.loadLog.push((from || "require") + ": loading " + name + " into " + obj.NAME); - Cu.import("resource://dactyl/" + name + ".jsm", obj); + JSMLoader.load("resource://dactyl/" + name + ".jsm", obj); } catch (e) { defineModule.dump("loading " + String.quote("resource://dactyl/" + name + ".jsm") + "\n"); @@ -176,7 +215,7 @@ function require(obj, name, from) { defineModule("base", { // sed -n 's/^(const|function) ([a-zA-Z0-9_]+).*/ "\2",/p' base.jsm | sort | fmt exports: [ - "ErrorBase", "Cc", "Ci", "Class", "Cr", "Cu", "Module", "Object", "Runnable", + "ErrorBase", "Cc", "Ci", "Class", "Cr", "Cu", "Module", "JSMLoader", "Object", "Runnable", "Struct", "StructBase", "Timer", "UTF8", "XPCOM", "XPCOMUtils", "array", "call", "callable", "ctypes", "curry", "debuggerProperties", "defineModule", "deprecated", "endModule", "forEach", "isArray", "isGenerator", @@ -478,7 +517,7 @@ function isSubclass(targ, src) { * @param {object|string|[object|string]} src The types to check targ against. * @returns {boolean} */ -const isinstance_types = { +var isinstance_types = { boolean: Boolean, string: String, function: Function, @@ -513,7 +552,7 @@ function isObject(obj) typeof obj === "object" && obj != null || obj instanceof * any window, frame, namespace, or execution context, which * is not the case when using (obj instanceof Array). */ -const isArray = +var isArray = Array.isArray // This is bloody stupid. ? function isArray(val) Array.isArray(val) || val && val.constructor && val.constructor.name === "Array" @@ -617,7 +656,7 @@ sandbox.__proto__ = this; * is prepended to its arguments. */ // Hack to get around lack of access to caller in strict mode. -const withCallerGlobal = Cu.evalInSandbox(<![CDATA[ +var withCallerGlobal = Cu.evalInSandbox(<![CDATA[ (function withCallerGlobal(fn) function withCallerGlobal_wrapped() fn.apply(this, @@ -860,7 +899,7 @@ function XPCOM(interfaces, superClass) { /** * An abstract base class for classes that wish to inherit from Error. */ -const ErrorBase = Class("ErrorBase", Error, { +var ErrorBase = Class("ErrorBase", Error, { level: 2, init: function (message, level) { level = level || 0; @@ -980,7 +1019,7 @@ let StructBase = Class("StructBase", Array, { } }); -const Timer = Class("Timer", { +var Timer = Class("Timer", { init: function (minInterval, maxInterval, callback) { this._timer = services.Timer(); this.callback = callback; @@ -1056,7 +1095,7 @@ function octal(decimal) parseInt(decimal, 8); /** * Array utility methods. */ -const array = Class("array", Array, { +var array = Class("array", Array, { init: function (ary) { if (isinstance(ary, ["Iterator", "Generator"]) || "__iterator__" in ary) ary = [k for (k in ary)]; diff --git a/common/modules/bookmarkcache.jsm b/common/modules/bookmarkcache.jsm index e230a077..faa37313 100644 --- a/common/modules/bookmarkcache.jsm +++ b/common/modules/bookmarkcache.jsm @@ -10,8 +10,8 @@ defineModule("bookmarkcache", { require: ["services", "storage", "util"] }); -const Bookmark = Struct("url", "title", "icon", "post", "keyword", "tags", "id"); -const Keyword = Struct("keyword", "title", "icon", "url"); +var Bookmark = Struct("url", "title", "icon", "post", "keyword", "tags", "id"); +var Keyword = Struct("keyword", "title", "icon", "url"); Bookmark.defaultValue("icon", function () BookmarkCache.getFavicon(this.url)); Bookmark.setter = function (key, func) this.prototype.__defineSetter__(key, func); Bookmark.prototype.__defineGetter__("extra", function () [ @@ -33,9 +33,9 @@ Bookmark.setter("tags", function (val) { services.tagging.tagURI(this.uri, val); }); -const name = "bookmark-cache"; +var name = "bookmark-cache"; -const BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver), { +var BookmarkCache = Module("BookmarkCache", XPCOM(Ci.nsINavBookmarkObserver), { POST: "bookmarkProperties/POSTData", init: function init() { diff --git a/common/modules/highlight.jsm b/common/modules/highlight.jsm index ebd15571..fd8d0709 100644 --- a/common/modules/highlight.jsm +++ b/common/modules/highlight.jsm @@ -11,9 +11,9 @@ defineModule("highlight", { use: ["template", "util"] }); -const Highlight = Struct("class", "selector", "sites", - "default", "value", "agent", - "base", "baseClass", "style"); +var Highlight = Struct("class", "selector", "sites", + "default", "value", "agent", + "base", "baseClass", "style"); Highlight.liveProperty = function (name, prop) { let i = this.prototype.members[name]; this.prototype.__defineGetter__(name, function () this[i]); @@ -52,7 +52,7 @@ Highlight.prototype.toString = function () * * @author Kris Maglione <maglione.k@gmail.com> */ -const Highlights = Module("Highlight", { +var Highlights = Module("Highlight", { init: function () { this.highlight = {}; this.loaded = {}; diff --git a/common/modules/overlay.jsm b/common/modules/overlay.jsm index c7217174..37aaf98d 100644 --- a/common/modules/overlay.jsm +++ b/common/modules/overlay.jsm @@ -14,7 +14,7 @@ defineModule("overlay", { * @class ModuleBase * The base class for all modules. */ -const ModuleBase = Class("ModuleBase", { +var ModuleBase = Class("ModuleBase", { /** * @property {[string]} A list of module prerequisites which * must be initialized before this module is loaded. @@ -24,7 +24,7 @@ const ModuleBase = Class("ModuleBase", { toString: function () "[module " + this.constructor.className + "]" }); -const Overlay = Module("Overlay", { +var Overlay = Module("Overlay", { init: function () { util.overlayWindow("chrome://browser/content/browser.xul", function (window) ({ init: function (document) { diff --git a/common/modules/prefs.jsm b/common/modules/prefs.jsm index 63ebac52..c948dca9 100644 --- a/common/modules/prefs.jsm +++ b/common/modules/prefs.jsm @@ -13,7 +13,7 @@ defineModule("prefs", { use: ["template"] }); -const Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), { +var Prefs = Module("prefs", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), { SAVED: "extensions.dactyl.saved.", RESTORE: "extensions.dactyl.restore.", diff --git a/common/modules/sanitizer.jsm b/common/modules/sanitizer.jsm index 13274585..f9141d2c 100644 --- a/common/modules/sanitizer.jsm +++ b/common/modules/sanitizer.jsm @@ -24,7 +24,7 @@ let tmp = {}; services.subscriptLoader.loadSubScript("chrome://browser/content/sanitize.js", tmp); tmp.Sanitizer.prototype.__proto__ = Class.prototype; -const Range = Struct("min", "max"); +var Range = Struct("min", "max"); Range.prototype.contains = function (date) date == null || (this.min == null || date >= this.min) && (this.max == null || date <= this.max); Range.prototype.__defineGetter__("isEternity", function () this.max == null && this.min == null); @@ -33,7 +33,7 @@ Range.prototype.__defineGetter__("native", function () this.isEternity ? null : [range.min || 0, range.max == null ? Number.MAX_VALUE : range.max]); -const Item = Class("Item", { +var Item = Class("Item", { init: function (name) { this.name = name; }, @@ -55,7 +55,7 @@ const Item = Class("Item", { SHUTDOWN_BRANCH: "privacy.clearOnShutdown." }); -const Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference], tmp.Sanitizer), { +var Sanitizer = Module("sanitizer", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference], tmp.Sanitizer), { sessionStart: Date.now() * 1000, init: function () { diff --git a/common/modules/services.jsm b/common/modules/services.jsm index d8cad7e0..da3faf17 100644 --- a/common/modules/services.jsm +++ b/common/modules/services.jsm @@ -14,7 +14,7 @@ defineModule("services", { /** * A lazily-instantiated XPCOM class and service cache. */ -const Services = Module("Services", { +var Services = Module("Services", { init: function () { this.classes = {}; this.services = {}; diff --git a/common/modules/storage.jsm b/common/modules/storage.jsm index 6e06377b..bb18bf0e 100644 --- a/common/modules/storage.jsm +++ b/common/modules/storage.jsm @@ -7,14 +7,14 @@ if (this.XPCSafeJSObjectWrapper == null) this.XPCSafeJSObjectWrapper = XPCNativeWrapper; -const myObject = Object; +var myObject = Object; Components.utils.import("resource://dactyl/base.jsm"); defineModule("storage", { exports: ["File", "storage"], require: ["services", "util"] }); -const win32 = /^win(32|nt)$/i.test(services.runtime.OS); +var win32 = /^win(32|nt)$/i.test(services.runtime.OS); function loadData(name, store, type) { try { @@ -33,7 +33,7 @@ function saveData(obj) { storage.infoPath.child(obj.name).write(obj.serial); } -const StoreBase = Class("StoreBase", { +var StoreBase = Class("StoreBase", { OPTIONS: ["privateData", "replacer"], fireEvent: function (event, arg) { storage.fireEvent(this.name, event, arg); }, @@ -61,7 +61,7 @@ const StoreBase = Class("StoreBase", { save: function () { saveData(this); }, }); -const ArrayStore = Class("ArrayStore", StoreBase, { +var ArrayStore = Class("ArrayStore", StoreBase, { _constructor: Array, get length() this._object.length, @@ -107,7 +107,7 @@ const ArrayStore = Class("ArrayStore", StoreBase, { __iterator__: function () Iterator(this._object), }); -const ObjectStore = Class("ObjectStore", StoreBase, { +var ObjectStore = Class("ObjectStore", StoreBase, { _constructor: myObject, clear: function () { @@ -142,7 +142,7 @@ const ObjectStore = Class("ObjectStore", StoreBase, { __iterator__: function () Iterator(this._object), }); -const Storage = Module("Storage", { +var Storage = Module("Storage", { alwaysReload: {}, init: function () { @@ -269,7 +269,7 @@ const Storage = Module("Storage", { * @param {boolean} checkPWD Whether to allow expansion relative to the * current directory. @default true */ -const File = Class("File", { +var File = Class("File", { init: function (path, checkPWD) { let file = services.File(); diff --git a/common/modules/styles.jsm b/common/modules/styles.jsm index 1049b899..bb4f0f03 100644 --- a/common/modules/styles.jsm +++ b/common/modules/styles.jsm @@ -12,11 +12,11 @@ defineModule("styles", { }); function cssUri(css) "chrome-data:text/css," + encodeURI(css); -const namespace = "@namespace html " + XHTML.uri.quote() + ";\n" + +var namespace = "@namespace html " + XHTML.uri.quote() + ";\n" + "@namespace xul " + XUL.uri.quote() + ";\n" + "@namespace dactyl " + NS.uri.quote() + ";\n"; -const Sheet = Struct("name", "id", "sites", "css", "hive", "agent"); +var Sheet = Struct("name", "id", "sites", "css", "hive", "agent"); Sheet.liveProperty = function (name) { let i = this.prototype.members[name]; this.prototype.__defineGetter__(name, function () this[i]); @@ -73,7 +73,7 @@ update(Sheet.prototype, { } }); -const Hive = Class("Hive", { +var Hive = Class("Hive", { init: function () { this.sheets = []; this.names = {}; @@ -212,7 +212,7 @@ const Hive = Class("Hive", { * * @author Kris Maglione <maglione.k@gmail.com> */ -const Styles = Module("Styles", { +var Styles = Module("Styles", { init: function () { this._id = 0; this.user = Hive(); diff --git a/common/modules/template.jsm b/common/modules/template.jsm index 4bcfeee3..0a4652fc 100644 --- a/common/modules/template.jsm +++ b/common/modules/template.jsm @@ -13,7 +13,7 @@ defineModule("template", { default xml namespace = XHTML; -const Template = Module("Template", { +var Template = Module("Template", { add: function add(a, b) a + b, join: function join(c) function (a, b) a + c + b, diff --git a/common/modules/util.jsm b/common/modules/util.jsm index 88f2de29..26e56e7a 100644 --- a/common/modules/util.jsm +++ b/common/modules/util.jsm @@ -15,10 +15,10 @@ defineModule("util", { use: ["highlight", "storage", "template"] }); -const XBL = Namespace("xbl", "http://www.mozilla.org/xbl"); -const XHTML = Namespace("html", "http://www.w3.org/1999/xhtml"); -const XUL = Namespace("xul", "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); -const NS = Namespace("dactyl", "http://vimperator.org/namespaces/liberator"); +var XBL = Namespace("xbl", "http://www.mozilla.org/xbl"); +var XHTML = Namespace("html", "http://www.w3.org/1999/xhtml"); +var XUL = Namespace("xul", "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); +var NS = Namespace("dactyl", "http://vimperator.org/namespaces/liberator"); default xml namespace = XHTML; memoize(this, "Commands", function () { @@ -28,7 +28,7 @@ memoize(this, "Commands", function () { return obj.Commands; }); -const FailedAssertion = Class("FailedAssertion", ErrorBase); +var FailedAssertion = Class("FailedAssertion", ErrorBase); function wrapCallback(fn) fn.wrapper = function wrappedCallback () { @@ -41,7 +41,7 @@ function wrapCallback(fn) } } -const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), { +var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]), { init: function () { this.Array = array; @@ -920,13 +920,16 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]) services.observer.removeObserver(this, "dactyl-rehash"); util.dump("dactyl: util: observe: dactyl-rehash"); - for (let module in values(defineModule.modules)) { - util.dump("dactyl: util: init(" + module + ")"); - if (module.reinit) - module.reinit(); - else - module.init(); - } + if (true) + JSMLoader.purge(); + else + for (let module in values(defineModule.modules)) { + util.dump("dactyl: util: init(" + module + ")"); + if (module.reinit) + module.reinit(); + else + module.init(); + } }, "toplevel-window-ready": function (window, data) { window.addEventListener("DOMContentLoaded", wrapCallback(function listener(event) { @@ -1427,7 +1430,7 @@ const Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]) * Math utility methods. * @singleton */ -const GlobalMath = Math; +var GlobalMath = Math; var Math = update(Object.create(GlobalMath), { /** * Returns the specified *value* constrained to the range *min* - *max*. |