1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-03-24 15:33:31 +01:00

Make :downloads mode change handler safer, more co-operative, and less kludgy.

This commit is contained in:
Kris Maglione
2011-01-22 05:31:24 -05:00
parent c889e7cd22
commit e8603ed458
2 changed files with 51 additions and 37 deletions

View File

@@ -569,6 +569,7 @@ var CommandLine = Module("commandline", {
_history: Modes.boundProperty(), _history: Modes.boundProperty(),
_lastClearable: Modes.boundProperty(), _lastClearable: Modes.boundProperty(),
_keepCommand: Modes.boundProperty(), _keepCommand: Modes.boundProperty(),
messages: Modes.boundProperty(),
multilineInputVisible: Modes.boundProperty({ multilineInputVisible: Modes.boundProperty({
set: function (value) { this.widgets.multilineInput.collapsed = !value; } set: function (value) { this.widgets.multilineInput.collapsed = !value; }
@@ -727,10 +728,10 @@ var CommandLine = Module("commandline", {
/** /**
* Display a multi-line message. * Display a multi-line message.
* *
* @param {string} str * @param {string} data
* @param {string} highlightGroup * @param {string} highlightGroup
*/ */
_echoMultiline: function echoMultiline(str, highlightGroup, silent) { _echoMultiline: function echoMultiline(data, highlightGroup, silent) {
let doc = this.widgets.multilineOutput.contentDocument; let doc = this.widgets.multilineOutput.contentDocument;
let win = this.widgets.multilineOutput.contentWindow; let win = this.widgets.multilineOutput.contentWindow;
let elem = doc.documentElement; let elem = doc.documentElement;
@@ -741,25 +742,38 @@ var CommandLine = Module("commandline", {
this.hide(); this.hide();
this._startHints = false; this._startHints = false;
if (modes.main != modes.OUTPUT_MULTILINE) if (modes.main != modes.OUTPUT_MULTILINE) {
modes.push(modes.OUTPUT_MULTILINE, null, { modes.push(modes.OUTPUT_MULTILINE, null, {
onEvent: this.closure.onMultilineOutputEvent onEvent: this.closure.onMultilineOutputEvent,
leave: this.closure(function leave(stack) {
if (stack.pop)
for (let message in values(this.messages))
if (message.leave)
message.leave(stack);
})
}); });
this.messages = [];
}
// If it's already XML, assume it knows what it's doing. // If it's already XML, assume it knows what it's doing.
// Otherwise, white space is significant. // Otherwise, white space is significant.
// The problem elsewhere is that E4X tends to insert new lines // The problem elsewhere is that E4X tends to insert new lines
// after interpolated data. // after interpolated data.
XML.ignoreWhitespace = false; XML.ignoreWhitespace = XML.prettyPrinting = false;
XML.prettyPrinting = false;
let style = typeof str === "string" ? "pre" : "nowrap"; if (isObject(data)) {
if (callable(str)) {
this._lastMowOutput = null; this._lastMowOutput = null;
var output = util.xmlToDom(<div class="ex-command-output" style="white-space: nowrap" highlight={highlightGroup}/>, doc); var output = util.xmlToDom(<div class="ex-command-output" style="white-space: nowrap" highlight={highlightGroup}/>, doc);
output.appendChild(str(doc)); data.document = doc;
output.appendChild(data.message);
this.messages.push(data);
} }
else { else {
this._lastMowOutput = <div class="ex-command-output" style={"white-space: " + style} highlight={highlightGroup}>{str}</div>; let style = isString(data) ? "pre" : "nowrap";
this._lastMowOutput = <div class="ex-command-output" style={"white-space: " + style} highlight={highlightGroup}>{data}</div>;
var output = util.xmlToDom(this._lastMowOutput, doc); var output = util.xmlToDom(this._lastMowOutput, doc);
} }
@@ -773,8 +787,9 @@ var CommandLine = Module("commandline", {
body.appendChild(output); body.appendChild(output);
let str = typeof data !== "xml" && data.message || data;
if (!silent) if (!silent)
dactyl.triggerObserver("echoMultiline", str, highlightGroup, output); dactyl.triggerObserver("echoMultiline", data, highlightGroup, output);
commandline.updateOutputHeight(true); commandline.updateOutputHeight(true);
@@ -812,7 +827,7 @@ var CommandLine = Module("commandline", {
* commandline.FORCE_MULTILINE - Forces the message to appear in * commandline.FORCE_MULTILINE - Forces the message to appear in
* the MOW. * the MOW.
*/ */
echo: function echo(str, highlightGroup, flags) { echo: function echo(data, highlightGroup, flags) {
// dactyl.echo uses different order of flags as it omits the highlight group, change commandline.echo argument order? --mst // dactyl.echo uses different order of flags as it omits the highlight group, change commandline.echo argument order? --mst
if (this._silent) if (this._silent)
return; return;
@@ -820,9 +835,9 @@ var CommandLine = Module("commandline", {
highlightGroup = highlightGroup || this.HL_NORMAL; highlightGroup = highlightGroup || this.HL_NORMAL;
if (flags & this.APPEND_TO_MESSAGES) { if (flags & this.APPEND_TO_MESSAGES) {
let message = isObject(str) ? str : { message: str }; let message = isObject(data) ? data : { message: data };
this._messageHistory.add(update({ highlight: highlightGroup }, message)); this._messageHistory.add(update({ highlight: highlightGroup }, message));
str = message.message; data = message.message;
} }
if ((flags & this.ACTIVE_WINDOW) && if ((flags & this.ACTIVE_WINDOW) &&
@@ -836,7 +851,7 @@ var CommandLine = Module("commandline", {
let single = flags & (this.FORCE_SINGLELINE | this.DISALLOW_MULTILINE); let single = flags & (this.FORCE_SINGLELINE | this.DISALLOW_MULTILINE);
let action = this._echoLine; let action = this._echoLine;
if ((flags & this.FORCE_MULTILINE) || (/\n/.test(str) || !isString(str)) && !(flags & this.FORCE_SINGLELINE)) if ((flags & this.FORCE_MULTILINE) || (/\n/.test(data) || !isString(data)) && !(flags & this.FORCE_SINGLELINE))
action = this._echoMultiline; action = this._echoMultiline;
if (single) if (single)
@@ -851,13 +866,13 @@ var CommandLine = Module("commandline", {
highlightGroup += " Message"; highlightGroup += " Message";
action = this._echoMultiline; action = this._echoMultiline;
} }
this._lastEcho = (action == this._echoLine) && str; this._lastEcho = (action == this._echoLine) && data;
} }
this._lastClearable = action === this._echoLine && String(str); this._lastClearable = action === this._echoLine && String(data);
if (action) if (action)
action.call(this, str, highlightGroup, single); action.call(this, data, highlightGroup, single);
}, },
/** /**
@@ -1215,6 +1230,7 @@ var CommandLine = Module("commandline", {
function observe(str, highlight, dom) { function observe(str, highlight, dom) {
buffer.push(dom && !isString(str) ? util.domToString(dom) : str); buffer.push(dom && !isString(str) ? util.domToString(dom) : str);
} }
this.savingOutput = true; this.savingOutput = true;
dactyl.trapErrors.apply(dactyl, [fn, self].concat(Array.slice(arguments, 2))); dactyl.trapErrors.apply(dactyl, [fn, self].concat(Array.slice(arguments, 2)));
this.savingOutput = false; this.savingOutput = false;

View File

@@ -178,10 +178,18 @@ var DownloadList = Class("DownloadList",
XPCOM([Ci.nsIDownloadProgressListener, XPCOM([Ci.nsIDownloadProgressListener,
Ci.nsIObserver, Ci.nsIObserver,
Ci.nsISupportsWeakReference]), { Ci.nsISupportsWeakReference]), {
init: function init(document, modules) { init: function init(modules) {
this.modules = modules; this.modules = modules;
this.document = document;
this.nodes = {}; this.nodes = {};
this.downloads = {};
},
cleanup: function cleanup() {
this.observe.unregister();
services.downloadManager.removeListener(this);
},
message: Class.memoize(function () {
util.xmlToDom(<ul highlight="Downloads" key="list" xmlns={XHTML}> util.xmlToDom(<ul highlight="Downloads" key="list" xmlns={XHTML}>
<li highlight="DownloadHead"> <li highlight="DownloadHead">
<span>Title</span> <span>Title</span>
@@ -194,20 +202,14 @@ var DownloadList = Class("DownloadList",
</li> </li>
</ul>, this.document, this.nodes); </ul>, this.document, this.nodes);
this.downloads = {};
for (let row in iter(services.downloadManager.DBConnection for (let row in iter(services.downloadManager.DBConnection
.createStatement("SELECT id FROM moz_downloads"))) .createStatement("SELECT id FROM moz_downloads")))
this.addDownload(row.id); this.addDownload(row.id);
},
initialize: function initialize() {
util.addObserver(this); util.addObserver(this);
services.downloadManager.addListener(this); services.downloadManager.addListener(this);
return this.nodes.list; return this.nodes.list;
}, }),
cleanup: function cleanup() {
this.observe.unregister();
services.downloadManager.removeListener(this);
},
addDownload: function addDownload(id) { addDownload: function addDownload(id) {
if (!(id in this.downloads)) { if (!(id in this.downloads)) {
@@ -281,15 +283,11 @@ var Downloads = Module("downloads", {
commands.add(["downl[oads]", "dl"], commands.add(["downl[oads]", "dl"],
"Display the downloads list", "Display the downloads list",
function (args) { function (args) {
modules.commandline.echo(function (doc) { let downloads = DownloadList(modules);
let downloads = DownloadList(doc, modules); modules.commandline.echo(downloads);
// Temporary and dangerous hack:
Object.defineProperty(modules.modes.getStack(0), "params", { if (modules.commandline.savingOutput)
get: function params() downloads, util.waitFor(function () downloads.document);
set: function params(val) { throw FailedAssertion("Not replacing mode change handler", 1) }
});
return downloads.initialize();
});
}); });
}, },
dactyl: function (dactyl, modules, window) { dactyl: function (dactyl, modules, window) {