1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-20 10:17:59 +01:00

Allow mapping keys in HINT and other modes. Closes issue #10. Closes issue #158.

This commit is contained in:
Kris Maglione
2010-12-22 15:32:19 -05:00
parent 797bf92c27
commit c65758864d
6 changed files with 265 additions and 187 deletions

View File

@@ -464,7 +464,8 @@ const CommandLine = Module("commandline", {
leave: function (params) { leave: function (params) {
if (params.pop) if (params.pop)
commandline.leave(); commandline.leave();
} },
mainMode: this.currentExtendedMode
}); });
this.currentExtendedMode = extendedMode || null; this.currentExtendedMode = extendedMode || null;
@@ -736,7 +737,8 @@ const CommandLine = Module("commandline", {
leave: function leave(stack) { leave: function leave(stack) {
commandline.leave(stack); commandline.leave(stack);
leave.supercall(this, stack); leave.supercall(this, stack);
} },
mainMode: extra.extended || modes.PROMPT
})); }));
this.currentExtendedMode = modes.PROMPT; this.currentExtendedMode = modes.PROMPT;

View File

@@ -1764,7 +1764,7 @@ const Dactyl = Module("dactyl", {
commands.add(["norm[al]"], commands.add(["norm[al]"],
"Execute Normal mode commands", "Execute Normal mode commands",
function (args) { events.feedkeys(args[0] || "", args.bang); }, function (args) { events.feedkeys(args[0] || "", args.bang, false, modes.NORMAL); },
{ {
argCount: "+", argCount: "+",
bang: true, bang: true,

View File

@@ -63,14 +63,6 @@ const Events = Module("events", {
this._code_key[60] = "lt"; this._code_key[60] = "lt";
} }
this._input = {
buffer: "", // partial command storage
pendingMotionMap: null, // e.g. "d{motion}" if we wait for a motion of the "d" command
pendingArgMap: null, // pending map storage for commands like m{a-z}
count: null, // parsed count from the input buffer
motionCount: null
};
this._activeMenubar = false; this._activeMenubar = false;
this.addSessionListener(window, "DOMMenuBarActive", this.onDOMMenuBarActive, true); this.addSessionListener(window, "DOMMenuBarActive", this.onDOMMenuBarActive, true);
this.addSessionListener(window, "DOMMenuBarInactive", this.onDOMMenuBarInactive, true); this.addSessionListener(window, "DOMMenuBarInactive", this.onDOMMenuBarInactive, true);
@@ -235,7 +227,7 @@ const Events = Module("events", {
* command line. * command line.
* @returns {boolean} * @returns {boolean}
*/ */
feedkeys: function (keys, noremap, quiet) { feedkeys: function (keys, noremap, quiet, mode) {
let wasFeeding = this.feedingKeys; let wasFeeding = this.feedingKeys;
this.feedingKeys = true; this.feedingKeys = true;
@@ -256,9 +248,10 @@ const Events = Module("events", {
else else
evt.noremap = !!noremap; evt.noremap = !!noremap;
evt.isMacro = true; evt.isMacro = true;
evt.dactylMode = mode;
let event = events.create(document.commandDispatcher.focusedWindow.document, type, evt); let event = events.create(document.commandDispatcher.focusedWindow.document, type, evt);
if (!evt_obj.dactylString && !evt_obj.dactylShift) if (!evt_obj.dactylString && !evt_obj.dactylShift && !mode)
events.dispatch(dactyl.focusedElement || buffer.focusedFrame, event); events.dispatch(dactyl.focusedElement || buffer.focusedFrame, event);
else else
events.onKeyPress(event); events.onKeyPress(event);
@@ -285,7 +278,7 @@ const Events = Module("events", {
let duringFeed = this.duringFeed; let duringFeed = this.duringFeed;
this.duringFeed = []; this.duringFeed = [];
for (let [, evt] in Iterator(duringFeed)) for (let [, evt] in Iterator(duringFeed))
events.dispatch(evt.target, evt); events.dispatch(evt.originalTarget, evt);
} }
} }
}, },
@@ -363,16 +356,23 @@ const Events = Module("events", {
dispatch: Class.memoize(function () dispatch: Class.memoize(function ()
util.haveGecko("2b") util.haveGecko("2b")
? function (target, event) { ? function (target, event) {
if (target instanceof Element) try {
// This causes a crash on Gecko<2.0, it seems. if (target instanceof Element)
(target.ownerDocument || target.document || target).defaultView // This causes a crash on Gecko<2.0, it seems.
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils) (target.ownerDocument || target.document || target).defaultView
.dispatchDOMEventViaPresShell(target, event, true) .QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils)
else .dispatchDOMEventViaPresShell(target, event, true)
target.dispatchEvent(event); else
target.dispatchEvent(event);
}
catch (e) {
util.reportError(e);
}
} }
: function (target, event) target.dispatchEvent(event)), : function (target, event) target.dispatchEvent(event)),
get defaultTarget() dactyl.focusedElement || content.document.body || document.documentElement,
/** /**
* Converts an event string into an array of pseudo-event objects. * Converts an event string into an array of pseudo-event objects.
* *
@@ -806,7 +806,6 @@ const Events = Module("events", {
// the command-line has focus // the command-line has focus
// TODO: ...help me...please... // TODO: ...help me...please...
onKeyPress: function onKeyPress(event) { onKeyPress: function onKeyPress(event) {
function isEscape(key) key == "<Esc>" || key == "<C-[>";
function killEvent() { function killEvent() {
event.preventDefault(); event.preventDefault();
@@ -855,176 +854,86 @@ const Events = Module("events", {
try { try {
let stop = false; let stop = false;
let mode = modes.getStack(0); let mode = modes.getStack(0);
var main = mode.main; if (event.dactylMode)
mode = Modes.StackElement(event.dactylMode);
function shouldPass() function shouldPass()
(!dactyl.focusedElement || Events.isContentNode(dactyl.focusedElement)) && (!dactyl.focusedElement || Events.isContentNode(dactyl.focusedElement)) &&
options.get("passkeys").has(events.toString(event)); options.get("passkeys").has(events.toString(event));
// menus have their own command handlers let input = this._input;
if (modes.extended & modes.MENU) this._input = null;
stop = true; if (!input) {
else if (modes.main == modes.PASS_THROUGH) // menus have their own command handlers
// let flow continue to handle these keys to cancel escape-all-keys mode if (modes.extended & modes.MENU)
stop = !isEscape(key) && key != "<C-v>"; stop = true;
// handle Escape-one-key mode (Ctrl-v) else if (modes.main == modes.PASS_THROUGH)
else if (modes.main == modes.QUOTE) { // let flow continue to handle these keys to cancel escape-all-keys mode
stop = !shouldPass() && (modes.getStack(1).main !== modes.PASS_THROUGH || isEscape(key)); stop = !Events.isEscape(key) && key != "<C-v>";
// We need to preserve QUOTE mode until the escape // handle Escape-one-key mode (Ctrl-v)
// handler to escape the <Esc> key else if (modes.main == modes.QUOTE) {
if (!stop || !isEscape(key)) if (modes.getStack(1).main == modes.PASS_THROUGH) {
modes.pop(); mode.params.mainMode = modes.getStack(2).main;
mode = modes.getStack(1); stop = Events.isEscape(key);
}
else if (!event.isMacro && !event.noremap && shouldPass())
stop = true;
// handle Escape-all-keys mode (Ctrl-q)
if (stop) {
this._input.buffer = "";
main = null;
return null;
}
if (key == "<C-c>")
util.interrupted = true;
stop = true; // set to false if we should NOT consume this event but let the host app handle it
// XXX: ugly hack for now pass certain keys to the host app as
// they are without beeping also fixes key navigation in combo
// boxes, submitting forms, etc.
// FIXME: breaks iabbr for now --mst
if (key in config.ignoreKeys && (config.ignoreKeys[key] & mode.main)) {
this._input.buffer = "";
return null;
}
if (mode.params.onEvent) {
this._input.buffer = "";
// Bloody hell.
if (key === "<C-h>")
key = event.dactylString = "<BS>";
if (mode.params.onEvent(event) === false)
killEvent();
return null;
}
let inputStr = this._input.buffer + key;
let countStr = inputStr.match(/^[1-9][0-9]*|/)[0];
let candidateCommand = inputStr.substr(countStr.length);
let map = mappings[event.noremap ? "getDefault" : "get"](mode.main, candidateCommand);
let candidates = mappings.getCandidates(mode.main, candidateCommand);
if (candidates.length == 0 && !map) {
map = this._input.pendingMap;
this._input.pendingMap = null;
if (map && map.arg)
this._input.pendingArgMap = map;
}
// counts must be at the start of a complete mapping (10j -> go 10 lines down)
if (countStr && !candidateCommand) {
// no count for insert mode mappings
if (!mode.mainMode.count || mode.mainMode.input)
stop = false;
else
this._input.buffer = inputStr;
}
else if (this._input.pendingArgMap) {
main = null;
this._input.buffer = "";
let map = this._input.pendingArgMap;
this._input.pendingArgMap = null;
if (!isEscape(key)) {
if (modes.isReplaying && !this.waitForPageLoad())
return null;
map.execute(null, this._input.count, key);
}
}
// only follow a map if there isn't a longer possible mapping
// (allows you to do :map z yy, when zz is a longer mapping than z)
else if (map && !event.skipmap && candidates.length == 0) {
this._input.pendingMap = null;
let count = this._input.pendingMotionMap ? "motionCount" : "count";
this._input[count] = parseInt(countStr, 10);
if (isNaN(this._input[count]))
this._input[count] = null;
this._input.buffer = "";
if (map.arg) {
this._input.buffer = inputStr;
this._input.pendingArgMap = map;
}
else if (this._input.pendingMotionMap) {
if (!isEscape(key))
this._input.pendingMotionMap.execute(candidateCommand, this._input.motionCount || this._input.count, null);
this._input.pendingMotionMap = null;
this._input.motionCount = null;
}
// no count support for these commands yet
else if (map.motion) {
this._input.pendingMotionMap = map;
}
else {
// Hack.
if (map.name == "<C-v>" && main == modes.QUOTE)
stop = false;
else {
if (modes.isReplaying && !this.waitForPageLoad())
return killEvent();
let ret = map.execute(null, this._input.count);
if (map.route && ret)
stop = false;
} }
main = null; else if (shouldPass())
mode.params.mainMode = modes.getStack(1).main;
else
stop = true;
if (stop && !Events.isEscape(key))
modes.pop();
} }
} else if (!event.isMacro && !event.noremap && shouldPass())
else if (mappings.getCandidates(mode.main, candidateCommand).length > 0 && !event.skipmap) { stop = true;
this._input.pendingMap = map;
this._input.buffer += key;
}
else { // if the key is neither a mapping nor the start of one
// the mode checking is necessary so that things like g<esc> do not beep
main = null;
if (this._input.buffer != "" && !event.skipmap &&
(mode.main & (modes.INSERT | modes.COMMAND_LINE | modes.TEXT_EDIT)))
events.feedkeys(this._input.buffer, { noremap: true, skipmap: true });
this._input.buffer = ""; if (stop)
this._input.pendingArgMap = null; return null;
this._input.pendingMotionMap = null;
this._input.pendingMap = null;
this._input.motionCount = null;
if (!isEscape(key)) { if (key == "<C-c>")
stop = (mode.main & (modes.TEXT_EDIT | modes.VISUAL)); util.interrupted = true;
if (stop)
dactyl.beep();
if (mode.main == modes.COMMAND_LINE) stop = true; // set to false if we should NOT consume this event but let the host app handle it
if (!(mode.extended & modes.INPUT_MULTILINE))
dactyl.trapErrors(commandline.onEvent, commandline, event); // XXX: ugly hack for now pass certain keys to the host app as
} // they are without beeping also fixes key navigation in combo
// boxes, submitting forms, etc.
// FIXME: breaks iabbr for now --mst
if (key in config.ignoreKeys && (config.ignoreKeys[key] & mode.main))
return null;
input = Events.KeyProcessor(mode.params.mainMode || mode.main, mode.extended);
if (mode.params.preExecute)
input.preExecute = mode.params.preExecute;
if (mode.params.postExecute)
input.postExecute = mode.params.postExecute;
if (mode.params.onEvent)
input.fallthrough = function (event) {
// Bloody hell.
if (events.toString(event) === "<C-h>")
event.dactylString = "<BS>";
return mode.params.onEvent(event) === false;
}
} }
if (stop) if (!input.process(event))
killEvent(); this._input = input;
} }
catch (e) { catch (e) {
dactyl.reportError(e); dactyl.reportError(e);
} }
finally { finally {
let motionMap = (this._input.pendingMotionMap && this._input.pendingMotionMap.names[0]) || ""; if (!this._input)
if (!(modes.extended & modes.HINTS)) statusline.updateInputBuffer("");
else if (!(modes.extended & modes.HINTS)) {
let motionMap = (this._input.pendingMotionMap && this._input.pendingMotionMap.names[0]) || "";
statusline.updateInputBuffer(motionMap + this._input.buffer); statusline.updateInputBuffer(motionMap + this._input.buffer);
}
// This is a stupid, silly, and revolting hack. // This is a stupid, silly, and revolting hack.
if (isEscape(key)) if (Events.isEscape(key) && !shouldPass())
this.onEscape(); this.onEscape();
if (main == modes.QUOTE)
modes.push(main);
} }
}, },
@@ -1090,6 +999,150 @@ const Events = Module("events", {
} }
} }
}, { }, {
KeyProcessor: Class("KeyProcessor", {
init: function init(main, extended) {
this.main = main;
this.extended = extended;
this.events = [];
},
buffer: "", // partial command storage
pendingMotionMap: null, // e.g. "d{motion}" if we wait for a motion of the "d" command
pendingArgMap: null, // pending map storage for commands like m{a-z}
count: null, // parsed count from the input buffer
motionCount: null,
append: function append(event) {
this.events.push(event);
this.buffer += events.toString(event);
},
process: function process(event) {
function kill(event) {
event.stopPropagation();
event.preventDefault();
}
let res = this.onKeyPress(event);
if (res === true)
kill(event);
else if (isArray(res)) {
if (this.fallthrough) {
if (this.fallthrough(res[0]) === true)
kill(res[0]);
}
else if (Events.isEscape(event))
kill(event);
else {
if (this.main & (modes.TEXT_EDIT | modes.VISUAL)) {
dactyl.beep();
kill(event);
}
if (this.main == modes.COMMAND_LINE)
if (!(this.extended & modes.INPUT_MULTILINE))
dactyl.trapErrors(commandline.onEvent, commandline, event);
}
// Unconsumed events
for (let event in values(res.slice(1)))
if (!event.skipmap)
if (event.originalTarget)
events.dispatch(event.originalTarget, event);
else
events.onKeyPress(event);
}
return res != null;
},
onKeyPress: function onKeyPress(event) {
const self = this;
let key = events.toString(event);
let inputStr = this.buffer + key;
let countStr = inputStr.match(/^[1-9][0-9]*|/)[0];
let candidateCommand = inputStr.substr(countStr.length);
let map = mappings[event.noremap ? "getDefault" : "get"](this.main, candidateCommand);
function execute(map) {
if (self.preExecute)
self.preExecute.apply(self, arguments);
let res = map.execute.apply(map, Array.slice(arguments, 1))
if (self.postExecute) // To do: get rid of this.
self.postExecute.apply(self, arguments);
return res;
}
let candidates = mappings.getCandidates(this.main, candidateCommand);
if (candidates.length == 0 && !map) {
map = this.pendingMap;
this.pendingMap = null;
if (map && map.arg)
this.pendingArgMap = map;
}
// counts must be at the start of a complete mapping (10j -> go 10 lines down)
if (countStr && !candidateCommand) {
// no count for insert mode mappings
if (!this.main.count || this.main.input)
return false;
else
this.append(event);
}
else if (this.pendingArgMap) {
let map = this.pendingArgMap;
if (!Events.isEscape(key)) {
if (!modes.isReplaying || this.waitForPageLoad())
execute(map, null, this.count, key);
return true;
}
}
// only follow a map if there isn't a longer possible mapping
// (allows you to do :map z yy, when zz is a longer mapping than z)
else if (map && !event.skipmap && candidates.length == 0) {
this.pendingMap = null;
let count = this.pendingMotionMap ? "motionCount" : "count";
this[count] = parseInt(countStr, 10);
if (isNaN(this[count]))
this[count] = null;
this.buffer = "";
if (map.arg) {
this.buffer = inputStr;
this.pendingArgMap = map;
}
else if (this.pendingMotionMap) {
if (!Events.isEscape(key))
execute(this.pendingMotionMap, candidateCommand, this.motionCount || this.count, null);
this.pendingMotionMap = null;
this.motionCount = null;
}
// no count support for these commands yet
else if (map.motion)
this.pendingMotionMap = map;
else {
if (modes.isReplaying && !this.waitForPageLoad())
return true;
let ret = execute(map, null, this.count);
if (map.route && ret)
return false;
}
return true;
}
else if (mappings.getCandidates(this.main, candidateCommand).length > 0 && !event.skipmap) {
this.pendingMap = map;
this.append(event);
}
else {
this.append(event);
return this.events;
}
return null;
}
}),
isContentNode: function isContentNode(node) { isContentNode: function isContentNode(node) {
let win = (node.ownerDocument || node).defaultView || node; let win = (node.ownerDocument || node).defaultView || node;
for (; win; win = win.parent != win && win.parent) for (; win; win = win.parent != win && win.parent)
@@ -1097,6 +1150,11 @@ const Events = Module("events", {
return true; return true;
return false; return false;
}, },
isEscape: function isEscape(event)
let (key = isString(event) ? event : events.toString(event))
key === "<Esc>" || key === "<C-[>",
isInputElemFocused: function isInputElemFocused() { isInputElemFocused: function isInputElemFocused() {
let elem = dactyl.focusedElement; let elem = dactyl.focusedElement;
return elem instanceof HTMLInputElement && set.has(util.editableInputs, elem.type) || return elem instanceof HTMLInputElement && set.has(util.editableInputs, elem.type) ||
@@ -1147,7 +1205,12 @@ const Events = Module("events", {
mappings.add(modes.all, mappings.add(modes.all,
["<C-v>"], "Pass through next key", ["<C-v>"], "Pass through next key",
function () { modes.push(modes.QUOTE); }); function () {
if (modes.main == modes.QUOTE)
return true;
modes.push(modes.QUOTE);
},
{ route: true });
mappings.add(modes.all, mappings.add(modes.all,
["<Nop>"], "Do nothing", ["<Nop>"], "Do nothing",

View File

@@ -426,7 +426,7 @@ const Mappings = Module("mappings", {
default: mapmodes || ["n", "v"], default: mapmodes || ["n", "v"],
validator: function (list) !list || list.every(findMode), validator: function (list) !list || list.every(findMode),
completer: function () [[array.compact([mode.name.toLowerCase().replace(/_/g, "-"), mode.char]), mode.disp] completer: function () [[array.compact([mode.name.toLowerCase().replace(/_/g, "-"), mode.char]), mode.disp]
for (mode in modes.mainModes)], for (mode in values(modes.all))],
}, },
{ {
names: ["-nopersist", "-n"], names: ["-nopersist", "-n"],
@@ -502,7 +502,7 @@ const Mappings = Module("mappings", {
} }
function findMode(name) { function findMode(name) {
for (let mode in modes.mainModes) for (let mode in values(modes.all))
if (name == mode || name == mode.char || String.toLowerCase(name).replace(/-/g, "_") == mode.name.toLowerCase()) if (name == mode || name == mode.char || String.toLowerCase(name).replace(/-/g, "_") == mode.name.toLowerCase())
return mode.mask; return mode.mask;
return null; return null;
@@ -546,7 +546,7 @@ const Mappings = Module("mappings", {
description: "The mode for which to list mappings", description: "The mode for which to list mappings",
default: "n", default: "n",
completer: function () [[array.compact([mode.name.toLowerCase().replace(/_/g, "-"), mode.char]), mode.disp] completer: function () [[array.compact([mode.name.toLowerCase().replace(/_/g, "-"), mode.char]), mode.disp]
for (mode in modes.mainModes)], for (mode in values(modes.all))],
validator: function (m) findMode(m) validator: function (m) findMode(m)
} }
] ]
@@ -573,7 +573,7 @@ const Mappings = Module("mappings", {
completion.userMapping = function userMapping(context, modes) { completion.userMapping = function userMapping(context, modes) {
// FIXME: have we decided on a 'standard' way to handle this clash? --djk // FIXME: have we decided on a 'standard' way to handle this clash? --djk
modes = modes || [modules.modes.NORMAL]; modes = modes || [modules.modes.NORMAL];
context.completions = [[m.names[0], ""] for (m in mappings.getUserIterator(modes))]; context.completions = [[m.names[0], m.description + ": " + m.action] for (m in mappings.getUserIterator(modes))];
}; };
}, },
javascript: function () { javascript: function () {

View File

@@ -29,6 +29,7 @@ const Modes = Module("modes", {
} }
}); });
this._modes = [];
this._mainModes = []; this._mainModes = [];
this._lastMode = 0; this._lastMode = 0;
this._modeMap = {}; this._modeMap = {};
@@ -49,8 +50,10 @@ const Modes = Module("modes", {
editor.unselectText(); editor.unselectText();
} }
}); });
this.addMode("COMMAND_LINE", { char: "c", input: true, this.addMode("COMMAND_LINE", { char: "c", input: true,
display: function () modes.extended & modes.OUTPUT_MULTILINE ? null : this.disp }); display: function () modes.extended & modes.OUTPUT_MULTILINE ? null : this.disp });
this.addMode("CARET", {}, { this.addMode("CARET", {}, {
get pref() prefs.get("accessibility.browsewithcaret"), get pref() prefs.get("accessibility.browsewithcaret"),
set pref(val) prefs.set("accessibility.browsewithcaret", val), set pref(val) prefs.set("accessibility.browsewithcaret", val),
@@ -68,11 +71,18 @@ const Modes = Module("modes", {
this.addMode("TEXT_EDIT", { char: "t", ownsFocus: true }); this.addMode("TEXT_EDIT", { char: "t", ownsFocus: true });
this.addMode("EMBED", { input: true, ownsFocus: true }); this.addMode("EMBED", { input: true, ownsFocus: true });
this.addMode("PASS_THROUGH"); this.addMode("PASS_THROUGH");
this.addMode("QUOTE", { this.addMode("QUOTE", {
display: function () modes.getStack(1).main == modes.PASS_THROUGH display: function () modes.getStack(1).main == modes.PASS_THROUGH
? (modes.getStack(2).mainMode.display() || modes.getStack(2).mainMode.name) + " (next)" ? (modes.getStack(2).mainMode.display() || modes.getStack(2).mainMode.name) + " (next)"
: "PASS THROUGH (next)" : "PASS THROUGH (next)"
}, {
// Fix me.
preExecute: function (map) { if (modes.main == modes.QUOTE && map.name !== "<C-v>") modes.pop() },
postExecute: function (map) { if (modes.main == modes.QUOTE && map.name === "<C-v>") modes.pop() },
onEvent: function () { if (modes.main == modes.QUOTE) modes.pop() }
}); });
// this._extended modes, can include multiple modes, and even main modes // this._extended modes, can include multiple modes, and even main modes
this.addMode("EX", true); this.addMode("EX", true);
this.addMode("HINTS", true); this.addMode("HINTS", true);
@@ -129,7 +139,7 @@ const Modes = Module("modes", {
__iterator__: function () array.iterValues(this.all), __iterator__: function () array.iterValues(this.all),
get all() this._mainModes.slice(), get all() this._modes.slice(),
get mainModes() (mode for ([k, mode] in Iterator(modes._modeMap)) if (!mode.extended && mode.name == k)), get mainModes() (mode for ([k, mode] in Iterator(modes._modeMap)) if (!mode.extended && mode.name == k)),
@@ -150,6 +160,7 @@ const Modes = Module("modes", {
} }
util.extend(mode, { util.extend(mode, {
toString: function () this.name,
count: true, count: true,
disp: disp, disp: disp,
extended: extended, extended: extended,
@@ -167,8 +178,11 @@ const Modes = Module("modes", {
mode.display = function () disp; mode.display = function () disp;
this._modeMap[name] = mode; this._modeMap[name] = mode;
this._modeMap[this[name]] = mode; this._modeMap[this[name]] = mode;
this._modes.push(mode);
if (!extended) if (!extended)
this._mainModes.push(this[name]); this._mainModes.push(mode);
dactyl.triggerObserver("mode-add", mode); dactyl.triggerObserver("mode-add", mode);
}, },
@@ -323,12 +337,13 @@ const Modes = Module("modes", {
}, { }, {
StackElement: (function () { StackElement: (function () {
let struct = Struct("main", "extended", "params", "saved"); let struct = Struct("main", "extended", "params", "saved");
struct.defaultValue("params", function () this.main.params);
struct.prototype.__defineGetter__("mainMode", function () modes.getMode(this.main)); struct.prototype.__defineGetter__("mainMode", function () modes.getMode(this.main));
struct.prototype.toString = function () !loaded.modes ? this.main : "[mode " + struct.prototype.toString = function () !loaded.modes ? this.main : "[mode " +
this.mainMode.name + this.mainMode.name +
(!this.extended ? "" : (!this.extended ? "" :
"(" + "(" +
[modes.getMode(1 << i).name for (i in util.range(0, 32)) if (this.extended & (1 << i))].join("|") + [modes.getMode(1 << i).name for (i in util.range(0, 32)) if (modes.getMode(1 << i) && (this.extended & (1 << i)))].join("|") +
")") + "]"; ")") + "]";
return struct; return struct;
})(), })(),

View File

@@ -36,8 +36,6 @@ update(Sheet.prototype, {
remove: function () { this.hive.remove(this) }, remove: function () { this.hive.remove(this) },
system: Class.Property({ get: deprecated("Please use Style#hive instead", function system() this.hive === styles.system) }),
get uri() cssUri(this.fullCSS), get uri() cssUri(this.fullCSS),
get enabled() this._enabled, get enabled() this._enabled,
@@ -216,12 +214,6 @@ const Styles = Module("Styles", {
this.system = Hive(); this.system = Hive();
}, },
userSheets: Class.Property({ get: deprecated("Please use Styles#user.sheets instead", function userSheets() this.user.sheets) }),
systemSheets: Class.Property({ get: deprecated("Please use Styles#system.sheets instead", function systemSheets() this.system.sheets) }),
userNames: Class.Property({ get: deprecated("Please use Styles#user.names instead", function userNames() this.user.names) }),
systemNames: Class.Property({ get: deprecated("Please use Styles#system.names instead", function systemNames() this.system.names) }),
sites: Class.Property({ get: deprecated("Please use Styles#user.sites instead", function sites() this.user.sites) }),
__iterator__: function () Iterator(this.user.sheets.concat(this.system.sheets)), __iterator__: function () Iterator(this.user.sheets.concat(this.system.sheets)),
_proxy: function (name, args) _proxy: function (name, args)
@@ -233,6 +225,12 @@ const Styles = Module("Styles", {
get: deprecated("Please use Styles#{user,system}.get instead", function get() this._proxy("get", arguments)), get: deprecated("Please use Styles#{user,system}.get instead", function get() this._proxy("get", arguments)),
removeSheet: deprecated("Please use Styles#{user,system}.remove instead", function removeSheet() this._proxy("remove", arguments)), removeSheet: deprecated("Please use Styles#{user,system}.remove instead", function removeSheet() this._proxy("remove", arguments)),
userSheets: Class.Property({ get: deprecated("Please use Styles#user.sheets instead", function userSheets() this.user.sheets) }),
systemSheets: Class.Property({ get: deprecated("Please use Styles#system.sheets instead", function systemSheets() this.system.sheets) }),
userNames: Class.Property({ get: deprecated("Please use Styles#user.names instead", function userNames() this.user.names) }),
systemNames: Class.Property({ get: deprecated("Please use Styles#system.names instead", function systemNames() this.system.names) }),
sites: Class.Property({ get: deprecated("Please use Styles#user.sites instead", function sites() this.user.sites) }),
registerSheet: function registerSheet(url, agent, reload) { registerSheet: function registerSheet(url, agent, reload) {
let uri = services.io.newURI(url, null, null); let uri = services.io.newURI(url, null, null);
if (reload) if (reload)