mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-22 00:37:58 +01:00
745 lines
24 KiB
JavaScript
745 lines
24 KiB
JavaScript
/*
|
|
* also includes methods for dealing with
|
|
* keywords and search engines
|
|
*/
|
|
function Bookmarks() //{{{
|
|
{
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////{{{
|
|
|
|
const search_service = Components.classes["@mozilla.org/browser/search-service;1"].
|
|
getService(Components.interfaces.nsIBrowserSearchService);
|
|
const rdf_service = Components.classes["@mozilla.org/rdf/rdf-service;1"].
|
|
getService( Components.interfaces.nsIRDFService );
|
|
|
|
var bookmarks = null;
|
|
var keywords = null;
|
|
|
|
if (vimperator.options["preload"])
|
|
setTimeout(function() { load(); } , 100);
|
|
|
|
function load()
|
|
{
|
|
// update our bookmark cache
|
|
var root = rdf_service.GetResource("NC:BookmarksRoot");
|
|
bookmarks = new Array(); // also clear our bookmark cache
|
|
keywords = new Array();
|
|
|
|
var bmarks = []; // here getAllChildren will store the bookmarks
|
|
BookmarksUtils.getAllChildren(root, bmarks);
|
|
for (var bm in bmarks)
|
|
{
|
|
if (bmarks[bm][0] && bmarks[bm][1])
|
|
bookmarks.push([bmarks[bm][1].Value, bmarks[bm][0].Value ]);
|
|
|
|
// keyword
|
|
if (bmarks[bm][1] && bmarks[bm][2])
|
|
keywords.push([bmarks[bm][2].Value, bmarks[bm][0].Value, bmarks[bm][1].Value]);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////}}}
|
|
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////{{{
|
|
|
|
/*
|
|
* @return a new Array() of our bookmarks
|
|
*/
|
|
this.get = function()
|
|
{
|
|
if (!bookmarks)
|
|
load();
|
|
|
|
return bookmarks;
|
|
}
|
|
|
|
/**
|
|
* @TODO: keyword support
|
|
*/
|
|
this.add = function (title, uri, keyword)
|
|
{
|
|
if (!bookmarks)
|
|
load();
|
|
|
|
folder = rdf_service.GetResource("NC:BookmarksRoot");
|
|
var rSource = BookmarksUtils.createBookmark(title, uri, keyword, title);
|
|
var selection = BookmarksUtils.getSelectionFromResource(rSource);
|
|
var target = BookmarksUtils.getTargetFromFolder(folder);
|
|
BookmarksUtils.insertAndCheckSelection("newbookmark", selection, target);
|
|
|
|
//also update bookmark cache
|
|
bookmarks.unshift([uri, title]);
|
|
return true;
|
|
}
|
|
|
|
/* no idea what it does, it Just Works (TM)
|
|
*
|
|
* @returns number of deleted bookmarks
|
|
*/
|
|
this.remove = function(url)
|
|
{
|
|
var deleted = 0;
|
|
if (!url)
|
|
return 0;
|
|
|
|
// gNC_NS for trunk, NC_NS for 1.X
|
|
//try { var pNC_NS; pNC_NS = gNC_NS;} catch (err) { pNC_NS = NC_NS;}
|
|
if (!BMSVC || !BMDS || !RDF || !gNC_NS) // defined from firefox
|
|
return 0;
|
|
|
|
var curfolder = RDF.GetResource("NC:BookmarksRoot");
|
|
var urlArc = RDF.GetResource(gNC_NS + "URL");
|
|
var urlLiteral = RDF.GetLiteral(url);
|
|
if (BMDS.hasArcIn(urlLiteral, urlArc))
|
|
{
|
|
var bmResources, bmResource, title, uri, type, ptype;
|
|
bmResources = BMSVC.GetSources(urlArc, urlLiteral, true);
|
|
while (bmResources.hasMoreElements())
|
|
{
|
|
bmResource = bmResources.getNext();
|
|
type = BookmarksUtils.resolveType(bmResource);
|
|
if (type != "ImmutableBookmark") {
|
|
ptype = BookmarksUtils.resolveType(BMSVC.getParent(bmResource));
|
|
// alert(type);
|
|
// if ( type == "Folder") // store the current folder
|
|
// curfolder = bmResource;
|
|
if ( (type == "Bookmark" || type == "IEFavorite") && ptype != "Livemark")
|
|
{
|
|
title = BookmarksUtils.getProperty(bmResource, gNC_NS + "Name");
|
|
uri = BookmarksUtils.getProperty(bmResource, gNC_NS + "URL");
|
|
|
|
if (uri == url)
|
|
{
|
|
RDFC.Init(BMDS, BMSVC.getParent(bmResource));
|
|
RDFC.RemoveElement(bmResource, true);
|
|
deleted++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// also update bookmark cache, if we removed at least one bookmark
|
|
if (deleted > 0)
|
|
load();
|
|
|
|
return deleted;
|
|
}
|
|
|
|
/* also ensures that each search engine has a vimperator-friendly alias */
|
|
this.getSearchEngines = function()
|
|
{
|
|
var search_engines = new Array();
|
|
var firefox_engines = search_service.getVisibleEngines({ });
|
|
for (var i in firefox_engines)
|
|
{
|
|
if (!firefox_engines[i].alias || !firefox_engines[i].alias.match(/^[a-z0-9_]+$/))
|
|
{
|
|
var alias = firefox_engines[i].name.replace(/^\W*(\w+).*/, "$1").toLowerCase();
|
|
firefox_engines[i].alias = alias;
|
|
}
|
|
search_engines.push([firefox_engines[i].alias, firefox_engines[i].description]);
|
|
}
|
|
|
|
return search_engines;
|
|
}
|
|
|
|
// format of returned array:
|
|
// [keyword, helptext, url]
|
|
this.getKeywords = function()
|
|
{
|
|
if (!keywords)
|
|
load();
|
|
|
|
return keywords;
|
|
}
|
|
|
|
// if the engine name is null, it uses the default search engine
|
|
// @returns the url for the search string
|
|
this.getSearchURL = function(text, engine_name)
|
|
{
|
|
var url = null;
|
|
if (!engine_name || engine_name == "")
|
|
engine_name = vimperator.options["defsearch"];
|
|
|
|
// first checks the search engines for a match
|
|
var engine = search_service.getEngineByAlias(engine_name);
|
|
if (engine)
|
|
{
|
|
if (text)
|
|
url = engine.getSubmission(text, null).uri.spec;
|
|
else
|
|
url = engine.searchForm;
|
|
}
|
|
else // check for keyword urls
|
|
{
|
|
if (!keywords)
|
|
load();
|
|
|
|
for (var i in keywords)
|
|
{
|
|
if (keywords[i][0] == engine_name)
|
|
{
|
|
if (text == null)
|
|
text = "";
|
|
url = keywords[i][2].replace(/%s/g, encodeURIComponent(text));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if we came here, the engine_name is neither a search engine or URL
|
|
return url;
|
|
}
|
|
|
|
this.list = function(filter, fullmode)
|
|
{
|
|
if (fullmode)
|
|
openURLsInNewTab("chrome://browser/content/bookmarks/bookmarksPanel.xul", true);
|
|
else
|
|
{
|
|
var items = vimperator.bookmarks.get(filter);
|
|
vimperator.previewwindow.show(items);
|
|
}
|
|
}
|
|
|
|
/*
|
|
res = parseBookmarkString("-t tag1,tag2 -T title http://www.orf.at");
|
|
res.tags is an array of tags
|
|
res.title is the title or "" if no one was given
|
|
res.url is the url as a string
|
|
returns null, if parsing failed
|
|
*/
|
|
Bookmarks.parseBookmarkString = function(str)
|
|
{
|
|
var res = {};
|
|
res.tags = [];
|
|
res.title = null;
|
|
res.url = null;
|
|
|
|
var re_title = /^\s*((-t|--title)\s+(\w+|\".*\"))(.*)/;
|
|
var re_tags = /^\s*((-T|--tags)\s+((\w+)(,\w+)*))(.*)/;
|
|
var re_url = /^\s*(\".+\"|\S+)(.*)/;
|
|
|
|
var match_tags = null;
|
|
var match_title = null;
|
|
var match_url = null;
|
|
|
|
while (!str.match(/^\s*$/))
|
|
{
|
|
/* first check for --tags */
|
|
match_tags = str.match(re_tags);
|
|
if (match_tags != null)
|
|
{
|
|
str = match_tags[match_tags.length-1]; // the last captured parenthesis is the rest of the string
|
|
tags = match_tags[3].split(",");
|
|
res.tags = res.tags.concat(tags);
|
|
}
|
|
else /* then for --titles */
|
|
{
|
|
|
|
match_title = str.match(re_title);
|
|
if (match_title != null)
|
|
{
|
|
// only one title allowed
|
|
if (res.title != null)
|
|
return null;
|
|
|
|
str = match_title[match_title.length-1]; // the last captured parenthesis is the rest of the string
|
|
var title = match_title[3];
|
|
if (title.charAt(0) == '"')
|
|
title = title.substring(1,title.length-1);
|
|
res.title = title;
|
|
}
|
|
else /* at last check for an url */
|
|
{
|
|
match_url = str.match(re_url);
|
|
if (match_url != null)
|
|
{
|
|
// only one url allowed
|
|
if (res.url != null)
|
|
return null;
|
|
|
|
str = match_url[match_url.length-1]; // the last captured parenthesis is the rest of the string
|
|
url = match_url[1];
|
|
if (url.charAt(0) == '"')
|
|
url = url.substring(1,url.length-1);
|
|
res.url = url;
|
|
}
|
|
else
|
|
return null; // no url, tag or title found but still text left, abort
|
|
}
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
//}}}
|
|
} //}}}
|
|
|
|
function History() //{{{
|
|
{
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////{{{
|
|
|
|
const rdf_service = Components.classes["@mozilla.org/rdf/rdf-service;1"].
|
|
getService( Components.interfaces.nsIRDFService );
|
|
const global_history_service = Components.classes["@mozilla.org/browser/global-history;2"].
|
|
getService(Components.interfaces.nsIRDFDataSource);
|
|
|
|
var history = null;
|
|
|
|
if (vimperator.options["preload"])
|
|
setTimeout(function() { load(); } , 100);
|
|
|
|
function load()
|
|
{
|
|
history = new Array();
|
|
|
|
var historytree = document.getElementById("hiddenHistoryTree");
|
|
if (!historytree)
|
|
return;
|
|
|
|
if (historytree.hidden)
|
|
{
|
|
historytree.hidden = false;
|
|
historytree.database.AddDataSource(global_history_service);
|
|
}
|
|
|
|
if (!historytree.ref)
|
|
historytree.ref = "NC:HistoryRoot";
|
|
|
|
var nameResource = rdf_service.GetResource(gNC_NS + "Name");
|
|
var builder = historytree.builder.QueryInterface(Components.interfaces.nsIXULTreeBuilder);
|
|
|
|
var count = historytree.view.rowCount;
|
|
for (var i = count-1; i >= 0; i--)
|
|
{
|
|
var res = builder.getResourceAtIndex(i);
|
|
var url = res.Value;
|
|
var title;
|
|
var titleRes = historytree.database.GetTarget(res, nameResource, true);
|
|
if (!titleRes)
|
|
continue;
|
|
|
|
var titleLiteral = titleRes.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
|
if (titleLiteral)
|
|
title = titleLiteral.Value;
|
|
else
|
|
title = "";
|
|
|
|
history.push([url, title]);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////}}}
|
|
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////{{{
|
|
|
|
/*
|
|
* @return a new Array() of our bookmarks
|
|
*/
|
|
this.get = function()
|
|
{
|
|
if (!history)
|
|
load();
|
|
|
|
return history;
|
|
}
|
|
|
|
this.add = function (url, title)
|
|
{
|
|
if (!history)
|
|
load();
|
|
|
|
history = history.filter(function(elem) {
|
|
return elem[0] != url;
|
|
});
|
|
|
|
history.unshift([url, title]);
|
|
return true;
|
|
};
|
|
|
|
// TODO: better names?
|
|
this.stepTo = function(steps)
|
|
{
|
|
var index = getWebNavigation().sessionHistory.index + steps;
|
|
if (index >= 0 && index < getWebNavigation().sessionHistory.count)
|
|
{
|
|
getWebNavigation().gotoIndex(index);
|
|
}
|
|
else
|
|
{
|
|
vimperator.beep();
|
|
if (index < 0)
|
|
vimperator.echo("Cannot go past beginning of history");
|
|
else
|
|
vimperator.echo("Cannot go past end of history");
|
|
}
|
|
}
|
|
|
|
this.goToStart = function()
|
|
{
|
|
var index = getWebNavigation().sessionHistory.index;
|
|
if (index == 0)
|
|
{
|
|
vimperator.echo("Already at beginning of history");
|
|
return;
|
|
}
|
|
getWebNavigation().gotoIndex(0);
|
|
}
|
|
|
|
this.goToEnd = function()
|
|
{
|
|
var index = getWebNavigation().sessionHistory.index;
|
|
var max = getWebNavigation().sessionHistory.count -1;
|
|
if (index == max)
|
|
{
|
|
vimperator.echo("Already at end of history");
|
|
return;
|
|
}
|
|
getWebNavigation().gotoIndex(max);
|
|
}
|
|
|
|
this.list = function(filter, fullmode)
|
|
{
|
|
if (fullmode)
|
|
openURLsInNewTab("chrome://browser/content/history/history-panel.xul", true);
|
|
else
|
|
{
|
|
var items = vimperator.history.get(filter);
|
|
vimperator.previewwindow.show(items);
|
|
}
|
|
}
|
|
//}}}
|
|
} //}}}
|
|
|
|
function Marks() //{{{
|
|
{
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////{{{
|
|
|
|
var local_marks = {};
|
|
var url_marks = {};
|
|
var pending_jumps = [];
|
|
var appcontent = document.getElementById("appcontent");
|
|
if (appcontent)
|
|
appcontent.addEventListener("load", onPageLoad, true);
|
|
|
|
function onPageLoad(event)
|
|
{
|
|
var win = event.originalTarget.defaultView;
|
|
for (var i = 0, length = pending_jumps.length; i < length; i++)
|
|
{
|
|
var mark = pending_jumps[i];
|
|
if (win.location.href == mark.location)
|
|
{
|
|
win.scrollTo(mark.position.x * win.scrollMaxX, mark.position.y * win.scrollMaxY);
|
|
pending_jumps.splice(i, 1);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
function removeLocalMark(mark)
|
|
{
|
|
if (mark in local_marks)
|
|
{
|
|
var win = window.content;
|
|
for (var i = 0; i < local_marks[mark].length; i++)
|
|
{
|
|
if (local_marks[mark][i].location == win.location.href)
|
|
{
|
|
vimperator.log("Deleting local mark: " + mark + " | " + local_marks[mark][i].location + " | (" + local_marks[mark][i].position.x + ", " + local_marks[mark][i].position.y + ") | tab: " + vimperator.tabs.index(local_marks[mark][i].tab), 5);
|
|
local_marks[mark].splice(i, 1);
|
|
if (local_marks[mark].length == 0)
|
|
delete local_marks[mark];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function removeURLMark(mark)
|
|
{
|
|
if (mark in url_marks)
|
|
{
|
|
vimperator.log("Deleting URL mark: " + mark + " | " + url_marks[mark].location + " | (" + url_marks[mark].position.x + ", " + url_marks[mark].position.y + ") | tab: " + vimperator.tabs.index(url_marks[mark].tab), 5);
|
|
delete url_marks[mark];
|
|
}
|
|
}
|
|
|
|
function isLocalMark(mark)
|
|
{
|
|
return /^[a-z]$/.test(mark);
|
|
}
|
|
|
|
function isURLMark(mark)
|
|
{
|
|
return /^[A-Z0-9]$/.test(mark);
|
|
}
|
|
|
|
function getSortedMarks()
|
|
{
|
|
// local marks
|
|
var lmarks = [];
|
|
for (var mark in local_marks)
|
|
{
|
|
for (var i = 0; i < local_marks[mark].length; i++)
|
|
{
|
|
if (local_marks[mark][i].location == window.content.location.href)
|
|
lmarks.push([mark, local_marks[mark][i]]);
|
|
}
|
|
}
|
|
lmarks.sort();
|
|
|
|
// URL marks
|
|
var umarks = [];
|
|
for (var mark in url_marks)
|
|
umarks.push([mark, url_marks[mark]]);
|
|
// FIXME: why does umarks.sort() cause a "Component is not available =
|
|
// NS_ERROR_NOT_AVAILABLE" exception when used here?
|
|
umarks.sort(function(a, b) {
|
|
if (a[0] < b[0])
|
|
return -1
|
|
else if (a[0] > b[0])
|
|
return 1;
|
|
return 0
|
|
});
|
|
|
|
return lmarks.concat(umarks);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////}}}
|
|
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////{{{
|
|
|
|
// TODO: add support for frameset pages
|
|
this.add = function(mark)
|
|
{
|
|
var win = window.content;
|
|
|
|
if (win.document.body.localName.toLowerCase() == "frameset")
|
|
{
|
|
vimperator.echo("marks support for frameset pages not implemented yet");
|
|
return;
|
|
}
|
|
|
|
var x = win.scrollMaxX ? win.pageXOffset / win.scrollMaxX : 0;
|
|
var y = win.scrollMaxY ? win.pageYOffset / win.scrollMaxY : 0;
|
|
var position = { x: x, y: y };
|
|
if (isURLMark(mark))
|
|
{
|
|
vimperator.log("Adding URL mark: " + mark + " | " + win.location.href + " | (" + position.x + ", " + position.y + ") | tab: " + vimperator.tabs.index(vimperator.tabs.getTab()), 5);
|
|
url_marks[mark] = { location: win.location.href, position: position, tab: vimperator.tabs.getTab() };
|
|
}
|
|
else if (isLocalMark(mark))
|
|
{
|
|
// remove any previous mark of the same name for this location
|
|
removeLocalMark(mark);
|
|
if (!local_marks[mark])
|
|
local_marks[mark] = [];
|
|
vimperator.log("Adding local mark: " + mark + " | " + win.location.href + " | (" + position.x + ", " + position.y + ")", 5);
|
|
local_marks[mark].push({ location: win.location.href, position: position });
|
|
}
|
|
}
|
|
|
|
this.remove = function(filter, special)
|
|
{
|
|
if (special)
|
|
{
|
|
// :delmarks! only deletes a-z marks
|
|
for (var mark in local_marks)
|
|
removeLocalMark(mark);
|
|
}
|
|
else
|
|
{
|
|
var pattern = new RegExp("[" + filter.replace(/\s+/g, '') + "]");
|
|
for (var mark in url_marks)
|
|
{
|
|
if (pattern.test(mark))
|
|
removeURLMark(mark);
|
|
}
|
|
for (var mark in local_marks)
|
|
{
|
|
if (pattern.test(mark))
|
|
removeLocalMark(mark);
|
|
}
|
|
}
|
|
}
|
|
|
|
this.jumpTo = function(mark)
|
|
{
|
|
var ok = false;
|
|
if (isURLMark(mark))
|
|
{
|
|
var slice = url_marks[mark];
|
|
if (slice && slice.tab && slice.tab.linkedBrowser)
|
|
{
|
|
if (!slice.tab.parentNode)
|
|
{
|
|
pending_jumps.push(slice);
|
|
// NOTE: this obviously won't work on generated pages using
|
|
// non-unique URLs, like Vimperator's help :(
|
|
openURLsInNewTab(slice.location, true);
|
|
return;
|
|
}
|
|
var index = vimperator.tabs.index(slice.tab);
|
|
if (index != -1)
|
|
{
|
|
vimperator.tabs.select(index);
|
|
var win = slice.tab.linkedBrowser.contentWindow;
|
|
if (win.location.href != slice.location)
|
|
{
|
|
pending_jumps.push(slice);
|
|
win.location.href = slice.location;
|
|
return;
|
|
}
|
|
vimperator.log("Jumping to URL mark: " + mark + " | " + slice.location + " | (" + slice.position.x + ", " + slice.position.y + ") | tab: " + vimperator.tabs.index(slice.tab), 5);
|
|
win.scrollTo(slice.position.x * win.scrollMaxX, slice.position.y * win.scrollMaxY);
|
|
ok = true;
|
|
}
|
|
}
|
|
}
|
|
else if (isLocalMark(mark))
|
|
{
|
|
var win = window.content;
|
|
var slice = local_marks[mark] || [];
|
|
for (var i = 0; i < slice.length; i++)
|
|
{
|
|
if (win.location.href == slice[i].location)
|
|
{
|
|
vimperator.log("Jumping to local mark: " + mark + " | " + slice[i].location + " | (" + slice[i].position.x + ", " + slice[i].position.y + ")", 5);
|
|
win.scrollTo(slice[i].position.x * win.scrollMaxX, slice[i].position.y * win.scrollMaxY);
|
|
ok = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!ok)
|
|
vimperator.echoerr("E20: Mark not set"); // FIXME: move up?
|
|
}
|
|
|
|
this.list = function(filter)
|
|
{
|
|
var marks = getSortedMarks();
|
|
|
|
if (marks.length == 0)
|
|
{
|
|
vimperator.echoerr("No marks set");
|
|
return;
|
|
}
|
|
|
|
if (filter.length > 0)
|
|
{
|
|
marks = marks.filter(function(mark) {
|
|
if (filter.indexOf(mark[0]) > -1)
|
|
return mark;
|
|
});
|
|
if (marks.length == 0)
|
|
{
|
|
vimperator.echoerr("E283: No marks matching \"" + filter + "\"");
|
|
return;
|
|
}
|
|
}
|
|
|
|
var list = "<table><tr style=\"color: magenta\"><td>mark</td><td>line</td><td>col</td><td>file</td></tr>";
|
|
for (var i = 0; i < marks.length; i++)
|
|
{
|
|
list += "<tr>"
|
|
+ "<td> " + marks[i][0] + "</td>"
|
|
+ "<td align=\"right\">" + Math.round(marks[i][1].position.y * 100) + "%</td>"
|
|
+ "<td align=\"right\">" + Math.round(marks[i][1].position.x * 100) + "%</td>"
|
|
+ "<td>" + marks[i][1].location + "</td>"
|
|
+ "</tr>";
|
|
}
|
|
list += "</table>";
|
|
|
|
vimperator.commandline.echo(list, true); // TODO: force of multiline widget a better way
|
|
}
|
|
//}}}
|
|
} //}}}
|
|
|
|
function QuickMarks() //{{{
|
|
{
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////{{{
|
|
|
|
var marks = {};
|
|
// load the saved quickmarks -- TODO: change to sqlite
|
|
var saved_marks = Options.getPref("quickmarks", "").split("\n");
|
|
for (var i = 0; i < saved_marks.length - 1; i += 2)
|
|
{
|
|
marks[saved_marks[i]] = saved_marks[i + 1];
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////}}}
|
|
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////{{{
|
|
|
|
this.add = function(mark, location)
|
|
{
|
|
marks[mark] = location;
|
|
}
|
|
|
|
this.remove = function(filter)
|
|
{
|
|
var pattern = new RegExp("[" + filter.replace(/\s+/g, '') + "]");
|
|
for (var mark in marks)
|
|
{
|
|
if (pattern.test(mark))
|
|
delete marks[mark];
|
|
}
|
|
}
|
|
|
|
this.jumpTo = function(mark, newtab)
|
|
{
|
|
var url = marks[mark];
|
|
if (url)
|
|
{
|
|
if (newtab)
|
|
openURLsInNewTab(url, true);
|
|
else
|
|
openURLs(url);
|
|
}
|
|
else
|
|
vimperator.echoerr("E20: QuickMark not set"); // FIXME: move up?
|
|
}
|
|
|
|
this.list = function()
|
|
{
|
|
var is_empty = true;
|
|
var list = "<table><tr style=\"color: magenta\"><td>mark</td><td>URL</td></tr>";
|
|
for (var i in marks)
|
|
{
|
|
is_empty = false;
|
|
list += "<tr><td> " + i + "</td><td>"
|
|
+ marks[i] + "</td></tr>";
|
|
}
|
|
list += "</table>";
|
|
|
|
if (!is_empty)
|
|
vimperator.commandline.echo(list, true); // TODO: force of multiline widget a better way
|
|
else
|
|
vimperator.echoerr("No quickmarks defined");
|
|
}
|
|
|
|
this.destroy = function()
|
|
{
|
|
// save the marks
|
|
var saved_marks = "";
|
|
for (var i in marks)
|
|
{
|
|
saved_marks += i + "\n";
|
|
saved_marks += marks[i] + "\n";
|
|
}
|
|
Options.setPref("quickmarks", saved_marks);
|
|
}
|
|
//}}}
|
|
} //}}}
|
|
|
|
// vim: set fdm=marker sw=4 ts=4 et:
|