mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 18:42:27 +01:00
Make :pageinfo extensible
This commit is contained in:
@@ -175,13 +175,14 @@ liberator.Bookmarks = function () //{{{
|
|||||||
bookmarksService.addObserver(observer, false);
|
bookmarksService.addObserver(observer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var cache = liberator.storage.newObject("bookmark-cache", Cache, false);
|
let bookmarkObserver = function (key, event, arg)
|
||||||
liberator.storage.addObserver("bookmark-cache", function (key, event, arg)
|
|
||||||
{
|
{
|
||||||
if (event == "add")
|
if (event == "add")
|
||||||
liberator.autocommands.trigger("BookmarkAdd", "");
|
liberator.autocommands.trigger("BookmarkAdd", "");
|
||||||
liberator.statusline.updateUrl();
|
liberator.statusline.updateUrl();
|
||||||
});
|
}
|
||||||
|
var cache = liberator.storage.newObject("bookmark-cache", Cache, false);
|
||||||
|
liberator.storage.addObserver("bookmark-cache", bookmarkObserver);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////}}}
|
/////////////////////////////////////////////////////////////////////////////}}}
|
||||||
////////////////////// OPTIONS /////////////////////////////////////////////////
|
////////////////////// OPTIONS /////////////////////////////////////////////////
|
||||||
@@ -494,6 +495,7 @@ liberator.Bookmarks = function () //{{{
|
|||||||
|
|
||||||
destroy: function ()
|
destroy: function ()
|
||||||
{
|
{
|
||||||
|
liberator.storage.removeObserver("bookmark-cache", bookmarkObserver);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//}}}
|
//}}}
|
||||||
|
|||||||
@@ -32,6 +32,13 @@ liberator.Buffer = function () //{{{
|
|||||||
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////{{{
|
/////////////////////////////////////////////////////////////////////////////{{{
|
||||||
|
|
||||||
|
function arrayIter(ary)
|
||||||
|
{
|
||||||
|
let length = ary.length;
|
||||||
|
for (let i = 0; i < length; i++)
|
||||||
|
yield ary[i];
|
||||||
|
}
|
||||||
|
|
||||||
var zoomLevels = [ 1, 10, 25, 50, 75, 90, 100,
|
var zoomLevels = [ 1, 10, 25, 50, 75, 90, 100,
|
||||||
120, 150, 200, 300, 500, 1000, 2000 ];
|
120, 150, 200, 300, 500, 1000, 2000 ];
|
||||||
|
|
||||||
@@ -138,6 +145,13 @@ liberator.Buffer = function () //{{{
|
|||||||
win.scrollTo(h, v);
|
win.scrollTo(h, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Holds option: [function, title] to generate :pageinfo sections
|
||||||
|
var pageInfo = {};
|
||||||
|
function addPageInfoSection(option, title, fn)
|
||||||
|
{
|
||||||
|
pageInfo[option] = [fn, title];
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////}}}
|
/////////////////////////////////////////////////////////////////////////////}}}
|
||||||
////////////////////// OPTIONS /////////////////////////////////////////////////
|
////////////////////// OPTIONS /////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////{{{
|
/////////////////////////////////////////////////////////////////////////////{{{
|
||||||
@@ -169,13 +183,8 @@ liberator.Buffer = function () //{{{
|
|||||||
{
|
{
|
||||||
completer: function (filter)
|
completer: function (filter)
|
||||||
{
|
{
|
||||||
return [
|
return [[k, v[1]] for ([k, v] in Iterator(pageInfo))]
|
||||||
["g", "General info"],
|
|
||||||
["f", "Feeds"],
|
|
||||||
["m", "Meta tags"]
|
|
||||||
];
|
|
||||||
},
|
},
|
||||||
validator: function (value) !(/[^gfm]/.test(value) || value.length > 3 || value.length < 1)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
liberator.options.add(["scroll", "scr"],
|
liberator.options.add(["scroll", "scr"],
|
||||||
@@ -601,6 +610,161 @@ liberator.Buffer = function () //{{{
|
|||||||
liberator.buffer.textZoom = level;
|
liberator.buffer.textZoom = level;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////}}}
|
||||||
|
////////////////////// PAGE INFO ///////////////////////////////////////////////
|
||||||
|
/////////////////////////////////////////////////////////////////////////////{{{
|
||||||
|
|
||||||
|
addPageInfoSection("f", "Feeds", function (verbose)
|
||||||
|
{
|
||||||
|
var doc = window.content.document;
|
||||||
|
|
||||||
|
const feedTypes = {
|
||||||
|
"application/rss+xml": "RSS",
|
||||||
|
"application/atom+xml": "Atom",
|
||||||
|
"text/xml": "XML",
|
||||||
|
"application/xml": "XML",
|
||||||
|
"application/rdf+xml": "XML"
|
||||||
|
};
|
||||||
|
|
||||||
|
function isValidFeed(data, principal, isFeed)
|
||||||
|
{
|
||||||
|
if (!data || !principal)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!isFeed)
|
||||||
|
{
|
||||||
|
var type = data.type && data.type.toLowerCase();
|
||||||
|
type = type.replace(/^\s+|\s*(?:;.*)?$/g, "");
|
||||||
|
|
||||||
|
isFeed = (type == "application/rss+xml" || type == "application/atom+xml");
|
||||||
|
if (!isFeed)
|
||||||
|
{
|
||||||
|
// really slimy: general XML types with magic letters in the title
|
||||||
|
const titleRegex = /(^|\s)rss($|\s)/i;
|
||||||
|
isFeed = ((type == "text/xml" || type == "application/rdf+xml" || type == "application/xml")
|
||||||
|
&& titleRegex.test(data.title));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFeed)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
urlSecurityCheck(data.href, principal,
|
||||||
|
Components.interfaces.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
|
||||||
|
}
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
isFeed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type)
|
||||||
|
data.type = type;
|
||||||
|
|
||||||
|
return isFeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// put feeds rss into pageFeeds[]
|
||||||
|
let nFeed = 0;
|
||||||
|
var linkNodes = doc.getElementsByTagName("link");
|
||||||
|
for (link in arrayIter(linkNodes)) {
|
||||||
|
if (!link.href)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var rel = link.rel && link.rel.toLowerCase();
|
||||||
|
|
||||||
|
if (rel == "feed" || (link.type && rel == "alternate"))
|
||||||
|
{
|
||||||
|
var feed = { title: link.title, href: link.href, type: link.type || "" };
|
||||||
|
if (isValidFeed(feed, doc.nodePrincipal, rel == "feed"))
|
||||||
|
{
|
||||||
|
nFeed++;
|
||||||
|
var type = feedTypes[feed.type] || feedTypes["application/rss+xml"];
|
||||||
|
if (verbose)
|
||||||
|
yield [feed.title, liberator.util.highlightURL(feed.href, true) + <span style="color: gray;"> ({type})</span>];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!verbose && nFeed)
|
||||||
|
yield nFeed + " feed" + (nFeed > 1 ? "s" : "");
|
||||||
|
});
|
||||||
|
|
||||||
|
addPageInfoSection("g", "General Info", function (verbose)
|
||||||
|
{
|
||||||
|
let doc = window.content.document;
|
||||||
|
|
||||||
|
// get file size
|
||||||
|
const nsICacheService = Components.interfaces.nsICacheService;
|
||||||
|
const ACCESS_READ = Components.interfaces.nsICache.ACCESS_READ;
|
||||||
|
const cacheService = Components.classes["@mozilla.org/network/cache-service;1"]
|
||||||
|
.getService(nsICacheService);
|
||||||
|
let cacheKey = doc.location.toString().replace(/#.*$/, "");
|
||||||
|
|
||||||
|
for (let proto in arrayIter(["HTTP", "FTP"]))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var cacheEntryDescriptor = cacheService.createSession(proto, 0, true)
|
||||||
|
.openCacheEntry(cacheKey, ACCESS_READ, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pageSize = []; // [0] bytes; [1] kbytes
|
||||||
|
if (cacheEntryDescriptor)
|
||||||
|
{
|
||||||
|
pageSize[0] = liberator.util.formatBytes(cacheEntryDescriptor.dataSize, 0, false);
|
||||||
|
pageSize[1] = liberator.util.formatBytes(cacheEntryDescriptor.dataSize, 2, true);
|
||||||
|
if (pageSize[1] == pageSize[0])
|
||||||
|
pageSize.length = 1; // don't output "xx Bytes" twice
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastModVerbose = new Date(doc.lastModified).toLocaleString();
|
||||||
|
var lastMod = new Date(doc.lastModified).toLocaleFormat("%x %X");
|
||||||
|
// FIXME: probably not portable across different language versions
|
||||||
|
if (lastModVerbose == "Invalid Date" || new Date(doc.lastModified).getFullYear() == 1970)
|
||||||
|
lastModVerbose = lastMod = null;
|
||||||
|
|
||||||
|
if (!verbose)
|
||||||
|
{
|
||||||
|
if (pageSize[0])
|
||||||
|
yield (pageSize[1] || pageSize[0]) + " bytes";
|
||||||
|
yield lastMod;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield ["Title", doc.title];
|
||||||
|
yield ["URL", liberator.util.highlightURL(doc.location.toString(), true)];
|
||||||
|
|
||||||
|
var ref = "referrer" in doc && doc.referrer;
|
||||||
|
if (ref)
|
||||||
|
yield ["Referrer", liberator.util.highlightURL(ref, true)];
|
||||||
|
|
||||||
|
if (pageSize[0])
|
||||||
|
yield ["File Size", pageSize[1] ? pageSize[1] + " (" + pageSize[0] + ")"
|
||||||
|
: pageSize[0]];
|
||||||
|
|
||||||
|
yield ["Mime-Type", doc.contentType];
|
||||||
|
yield ["Encoding", doc.characterSet];
|
||||||
|
yield ["Compatibility", doc.compatMode == "BackCompat" ? "Quirks Mode" : "Full/Almost Standards Mode"];
|
||||||
|
if (lastModVerbose)
|
||||||
|
yield ["Last Modified", lastModVerbose];
|
||||||
|
});
|
||||||
|
|
||||||
|
addPageInfoSection("m", "Meta Tags", function (verbose)
|
||||||
|
{
|
||||||
|
// get meta tag data, sort and put into pageMeta[]
|
||||||
|
var metaNodes = window.content.document.getElementsByTagName("meta");
|
||||||
|
|
||||||
|
let nodes = Array.map(metaNodes, function (node) [(node.name || node.httpEquiv), node.content])
|
||||||
|
.sort(function (a, b) String.localeCompare(a[0].toLowerCase(), b[0].toLowerCase()));
|
||||||
|
return ([node[0], liberator.util.highlightURL(node[1], false)]
|
||||||
|
for each (node in arrayIter(nodes)));
|
||||||
|
});
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////}}}
|
/////////////////////////////////////////////////////////////////////////////}}}
|
||||||
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////{{{
|
/////////////////////////////////////////////////////////////////////////////{{{
|
||||||
@@ -618,6 +782,8 @@ liberator.Buffer = function () //{{{
|
|||||||
return stylesheets;
|
return stylesheets;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get pageInfo() pageInfo,
|
||||||
|
|
||||||
// 0 if loading, 1 if loaded or 2 if load failed
|
// 0 if loading, 1 if loaded or 2 if load failed
|
||||||
get loaded()
|
get loaded()
|
||||||
{
|
{
|
||||||
@@ -677,6 +843,8 @@ liberator.Buffer = function () //{{{
|
|||||||
return window.content.document.title;
|
return window.content.document.title;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addPageInfoSection: addPageInfoSection,
|
||||||
|
|
||||||
// returns an XPathResult object
|
// returns an XPathResult object
|
||||||
evaluateXPath: function (expression, doc, elem, asIterator)
|
evaluateXPath: function (expression, doc, elem, asIterator)
|
||||||
{
|
{
|
||||||
@@ -1099,202 +1267,34 @@ liberator.Buffer = function () //{{{
|
|||||||
|
|
||||||
showPageInfo: function (verbose)
|
showPageInfo: function (verbose)
|
||||||
{
|
{
|
||||||
var doc = window.content.document;
|
|
||||||
|
|
||||||
const feedTypes = {
|
|
||||||
"application/rss+xml": "RSS",
|
|
||||||
"application/atom+xml": "Atom",
|
|
||||||
"text/xml": "XML",
|
|
||||||
"application/xml": "XML",
|
|
||||||
"application/rdf+xml": "XML"
|
|
||||||
};
|
|
||||||
|
|
||||||
function isValidFeed(data, principal, isFeed)
|
|
||||||
{
|
|
||||||
if (!data || !principal)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!isFeed)
|
|
||||||
{
|
|
||||||
var type = data.type && data.type.toLowerCase();
|
|
||||||
type = type.replace(/^\s+|\s*(?:;.*)?$/g, "");
|
|
||||||
|
|
||||||
isFeed = (type == "application/rss+xml" || type == "application/atom+xml");
|
|
||||||
if (!isFeed)
|
|
||||||
{
|
|
||||||
// really slimy: general XML types with magic letters in the title
|
|
||||||
const titleRegex = /(^|\s)rss($|\s)/i;
|
|
||||||
isFeed = ((type == "text/xml" || type == "application/rdf+xml" ||
|
|
||||||
type == "application/xml") && titleRegex.test(data.title));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isFeed)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
urlSecurityCheck(data.href, principal,
|
|
||||||
Components.interfaces.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
isFeed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type)
|
|
||||||
data.type = type;
|
|
||||||
|
|
||||||
return isFeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
var pageGeneral = [];
|
|
||||||
var pageFeeds = [];
|
|
||||||
var pageMeta = [];
|
|
||||||
|
|
||||||
// get file size
|
|
||||||
const nsICacheService = Components.interfaces.nsICacheService;
|
|
||||||
const ACCESS_READ = Components.interfaces.nsICache.ACCESS_READ;
|
|
||||||
const cacheService = Components.classes["@mozilla.org/network/cache-service;1"]
|
|
||||||
.getService(nsICacheService);
|
|
||||||
var httpCacheSession = cacheService.createSession("HTTP", 0, true);
|
|
||||||
var ftpCacheSession = cacheService.createSession("FTP", 0, true);
|
|
||||||
httpCacheSession.doomEntriesIfExpired = false;
|
|
||||||
ftpCacheSession.doomEntriesIfExpired = false;
|
|
||||||
var cacheKey = doc.location.toString().replace(/#.*$/, "");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var cacheEntryDescriptor = httpCacheSession.openCacheEntry(cacheKey, ACCESS_READ, false);
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
cacheEntryDescriptor = ftpCacheSession.openCacheEntry(cacheKey, ACCESS_READ, false);
|
|
||||||
}
|
|
||||||
catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
var pageSize = []; // [0] bytes; [1] kbytes
|
|
||||||
if (cacheEntryDescriptor)
|
|
||||||
{
|
|
||||||
pageSize[0] = liberator.util.formatBytes(cacheEntryDescriptor.dataSize, 0, false);
|
|
||||||
pageSize[1] = liberator.util.formatBytes(cacheEntryDescriptor.dataSize, 2, true);
|
|
||||||
if (pageSize[1] == pageSize[0])
|
|
||||||
pageSize[1] = null; // don't output "xx Bytes" twice
|
|
||||||
}
|
|
||||||
|
|
||||||
// put feeds rss into pageFeeds[]
|
|
||||||
var linkNodes = doc.getElementsByTagName("link");
|
|
||||||
Array.forEach(linkNodes, function (link) {
|
|
||||||
if (!link.href)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Ok... I don't know what this insanity was trying
|
|
||||||
* to do, but, as far as I can tell, it was:
|
|
||||||
*/
|
|
||||||
var rel = link.rel && link.rel.toLowerCase();
|
|
||||||
|
|
||||||
if (rel == "feed" || (link.type && rel == "alternate"))
|
|
||||||
{
|
|
||||||
var feed = { title: link.title, href: link.href, type: link.type || "" };
|
|
||||||
if (isValidFeed(feed, doc.nodePrincipal, rel == "feed"))
|
|
||||||
{
|
|
||||||
var type = feedTypes[feed.type] || feedTypes["application/rss+xml"];
|
|
||||||
pageFeeds.push([feed.title, liberator.util.highlightURL(feed.href, true) + <span style="color: gray;"> ({type})</span>]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var lastModVerbose = new Date(doc.lastModified).toLocaleString();
|
|
||||||
var lastMod = new Date(doc.lastModified).toLocaleFormat("%x %X");
|
|
||||||
// FIXME: probably not portable across different language versions
|
|
||||||
if (lastModVerbose == "Invalid Date" || new Date(doc.lastModified).getFullYear() == 1970)
|
|
||||||
lastModVerbose = lastMod = null;
|
|
||||||
|
|
||||||
// Ctrl-g single line output
|
// Ctrl-g single line output
|
||||||
if (!verbose)
|
if (!verbose)
|
||||||
{
|
{
|
||||||
var info = []; // tmp array for joining later
|
let file = content.document.location.pathname.split("/").pop() || "[No Name]";
|
||||||
var file = doc.location.pathname.split("/").pop() || "[No Name]";
|
let title = content.document.title || "[No Title]";
|
||||||
var title = doc.title || "[No Title]";
|
|
||||||
|
|
||||||
if (pageSize[0])
|
let info = liberator.template.map("gf", function (opt)
|
||||||
info.push(pageSize[1] || pageSize[0]);
|
liberator.template.map(pageInfo[opt][0](), function (val) val, ", "),
|
||||||
|
", ");
|
||||||
if (lastMod)
|
|
||||||
info.push(lastMod);
|
|
||||||
|
|
||||||
var countFeeds = "";
|
|
||||||
if (pageFeeds.length)
|
|
||||||
countFeeds = pageFeeds.length + (pageFeeds.length == 1 ? " feed" : " feeds");
|
|
||||||
|
|
||||||
if (countFeeds)
|
|
||||||
info.push(countFeeds);
|
|
||||||
|
|
||||||
if (liberator.bookmarks.isBookmarked(this.URL))
|
if (liberator.bookmarks.isBookmarked(this.URL))
|
||||||
info.push("bookmarked");
|
info += ", bookmarked";
|
||||||
|
|
||||||
var pageInfoText = '"' + file + '" [' + info.join(", ") + "] " + title;
|
var pageInfoText = <>"{file}" [{info}] {title}</>;
|
||||||
liberator.echo(pageInfoText, liberator.commandline.FORCE_SINGLELINE);
|
liberator.echo(pageInfoText, liberator.commandline.FORCE_SINGLELINE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get general infos
|
let option = liberator.options["pageinfo"];
|
||||||
pageGeneral.push(["Title", doc.title]);
|
let list = liberator.template.map(option, function (option)
|
||||||
pageGeneral.push(["URL", liberator.util.highlightURL(doc.location.toString(), true)]);
|
|
||||||
|
|
||||||
var ref = "referrer" in doc && doc.referrer;
|
|
||||||
if (ref)
|
|
||||||
pageGeneral.push(["Referrer", liberator.util.highlightURL(ref, true)]);
|
|
||||||
|
|
||||||
if (pageSize[0])
|
|
||||||
{
|
{
|
||||||
if (pageSize[1])
|
let opt = pageInfo[option];
|
||||||
pageGeneral.push(["File Size", pageSize[1] + " (" + pageSize[0] + ")"]);
|
if (opt)
|
||||||
else
|
return liberator.template.table(opt[1], opt[0](true));
|
||||||
pageGeneral.push(["File Size", pageSize[0]]);
|
else alert(option);
|
||||||
}
|
}, <br/>);
|
||||||
|
XML.prettyPrinting = false;
|
||||||
pageGeneral.push(["Mime-Type", doc.contentType]);
|
liberator.echo(list, liberator.commandline.FORCE_MULTILINE);
|
||||||
pageGeneral.push(["Encoding", doc.characterSet]);
|
|
||||||
pageGeneral.push(["Compatibility", doc.compatMode == "BackCompat" ? "Quirks Mode" : "Full/Almost Standards Mode"]);
|
|
||||||
if (lastModVerbose)
|
|
||||||
pageGeneral.push(["Last Modified", lastModVerbose]);
|
|
||||||
|
|
||||||
// get meta tag data, sort and put into pageMeta[]
|
|
||||||
var metaNodes = doc.getElementsByTagName("meta");
|
|
||||||
if (metaNodes.length)
|
|
||||||
{
|
|
||||||
let nodes = [];
|
|
||||||
let i = 0;
|
|
||||||
|
|
||||||
nodes = Array.map(metaNodes, function (node) [node.name || node.httpEquiv, node.content]);
|
|
||||||
nodes.sort(function (a, b) String.localeCompare(a[0].toLowerCase(), b[0].toLowerCase()));
|
|
||||||
|
|
||||||
pageMeta = [[node[0], liberator.util.highlightURL(node[1], false)]
|
|
||||||
for each (node in nodes)];
|
|
||||||
}
|
|
||||||
|
|
||||||
var pageInfoText = "";
|
|
||||||
var option = liberator.options["pageinfo"];
|
|
||||||
var br = "";
|
|
||||||
|
|
||||||
let options = {
|
|
||||||
g: [pageGeneral, "General Info"],
|
|
||||||
f: [pageFeeds, "Feeds"],
|
|
||||||
m: [pageMeta, "Meta Tags"],
|
|
||||||
};
|
|
||||||
Array.forEach(option, function (option)
|
|
||||||
{
|
|
||||||
let opt = options[option];
|
|
||||||
if (opt && opt[0].length > 0)
|
|
||||||
pageInfoText += br + liberator.template.table(opt[1], opt[0]);
|
|
||||||
if (!br)
|
|
||||||
br = "<br/>";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
liberator.echo(pageInfoText, liberator.commandline.FORCE_MULTILINE);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
viewSelectionSource: function ()
|
viewSelectionSource: function ()
|
||||||
@@ -1715,21 +1715,18 @@ liberator.template = {
|
|||||||
|
|
||||||
map: function (iter, fn, sep)
|
map: function (iter, fn, sep)
|
||||||
{
|
{
|
||||||
|
if (iter.length) /* Kludge? */
|
||||||
|
iter = liberator.util.arrayIter(iter);
|
||||||
let ret = <></>;
|
let ret = <></>;
|
||||||
if (sep == undefined)
|
|
||||||
{
|
|
||||||
for each (let i in iter)
|
|
||||||
ret += fn(i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
let n = 0;
|
let n = 0;
|
||||||
for each (let i in iter)
|
for each (let i in iter)
|
||||||
{
|
{
|
||||||
if (n++)
|
let val = fn(i);
|
||||||
|
if (val == undefined)
|
||||||
|
continue;
|
||||||
|
if (sep && n++)
|
||||||
ret += sep;
|
ret += sep;
|
||||||
ret += fn(i);
|
ret += val;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
@@ -1846,9 +1843,7 @@ liberator.template = {
|
|||||||
|
|
||||||
table: function (title, data)
|
table: function (title, data)
|
||||||
{
|
{
|
||||||
let self = this;
|
let table =
|
||||||
|
|
||||||
return this.generic(
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="hl-Title" align="left" colspan="2">{title}</th>
|
<th class="hl-Title" align="left" colspan="2">{title}</th>
|
||||||
@@ -1857,10 +1852,12 @@ liberator.template = {
|
|||||||
this.map(data, function (datum)
|
this.map(data, function (datum)
|
||||||
<tr>
|
<tr>
|
||||||
<td style="font-weight: bold; min-width: 150px">{datum[0]}</td>
|
<td style="font-weight: bold; min-width: 150px">{datum[0]}</td>
|
||||||
<td>{self.maybeXML(datum[1])}</td>
|
<td>{liberator.template.maybeXML(datum[1])}</td>
|
||||||
</tr>)
|
</tr>)
|
||||||
}
|
}
|
||||||
</table>);
|
</table>;
|
||||||
|
if (table.tr.length() > 1)
|
||||||
|
return table;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ liberator.Completion = function () //{{{
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
files = liberator.io.readDirectory(dir);
|
files = liberator.io.readDirectory(dir, true);
|
||||||
|
|
||||||
if (liberator.options["wildignore"])
|
if (liberator.options["wildignore"])
|
||||||
{
|
{
|
||||||
@@ -244,8 +244,7 @@ liberator.Completion = function () //{{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
mapped = files.map(function (file) [tail ? file.leafName : (dir + file.leafName),
|
mapped = files.map(function (file) [tail ? file.leafName : (dir + file.leafName),
|
||||||
file.isDirectory() ? "Directory" : "File"])
|
file.isDirectory() ? "Directory" : "File"]);
|
||||||
.sort(function (a, b) a[1].localeCompare(b[1]) || a[0].localeCompare(b[0]));
|
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ liberator.IO = function () //{{{
|
|||||||
|
|
||||||
// go directly to an absolute path or look for a relative path
|
// go directly to an absolute path or look for a relative path
|
||||||
// match in 'cdpath'
|
// match in 'cdpath'
|
||||||
if (/^(~|\/|[a-z]:|\.\/|\.\.\/)/i.test(args))
|
if (/^(~|\/|\.\/|\.\.\/)/.test(args))
|
||||||
{
|
{
|
||||||
// TODO: apparently we don't handle ../ or ./ paths yet
|
// TODO: apparently we don't handle ../ or ./ paths yet
|
||||||
if (liberator.io.setCurrentDirectory(args))
|
if (liberator.io.setCurrentDirectory(args))
|
||||||
@@ -323,12 +323,12 @@ liberator.IO = function () //{{{
|
|||||||
XML.prettyPrinting = false;
|
XML.prettyPrinting = false;
|
||||||
var list =
|
var list =
|
||||||
<table>
|
<table>
|
||||||
{
|
{[
|
||||||
liberator.template.map2(scriptNames, function (i, name)
|
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: right">{i+1}</td>
|
<td style="text-align: right">{i+1}</td>
|
||||||
<td>{name}</td>
|
<td>{name}</td>
|
||||||
</tr>)
|
</tr>
|
||||||
|
for ([i, name] in Iterator(striptNames))].reduce(liberator.buffer.template.add, <></>)
|
||||||
}
|
}
|
||||||
</table>.toXMLString();
|
</table>.toXMLString();
|
||||||
liberator.commandline.echo(list, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE);
|
liberator.commandline.echo(list, liberator.commandline.HL_NORMAL, liberator.commandline.FORCE_MULTILINE);
|
||||||
@@ -551,7 +551,7 @@ liberator.IO = function () //{{{
|
|||||||
},
|
},
|
||||||
|
|
||||||
// file is either a full pathname or an instance of file instanceof nsILocalFile
|
// file is either a full pathname or an instance of file instanceof nsILocalFile
|
||||||
readDirectory: function (file)
|
readDirectory: function (file, sort)
|
||||||
{
|
{
|
||||||
if (typeof file == "string")
|
if (typeof file == "string")
|
||||||
file = ioManager.getFile(file);
|
file = ioManager.getFile(file);
|
||||||
@@ -568,6 +568,8 @@ liberator.IO = function () //{{{
|
|||||||
entry.QueryInterface(Components.interfaces.nsIFile);
|
entry.QueryInterface(Components.interfaces.nsIFile);
|
||||||
array.push(entry);
|
array.push(entry);
|
||||||
}
|
}
|
||||||
|
if (sort)
|
||||||
|
return array.sort(function (a, b) b.isDirectory() - a.isDirectory() || String.localeCompare(a.path, b.path));
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -37,10 +37,17 @@ const liberator = (function () //{{{
|
|||||||
function loadModule(name, func)
|
function loadModule(name, func)
|
||||||
{
|
{
|
||||||
var message = "Loading module " + name + "...";
|
var message = "Loading module " + name + "...";
|
||||||
|
try
|
||||||
|
{
|
||||||
liberator.log(message, 0);
|
liberator.log(message, 0);
|
||||||
liberator.dump(message + "\n");
|
liberator.dump(message + "\n");
|
||||||
liberator[name] = func();
|
liberator[name] = func();
|
||||||
}
|
}
|
||||||
|
catch(e)
|
||||||
|
{
|
||||||
|
liberator.dump(e + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only general options are added here, which are valid for all vimperator like extensions
|
// Only general options are added here, which are valid for all vimperator like extensions
|
||||||
function addOptions()
|
function addOptions()
|
||||||
@@ -1111,9 +1118,9 @@ const liberator = (function () //{{{
|
|||||||
|
|
||||||
liberator.log("Sourcing plugin directory: " + dir.path + "...", 3);
|
liberator.log("Sourcing plugin directory: " + dir.path + "...", 3);
|
||||||
|
|
||||||
let files = liberator.io.readDirectory(dir.path);
|
let files = liberator.io.readDirectory(dir.path, true);
|
||||||
|
|
||||||
files.sort(function (a, b) String.localeCompare(a.path, b.path)).forEach(function (file) {
|
files.forEach(function (file) {
|
||||||
if (!file.isDirectory() && /\.(js|vimp)$/i.test(file.path))
|
if (!file.isDirectory() && /\.(js|vimp)$/i.test(file.path))
|
||||||
liberator.io.source(file.path, false);
|
liberator.io.source(file.path, false);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -847,7 +847,7 @@ liberator.Options = function () //{{{
|
|||||||
isDefault: opt.value == opt.defaultValue,
|
isDefault: opt.value == opt.defaultValue,
|
||||||
name: opt.name,
|
name: opt.name,
|
||||||
default: opt.defaultValue,
|
default: opt.defaultValue,
|
||||||
pre: <>  </>,
|
pre: " ", /* Unicode nonbreaking space. */
|
||||||
value: <></>,
|
value: <></>,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -897,7 +897,7 @@ liberator.Options = function () //{{{
|
|||||||
default: loadPreference(pref, null, true),
|
default: loadPreference(pref, null, true),
|
||||||
value: <>={liberator.util.colorize(value, false)}</>,
|
value: <>={liberator.util.colorize(value, false)}</>,
|
||||||
name: pref,
|
name: pref,
|
||||||
pre: <>  </>,
|
pre: " ", /* Unicode nonbreaking space. */
|
||||||
};
|
};
|
||||||
|
|
||||||
yield option;
|
yield option;
|
||||||
|
|||||||
@@ -28,6 +28,13 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
|||||||
|
|
||||||
liberator.util = { //{{{
|
liberator.util = { //{{{
|
||||||
|
|
||||||
|
arrayIter: function (ary)
|
||||||
|
{
|
||||||
|
let length = ary.length;
|
||||||
|
for (let i = 0; i < length; i++)
|
||||||
|
yield ary[i];
|
||||||
|
},
|
||||||
|
|
||||||
clip: function (str, length)
|
clip: function (str, length)
|
||||||
{
|
{
|
||||||
return str.length <= length ? str : str.substr(0, length - 3) + "...";
|
return str.length <= length ? str : str.substr(0, length - 3) + "...";
|
||||||
|
|||||||
Reference in New Issue
Block a user