mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 16:12:26 +01:00
Make bookmark cache window independent and more dynamic.
This commit is contained in:
@@ -206,9 +206,7 @@ liberator.Addressbook = function () //{{{
|
|||||||
"<table><tr align=\"left\" class=\"hl-Title\"><th>Name</th><th>Address</th></tr>";
|
"<table><tr align=\"left\" class=\"hl-Title\"><th>Name</th><th>Address</th></tr>";
|
||||||
for (var i = 0; i < addresses.length; i++)
|
for (var i = 0; i < addresses.length; i++)
|
||||||
{
|
{
|
||||||
var displayName = liberator.util.escapeHTML(addresses[i][0]);
|
var displayName = liberator.util.escapeHTML(liberator.util.clip(addresses[i][0], 50));
|
||||||
if (displayName.length > 50)
|
|
||||||
displayName = displayName.substr(0, 47) + "...";
|
|
||||||
var mailAddr = liberator.util.escapeHTML(addresses[i][1]);
|
var mailAddr = liberator.util.escapeHTML(addresses[i][1]);
|
||||||
list += "<tr><td>" + displayName + "</td><td style=\"width: 100%\"><a href=\"#\" class=\"hl-URL\">" + mailAddr + "</a></td></tr>";
|
list += "<tr><td>" + displayName + "</td><td style=\"width: 100%\"><a href=\"#\" class=\"hl-URL\">" + mailAddr + "</a></td></tr>";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,30 +33,72 @@ liberator.Bookmarks = function () //{{{
|
|||||||
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////{{{
|
/////////////////////////////////////////////////////////////////////////////{{{
|
||||||
|
|
||||||
const historyService = Components.classes["@mozilla.org/browser/nav-history-service;1"]
|
const historyService = PlacesUtils.history;
|
||||||
.getService(Components.interfaces.nsINavHistoryService);
|
const bookmarksService = PlacesUtils.bookmarks;
|
||||||
const bookmarksService = Components.classes["@mozilla.org/browser/nav-bookmarks-service;1"]
|
const taggingService = PlacesUtils.tagging;
|
||||||
.getService(Components.interfaces.nsINavBookmarksService);
|
|
||||||
const taggingService = Components.classes["@mozilla.org/browser/tagging-service;1"]
|
|
||||||
.getService(Components.interfaces.nsITaggingService);
|
|
||||||
const searchService = Components.classes["@mozilla.org/browser/search-service;1"]
|
const searchService = Components.classes["@mozilla.org/browser/search-service;1"]
|
||||||
.getService(Components.interfaces.nsIBrowserSearchService);
|
.getService(Components.interfaces.nsIBrowserSearchService);
|
||||||
const ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
const ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||||
.getService(Components.interfaces.nsIIOService);
|
.getService(Components.interfaces.nsIIOService);
|
||||||
|
|
||||||
var bookmarks = null;
|
function Cache(name, store, serial)
|
||||||
var keywords = null;
|
|
||||||
|
|
||||||
if (liberator.options["preload"])
|
|
||||||
setTimeout(function () { load(); }, 100);
|
|
||||||
|
|
||||||
function load()
|
|
||||||
{
|
{
|
||||||
|
const properties = { uri: 0, title: 1, keyword: 2, tags: 3, id: 4 };
|
||||||
|
const rootFolders = [bookmarksService.toolbarFolder, bookmarksService.bookmarksMenuFolder, bookmarksService.unfiledBookmarksFolder];
|
||||||
|
|
||||||
|
var bookmarks = [];
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
this.__defineGetter__("name", function () key);
|
||||||
|
this.__defineGetter__("store", function () store);
|
||||||
|
this.__defineGetter__("bookmarks", function () { this.load(); return bookmarks });
|
||||||
|
|
||||||
|
this.__defineGetter__("keywords",
|
||||||
|
function () [[k[2], k[1], k[0]] for each (k in self.bookmarks) if (k[2])]);
|
||||||
|
|
||||||
|
this.__iterator__ = (val for each (val in self.bookmarks));
|
||||||
|
|
||||||
|
function loadBookmark(node)
|
||||||
|
{
|
||||||
|
var keyword = bookmarksService.getKeywordForBookmark(node.itemId);
|
||||||
|
var tags = taggingService.getTagsForURI(ioService.newURI(node.uri, null, null), {});
|
||||||
|
bookmarks.push([node.uri, node.title, keyword, tags, node.itemId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function readBookmark(id)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
itemId: id,
|
||||||
|
uri: bookmarksService.getBookmarkURI(id).spec,
|
||||||
|
title: bookmarksService.getItemTitle(id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteBookmark(id)
|
||||||
|
{
|
||||||
|
var length = bookmarks.length;
|
||||||
|
bookmarks = bookmarks.filter(function (item) item[properties.id] != id);
|
||||||
|
return bookmarks.length < length;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findRoot(id)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
var root = id;
|
||||||
|
id = bookmarksService.getFolderIdForItem(id);
|
||||||
|
} while (id != bookmarksService.placesRoot && id != root);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.load = function load()
|
||||||
|
{
|
||||||
|
liberator.dump("cache.load()\n");
|
||||||
// update our bookmark cache
|
// update our bookmark cache
|
||||||
bookmarks = [];
|
bookmarks = [];
|
||||||
keywords = [];
|
this.__defineGetter__("bookmarks", function () bookmarks);
|
||||||
|
|
||||||
var folders = [bookmarksService.toolbarFolder, bookmarksService.bookmarksMenuFolder, bookmarksService.unfiledBookmarksFolder];
|
var folders = rootFolders.concat([]);
|
||||||
var query = historyService.getNewQuery();
|
var query = historyService.getNewQuery();
|
||||||
var options = historyService.getNewQueryOptions();
|
var options = historyService.getNewQueryOptions();
|
||||||
while (folders.length > 0)
|
while (folders.length > 0)
|
||||||
@@ -64,13 +106,12 @@ liberator.Bookmarks = function () //{{{
|
|||||||
//comment out the next line for now; the bug hasn't been fixed; final version should include the next line
|
//comment out the next line for now; the bug hasn't been fixed; final version should include the next line
|
||||||
//options.setGroupingMode(options.GROUP_BY_FOLDER);
|
//options.setGroupingMode(options.GROUP_BY_FOLDER);
|
||||||
query.setFolders(folders, 1);
|
query.setFolders(folders, 1);
|
||||||
|
folders.shift();
|
||||||
var result = historyService.executeQuery(query, options);
|
var result = historyService.executeQuery(query, options);
|
||||||
//result.sortingMode = options.SORT_BY_DATE_DESCENDING;
|
result.sortingMode = options.SORT_BY_VISITCOUNT_DESCENDING; /* This is silly. Results are still sorted by folder first. --Kris */
|
||||||
result.sortingMode = options.SORT_BY_VISITCOUNT_DESCENDING;
|
|
||||||
var rootNode = result.root;
|
var rootNode = result.root;
|
||||||
rootNode.containerOpen = true;
|
rootNode.containerOpen = true;
|
||||||
|
|
||||||
folders.shift();
|
|
||||||
// iterate over the immediate children of this folder
|
// iterate over the immediate children of this folder
|
||||||
for (var i = 0; i < rootNode.childCount; i++)
|
for (var i = 0; i < rootNode.childCount; i++)
|
||||||
{
|
{
|
||||||
@@ -78,38 +119,52 @@ liberator.Bookmarks = function () //{{{
|
|||||||
if (node.type == node.RESULT_TYPE_FOLDER) // folder
|
if (node.type == node.RESULT_TYPE_FOLDER) // folder
|
||||||
folders.push(node.itemId);
|
folders.push(node.itemId);
|
||||||
else if (node.type == node.RESULT_TYPE_URI) // bookmark
|
else if (node.type == node.RESULT_TYPE_URI) // bookmark
|
||||||
{
|
loadBookmark(node);
|
||||||
var kw = bookmarksService.getKeywordForBookmark(node.itemId);
|
|
||||||
if (kw)
|
|
||||||
keywords.push([kw, node.title, node.uri]);
|
|
||||||
|
|
||||||
var count = {};
|
|
||||||
var tags = taggingService.getTagsForURI(ioService.newURI(node.uri, null, null), count);
|
|
||||||
bookmarks.push([node.uri, node.title, kw, tags]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// close a container after using it!
|
// close a container after using it!
|
||||||
rootNode.containerOpen = false;
|
rootNode.containerOpen = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function flush()
|
|
||||||
{
|
|
||||||
bookmarks = null;
|
|
||||||
if (liberator.options["preload"])
|
|
||||||
load();
|
|
||||||
}
|
|
||||||
|
|
||||||
var observer = {
|
var observer = {
|
||||||
onBeginUpdateBatch: function () {},
|
onBeginUpdateBatch: function () {},
|
||||||
onEndUpdateBatch: function () {},
|
onEndUpdateBatch: function () {},
|
||||||
onItemVisited: function () {},
|
onItemVisited: function () {},
|
||||||
/* FIXME: Should probably just update the given bookmark. */
|
onItemMoved: function () {},
|
||||||
onItemMoved: flush,
|
onItemAdded: function (itemId, folder, index)
|
||||||
onItemAdded: flush,
|
{
|
||||||
onItemRemoved: flush,
|
// liberator.dump("onItemAdded(" + itemId + ", " + folder + ", " + index + ")\n");
|
||||||
onItemChanged: flush,
|
if (bookmarksService.getItemType(itemId) == bookmarksService.TYPE_BOOKMARK)
|
||||||
|
{
|
||||||
|
if (rootFolders.indexOf(findRoot(itemId)) >= 0)
|
||||||
|
{
|
||||||
|
loadBookmark(readBookmark(itemId));
|
||||||
|
liberator.storage.fireEvent(name, "add", itemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onItemRemoved: function (itemId, folder, index)
|
||||||
|
{
|
||||||
|
// liberator.dump("onItemRemoved(" + itemId + ", " + folder + ", " + index + ")\n");
|
||||||
|
if (deleteBookmark(itemId))
|
||||||
|
liberator.storage.fireEvent(name, "remove", itemId);
|
||||||
|
},
|
||||||
|
onItemChanged: function (itemId, property, isAnnotation, value)
|
||||||
|
{
|
||||||
|
if(isAnnotation)
|
||||||
|
return;
|
||||||
|
// liberator.dump("onItemChanged(" + itemId + ", " + property + ", " + value + ")\n");
|
||||||
|
var bookmark = bookmarks.filter(function (item) item[properties.id] == itemId)[0];
|
||||||
|
if(bookmark)
|
||||||
|
{
|
||||||
|
if(property == "tags")
|
||||||
|
value = taggingService.getTagsForURI(ioService.newURI(bookmark[properties.uri], null, null), {});
|
||||||
|
if(property in properties)
|
||||||
|
bookmark[properties[property]] = value;
|
||||||
|
liberator.storage.fireEvent(name, "change", itemId);
|
||||||
|
}
|
||||||
|
},
|
||||||
QueryInterface: function (iid) {
|
QueryInterface: function (iid) {
|
||||||
if (iid.equals(Components.interfaces.nsINavBookmarkObserver) || iid.equals(Components.interfaces.nsISupports))
|
if (iid.equals(Components.interfaces.nsINavBookmarkObserver) || iid.equals(Components.interfaces.nsISupports))
|
||||||
return this;
|
return this;
|
||||||
@@ -118,6 +173,15 @@ liberator.Bookmarks = function () //{{{
|
|||||||
};
|
};
|
||||||
|
|
||||||
bookmarksService.addObserver(observer, false);
|
bookmarksService.addObserver(observer, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
var cache = liberator.storage.newObject("bookmark-cache", Cache, false);
|
||||||
|
liberator.storage.addObserver("bookmark-cache", function (key, event, arg)
|
||||||
|
{
|
||||||
|
if(event == "add")
|
||||||
|
liberator.autocommands.trigger("BookmarkAdd", "");
|
||||||
|
liberator.statusline.updateUrl();
|
||||||
|
});
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////}}}
|
/////////////////////////////////////////////////////////////////////////////}}}
|
||||||
////////////////////// OPTIONS /////////////////////////////////////////////////
|
////////////////////// OPTIONS /////////////////////////////////////////////////
|
||||||
@@ -256,38 +320,23 @@ liberator.Bookmarks = function () //{{{
|
|||||||
// takes about 1 sec
|
// takes about 1 sec
|
||||||
get: function (filter, tags, bypassCache)
|
get: function (filter, tags, bypassCache)
|
||||||
{
|
{
|
||||||
if (!bookmarks || bypassCache)
|
return liberator.completion.filterURLArray(cache.bookmarks, filter, tags);
|
||||||
load();
|
|
||||||
|
|
||||||
return liberator.completion.filterURLArray(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
|
||||||
add: function (starOnly, title, url, keyword, tags)
|
add: function (starOnly, title, url, keyword, tags)
|
||||||
{
|
{
|
||||||
if (!bookmarks)
|
|
||||||
load();
|
|
||||||
|
|
||||||
// if no protocol specified, default to http://, isn't there a better way?
|
|
||||||
if (!/^[\w-]+:/.test(url))
|
|
||||||
url = "http://" + url;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var uri = ioService.newURI(url, null, null);
|
var uri = PlacesUIUtils.createFixedURI(url);
|
||||||
var id = bookmarksService.insertBookmark(
|
var id = bookmarksService.insertBookmark(
|
||||||
starOnly ? bookmarksService.unfiledBookmarksFolder : bookmarksService.bookmarksMenuFolder,
|
bookmarksService[starOnly ? "unfiledBookmarksFolder" : "bookmarksMenuFolder"],
|
||||||
uri, -1, title);
|
uri, -1, title);
|
||||||
|
|
||||||
if (!id)
|
if (!id)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (keyword)
|
if (keyword)
|
||||||
{
|
|
||||||
bookmarksService.setKeywordForBookmark(id, keyword);
|
bookmarksService.setKeywordForBookmark(id, keyword);
|
||||||
keywords.unshift([keyword, title, url]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tags)
|
if (tags)
|
||||||
taggingService.tagURI(uri, tags);
|
taggingService.tagURI(uri, tags);
|
||||||
}
|
}
|
||||||
@@ -297,11 +346,6 @@ liberator.Bookmarks = function () //{{{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the display of our "bookmarked" symbol
|
|
||||||
liberator.statusline.updateUrl();
|
|
||||||
|
|
||||||
liberator.autocommands.trigger("BookmarkAdd", "");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -331,15 +375,12 @@ liberator.Bookmarks = function () //{{{
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var uri = ioService.newURI(url, null, null);
|
var uri = ioService.newURI(url, null, null);
|
||||||
var count = {};
|
return (bookmarksService.getBookmarkedURIFor(uri) != null)
|
||||||
bookmarksService.getBookmarkIdsForURI(uri, count);
|
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (e)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count.value > 0;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// returns number of deleted bookmarks
|
// returns number of deleted bookmarks
|
||||||
@@ -408,10 +449,7 @@ liberator.Bookmarks = function () //{{{
|
|||||||
// [keyword, helptext, url]
|
// [keyword, helptext, url]
|
||||||
getKeywords: function ()
|
getKeywords: function ()
|
||||||
{
|
{
|
||||||
if (!keywords)
|
return cache.keywords;
|
||||||
load();
|
|
||||||
|
|
||||||
return keywords;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// full search string including engine name as first word in @param text
|
// full search string including engine name as first word in @param text
|
||||||
@@ -457,16 +495,14 @@ liberator.Bookmarks = function () //{{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (openItems)
|
if (openItems)
|
||||||
return liberator.open([i[0] for (i in items)], liberator.NEW_TAB);
|
return liberator.open([i[0] for each (i in items)], liberator.NEW_TAB);
|
||||||
|
|
||||||
var title, url, tags, keyword, extra;
|
var title, url, tags, keyword, extra;
|
||||||
var list = ":" + liberator.util.escapeHTML(liberator.commandline.getCommand()) + "<br/>" +
|
var list = ":" + liberator.util.escapeHTML(liberator.commandline.getCommand()) + "<br/>" +
|
||||||
"<table><tr align=\"left\" class=\"hl-Title\"><th>title</th><th>URL</th></tr>";
|
"<table><tr align=\"left\" class=\"hl-Title\"><th>title</th><th>URL</th></tr>";
|
||||||
for (var i = 0; i < items.length; i++)
|
for (var i = 0; i < items.length; i++)
|
||||||
{
|
{
|
||||||
title = liberator.util.escapeHTML(items[i][1]);
|
title = liberator.util.escapeHTML(liberator.util.clip(items[i][1], 50));
|
||||||
if (title.length > 50)
|
|
||||||
title = title.substr(0, 47) + "...";
|
|
||||||
url = liberator.util.escapeHTML(items[i][0]);
|
url = liberator.util.escapeHTML(items[i][0]);
|
||||||
keyword = items[i][2];
|
keyword = items[i][2];
|
||||||
tags = items[i][3].join(", ");
|
tags = items[i][3].join(", ");
|
||||||
@@ -762,7 +798,7 @@ liberator.History = function () //{{{
|
|||||||
|
|
||||||
if (openItems)
|
if (openItems)
|
||||||
{
|
{
|
||||||
return liberator.open([i[0] for (i in items)], liberator.NEW_TAB);
|
return liberator.open([i[0] for each (i in items)], liberator.NEW_TAB);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -770,9 +806,7 @@ liberator.History = function () //{{{
|
|||||||
"<table><tr align=\"left\" class=\"hl-Title\"><th>title</th><th>URL</th></tr>";
|
"<table><tr align=\"left\" class=\"hl-Title\"><th>title</th><th>URL</th></tr>";
|
||||||
for (var i = 0; i < items.length; i++)
|
for (var i = 0; i < items.length; i++)
|
||||||
{
|
{
|
||||||
var title = liberator.util.escapeHTML(items[i][1]);
|
var title = liberator.util.escapeHTML(liberator.util.clip(items[i][1], 50));
|
||||||
if (title.length > 50)
|
|
||||||
title = title.substr(0, 47) + "...";
|
|
||||||
var url = liberator.util.escapeHTML(items[i][0]);
|
var url = liberator.util.escapeHTML(items[i][0]);
|
||||||
list += "<tr><td>" + title + "</td><td><a href=\"#\" class=\"hl-URL\">" + url + "</a></td></tr>";
|
list += "<tr><td>" + title + "</td><td><a href=\"#\" class=\"hl-URL\">" + url + "</a></td></tr>";
|
||||||
}
|
}
|
||||||
@@ -922,21 +956,13 @@ liberator.QuickMarks = function () //{{{
|
|||||||
|
|
||||||
list: function (filter)
|
list: function (filter)
|
||||||
{
|
{
|
||||||
var lowercaseMarks = [];
|
var marks = [key for ([key,val] in qmarks)];
|
||||||
var uppercaseMarks = [];
|
// This was a lot nicer without the lambda...
|
||||||
var numberMarks = [];
|
var lowercaseMarks = marks.filter(function (x) /[a-z]/.test(x)).sort();
|
||||||
|
var uppercaseMarks = marks.filter(function (x) /[A-Z]/.test(x)).sort();
|
||||||
|
var numberMarks = marks.filter(function (x) /[0-9]/.test(x)).sort();
|
||||||
|
|
||||||
for (var [qmark,] in qmarks)
|
marks = Array.concat(lowercaseMarks, uppercaseMarks, numberMarks);
|
||||||
{
|
|
||||||
if (/[a-z]/.test(qmark))
|
|
||||||
lowercaseMarks.push(qmark);
|
|
||||||
else if (/[A-Z]/.test(qmark))
|
|
||||||
uppercaseMarks.push(qmark);
|
|
||||||
else
|
|
||||||
numberMarks.push(qmark);
|
|
||||||
}
|
|
||||||
|
|
||||||
var marks = lowercaseMarks.sort().concat(uppercaseMarks.sort()).concat(numberMarks.sort());
|
|
||||||
|
|
||||||
if (marks.length == 0)
|
if (marks.length == 0)
|
||||||
{
|
{
|
||||||
@@ -946,11 +972,7 @@ liberator.QuickMarks = function () //{{{
|
|||||||
|
|
||||||
if (filter.length > 0)
|
if (filter.length > 0)
|
||||||
{
|
{
|
||||||
marks = marks.filter(function (qmark) {
|
marks = marks.filter(function (qmark) filter.indexOf(qmark) >= 0)
|
||||||
if (filter.indexOf(qmark) > -1)
|
|
||||||
return qmark;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (marks.length == 0)
|
if (marks.length == 0)
|
||||||
{
|
{
|
||||||
liberator.echoerr("E283: No QuickMarks matching \"" + filter + "\"");
|
liberator.echoerr("E283: No QuickMarks matching \"" + filter + "\"");
|
||||||
|
|||||||
@@ -891,16 +891,16 @@ liberator.Buffer = function () //{{{
|
|||||||
offsetY = Number(coords[1]) + 1;
|
offsetY = Number(coords[1]) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newTab = false, newWindow = false;
|
var ctrlKey = false, shiftKey = false;
|
||||||
switch (where)
|
switch (where)
|
||||||
{
|
{
|
||||||
case liberator.NEW_TAB:
|
case liberator.NEW_TAB:
|
||||||
case liberator.NEW_BACKGROUND_TAB:
|
case liberator.NEW_BACKGROUND_TAB:
|
||||||
newTab = true;
|
ctrlKey = true;
|
||||||
newWindow = (where == liberator.NEW_BACKGROUND_TAB);
|
shiftKey = (where == liberator.NEW_BACKGROUND_TAB);
|
||||||
break;
|
break;
|
||||||
case liberator.NEW_WINDOW:
|
case liberator.NEW_WINDOW:
|
||||||
newWindow = true;
|
shiftKey = true;
|
||||||
break;
|
break;
|
||||||
case liberator.CURRENT_TAB:
|
case liberator.CURRENT_TAB:
|
||||||
break;
|
break;
|
||||||
@@ -913,9 +913,8 @@ liberator.Buffer = function () //{{{
|
|||||||
var evt = doc.createEvent("MouseEvents");
|
var evt = doc.createEvent("MouseEvents");
|
||||||
for each (event in ["mousedown", "mouseup", "click"])
|
for each (event in ["mousedown", "mouseup", "click"])
|
||||||
{
|
{
|
||||||
evt.initMouseEvent(event, true, true, view, 1, offsetX, offsetY,
|
evt.initMouseEvent(event, true, true, view, 1, offsetX, offsetY, 0, 0,
|
||||||
0, 0, /*ctrl*/ newTab, /*event.altKey*/0, /*event.shiftKey*/ newWindow,
|
ctrlKey, /*altKey*/0, shiftKey, /*metaKey*/ ctrlKey, 0, null);
|
||||||
/*event.metaKey*/ newTab, 0, null);
|
|
||||||
elem.dispatchEvent(evt);
|
elem.dispatchEvent(evt);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1016,8 +1015,7 @@ liberator.Buffer = function () //{{{
|
|||||||
{
|
{
|
||||||
if (frame.document.body.localName.toLowerCase() == "body")
|
if (frame.document.body.localName.toLowerCase() == "body")
|
||||||
frames.push(frame);
|
frames.push(frame);
|
||||||
for (var i = 0; i < frame.frames.length; i++)
|
Array.forEach(frame.frames, arguments.callee);
|
||||||
arguments.callee(frame.frames[i]);
|
|
||||||
})(window.content);
|
})(window.content);
|
||||||
|
|
||||||
if (frames.length == 0) // currently top is always included
|
if (frames.length == 0) // currently top is always included
|
||||||
@@ -1038,15 +1036,7 @@ liberator.Buffer = function () //{{{
|
|||||||
// focused. Since this is not the current FF behaviour,
|
// focused. Since this is not the current FF behaviour,
|
||||||
// we initalize current to -1 so the first call takes us to the
|
// we initalize current to -1 so the first call takes us to the
|
||||||
// first frame.
|
// first frame.
|
||||||
var current = -1;
|
var current = frames.indexOf(document.commandDispatcher.focusedWindow);
|
||||||
for (var i = 0; i < frames.length; i++)
|
|
||||||
{
|
|
||||||
if (frames[i] == document.commandDispatcher.focusedWindow)
|
|
||||||
{
|
|
||||||
var current = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate the next frame to focus
|
// calculate the next frame to focus
|
||||||
var next = current;
|
var next = current;
|
||||||
@@ -1497,19 +1487,21 @@ liberator.Marks = function () //{{{
|
|||||||
|
|
||||||
function getSortedMarks()
|
function getSortedMarks()
|
||||||
{
|
{
|
||||||
var lmarks, umarks;
|
var location = window.content.location.href;
|
||||||
|
var lmarks = [];
|
||||||
|
|
||||||
// local marks
|
// local marks
|
||||||
lmarks = [[[mark, value[i]] for (i in value)
|
for (let [mark, value] in Iterator(localMarks))
|
||||||
if (value[i].location == window.content.location.href)]
|
{
|
||||||
for ([mark, value] in localMarks)];
|
for each (val in value.filter(function (val) val.location == location))
|
||||||
lmarks = Array.concat.apply(Array, lmarks);
|
lmarks.push([mark, val]);
|
||||||
|
}
|
||||||
lmarks.sort();
|
lmarks.sort();
|
||||||
|
|
||||||
// URL marks
|
// URL marks
|
||||||
// FIXME: why does umarks.sort() cause a "Component is not available =
|
// FIXME: why does umarks.sort() cause a "Component is not available =
|
||||||
// NS_ERROR_NOT_AVAILABLE" exception when used here?
|
// NS_ERROR_NOT_AVAILABLE" exception when used here?
|
||||||
umarks = [[key, mark] for ([key, mark] in urlMarks)];
|
var umarks = [[key, mark] for ([key, mark] in urlMarks)];
|
||||||
umarks.sort(function (a, b) a[0].localeCompare(b[0]));
|
umarks.sort(function (a, b) a[0].localeCompare(b[0]));
|
||||||
|
|
||||||
return lmarks.concat(umarks);
|
return lmarks.concat(umarks);
|
||||||
|
|||||||
@@ -506,7 +506,7 @@ liberator.Completion = function () //{{{
|
|||||||
// 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]], [...]]
|
||||||
filterURLArray: function (urls, filter, tags)
|
filterURLArray: function (urls, filter, filterTags)
|
||||||
{
|
{
|
||||||
var filtered = [];
|
var filtered = [];
|
||||||
// completions which don't match the url but just the description
|
// completions which don't match the url but just the description
|
||||||
@@ -518,49 +518,40 @@ liberator.Completion = function () //{{{
|
|||||||
|
|
||||||
var hasTags = urls[0].length >= 4;
|
var hasTags = urls[0].length >= 4;
|
||||||
// TODO: create a copy of urls?
|
// TODO: create a copy of urls?
|
||||||
if (!filter && (!hasTags || !tags))
|
if (!filter && (!hasTags || !filterTags))
|
||||||
return urls;
|
return urls;
|
||||||
|
|
||||||
tags = tags || [];
|
filterTags = filterTags || [];
|
||||||
|
|
||||||
// TODO: use ignorecase and smartcase settings
|
// TODO: use ignorecase and smartcase settings
|
||||||
var ignorecase = true;
|
var ignorecase = (filter == filter.toLowerCase() && filterTags.join(",") == filterTags.join(",").toLowerCase());
|
||||||
if (filter != filter.toLowerCase() || tags.join(",") != tags.join(",").toLowerCase())
|
|
||||||
ignorecase = false;
|
|
||||||
|
|
||||||
if (ignorecase)
|
if (ignorecase)
|
||||||
{
|
{
|
||||||
filter = filter.toLowerCase();
|
filter = filter.toLowerCase();
|
||||||
tags = tags.map(function (t) { return t.toLowerCase(); });
|
filterTags = filterTags.map(String.toLowerCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Longest Common Subsequence
|
// Longest Common Subsequence
|
||||||
// This shouldn't use buildLongestCommonSubstring for performance
|
// This shouldn't use buildLongestCommonSubstring for performance
|
||||||
// reasons, so as not to cycle through the urls twice
|
// reasons, so as not to cycle through the urls twice
|
||||||
outer:
|
for each (elem in urls)
|
||||||
for (var i = 0; i < urls.length; i++)
|
|
||||||
{
|
{
|
||||||
var url = urls[i][0] || "";
|
var url = elem[0] || "";
|
||||||
var title = urls[i][1] || "";
|
var title = elem[1] || "";
|
||||||
var tag = urls[i][3] || [];
|
var tags = elem[3] || [];
|
||||||
|
|
||||||
if (ignorecase)
|
if (ignorecase)
|
||||||
{
|
{
|
||||||
url = url.toLowerCase();
|
url = url.toLowerCase();
|
||||||
title = title.toLowerCase();
|
title = title.toLowerCase();
|
||||||
tag = tag.map(function (t) { return t.toLowerCase(); });
|
tags = tags.map(String.toLowerCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter on tags
|
// filter on tags
|
||||||
for (var j = 0; j < tags.length; j++)
|
if(filterTags.some(function (tag) tag && tags.indexOf(tag) == -1))
|
||||||
{
|
|
||||||
if (!tags[j])
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (tag.indexOf(tags[j]) == -1)
|
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url.indexOf(filter) == -1)
|
if (url.indexOf(filter) == -1)
|
||||||
{
|
{
|
||||||
// no direct match of filter in the url, but still accept this item
|
// no direct match of filter in the url, but still accept this item
|
||||||
@@ -568,7 +559,7 @@ liberator.Completion = function () //{{{
|
|||||||
if (filter.split(/\s+/).every(function (token) {
|
if (filter.split(/\s+/).every(function (token) {
|
||||||
return (url.indexOf(token) > -1 || title.indexOf(token) > -1);
|
return (url.indexOf(token) > -1 || title.indexOf(token) > -1);
|
||||||
}))
|
}))
|
||||||
additionalCompletions.push(urls[i]);
|
additionalCompletions.push(elem);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -594,7 +585,7 @@ liberator.Completion = function () //{{{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
filtered.push(urls[i]);
|
filtered.push(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return filtered.concat(additionalCompletions);
|
return filtered.concat(additionalCompletions);
|
||||||
|
|||||||
@@ -60,18 +60,20 @@ function loadPref(name, store, type)
|
|||||||
if (store)
|
if (store)
|
||||||
var pref = getCharPref(prefName(name));
|
var pref = getCharPref(prefName(name));
|
||||||
if (pref)
|
if (pref)
|
||||||
var obj = json.decode(pref);
|
var result = json.decode(pref);
|
||||||
if (obj instanceof type)
|
if (result instanceof type)
|
||||||
return obj;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function savePref(obj)
|
||||||
|
{
|
||||||
|
if (obj.store)
|
||||||
|
prefService.setCharPref(prefName(obj.name), obj.serial)
|
||||||
}
|
}
|
||||||
|
|
||||||
var prototype = {
|
var prototype = {
|
||||||
fireEvent: function (event, arg) { storage.fireEvent(this.name, event, arg) },
|
fireEvent: function (event, arg) { storage.fireEvent(this.name, event, arg) },
|
||||||
save: function ()
|
save: function () { savePref(this) },
|
||||||
{
|
|
||||||
if (this.store)
|
|
||||||
prefService.setCharPref(prefName(this.name), this.serial)
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function ObjectStore(name, store)
|
function ObjectStore(name, store)
|
||||||
@@ -207,6 +209,13 @@ var storage = {
|
|||||||
return this[key];
|
return this[key];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
newObject: function newObject(key, constructor, store)
|
||||||
|
{
|
||||||
|
if(!(key in keys))
|
||||||
|
this._addKey(key, new constructor(key, store, loadPref(key, store, Object)));
|
||||||
|
return this[key];
|
||||||
|
},
|
||||||
|
|
||||||
addObserver: function addObserver(key, callback)
|
addObserver: function addObserver(key, callback)
|
||||||
{
|
{
|
||||||
if (!(key in observers))
|
if (!(key in observers))
|
||||||
@@ -231,11 +240,16 @@ var storage = {
|
|||||||
callback(key, event, arg);
|
callback(key, event, arg);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
save: function save(key)
|
||||||
|
{
|
||||||
|
savePref(keys[key]);
|
||||||
|
},
|
||||||
|
|
||||||
saveAll: function storeAll()
|
saveAll: function storeAll()
|
||||||
{
|
{
|
||||||
for each(key in keys)
|
for each (obj in keys)
|
||||||
key.save();
|
savePref(obj);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// vim: set fdm=marker sw=4 sts=4 et ft=javascript:
|
// vim: set fdm=marker sw=4 sts=4 et ft=javascript:
|
||||||
|
|||||||
@@ -1402,7 +1402,7 @@ liberator.StatusLine = function () //{{{
|
|||||||
modified += "+";
|
modified += "+";
|
||||||
if (sh.index < sh.count -1)
|
if (sh.index < sh.count -1)
|
||||||
modified += "-";
|
modified += "-";
|
||||||
if (liberator.bookmarks.isBookmarked(url))
|
if (liberator.bookmarks.isBookmarked(liberator.buffer.URL))
|
||||||
modified += "\u2764"; // a heart symbol: ❤
|
modified += "\u2764"; // a heart symbol: ❤
|
||||||
//modified += "\u2665"; // a heart symbol: ♥
|
//modified += "\u2665"; // a heart symbol: ♥
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
|||||||
|
|
||||||
liberator.util = { //{{{
|
liberator.util = { //{{{
|
||||||
|
|
||||||
|
clip: function (str, length)
|
||||||
|
{
|
||||||
|
return str.length <= length ? str : str.substr(0, length - 3) + "...";
|
||||||
|
},
|
||||||
|
|
||||||
// TODO: use :highlight color groups
|
// TODO: use :highlight color groups
|
||||||
// if "processStrings" is true, any passed strings will be surrounded by " and
|
// if "processStrings" is true, any passed strings will be surrounded by " and
|
||||||
// any line breaks are displayed as \n
|
// any line breaks are displayed as \n
|
||||||
|
|||||||
Reference in New Issue
Block a user