mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-24 00:32:27 +01:00
move some completion code to completion.js
This commit is contained in:
@@ -283,7 +283,7 @@ liberator.Bookmarks = function () //{{{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
bang: true,
|
bang: true,
|
||||||
completer: function (filter) [0, liberator.bookmarks.get(filter)],
|
completer: function (filter) liberator.completion.bookmark(filter),
|
||||||
options: [[["-tags", "-T"], liberator.commands.OPTION_LIST]]
|
options: [[["-tags", "-T"], liberator.commands.OPTION_LIST]]
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -296,7 +296,7 @@ liberator.Bookmarks = function () //{{{
|
|||||||
|
|
||||||
liberator.echo(deletedCount + " bookmark(s) with url `" + url + "' deleted", liberator.commandline.FORCE_SINGLELINE);
|
liberator.echo(deletedCount + " bookmark(s) with url `" + url + "' deleted", liberator.commandline.FORCE_SINGLELINE);
|
||||||
},
|
},
|
||||||
{ completer: function (filter) [0, liberator.bookmarks.get(filter)] });
|
{ completer: function (filter) liberator.completion.bookmark(filter) });
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////}}}
|
/////////////////////////////////////////////////////////////////////////////}}}
|
||||||
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
||||||
@@ -696,7 +696,7 @@ liberator.History = function () //{{{
|
|||||||
function (args, special) { liberator.history.list(args, special); },
|
function (args, special) { liberator.history.list(args, special); },
|
||||||
{
|
{
|
||||||
bang: true,
|
bang: true,
|
||||||
completer: function (filter) [0, liberator.history.get(filter)]
|
completer: function (filter) liberator.completion.history(filter)
|
||||||
});
|
});
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////}}}
|
/////////////////////////////////////////////////////////////////////////////}}}
|
||||||
|
|||||||
@@ -805,6 +805,7 @@ liberator.Buffer = function () //{{{
|
|||||||
liberator.buffer.highlight(key, css, special);
|
liberator.buffer.highlight(key, css, special);
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
// TODO: add this as a standard highlight completion function?
|
||||||
completer: function (filter) [0, liberator.completion.filter([[v, ""] for ([k, v] in Iterator(highlightClasses))], filter)],
|
completer: function (filter) [0, liberator.completion.filter([[v, ""] for ([k, v] in Iterator(highlightClasses))], filter)],
|
||||||
hereDoc: true,
|
hereDoc: true,
|
||||||
bang: true,
|
bang: true,
|
||||||
|
|||||||
@@ -510,267 +510,6 @@ liberator.Completion = function () //{{{
|
|||||||
return cacheResults[key];
|
return cacheResults[key];
|
||||||
},
|
},
|
||||||
|
|
||||||
autocommand: function (filter)
|
|
||||||
{
|
|
||||||
let autoCmds = liberator.config.autocommands;
|
|
||||||
return [0, this.filter(autoCmds, filter)];
|
|
||||||
},
|
|
||||||
|
|
||||||
// FIXME: items shouldn't be [[[a], b]], but [[a, b]] and only mapped if at all for bLCS --mst
|
|
||||||
buffer: function (filter)
|
|
||||||
{
|
|
||||||
var items = [];
|
|
||||||
var num = getBrowser().browsers.length;
|
|
||||||
var title, url;
|
|
||||||
|
|
||||||
for (let i = 0; i < num; i++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
title = getBrowser().getBrowserAtIndex(i).contentDocument.title;
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
title = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
url = getBrowser().getBrowserAtIndex(i).contentDocument.location.href;
|
|
||||||
|
|
||||||
if (title.indexOf(filter) == -1 && url.indexOf(filter) == -1 &&
|
|
||||||
(i + 1).toString().indexOf(filter) == -1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (title.indexOf(filter) != -1 || url.indexOf(filter) != -1 ||
|
|
||||||
(i + 1).toString().indexOf(filter) != -1)
|
|
||||||
{
|
|
||||||
if (title == "")
|
|
||||||
title = "(Untitled)";
|
|
||||||
items.push([[(i + 1) + ": " + title, (i + 1) + ": " + url], url]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filter)
|
|
||||||
return [0, items.map(function (i) [i[0][0], i[1]])];
|
|
||||||
|
|
||||||
return [0, buildLongestCommonSubstring(items, filter)];
|
|
||||||
},
|
|
||||||
|
|
||||||
command: function (filter)
|
|
||||||
{
|
|
||||||
var completions = [];
|
|
||||||
|
|
||||||
if (!filter)
|
|
||||||
{
|
|
||||||
for (let command in liberator.commands)
|
|
||||||
completions.push([command.name, command.description]);
|
|
||||||
return [0, completions];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let command in liberator.commands)
|
|
||||||
completions.push([command.longNames, command.description]);
|
|
||||||
|
|
||||||
return [0, buildLongestStartingSubstring(completions, filter)];
|
|
||||||
},
|
|
||||||
|
|
||||||
// TODO: support file:// and \ or / path separators on both platforms
|
|
||||||
// if "tail" is true, only return names without any directory components
|
|
||||||
file: function (filter, tail)
|
|
||||||
{
|
|
||||||
var dir = "", compl = "";
|
|
||||||
var matches = filter.match(/^(.*[\/\\])?(.*?)$/);
|
|
||||||
|
|
||||||
if (matches)
|
|
||||||
{
|
|
||||||
dir = matches[1] || ""; // "" is expanded inside readDirectory to the current dir
|
|
||||||
compl = matches[2] || "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var files = [], mapped = [];
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
files = liberator.io.readDirectory(dir, true);
|
|
||||||
|
|
||||||
if (liberator.options["wildignore"])
|
|
||||||
{
|
|
||||||
var wigRegexp = new RegExp("(^" + liberator.options["wildignore"].replace(",", "|", "g") + ")$");
|
|
||||||
|
|
||||||
files = files.filter(function (f) f.isDirectory() || !wigRegexp.test(f.leafName))
|
|
||||||
}
|
|
||||||
|
|
||||||
mapped = files.map(function (file) [tail ? file.leafName : (dir + file.leafName),
|
|
||||||
file.isDirectory() ? "Directory" : "File"]);
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
return [0, []];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tail)
|
|
||||||
return [dir.length, buildLongestStartingSubstring(mapped, compl, true)];
|
|
||||||
else
|
|
||||||
return [0, buildLongestStartingSubstring(mapped, filter, true)];
|
|
||||||
},
|
|
||||||
|
|
||||||
javascript: function (str)
|
|
||||||
{
|
|
||||||
return javascript.complete(str);
|
|
||||||
},
|
|
||||||
|
|
||||||
macro: function (filter)
|
|
||||||
{
|
|
||||||
var macros = [item for (item in liberator.events.getMacros())];
|
|
||||||
|
|
||||||
return [0, liberator.completion.filter(macros, filter)];
|
|
||||||
},
|
|
||||||
|
|
||||||
search: function (filter)
|
|
||||||
{
|
|
||||||
let results = this.cached("search", filter,
|
|
||||||
function () Array.concat(liberator.bookmarks.getKeywords().map(function (k) [k[0], k[1], k[3]]),
|
|
||||||
liberator.bookmarks.getSearchEngines()),
|
|
||||||
"filter", false, true);
|
|
||||||
return [0, results];
|
|
||||||
},
|
|
||||||
|
|
||||||
// XXX: Move to bookmarks.js?
|
|
||||||
searchEngineSuggest: function (filter, engineAliases)
|
|
||||||
{
|
|
||||||
if (!filter)
|
|
||||||
return [0, []];
|
|
||||||
|
|
||||||
var engineList = (engineAliases || liberator.options["suggestengines"]).split(",");
|
|
||||||
var responseType = "application/x-suggestions+json";
|
|
||||||
var ss = Components.classes["@mozilla.org/browser/search-service;1"]
|
|
||||||
.getService(Components.interfaces.nsIBrowserSearchService);
|
|
||||||
|
|
||||||
var completions = [];
|
|
||||||
engineList.forEach(function (name) {
|
|
||||||
var query = filter;
|
|
||||||
var queryURI;
|
|
||||||
var engine = ss.getEngineByAlias(name);
|
|
||||||
var reg = new RegExp("^\s*(" + name + "\\s+)(.*)$");
|
|
||||||
var matches = query.match(reg);
|
|
||||||
if (matches)
|
|
||||||
query = matches[2];
|
|
||||||
|
|
||||||
if (engine && engine.supportsResponseType(responseType))
|
|
||||||
queryURI = engine.getSubmission(query, responseType).uri.asciiSpec;
|
|
||||||
else
|
|
||||||
return [0, []];
|
|
||||||
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.open("GET", queryURI, false);
|
|
||||||
xhr.send(null);
|
|
||||||
|
|
||||||
var json = Components.classes["@mozilla.org/dom/json;1"]
|
|
||||||
.createInstance(Components.interfaces.nsIJSON);
|
|
||||||
var results = json.decode(xhr.responseText)[1];
|
|
||||||
if (!results)
|
|
||||||
return [0, []];
|
|
||||||
|
|
||||||
results.forEach(function (item) {
|
|
||||||
// make sure we receive strings, otherwise a man-in-the-middle attack
|
|
||||||
// could return objects which toString() method could be called to
|
|
||||||
// execute untrusted code
|
|
||||||
if (typeof item != "string")
|
|
||||||
return [0, []];
|
|
||||||
|
|
||||||
completions.push([(matches ? matches[1] : "") + item, engine.name + " suggestion"]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return [0, completions];
|
|
||||||
},
|
|
||||||
|
|
||||||
stylesheet: function (filter)
|
|
||||||
{
|
|
||||||
var completions = liberator.buffer.alternateStyleSheets.map(
|
|
||||||
function (stylesheet) [stylesheet.title, stylesheet.href || "inline"]
|
|
||||||
);
|
|
||||||
|
|
||||||
// unify split style sheets
|
|
||||||
completions.forEach(function (stylesheet) {
|
|
||||||
for (let i = 0; i < completions.length; i++)
|
|
||||||
{
|
|
||||||
if (stylesheet[0] == completions[i][0] && stylesheet[1] != completions[i][1])
|
|
||||||
{
|
|
||||||
stylesheet[1] += ", " + completions[i][1];
|
|
||||||
completions.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return [0, this.filter(completions, filter)];
|
|
||||||
},
|
|
||||||
|
|
||||||
// filter a list of urls
|
|
||||||
//
|
|
||||||
// may consist of search engines, filenames, bookmarks and history,
|
|
||||||
// depending on the 'complete' option
|
|
||||||
// if the 'complete' argument is passed like "h", it temporarily overrides the complete option
|
|
||||||
url: function (filter, complete)
|
|
||||||
{
|
|
||||||
var completions = [];
|
|
||||||
var start = 0;
|
|
||||||
var skip = filter.match("^(.*" + liberator.options["urlseparator"] + ")(.*)"); // start after the last 'urlseparator'
|
|
||||||
if (skip)
|
|
||||||
{
|
|
||||||
start += skip[1].length;
|
|
||||||
filter = skip[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
var cpt = complete || liberator.options["complete"];
|
|
||||||
var suggestEngineAlias = liberator.options["suggestengines"] || "google";
|
|
||||||
// join all completion arrays together
|
|
||||||
for (let c in liberator.util.arrayIter(cpt))
|
|
||||||
{
|
|
||||||
if (c == "s")
|
|
||||||
completions.push(this.search(filter)[1]);
|
|
||||||
else if (c == "f")
|
|
||||||
completions.push(this.file(filter, false)[1]);
|
|
||||||
else if (c == "S")
|
|
||||||
completions.push(this.searchEngineSuggest(filter, suggestEngineAlias)[1]);
|
|
||||||
else if (c == "b")
|
|
||||||
completions.push(liberator.bookmarks.get(filter).map(function (a) [a[0], a[1], a[5]]));
|
|
||||||
else if (c == "h")
|
|
||||||
completions.push(liberator.history.get(filter));
|
|
||||||
else if (c == "l" && completionService) // add completions like Firefox's smart location bar
|
|
||||||
{
|
|
||||||
completionService.stopSearch();
|
|
||||||
completionService.startSearch(filter, "", historyResult, {
|
|
||||||
onSearchResult: function (search, result) {
|
|
||||||
historyResult = result;
|
|
||||||
historyTimer.tell();
|
|
||||||
if (result.searchResult <= result.RESULT_SUCCESS)
|
|
||||||
historyTimer.flush();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
completionCache = liberator.util.flatten(completions);
|
|
||||||
return [start, completionCache.concat(historyCache)];
|
|
||||||
},
|
|
||||||
|
|
||||||
userCommand: function (filter)
|
|
||||||
{
|
|
||||||
var commands = liberator.commands.getUserCommands();
|
|
||||||
commands = commands.map(function (command) [command.name, ""]);
|
|
||||||
return [0, this.filter(commands, filter)];
|
|
||||||
},
|
|
||||||
|
|
||||||
userMapping: function (filter, modes)
|
|
||||||
{
|
|
||||||
// TODO: add appropriate getters to l.mappings
|
|
||||||
var mappings = [];
|
|
||||||
|
|
||||||
for (let map in liberator.mappings.getUserIterator(modes))
|
|
||||||
mappings.push([map.names[0], ""]);
|
|
||||||
|
|
||||||
return [0, this.filter(mappings, filter)];
|
|
||||||
},
|
|
||||||
|
|
||||||
// discard all entries in the 'urls' array, which don't match 'filter
|
// discard all entries in the 'urls' array, which don't match 'filter
|
||||||
// urls must be of type [["url", "title"], [...]] or optionally
|
// urls must be of type [["url", "title"], [...]] or optionally
|
||||||
// [["url", "title", keyword, [tags]], [...]]
|
// [["url", "title", keyword, [tags]], [...]]
|
||||||
@@ -865,6 +604,72 @@ liberator.Completion = function () //{{{
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////// COMPLETION TYPES ////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////////////////{{{
|
||||||
|
|
||||||
|
bookmark: function (filter) [0, liberator.bookmarks.get(filter)],
|
||||||
|
|
||||||
|
// FIXME: items shouldn't be [[[a], b]], but [[a, b]] and only mapped if at all for bLCS --mst
|
||||||
|
buffer: function (filter)
|
||||||
|
{
|
||||||
|
var items = [];
|
||||||
|
var num = getBrowser().browsers.length;
|
||||||
|
var title, url;
|
||||||
|
|
||||||
|
for (let i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
title = getBrowser().getBrowserAtIndex(i).contentDocument.title;
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
title = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
url = getBrowser().getBrowserAtIndex(i).contentDocument.location.href;
|
||||||
|
|
||||||
|
if (title.indexOf(filter) == -1 && url.indexOf(filter) == -1 &&
|
||||||
|
(i + 1).toString().indexOf(filter) == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (title.indexOf(filter) != -1 || url.indexOf(filter) != -1 ||
|
||||||
|
(i + 1).toString().indexOf(filter) != -1)
|
||||||
|
{
|
||||||
|
if (title == "")
|
||||||
|
title = "(Untitled)";
|
||||||
|
items.push([[(i + 1) + ": " + title, (i + 1) + ": " + url], url]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filter)
|
||||||
|
return [0, items.map(function (i) [i[0][0], i[1]])];
|
||||||
|
|
||||||
|
return [0, buildLongestCommonSubstring(items, filter)];
|
||||||
|
},
|
||||||
|
|
||||||
|
command: function (filter)
|
||||||
|
{
|
||||||
|
var completions = [];
|
||||||
|
|
||||||
|
if (!filter)
|
||||||
|
{
|
||||||
|
for (let command in liberator.commands)
|
||||||
|
completions.push([command.name, command.description]);
|
||||||
|
return [0, completions];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let command in liberator.commands)
|
||||||
|
completions.push([command.longNames, command.description]);
|
||||||
|
|
||||||
|
return [0, buildLongestStartingSubstring(completions, filter)];
|
||||||
|
},
|
||||||
|
|
||||||
|
dialog: function (filter) [0, this.filter(liberator.config.dialogs || [], filter)],
|
||||||
|
|
||||||
|
event: function (filter) [0, this.filter(liberator.config.autocommands, filter)],
|
||||||
|
|
||||||
// provides completions for ex commands, including their arguments
|
// provides completions for ex commands, including their arguments
|
||||||
ex: function (str)
|
ex: function (str)
|
||||||
{
|
{
|
||||||
@@ -889,7 +694,247 @@ liberator.Completion = function () //{{{
|
|||||||
[start, completions] = command.completer.call(this, args, special);
|
[start, completions] = command.completer.call(this, args, special);
|
||||||
}
|
}
|
||||||
return [exLength + start, completions];
|
return [exLength + start, completions];
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO: support file:// and \ or / path separators on both platforms
|
||||||
|
// if "tail" is true, only return names without any directory components
|
||||||
|
file: function (filter, tail)
|
||||||
|
{
|
||||||
|
var dir = "", compl = "";
|
||||||
|
var matches = filter.match(/^(.*[\/\\])?(.*?)$/);
|
||||||
|
|
||||||
|
if (matches)
|
||||||
|
{
|
||||||
|
dir = matches[1] || ""; // "" is expanded inside readDirectory to the current dir
|
||||||
|
compl = matches[2] || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var files = [], mapped = [];
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
files = liberator.io.readDirectory(dir, true);
|
||||||
|
|
||||||
|
if (liberator.options["wildignore"])
|
||||||
|
{
|
||||||
|
var wigRegexp = new RegExp("(^" + liberator.options["wildignore"].replace(",", "|", "g") + ")$");
|
||||||
|
|
||||||
|
files = files.filter(function (f) f.isDirectory() || !wigRegexp.test(f.leafName))
|
||||||
|
}
|
||||||
|
|
||||||
|
mapped = files.map(function (file) [tail ? file.leafName : (dir + file.leafName),
|
||||||
|
file.isDirectory() ? "Directory" : "File"]);
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
return [0, []];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tail)
|
||||||
|
return [dir.length, buildLongestStartingSubstring(mapped, compl, true)];
|
||||||
|
else
|
||||||
|
return [0, buildLongestStartingSubstring(mapped, filter, true)];
|
||||||
|
},
|
||||||
|
|
||||||
|
help: function (filter)
|
||||||
|
{
|
||||||
|
var files = liberator.config.helpFiles || [];
|
||||||
|
var res = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var xmlhttp = new XMLHttpRequest();
|
||||||
|
xmlhttp.open("GET", "chrome://" + liberator.config.name.toLowerCase() + "/locale/" + files[i], false);
|
||||||
|
xmlhttp.send(null);
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
liberator.log("Error opening chrome://" + liberator.config.name.toLowerCase() + "/locale/" + files[i], 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var doc = xmlhttp.responseXML;
|
||||||
|
var elems = doc.getElementsByClassName("tag");
|
||||||
|
for (let j = 0; j < elems.length; j++)
|
||||||
|
res.push([elems[j].textContent, files[i]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [0, this.filter(res, filter)];
|
||||||
|
},
|
||||||
|
|
||||||
|
history: function (filter) [0, liberator.history.get(filter)],
|
||||||
|
|
||||||
|
javascript: function (str)
|
||||||
|
{
|
||||||
|
return javascript.complete(str);
|
||||||
|
},
|
||||||
|
|
||||||
|
macro: function (filter)
|
||||||
|
{
|
||||||
|
var macros = [item for (item in liberator.events.getMacros())];
|
||||||
|
|
||||||
|
return [0, this.filter(macros, filter)];
|
||||||
|
},
|
||||||
|
|
||||||
|
search: function (filter)
|
||||||
|
{
|
||||||
|
let results = this.cached("search", filter,
|
||||||
|
function () Array.concat(liberator.bookmarks.getKeywords().map(function (k) [k[0], k[1], k[3]]),
|
||||||
|
liberator.bookmarks.getSearchEngines()),
|
||||||
|
"filter", false, true);
|
||||||
|
return [0, results];
|
||||||
|
},
|
||||||
|
|
||||||
|
// XXX: Move to bookmarks.js?
|
||||||
|
searchEngineSuggest: function (filter, engineAliases)
|
||||||
|
{
|
||||||
|
if (!filter)
|
||||||
|
return [0, []];
|
||||||
|
|
||||||
|
var engineList = (engineAliases || liberator.options["suggestengines"]).split(",");
|
||||||
|
var responseType = "application/x-suggestions+json";
|
||||||
|
var ss = Components.classes["@mozilla.org/browser/search-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIBrowserSearchService);
|
||||||
|
|
||||||
|
var completions = [];
|
||||||
|
engineList.forEach(function (name) {
|
||||||
|
var query = filter;
|
||||||
|
var queryURI;
|
||||||
|
var engine = ss.getEngineByAlias(name);
|
||||||
|
var reg = new RegExp("^\s*(" + name + "\\s+)(.*)$");
|
||||||
|
var matches = query.match(reg);
|
||||||
|
if (matches)
|
||||||
|
query = matches[2];
|
||||||
|
|
||||||
|
if (engine && engine.supportsResponseType(responseType))
|
||||||
|
queryURI = engine.getSubmission(query, responseType).uri.asciiSpec;
|
||||||
|
else
|
||||||
|
return [0, []];
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", queryURI, false);
|
||||||
|
xhr.send(null);
|
||||||
|
|
||||||
|
var json = Components.classes["@mozilla.org/dom/json;1"]
|
||||||
|
.createInstance(Components.interfaces.nsIJSON);
|
||||||
|
var results = json.decode(xhr.responseText)[1];
|
||||||
|
if (!results)
|
||||||
|
return [0, []];
|
||||||
|
|
||||||
|
results.forEach(function (item) {
|
||||||
|
// make sure we receive strings, otherwise a man-in-the-middle attack
|
||||||
|
// could return objects which toString() method could be called to
|
||||||
|
// execute untrusted code
|
||||||
|
if (typeof item != "string")
|
||||||
|
return [0, []];
|
||||||
|
|
||||||
|
completions.push([(matches ? matches[1] : "") + item, engine.name + " suggestion"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return [0, completions];
|
||||||
|
},
|
||||||
|
|
||||||
|
sidebar: function (filter)
|
||||||
|
{
|
||||||
|
var menu = document.getElementById("viewSidebarMenu");
|
||||||
|
var nodes = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < menu.childNodes.length; i++)
|
||||||
|
nodes.push([menu.childNodes[i].label, ""]);
|
||||||
|
|
||||||
|
return [0, this.filter(nodes, filter)];
|
||||||
|
},
|
||||||
|
|
||||||
|
stylesheet: function (filter)
|
||||||
|
{
|
||||||
|
var completions = liberator.buffer.alternateStyleSheets.map(
|
||||||
|
function (stylesheet) [stylesheet.title, stylesheet.href || "inline"]
|
||||||
|
);
|
||||||
|
|
||||||
|
// unify split style sheets
|
||||||
|
completions.forEach(function (stylesheet) {
|
||||||
|
for (let i = 0; i < completions.length; i++)
|
||||||
|
{
|
||||||
|
if (stylesheet[0] == completions[i][0] && stylesheet[1] != completions[i][1])
|
||||||
|
{
|
||||||
|
stylesheet[1] += ", " + completions[i][1];
|
||||||
|
completions.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return [0, this.filter(completions, filter)];
|
||||||
|
},
|
||||||
|
|
||||||
|
// filter a list of urls
|
||||||
|
//
|
||||||
|
// may consist of search engines, filenames, bookmarks and history,
|
||||||
|
// depending on the 'complete' option
|
||||||
|
// if the 'complete' argument is passed like "h", it temporarily overrides the complete option
|
||||||
|
url: function (filter, complete)
|
||||||
|
{
|
||||||
|
var completions = [];
|
||||||
|
var start = 0;
|
||||||
|
var skip = filter.match("^(.*" + liberator.options["urlseparator"] + ")(.*)"); // start after the last 'urlseparator'
|
||||||
|
if (skip)
|
||||||
|
{
|
||||||
|
start += skip[1].length;
|
||||||
|
filter = skip[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
var cpt = complete || liberator.options["complete"];
|
||||||
|
var suggestEngineAlias = liberator.options["suggestengines"] || "google";
|
||||||
|
// join all completion arrays together
|
||||||
|
for (let c in liberator.util.arrayIter(cpt))
|
||||||
|
{
|
||||||
|
if (c == "s")
|
||||||
|
completions.push(this.search(filter)[1]);
|
||||||
|
else if (c == "f")
|
||||||
|
completions.push(this.file(filter, false)[1]);
|
||||||
|
else if (c == "S")
|
||||||
|
completions.push(this.searchEngineSuggest(filter, suggestEngineAlias)[1]);
|
||||||
|
else if (c == "b")
|
||||||
|
completions.push(liberator.bookmarks.get(filter).map(function (a) [a[0], a[1], a[5]]));
|
||||||
|
else if (c == "h")
|
||||||
|
completions.push(liberator.history.get(filter));
|
||||||
|
else if (c == "l" && completionService) // add completions like Firefox's smart location bar
|
||||||
|
{
|
||||||
|
completionService.stopSearch();
|
||||||
|
completionService.startSearch(filter, "", historyResult, {
|
||||||
|
onSearchResult: function (search, result) {
|
||||||
|
historyResult = result;
|
||||||
|
historyTimer.tell();
|
||||||
|
if (result.searchResult <= result.RESULT_SUCCESS)
|
||||||
|
historyTimer.flush();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
completionCache = liberator.util.flatten(completions);
|
||||||
|
return [start, completionCache.concat(historyCache)];
|
||||||
|
},
|
||||||
|
|
||||||
|
userCommand: function (filter)
|
||||||
|
{
|
||||||
|
var commands = liberator.commands.getUserCommands();
|
||||||
|
commands = commands.map(function (command) [command.name, ""]);
|
||||||
|
return [0, this.filter(commands, filter)];
|
||||||
|
},
|
||||||
|
|
||||||
|
userMapping: function (filter, modes)
|
||||||
|
{
|
||||||
|
// TODO: add appropriate getters to l.mappings
|
||||||
|
var mappings = [];
|
||||||
|
|
||||||
|
for (let map in liberator.mappings.getUserIterator(modes))
|
||||||
|
mappings.push([map.names[0], ""]);
|
||||||
|
|
||||||
|
return [0, this.filter(mappings, filter)];
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
};
|
};
|
||||||
//}}}
|
//}}}
|
||||||
}; //}}}
|
}; //}}}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ liberator.AutoCommands = function () //{{{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
bang: true,
|
bang: true,
|
||||||
completer: function (filter) liberator.completion.autocommand(filter)
|
completer: function (filter) liberator.completion.event(filter)
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: expand target to all buffers
|
// TODO: expand target to all buffers
|
||||||
@@ -139,7 +139,7 @@ liberator.AutoCommands = function () //{{{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
argCount: "+",
|
argCount: "+",
|
||||||
completer: function (filter) liberator.completion.autocommand(filter)
|
completer: function (filter) liberator.completion.event(filter)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ liberator.AutoCommands = function () //{{{
|
|||||||
{
|
{
|
||||||
// TODO: Vim actually just displays "No matching autocommands" when no arg is specified
|
// TODO: Vim actually just displays "No matching autocommands" when no arg is specified
|
||||||
argCount: "+",
|
argCount: "+",
|
||||||
completer: function (filter) liberator.completion.autocommand(filter)
|
completer: function (filter) liberator.completion.event(filter)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -241,11 +241,10 @@ const liberator = (function () //{{{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
argCount: "+", // NOTE: single arg may contain unescaped whitespace
|
argCount: "+", // NOTE: single arg may contain unescaped whitespace
|
||||||
|
// TODO: add this as a standard menu completion function
|
||||||
completer: function (filter)
|
completer: function (filter)
|
||||||
{
|
{
|
||||||
var completions = getMenuItems().map(
|
let completions = getMenuItems().map(function (item) [item.fullMenuPath, item.label]);
|
||||||
function (item) [item.fullMenuPath, item.label]
|
|
||||||
);
|
|
||||||
return [0, liberator.completion.filter(completions, filter)];
|
return [0, liberator.completion.filter(completions, filter)];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -313,7 +312,7 @@ const liberator = (function () //{{{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
bang: true,
|
bang: true,
|
||||||
completer: function (filter) getHelpCompletions(filter)
|
completer: function (filter) liberator.completion.help(filter)
|
||||||
});
|
});
|
||||||
|
|
||||||
liberator.commands.add(["javas[cript]", "js"],
|
liberator.commands.add(["javas[cript]", "js"],
|
||||||
@@ -543,33 +542,6 @@ const liberator = (function () //{{{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHelpCompletions(filter)
|
|
||||||
{
|
|
||||||
var files = liberator.config.helpFiles || [];
|
|
||||||
var res = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < files.length; i++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var xmlhttp = new XMLHttpRequest();
|
|
||||||
xmlhttp.open("GET", "chrome://" + liberator.config.name.toLowerCase() + "/locale/" + files[i], false);
|
|
||||||
xmlhttp.send(null);
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
liberator.log("Error opening chrome://" + liberator.config.name.toLowerCase() + "/locale/" + files[i], 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var doc = xmlhttp.responseXML;
|
|
||||||
var elems = doc.getElementsByClassName("tag");
|
|
||||||
for (let j = 0; j < elems.length; j++)
|
|
||||||
res.push([elems[j].textContent, files[i]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [0, liberator.completion.filter(res, filter)];
|
|
||||||
}
|
|
||||||
|
|
||||||
// initially hide all GUI, it is later restored unless the user has :set go= or something
|
// initially hide all GUI, it is later restored unless the user has :set go= or something
|
||||||
// similar in his config
|
// similar in his config
|
||||||
function hideGUI()
|
function hideGUI()
|
||||||
@@ -905,7 +877,7 @@ const liberator = (function () //{{{
|
|||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
var [, items] = getHelpCompletions(topic);
|
var [, items] = liberator.completion.help(topic);
|
||||||
var partialMatch = -1;
|
var partialMatch = -1;
|
||||||
|
|
||||||
for (let i = 0; i < items.length; i++)
|
for (let i = 0; i < items.length; i++)
|
||||||
|
|||||||
@@ -331,16 +331,7 @@ liberator.config = { //{{{
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
argCount: "+",
|
argCount: "+",
|
||||||
completer: function (filter)
|
completer: function (filter) liberator.completion.sidebar(filter)
|
||||||
{
|
|
||||||
var menu = document.getElementById("viewSidebarMenu");
|
|
||||||
var nodes = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < menu.childNodes.length; i++)
|
|
||||||
nodes.push([menu.childNodes[i].label, ""]);
|
|
||||||
|
|
||||||
return [0, liberator.completion.filter(nodes, filter)];
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
liberator.commands.add(["winc[lose]", "wc[lose]"],
|
liberator.commands.add(["winc[lose]", "wc[lose]"],
|
||||||
|
|||||||
Reference in New Issue
Block a user