From 924f400ba60425a5516ff65b486b2ab59ea5d63c Mon Sep 17 00:00:00 2001 From: Jeremy Maitin-Shepard Date: Thu, 9 Oct 2008 18:00:22 -0700 Subject: [PATCH] Add generic label mechanism --- modules/conkeror.js | 1 + modules/labels.js | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 modules/labels.js diff --git a/modules/conkeror.js b/modules/conkeror.js index b3fda86..6826382 100644 --- a/modules/conkeror.js +++ b/modules/conkeror.js @@ -8,6 +8,7 @@ var start_time = Date.now (); require("keywords.js"); // not required to be listed as dep. +require("labels.js"); // not required to be listed as a dep. require("coroutine.js"); // not required to be listed as dep. require("hook.js"); diff --git a/modules/labels.js b/modules/labels.js new file mode 100644 index 0000000..ac0be16 --- /dev/null +++ b/modules/labels.js @@ -0,0 +1,85 @@ +/** + * (C) Copyright 2008 Jeremy Maitin-Shepard + * + * Use, modification, and distribution are subject to the terms specified in the + * COPYING file. +**/ + +require_later("help.js"); // for pretty_print_value + +/** + * @param name specifies the name of the label to be defined + * + * The remaining arguments should be strings, specifying the names of + * required arguments. Additionally, the last additional argument can + * be `null', which indicates that unlimited optional arguments can + * follow. If `null' is not specified as the last argument, then it is + * assumed that all optional arguments are keyword arguments. The + * optional arguments are stored as an array in a member called $. + */ +function define_label(name) { + var allow_optional = false; + var required_args = []; + for (let i = 1; i < arguments.length; ++i) { + if (arguments[i] === null) { + allow_optional = true; + if (i + 1 != arguments.length) + throw new Error("null must be the last argument"); + } else { + required_args.push(arguments[i]); + } + } + function toString() { + let optional = this.$; + if (optional == null) + optional = []; + let printed_args = []; + let seen_defined_yet = false; + for (let i = required_args.length - 1; i >= 0; --i) { + let arg = required_args[i]; + if (seen_defined_yet || this[arg] !== undefined) { + printed_args.unshift(arg + " = " + pretty_print_value(this[arg])); + seen_defined_yet = true; + } + } + printed_args.push.apply(null, optional.map(pretty_print_value)); + for (let i in this) { + if (i.length > 1 && i[0] == "$") + printed_args.push(i + " = " + this[i]); + } + if (printed_args.length > 0) + printed_args = "(" + printed_args.join(", ") + ")"; + else + printed_args = ""; + return this._name + printed_args; + } + var result; + result = function () { + var o = {_name: name, toString: toString, _id: result, __is_label: true, toSource: toString}; + let max_req_arg = arguments.length; + if (max_req_arg > required_args.length) + max_req_arg = required_args.length; + for (let i = 0; i < max_req_arg; ++i) + o[required_args[i]] = arguments[i]; + if (allow_optional) + o.$ = Array.prototype.slice.call(arguments, required_args.length); + else { + write_keywords(o, arguments, required_args.length); + } + return o; + } + result._name = name; + result._id = result; + result.$ = []; + for (let i in required_args) + result[i] = undefined; + result.toString = toString; + result.__is_label = true; + conkeror[name] = result; +} + +function label_id(value) { + if (value == null) + return null; + return value._id; +} -- 2.11.4.GIT