mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 11:48:00 +01:00
Kill filterURLArray
This commit is contained in:
@@ -63,7 +63,7 @@ function Bookmarks() //{{{
|
|||||||
var bookmarks = [];
|
var bookmarks = [];
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this.__defineGetter__("name", function () key);
|
this.__defineGetter__("name", function () name);
|
||||||
this.__defineGetter__("store", function () store);
|
this.__defineGetter__("store", function () store);
|
||||||
this.__defineGetter__("bookmarks", function () { this.load(); return bookmarks; });
|
this.__defineGetter__("bookmarks", function () { this.load(); return bookmarks; });
|
||||||
|
|
||||||
@@ -324,6 +324,7 @@ function Bookmarks() //{{{
|
|||||||
completer: function completer(context, args)
|
completer: function completer(context, args)
|
||||||
{
|
{
|
||||||
context.quote = null;
|
context.quote = null;
|
||||||
|
context.filter = args.join(" ");
|
||||||
completion.bookmark(context, args["-tags"]);
|
completion.bookmark(context, args["-tags"]);
|
||||||
},
|
},
|
||||||
options: [[["-tags", "-T"], commands.OPTION_LIST, null, tags],
|
options: [[["-tags", "-T"], commands.OPTION_LIST, null, tags],
|
||||||
@@ -359,11 +360,9 @@ function Bookmarks() //{{{
|
|||||||
// if "bypassCache" is true, it will force a reload of the bookmarks database
|
// if "bypassCache" is true, it will force a reload of the bookmarks database
|
||||||
// on my PC, it takes about 1ms for each bookmark to load, so loading 1000 bookmarks
|
// on my PC, it takes about 1ms for each bookmark to load, so loading 1000 bookmarks
|
||||||
// takes about 1 sec
|
// takes about 1 sec
|
||||||
get: function get(filter, tags, bypassCache)
|
get: function get(filter, tags, maxItems)
|
||||||
{
|
{
|
||||||
if (bypassCache) // Is this really necessary anymore?
|
return completion.runCompleter("bookmark", filter, maxItems, tags);
|
||||||
cache.load();
|
|
||||||
return completion.filterURLArray(cache.bookmarks, filter, tags);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// if starOnly = true it is saved in the unfiledBookmarksFolder, otherwise in the bookmarksMenuFolder
|
// if starOnly = true it is saved in the unfiledBookmarksFolder, otherwise in the bookmarksMenuFolder
|
||||||
|
|||||||
@@ -43,9 +43,7 @@ function CompletionContext(editor, name, offset)
|
|||||||
self = this.contexts[name];
|
self = this.contexts[name];
|
||||||
else
|
else
|
||||||
self.contexts[name] = this;
|
self.contexts[name] = this;
|
||||||
self.filters = parent.filters.slice();
|
|
||||||
self.incomplete = false;
|
self.incomplete = false;
|
||||||
self.keys = util.cloneObject(parent.keys);
|
|
||||||
self.message = null;
|
self.message = null;
|
||||||
self.offset = parent.offset + (offset || 0);
|
self.offset = parent.offset + (offset || 0);
|
||||||
self.parent = parent;
|
self.parent = parent;
|
||||||
@@ -53,7 +51,11 @@ function CompletionContext(editor, name, offset)
|
|||||||
delete self._filter; // FIXME?
|
delete self._filter; // FIXME?
|
||||||
delete self._generate;
|
delete self._generate;
|
||||||
delete self._ignoreCase;
|
delete self._ignoreCase;
|
||||||
["anchored", "compare", "editor", "filterFunc", "keys", "_process", "quote", "title", "top"].forEach(function (key)
|
["filters", "keys", "title", "quote"].forEach(function (key) {
|
||||||
|
if (parent[key])
|
||||||
|
self[key] = util.cloneObject(parent[key]);
|
||||||
|
});
|
||||||
|
["anchored", "compare", "editor", "filterFunc", "keys", "_process", "top"].forEach(function (key)
|
||||||
self[key] = parent[key]);
|
self[key] = parent[key]);
|
||||||
if (self != this)
|
if (self != this)
|
||||||
return self;
|
return self;
|
||||||
@@ -103,7 +105,9 @@ function CompletionContext(editor, name, offset)
|
|||||||
this.message = null;
|
this.message = null;
|
||||||
this.name = name || "";
|
this.name = name || "";
|
||||||
this._completions = []; // FIXME
|
this._completions = []; // FIXME
|
||||||
this.getKey = function (item, key) (typeof self.keys[key] == "function") ? self.keys[key].call(this, item) : item.item[self.keys[key]];
|
this.getKey = function (item, key) (typeof self.keys[key] == "function") ? self.keys[key].call(this, item) :
|
||||||
|
key in self.keys ? item.item[self.keys[key]]
|
||||||
|
: item.item[key];
|
||||||
}
|
}
|
||||||
CompletionContext.prototype = {
|
CompletionContext.prototype = {
|
||||||
// Temporary
|
// Temporary
|
||||||
@@ -162,7 +166,7 @@ CompletionContext.prototype = {
|
|||||||
{
|
{
|
||||||
// Accept a generator
|
// Accept a generator
|
||||||
if (!(items instanceof Array))
|
if (!(items instanceof Array))
|
||||||
items = [x for (x in items)];
|
items = [x for (x in Iterator(items))];
|
||||||
delete this.cache.filtered;
|
delete this.cache.filtered;
|
||||||
delete this.cache.filter;
|
delete this.cache.filter;
|
||||||
this.cache.rows = [];
|
this.cache.rows = [];
|
||||||
@@ -1102,67 +1106,6 @@ function Completion() //{{{
|
|||||||
completionService.stopSearch();
|
completionService.stopSearch();
|
||||||
},
|
},
|
||||||
|
|
||||||
// discard all entries in the 'urls' array, which don't match 'filter
|
|
||||||
// urls must be of type [{ url: "..", title: "..", tags: [...], keyword: ".." }, ...]
|
|
||||||
filterURLArray: function filterURLArray(urls, filter, filterTags)
|
|
||||||
{
|
|
||||||
var filtered = [];
|
|
||||||
// completions which don't match the url but just the description
|
|
||||||
// list them at the end of the array
|
|
||||||
var additionalCompletions = [];
|
|
||||||
|
|
||||||
if (urls.length == 0)
|
|
||||||
return [];
|
|
||||||
|
|
||||||
var hasTags = urls[0].tags !== undefined;
|
|
||||||
|
|
||||||
filterTags = filterTags || [];
|
|
||||||
|
|
||||||
// TODO: use ignorecase and smartcase settings
|
|
||||||
var ignorecase = (filter == filter.toLowerCase() && filterTags.every(function checkMixedCase(t) t == t.toLowerCase()));
|
|
||||||
|
|
||||||
if (ignorecase)
|
|
||||||
{
|
|
||||||
filter = filter.toLowerCase();
|
|
||||||
filterTags = filterTags.map(String.toLowerCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Longest Common Subsequence
|
|
||||||
// This shouldn't use buildLongestCommonSubstring for performance
|
|
||||||
// reasons, so as not to cycle through the urls twice
|
|
||||||
let filterTokens = filter.split(/\s+/);
|
|
||||||
for (let [,elem] in Iterator(urls))
|
|
||||||
{
|
|
||||||
let item = elem.item || elem; // Kludge
|
|
||||||
let url = item.url || "";
|
|
||||||
let title = item.title || "";
|
|
||||||
let tags = item.tags || [];
|
|
||||||
if (ignorecase)
|
|
||||||
{
|
|
||||||
url = url.toLowerCase();
|
|
||||||
title = title.toLowerCase();
|
|
||||||
tags = tags.map(String.toLowerCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter on tags
|
|
||||||
if (filterTags.some(function aryIndex(tag) tag && tags.indexOf(tag) == -1))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (url.indexOf(filter) == -1)
|
|
||||||
{
|
|
||||||
// no direct match of filter in the url, but still accept this item
|
|
||||||
// if _all_ tokens of filter match either the url or the title
|
|
||||||
if (filterTokens.every(function (token) url.indexOf(token) > -1 || title.indexOf(token) > -1))
|
|
||||||
additionalCompletions.push(elem);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
filtered.push(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return filtered.concat(additionalCompletions);
|
|
||||||
},
|
|
||||||
|
|
||||||
// generic helper function which checks if the given "items" array pass "filter"
|
// generic helper function which checks if the given "items" array pass "filter"
|
||||||
// items must be an array of strings
|
// items must be an array of strings
|
||||||
match: function match(items, filter, caseSensitive)
|
match: function match(items, filter, caseSensitive)
|
||||||
@@ -1209,10 +1152,10 @@ function Completion() //{{{
|
|||||||
{
|
{
|
||||||
context.title = ["Bookmark", "Title"];
|
context.title = ["Bookmark", "Title"];
|
||||||
context.format = bookmarks.format;
|
context.format = bookmarks.format;
|
||||||
context.completions = bookmarks.get(context.filter)
|
// Need to make a copy because set completions() checks instanceof Array,
|
||||||
context.filters = [];
|
// and this may be an Array from another window.
|
||||||
if (tags)
|
context.completions = Array.slice(storage["bookmark-cache"].bookmarks);
|
||||||
context.filters.push(function ({ item: item }) tags.every(function (tag) item.tags.indexOf(tag) > -1));
|
completion.urls(context, tags);
|
||||||
},
|
},
|
||||||
|
|
||||||
buffer: function buffer(context)
|
buffer: function buffer(context)
|
||||||
@@ -1659,6 +1602,49 @@ function Completion() //{{{
|
|||||||
this.urlCompleters[opt] = UrlCompleter.apply(null, Array.slice(arguments));
|
this.urlCompleters[opt] = UrlCompleter.apply(null, Array.slice(arguments));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
urls: function (context, tags)
|
||||||
|
{
|
||||||
|
let compare = String.localeCompare;
|
||||||
|
let contains = String.indexOf
|
||||||
|
if (context.ignoreCase)
|
||||||
|
{
|
||||||
|
compare = util.compareIgnoreCase;
|
||||||
|
contains = function (a, b) a && a.toLowerCase().indexOf(b.toLowerCase()) > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tags)
|
||||||
|
context.filters.push(function (item) tags.
|
||||||
|
every(function (tag) (context.getKey(item, "tags") || []).
|
||||||
|
some(function (t) !compare(tag, t))));
|
||||||
|
|
||||||
|
if (!context.title)
|
||||||
|
context.title = ["URL", "Title"];
|
||||||
|
|
||||||
|
context.fork("additional", 0, this, function (context) {
|
||||||
|
context.title[0] += " (additional)";
|
||||||
|
context.filter = context.parent.filter; // FIXME
|
||||||
|
context.completions = context.parent.completions;
|
||||||
|
// For items whose URL doesn't exactly match the filter,
|
||||||
|
// accept them if all tokens match either the URL or the title.
|
||||||
|
// Filter out all directly matching strings.
|
||||||
|
let match = context.filters[0];
|
||||||
|
context.filters[0] = function (item) !match.call(this, item);
|
||||||
|
// and all that don't match the tokens.
|
||||||
|
let tokens = context.filter.split(/\s+/);
|
||||||
|
context.filters.push(function (item) tokens.every(
|
||||||
|
function (tok) contains(context.getKey(item, "url"), tok) ||
|
||||||
|
contains(context.getKey(item, "title"), tok)));
|
||||||
|
|
||||||
|
let re = RegExp(tokens.filter(util.identity).map(util.escapeRegex).join("|"), "g");
|
||||||
|
function highlight(item, text, i) process[i].call(this, item, template.highlightRegexp(text, re));
|
||||||
|
let process = [template.icon, function (item, k) k];
|
||||||
|
context.process = [
|
||||||
|
function (item, text) highlight.call(this, item, item.text, 0),
|
||||||
|
function (item, text) highlight.call(this, item, text, 1)
|
||||||
|
];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
userCommand: function userCommand(context)
|
userCommand: function userCommand(context)
|
||||||
{
|
{
|
||||||
context.title = ["User Command", "Definition"];
|
context.title = ["User Command", "Definition"];
|
||||||
|
|||||||
@@ -169,8 +169,11 @@ const template = {
|
|||||||
str = String(str).replace(" ", "\u00a0");
|
str = String(str).replace(" ", "\u00a0");
|
||||||
let s = <></>;
|
let s = <></>;
|
||||||
let start = 0;
|
let start = 0;
|
||||||
|
let n = 0;
|
||||||
for (let [i, length] in iter)
|
for (let [i, length] in iter)
|
||||||
{
|
{
|
||||||
|
if (n++ > 8)
|
||||||
|
return s + <>{str.substr(start)}</>;
|
||||||
XML.ignoreWhitespace = false;
|
XML.ignoreWhitespace = false;
|
||||||
s += <>{str.substring(start, i)}</>;
|
s += <>{str.substring(start, i)}</>;
|
||||||
s += highlight(str.substr(i, length));
|
s += highlight(str.substr(i, length));
|
||||||
|
|||||||
@@ -138,6 +138,8 @@ const util = { //{{{
|
|||||||
|
|
||||||
cloneObject: function cloneObject(obj)
|
cloneObject: function cloneObject(obj)
|
||||||
{
|
{
|
||||||
|
if (obj instanceof Array)
|
||||||
|
return obj.slice();
|
||||||
let newObj = {};
|
let newObj = {};
|
||||||
for (let [k, v] in Iterator(obj))
|
for (let [k, v] in Iterator(obj))
|
||||||
newObj[k] = v;
|
newObj[k] = v;
|
||||||
|
|||||||
Reference in New Issue
Block a user