mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-22 15:18:00 +01:00
Display a sensible prompt rather than a dialog for ;s. Co-opt ;a for "Add bookmark".
This commit is contained in:
@@ -104,7 +104,11 @@ var Bookmarks = Module("bookmarks", {
|
|||||||
* @param {Element} elem A form element for which to add a keyword.
|
* @param {Element} elem A form element for which to add a keyword.
|
||||||
*/
|
*/
|
||||||
addSearchKeyword: function (elem) {
|
addSearchKeyword: function (elem) {
|
||||||
let [url, post, charset] = util.parseForm(elem);
|
if (elem instanceof HTMLFormElement || elem.form)
|
||||||
|
var [url, post, charset] = util.parseForm(elem);
|
||||||
|
else
|
||||||
|
var [url, post, charset] = [elem.href || elem.src, null, elem.ownerDocument.characterSet];
|
||||||
|
|
||||||
let options = { "-title": "Search " + elem.ownerDocument.title };
|
let options = { "-title": "Search " + elem.ownerDocument.title };
|
||||||
if (post != null)
|
if (post != null)
|
||||||
options["-post"] = post;
|
options["-post"] = post;
|
||||||
|
|||||||
@@ -162,12 +162,38 @@ var Buffer = Module("buffer", {
|
|||||||
destroy: function () {
|
destroy: function () {
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultNames: function getDefaultNames(doc) {
|
getDefaultNames: function getDefaultNames(node) {
|
||||||
let ext = services.mime.getPrimaryExtension(doc.contentType, doc.location.href.replace(/.*\./, ""));
|
let url = node.href || node.src || node.documentURI;
|
||||||
return [[doc.title, "Page Name"], [doc.location.pathname.replace(/.*\//, ""), "File Name"]]
|
let currExt = url.replace(/.*(?:\.([a-z0-9]+))?$/, "$1").toLowerCase();
|
||||||
.filter(function ([leaf, title]) leaf)
|
|
||||||
|
if (isinstance(node, [Document, HTMLImageElement])) {
|
||||||
|
let type = node.contentType || node.QueryInterface(Ci.nsIImageLoadingContent)
|
||||||
|
.getRequest(0).mimeType;
|
||||||
|
|
||||||
|
var ext = "." + services.mime.getPrimaryExtension(type, currExt);
|
||||||
|
}
|
||||||
|
else if (currExt)
|
||||||
|
ext = "." + currExt;
|
||||||
|
else
|
||||||
|
ext = "";
|
||||||
|
let re = ext ? RegExp("(\\." + currExt + ")?$") : /$/;
|
||||||
|
util.dump(ext.quote(),
|
||||||
|
isinstance(node, [Document, HTMLImageElement]),
|
||||||
|
node.contentType);
|
||||||
|
|
||||||
|
var names = [];
|
||||||
|
if (node.title)
|
||||||
|
names.push([node.title, "Page Name"]);
|
||||||
|
if (node.alt)
|
||||||
|
names.push([node.alt, "Alternate Text"]);
|
||||||
|
if (!isinstance(node, Document) && node.textContent)
|
||||||
|
names.push([node.textContent, "Link Text"]);
|
||||||
|
|
||||||
|
names.push([decodeURIComponent(url.replace(/.*?([^\/]*)\/*$/, "$1")), "File Name"]);
|
||||||
|
|
||||||
|
return names.filter(function ([leaf, title]) leaf)
|
||||||
.map(function ([leaf, title]) [leaf.replace(util.OS.illegalCharacters, encodeURIComponent)
|
.map(function ([leaf, title]) [leaf.replace(util.OS.illegalCharacters, encodeURIComponent)
|
||||||
.replace(RegExp("(\\." + ext + ")?$"), "." + ext), title]);
|
.replace(re, ext), title]);
|
||||||
},
|
},
|
||||||
|
|
||||||
_triggerLoadAutocmd: function _triggerLoadAutocmd(name, doc, uri) {
|
_triggerLoadAutocmd: function _triggerLoadAutocmd(name, doc, uri) {
|
||||||
@@ -741,14 +767,34 @@ var Buffer = Module("buffer", {
|
|||||||
*/
|
*/
|
||||||
saveLink: function (elem, skipPrompt) {
|
saveLink: function (elem, skipPrompt) {
|
||||||
let doc = elem.ownerDocument;
|
let doc = elem.ownerDocument;
|
||||||
let url = window.makeURLAbsolute(elem.baseURI, elem.href);
|
let uri = util.newURI(elem.href || elem.src, null, util.newURI(elem.baseURI));
|
||||||
let text = elem.textContent;
|
let referrer = util.newURI(doc.documentURI, doc.characterSet);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
window.urlSecurityCheck(url, doc.nodePrincipal);
|
window.urlSecurityCheck(uri.spec, doc.nodePrincipal);
|
||||||
// we always want to save that link relative to the current working directory
|
|
||||||
prefs.set("browser.download.lastDir", io.cwd);
|
commandline.input("Save link: ", function (path) {
|
||||||
window.saveURL(url, text, null, true, skipPrompt, makeURI(url, doc.characterSet));
|
let file = io.File(path);
|
||||||
|
if (file.exists() && file.isDirectory())
|
||||||
|
file.append(buffer.getDefaultNames(elem)[0][0]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!file.exists())
|
||||||
|
file.create(File.NORMAL_FILE_TYPE, octal(644));
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
util.assert(false, "Invalid destination: " + e.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
var persist = services.Persist();
|
||||||
|
persist.persistFlags = persist.PERSIST_FLAGS_FROM_CACHE
|
||||||
|
| persist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
|
||||||
|
persist.saveURI(uri, null, null, null, null, file);
|
||||||
|
}, {
|
||||||
|
autocomplete: true,
|
||||||
|
completer: function (context) completion.savePage(context, elem),
|
||||||
|
history: "file"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
dactyl.echoerr(e);
|
dactyl.echoerr(e);
|
||||||
@@ -1365,11 +1411,7 @@ var Buffer = Module("buffer", {
|
|||||||
if (/^>>/.test(context.filter))
|
if (/^>>/.test(context.filter))
|
||||||
context.advance(/^>>\s*/.exec(context.filter)[0].length);
|
context.advance(/^>>\s*/.exec(context.filter)[0].length);
|
||||||
|
|
||||||
context.fork("generated", context.filter.replace(/[^/]*$/, "").length,
|
return completion.savePage(context, content.document);
|
||||||
this, function (context) {
|
|
||||||
context.completions = buffer.getDefaultNames(content.document);
|
|
||||||
});
|
|
||||||
return context.fork("files", 0, completion, "file");
|
|
||||||
},
|
},
|
||||||
literal: 0
|
literal: 0
|
||||||
});
|
});
|
||||||
@@ -1475,6 +1517,14 @@ var Buffer = Module("buffer", {
|
|||||||
});
|
});
|
||||||
}, vals);
|
}, vals);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
completion.savePage = function savePage(context, node) {
|
||||||
|
context.fork("generated", context.filter.replace(/[^/]*$/, "").length,
|
||||||
|
this, function (context) {
|
||||||
|
context.completions = buffer.getDefaultNames(node);
|
||||||
|
});
|
||||||
|
return context.fork("files", 0, completion, "file");
|
||||||
|
};
|
||||||
},
|
},
|
||||||
events: function () {
|
events: function () {
|
||||||
events.addSessionListener(config.browser, "DOMContentLoaded", this.closure.onDOMContentLoaded, true);
|
events.addSessionListener(config.browser, "DOMContentLoaded", this.closure.onDOMContentLoaded, true);
|
||||||
|
|||||||
@@ -461,14 +461,14 @@ var CommandLine = Module("commandline", {
|
|||||||
let callback = self._input.cancel;
|
let callback = self._input.cancel;
|
||||||
self._input = {};
|
self._input = {};
|
||||||
if (callback)
|
if (callback)
|
||||||
callback.call(self, value != null ? value : commandline.command);
|
dactyl.trapErrors(callback, self, value != null ? value : commandline.command);
|
||||||
}
|
}
|
||||||
|
|
||||||
function closePrompt(value) {
|
function closePrompt(value) {
|
||||||
let callback = self._input.submit;
|
let callback = self._input.submit;
|
||||||
self._input = {};
|
self._input = {};
|
||||||
if (callback)
|
if (callback)
|
||||||
callback.call(self, value != null ? value : commandline.command);
|
dactyl.trapErrors(callback, self, value != null ? value : commandline.command);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -540,7 +540,12 @@ var CommandLine = Module("commandline", {
|
|||||||
|
|
||||||
triggerCallback: function (type, mode) {
|
triggerCallback: function (type, mode) {
|
||||||
if (this._callbacks[type] && this._callbacks[type][mode])
|
if (this._callbacks[type] && this._callbacks[type][mode])
|
||||||
|
try {
|
||||||
this._callbacks[type][mode].apply(this, Array.slice(arguments, 2));
|
this._callbacks[type][mode].apply(this, Array.slice(arguments, 2));
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
dactyl.reportError(e, true);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
runSilently: function (func, self) {
|
runSilently: function (func, self) {
|
||||||
@@ -588,6 +593,7 @@ var CommandLine = Module("commandline", {
|
|||||||
this.widgets.message = null;
|
this.widgets.message = null;
|
||||||
|
|
||||||
modes.push(modes.COMMAND_LINE, this.currentExtendedMode, {
|
modes.push(modes.COMMAND_LINE, this.currentExtendedMode, {
|
||||||
|
autocomplete: cmd.length,
|
||||||
onEvent: this.closure.onEvent,
|
onEvent: this.closure.onEvent,
|
||||||
history: (extendedMode || {}).params.history,
|
history: (extendedMode || {}).params.history,
|
||||||
leave: function (params) {
|
leave: function (params) {
|
||||||
@@ -605,18 +611,19 @@ var CommandLine = Module("commandline", {
|
|||||||
this.widgets.command = cmd || "";
|
this.widgets.command = cmd || "";
|
||||||
|
|
||||||
this.enter();
|
this.enter();
|
||||||
|
|
||||||
// open the completion list automatically if wanted
|
|
||||||
if (cmd.length) {
|
|
||||||
commandline.triggerCallback("change", this.currentExtendedMode, cmd);
|
|
||||||
this._autocompleteTimer.flush();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
enter: function enter() {
|
enter: function enter() {
|
||||||
if (modes.getStack(0).params.history)
|
let params = modes.getStack(0).params;
|
||||||
this._history = CommandLine.History(this.widgets.active.command.inputField, modes.getStack(0).params.history);
|
|
||||||
|
if (params.history)
|
||||||
|
this._history = CommandLine.History(this.widgets.active.command.inputField, params.history);
|
||||||
this._completions = CommandLine.Completions(this.widgets.active.command.inputField);
|
this._completions = CommandLine.Completions(this.widgets.active.command.inputField);
|
||||||
|
|
||||||
|
if (params.autocomplete) {
|
||||||
|
commandline.triggerCallback("change", this.currentExtendedMode, commandline.command);
|
||||||
|
this._autocompleteTimer.flush();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -50,8 +50,7 @@ var Hints = Module("hints", {
|
|||||||
this._hintModes = {};
|
this._hintModes = {};
|
||||||
this.addMode(";", "Focus hint", buffer.closure.focusElement);
|
this.addMode(";", "Focus hint", buffer.closure.focusElement);
|
||||||
this.addMode("?", "Show information for hint", function (elem) buffer.showElementInfo(elem));
|
this.addMode("?", "Show information for hint", function (elem) buffer.showElementInfo(elem));
|
||||||
this.addMode("s", "Save hint", function (elem) buffer.saveLink(elem, true));
|
this.addMode("s", "Save hint", function (elem) buffer.saveLink(elem, false));
|
||||||
this.addMode("a", "Save hint with prompt", function (elem) buffer.saveLink(elem, false));
|
|
||||||
this.addMode("f", "Focus frame", function (elem) dactyl.focus(elem.ownerDocument.defaultView));
|
this.addMode("f", "Focus frame", function (elem) dactyl.focus(elem.ownerDocument.defaultView));
|
||||||
this.addMode("F", "Focus frame or pseudo-frame", buffer.closure.focusElement, null, isScrollable);
|
this.addMode("F", "Focus frame or pseudo-frame", buffer.closure.focusElement, null, isScrollable);
|
||||||
this.addMode("o", "Follow hint", function (elem) buffer.followLink(elem, dactyl.CURRENT_TAB));
|
this.addMode("o", "Follow hint", function (elem) buffer.followLink(elem, dactyl.CURRENT_TAB));
|
||||||
@@ -61,6 +60,7 @@ var Hints = Module("hints", {
|
|||||||
this.addMode("O", "Generate an ‘:open URL’ prompt", function (elem, loc) commandline.open(":", "open " + loc, modes.EX));
|
this.addMode("O", "Generate an ‘:open URL’ prompt", function (elem, loc) commandline.open(":", "open " + loc, modes.EX));
|
||||||
this.addMode("T", "Generate a ‘:tabopen URL’ prompt", function (elem, loc) commandline.open(":", "tabopen " + loc, modes.EX));
|
this.addMode("T", "Generate a ‘:tabopen URL’ prompt", function (elem, loc) commandline.open(":", "tabopen " + loc, modes.EX));
|
||||||
this.addMode("W", "Generate a ‘:winopen URL’ prompt", function (elem, loc) commandline.open(":", "winopen " + loc, modes.EX));
|
this.addMode("W", "Generate a ‘:winopen URL’ prompt", function (elem, loc) commandline.open(":", "winopen " + loc, modes.EX));
|
||||||
|
this.addMode("a", "Add a bookmark", function (elem) bookmarks.addSearchKeyword(elem));
|
||||||
this.addMode("S", "Add a search keyword", function (elem) bookmarks.addSearchKeyword(elem));
|
this.addMode("S", "Add a search keyword", function (elem) bookmarks.addSearchKeyword(elem));
|
||||||
this.addMode("v", "View hint source", function (elem, loc) buffer.viewSource(loc, false));
|
this.addMode("v", "View hint source", function (elem, loc) buffer.viewSource(loc, false));
|
||||||
this.addMode("V", "View hint source in external editor", function (elem, loc) buffer.viewSource(loc, true));
|
this.addMode("V", "View hint source in external editor", function (elem, loc) buffer.viewSource(loc, true));
|
||||||
@@ -1157,7 +1157,7 @@ var Hints = Module("hints", {
|
|||||||
options.add(["extendedhinttags", "eht"],
|
options.add(["extendedhinttags", "eht"],
|
||||||
"XPath strings of hintable elements for extended hint modes",
|
"XPath strings of hintable elements for extended hint modes",
|
||||||
"regexpmap", "[iI]:" + xpath(["img"]) +
|
"regexpmap", "[iI]:" + xpath(["img"]) +
|
||||||
",[OTivVWy]:" + xpath(["{a,area}[@href]", "{img,iframe}[@src]"]) +
|
",[asOTivVWy]:" + xpath(["{a,area}[@href]", "{img,iframe}[@src]"]) +
|
||||||
",[F]:" + xpath(["body", "code", "div", "html", "p", "pre", "span"]) +
|
",[F]:" + xpath(["body", "code", "div", "html", "p", "pre", "span"]) +
|
||||||
",[S]:" + xpath(["input[not(@type='hidden')]", "textarea", "button", "select"]),
|
",[S]:" + xpath(["input[not(@type='hidden')]", "textarea", "button", "select"]),
|
||||||
{ validator: Option.validateXPath });
|
{ validator: Option.validateXPath });
|
||||||
|
|||||||
@@ -96,7 +96,6 @@
|
|||||||
<li tag=";;"><em>;</em> to focus a link</li>
|
<li tag=";;"><em>;</em> to focus a link</li>
|
||||||
<li tag=";?"><em>?</em> to show information about the element (incomplete)</li>
|
<li tag=";?"><em>?</em> to show information about the element (incomplete)</li>
|
||||||
<li tag=";s"><em>s</em> to save its destination</li>
|
<li tag=";s"><em>s</em> to save its destination</li>
|
||||||
<li tag=";a"><em>a</em> to save its destination (prompting for save location)</li>
|
|
||||||
<li tag=";f"><em>f</em> to focus a frame</li>
|
<li tag=";f"><em>f</em> to focus a frame</li>
|
||||||
<li tag=";F"><em>F</em> to focus a frame or pseudo-frame</li>
|
<li tag=";F"><em>F</em> to focus a frame or pseudo-frame</li>
|
||||||
<li tag=";o"><em>o</em> to open its location in the current tab</li>
|
<li tag=";o"><em>o</em> to open its location in the current tab</li>
|
||||||
@@ -106,6 +105,7 @@
|
|||||||
<li tag=";O"><em>O</em> to generate an <ex>:open</ex> prompt with hint’s URL</li>
|
<li tag=";O"><em>O</em> to generate an <ex>:open</ex> prompt with hint’s URL</li>
|
||||||
<li tag=";T"><em>T</em> to generate a <ex>:tabopen</ex> prompt with hint’s URL (like <k>;O</k>)</li>
|
<li tag=";T"><em>T</em> to generate a <ex>:tabopen</ex> prompt with hint’s URL (like <k>;O</k>)</li>
|
||||||
<li tag=";W"><em>W</em> to generate a <ex>:winopen</ex> prompt with hint’s URL (like <k>;T</k>)</li>
|
<li tag=";W"><em>W</em> to generate a <ex>:winopen</ex> prompt with hint’s URL (like <k>;T</k>)</li>
|
||||||
|
<li tag=";a"><em>a</em> to add a bookmark</li>
|
||||||
<li tag=";S"><em>S</em> to add a search keyword for the hint’s form</li>
|
<li tag=";S"><em>S</em> to add a search keyword for the hint’s form</li>
|
||||||
<li tag=";v"><em>v</em> to view its destination source</li>
|
<li tag=";v"><em>v</em> to view its destination source</li>
|
||||||
<li tag=";V"><em>V</em> to view its destination source in the external editor</li>
|
<li tag=";V"><em>V</em> to view its destination source in the external editor</li>
|
||||||
|
|||||||
@@ -776,7 +776,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
|||||||
/** @property {boolean} True if the OS is some other *nix variant. */
|
/** @property {boolean} True if the OS is some other *nix variant. */
|
||||||
get isUnix() !this.isWindows && !this.isMacOSX,
|
get isUnix() !this.isWindows && !this.isMacOSX,
|
||||||
/** @property {RegExp} A RegExp which matches illegal characters in path components. */
|
/** @property {RegExp} A RegExp which matches illegal characters in path components. */
|
||||||
get illegalCharacters() this.isWindows ? /[<>:"/\\|?*\x00-\x1f]/ : /\//
|
get illegalCharacters() this.isWindows ? /[<>:"/\\|?*\x00-\x1f]/g : /\//g
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -42,7 +42,9 @@
|
|||||||
- Added g; continued extended hint mode, which allows
|
- Added g; continued extended hint mode, which allows
|
||||||
selecting multiple hints. Removed ;F.
|
selecting multiple hints. Removed ;F.
|
||||||
- Hints are now updated after scrolling and window resizing.
|
- Hints are now updated after scrolling and window resizing.
|
||||||
- Added ;S mode for creating search keywords.
|
- ;s now prompts for a filename on the command-line rather
|
||||||
|
than in a dialog.
|
||||||
|
- Added ;a and ;S modes for creating bookmarks and search keywords.
|
||||||
- Added 'hintkeys' option.
|
- Added 'hintkeys' option.
|
||||||
- Added "transliterated" option to 'hintmatching'.
|
- Added "transliterated" option to 'hintmatching'.
|
||||||
* JavaScript completion improvements, including:
|
* JavaScript completion improvements, including:
|
||||||
|
|||||||
Reference in New Issue
Block a user