diff --git a/common/content/buffer.js b/common/content/buffer.js
index d8322160..a1a2782f 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -20,197 +20,14 @@ var Buffer = Module("buffer", {
this.win = win;
else
this.__defineGetter__("win", function () content);
-
- this.pageInfo = {};
-
- this.addPageInfoSection("e", "Search Engines", function (verbose) {
-
- let n = 1;
- let nEngines = 0;
- for (let { document: doc } in values(buffer.allFrames())) {
- let engines = DOM("link[href][rel=search][type='application/opensearchdescription+xml']", doc);
- nEngines += engines.length;
-
- if (verbose)
- for (let link in engines)
- yield [link.title || /*L*/ "Engine " + n++,
- {link.href}];
- }
-
- if (!verbose && nEngines)
- yield nEngines + /*L*/" engine" + (nEngines > 1 ? "s" : "");
- });
-
- this.addPageInfoSection("f", "Feeds", function (verbose) {
- 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 = ["application/rss+xml", "application/atom+xml"].indexOf(type) >= 0 ||
- // really slimy: general XML types with magic letters in the title
- type in feedTypes && /\brss\b/i.test(data.title);
- }
-
- if (isFeed) {
- try {
- window.urlSecurityCheck(data.href, principal,
- Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
- }
- catch (e) {
- isFeed = false;
- }
- }
-
- if (type)
- data.type = type;
-
- return isFeed;
- }
-
- let nFeed = 0;
- for (let [i, win] in Iterator(buffer.allFrames())) {
- let doc = win.document;
-
- for (let link in DOM("link[href][rel=feed], link[href][rel=alternate][type]", doc)) {
- let rel = link.rel.toLowerCase();
- let feed = { title: link.title, href: link.href, type: link.type || "" };
- if (isValidFeed(feed, doc.nodePrincipal, rel == "feed")) {
- nFeed++;
- let type = feedTypes[feed.type] || "RSS";
- if (verbose)
- yield [feed.title, template.highlightURL(feed.href, true) + ];
- }
- }
-
- }
-
- if (!verbose && nFeed)
- yield nFeed + /*L*/" feed" + (nFeed > 1 ? "s" : "");
- });
-
- this.addPageInfoSection("g", "General Info", function (verbose) {
- let doc = buffer.focusedFrame.document;
-
- // get file size
- const ACCESS_READ = Ci.nsICache.ACCESS_READ;
- let cacheKey = doc.documentURI;
-
- for (let proto in array.iterValues(["HTTP", "FTP"])) {
- try {
- var cacheEntryDescriptor = services.cache.createSession(proto, 0, true)
- .openCacheEntry(cacheKey, ACCESS_READ, false);
- break;
- }
- catch (e) {}
- }
-
- let pageSize = []; // [0] bytes; [1] kbytes
- if (cacheEntryDescriptor) {
- pageSize[0] = util.formatBytes(cacheEntryDescriptor.dataSize, 0, false);
- pageSize[1] = util.formatBytes(cacheEntryDescriptor.dataSize, 2, true);
- if (pageSize[1] == pageSize[0])
- pageSize.length = 1; // don't output "xx Bytes" twice
- }
-
- let lastModVerbose = new Date(doc.lastModified).toLocaleString();
- let lastMod = new Date(doc.lastModified).toLocaleFormat("%x %X");
-
- if (lastModVerbose == "Invalid Date" || new Date(doc.lastModified).getFullYear() == 1970)
- lastModVerbose = lastMod = null;
-
- if (!verbose) {
- if (pageSize[0])
- yield (pageSize[1] || pageSize[0]) + /*L*/" bytes";
- yield lastMod;
- return;
- }
-
- yield ["Title", doc.title];
- yield ["URL", template.highlightURL(doc.location.href, true)];
-
- let ref = "referrer" in doc && doc.referrer;
- if (ref)
- yield ["Referrer", template.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];
- });
-
- this.addPageInfoSection("m", "Meta Tags", function (verbose) {
- if (!verbose)
- return [];
-
- // get meta tag data, sort and put into pageMeta[]
- let metaNodes = buffer.focusedFrame.document.getElementsByTagName("meta");
-
- return Array.map(metaNodes, function (node) [(node.name || node.httpEquiv), template.highlightURL(node.content)])
- .sort(function (a, b) util.compareIgnoreCase(a[0], b[0]));
- });
-
- let identity = window.gIdentityHandler;
- this.addPageInfoSection("s", "Security", function (verbose) {
- if (!verbose || !identity)
- return; // For now
-
- // Modified from Firefox
- function location(data) array.compact([
- data.city, data.state, data.country
- ]).join(", ");
-
- switch (statusline.security) {
- case "secure":
- case "extended":
- var data = identity.getIdentityData();
-
- yield ["Host", identity.getEffectiveHost()];
-
- if (statusline.security === "extended")
- yield ["Owner", data.subjectOrg];
- else
- yield ["Owner", _("pageinfo.s.ownerUnverified", data.subjectOrg)];
-
- if (location(data).length)
- yield ["Location", location(data)];
-
- yield ["Verified by", data.caOrg];
-
- if (identity._overrideService.hasMatchingOverride(identity._lastLocation.hostname,
- (identity._lastLocation.port || 443),
- data.cert, {}, {}))
- yield ["User exception", /*L*/"true"];
- break;
- }
- });
-
- dactyl.commands["buffer.viewSource"] = function (event) {
- let elem = event.originalTarget;
- let obj = { url: elem.getAttribute("href"), line: Number(elem.getAttribute("line")) };
- if (elem.hasAttribute("column"))
- obj.column = elem.getAttribute("column");
-
- buffer.viewSource(obj);
- };
},
+ addPageInfoSection: deprecated("Buffer.addPageInfoSection",
+ { get: function addPageInfoSection() Buffer.closure.addPageInfoSection }),
+
+ pageInfo: deprecated("Buffer.pageInfo",
+ { get: function pageInfo() Buffer.pageInfo }),
+
// called when the active document is scrolled
_updateBufferPosition: function _updateBufferPosition() {
statusline.updateBufferPosition();
@@ -255,12 +72,6 @@ var Buffer = Module("buffer", {
dactyl.open(matches.slice(1).join(""));
},
- /**
- * @property {Object} A map of page info sections to their
- * content generating functions.
- */
- pageInfo: null,
-
/**
* @property {number} True when the buffer is fully loaded.
*/
@@ -370,19 +181,6 @@ var Buffer = Module("buffer", {
*/
get scrollPosition() Buffer.getScrollPosition(this.findScrollable(0, false)),
- /**
- * Adds a new section to the page information output.
- *
- * @param {string} option The section's value in 'pageinfo'.
- * @param {string} title The heading for this section's
- * output.
- * @param {function} func The function to generate this
- * section's output.
- */
- addPageInfoSection: function addPageInfoSection(option, title, func) {
- this.pageInfo[option] = Buffer.PageInfo(option, title, func);
- },
-
/**
* Returns a list of all frames in the given window or current buffer.
*/
@@ -944,13 +742,15 @@ var Buffer = Module("buffer", {
* @default The value of 'pageinfo'.
*/
showPageInfo: function showPageInfo(verbose, sections) {
+ let self = this;
+
// Ctrl-g single line output
if (!verbose) {
let file = this.win.location.pathname.split("/").pop() || _("buffer.noName");
let title = this.win.document.title || _("buffer.noTitle");
let info = template.map(sections || options["pageinfo"],
- function (opt) template.map(buffer.pageInfo[opt].action(), util.identity, ", "),
+ function (opt) template.map(Buffer.pageInfo[opt].action.call(self), util.identity, ", "),
", ");
if (bookmarkcache.isBookmarked(this.URL))
@@ -962,9 +762,10 @@ var Buffer = Module("buffer", {
}
let list = template.map(sections || options["pageinfo"], function (option) {
- let { action, title } = buffer.pageInfo[option];
- return template.table(title, action(true));
+ let { action, title } = Buffer.pageInfo[option];
+ return template.table(title, action.call(self, true));
},
);
+
dactyl.echo(list, commandline.FORCE_MULTILINE);
},
@@ -1194,6 +995,21 @@ var Buffer = Module("buffer", {
PageInfo: Struct("PageInfo", "name", "title", "action")
.localize("title"),
+ pageInfo: {},
+
+ /**
+ * Adds a new section to the page information output.
+ *
+ * @param {string} option The section's value in 'pageinfo'.
+ * @param {string} title The heading for this section's
+ * output.
+ * @param {function} func The function to generate this
+ * section's output.
+ */
+ addPageInfoSection: function addPageInfoSection(option, title, func) {
+ this.pageInfo[option] = Buffer.PageInfo(option, title, func);
+ },
+
Scrollable: function Scrollable(elem) {
if (elem instanceof Element)
return elem;
@@ -1513,6 +1329,195 @@ var Buffer = Module("buffer", {
}).open(elem.value);
}
}, {
+ init: function init(dactyl, modules, window) {
+
+ Buffer.addPageInfoSection("e", "Search Engines", function (verbose) {
+
+ let n = 1;
+ let nEngines = 0;
+ for (let { document: doc } in values(this.allFrames())) {
+ let engines = DOM("link[href][rel=search][type='application/opensearchdescription+xml']", doc);
+ nEngines += engines.length;
+
+ if (verbose)
+ for (let link in engines)
+ yield [link.title || /*L*/ "Engine " + n++,
+ {link.href}];
+ }
+
+ if (!verbose && nEngines)
+ yield nEngines + /*L*/" engine" + (nEngines > 1 ? "s" : "");
+ });
+
+ Buffer.addPageInfoSection("f", "Feeds", function (verbose) {
+ 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 = ["application/rss+xml", "application/atom+xml"].indexOf(type) >= 0 ||
+ // really slimy: general XML types with magic letters in the title
+ type in feedTypes && /\brss\b/i.test(data.title);
+ }
+
+ if (isFeed) {
+ try {
+ window.urlSecurityCheck(data.href, principal,
+ Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
+ }
+ catch (e) {
+ isFeed = false;
+ }
+ }
+
+ if (type)
+ data.type = type;
+
+ return isFeed;
+ }
+
+ let nFeed = 0;
+ for (let [i, win] in Iterator(this.allFrames())) {
+ let doc = win.document;
+
+ for (let link in DOM("link[href][rel=feed], link[href][rel=alternate][type]", doc)) {
+ let rel = link.rel.toLowerCase();
+ let feed = { title: link.title, href: link.href, type: link.type || "" };
+ if (isValidFeed(feed, doc.nodePrincipal, rel == "feed")) {
+ nFeed++;
+ let type = feedTypes[feed.type] || "RSS";
+ if (verbose)
+ yield [feed.title, template.highlightURL(feed.href, true) + ];
+ }
+ }
+
+ }
+
+ if (!verbose && nFeed)
+ yield nFeed + /*L*/" feed" + (nFeed > 1 ? "s" : "");
+ });
+
+ Buffer.addPageInfoSection("g", "General Info", function (verbose) {
+ let doc = this.focusedFrame.document;
+
+ // get file size
+ const ACCESS_READ = Ci.nsICache.ACCESS_READ;
+ let cacheKey = doc.documentURI;
+
+ for (let proto in array.iterValues(["HTTP", "FTP"])) {
+ try {
+ var cacheEntryDescriptor = services.cache.createSession(proto, 0, true)
+ .openCacheEntry(cacheKey, ACCESS_READ, false);
+ break;
+ }
+ catch (e) {}
+ }
+
+ let pageSize = []; // [0] bytes; [1] kbytes
+ if (cacheEntryDescriptor) {
+ pageSize[0] = util.formatBytes(cacheEntryDescriptor.dataSize, 0, false);
+ pageSize[1] = util.formatBytes(cacheEntryDescriptor.dataSize, 2, true);
+ if (pageSize[1] == pageSize[0])
+ pageSize.length = 1; // don't output "xx Bytes" twice
+ }
+
+ let lastModVerbose = new Date(doc.lastModified).toLocaleString();
+ let lastMod = new Date(doc.lastModified).toLocaleFormat("%x %X");
+
+ if (lastModVerbose == "Invalid Date" || new Date(doc.lastModified).getFullYear() == 1970)
+ lastModVerbose = lastMod = null;
+
+ if (!verbose) {
+ if (pageSize[0])
+ yield (pageSize[1] || pageSize[0]) + /*L*/" bytes";
+ yield lastMod;
+ return;
+ }
+
+ yield ["Title", doc.title];
+ yield ["URL", template.highlightURL(doc.location.href, true)];
+
+ let ref = "referrer" in doc && doc.referrer;
+ if (ref)
+ yield ["Referrer", template.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];
+ });
+
+ this.addPageInfoSection("m", "Meta Tags", function (verbose) {
+ if (!verbose)
+ return [];
+
+ // get meta tag data, sort and put into pageMeta[]
+ let metaNodes = this.focusedFrame.document.getElementsByTagName("meta");
+
+ return Array.map(metaNodes, function (node) [(node.name || node.httpEquiv), template.highlightURL(node.content)])
+ .sort(function (a, b) util.compareIgnoreCase(a[0], b[0]));
+ });
+
+ let identity = window.gIdentityHandler;
+ this.addPageInfoSection("s", "Security", function (verbose) {
+ if (!verbose || !identity)
+ return; // For now
+
+ // Modified from Firefox
+ function location(data) array.compact([
+ data.city, data.state, data.country
+ ]).join(", ");
+
+ switch (statusline.security) {
+ case "secure":
+ case "extended":
+ var data = identity.getIdentityData();
+
+ yield ["Host", identity.getEffectiveHost()];
+
+ if (statusline.security === "extended")
+ yield ["Owner", data.subjectOrg];
+ else
+ yield ["Owner", _("pageinfo.s.ownerUnverified", data.subjectOrg)];
+
+ if (location(data).length)
+ yield ["Location", location(data)];
+
+ yield ["Verified by", data.caOrg];
+
+ if (identity._overrideService.hasMatchingOverride(identity._lastLocation.hostname,
+ (identity._lastLocation.port || 443),
+ data.cert, {}, {}))
+ yield ["User exception", /*L*/"true"];
+ break;
+ }
+ });
+
+ dactyl.commands["buffer.viewSource"] = function (event) {
+ let elem = event.originalTarget;
+ let obj = { url: elem.getAttribute("href"), line: Number(elem.getAttribute("line")) };
+ if (elem.hasAttribute("column"))
+ obj.column = elem.getAttribute("column");
+
+ buffer.viewSource(obj);
+ };
+ },
commands: function initCommands(dactyl, modules, window) {
commands.add(["frameo[nly]"],
"Show only the current frame's page",
@@ -2250,7 +2255,7 @@ var Buffer = Module("buffer", {
options.add(["pageinfo", "pa"],
"Define which sections are shown by the :pageinfo command",
"charlist", "gesfm",
- { get values() values(buffer.pageInfo).toObject() });
+ { get values() values(Buffer.pageInfo).toObject() });
options.add(["scroll", "scr"],
"Number of lines to scroll with and commands",