diff --git a/Donators b/Donators index 556f8736..470f8d7b 100644 --- a/Donators +++ b/Donators @@ -3,6 +3,7 @@ 2007 (most recent donators first): +* Christian Walther * Ivo-Jose Jimenez-Ramos * Robert Heckel * Ramana Kumar diff --git a/content/buffers.js b/content/buffers.js index 4dc36c1c..f4632dfe 100644 --- a/content/buffers.js +++ b/content/buffers.js @@ -34,11 +34,9 @@ vimperator.Buffer = function() //{{{ // used for the "B" mapping to remember the last :buffer[!] command var lastBufferSwitchArgs = ""; var lastBufferSwitchSpecial = true; - var zoom_levels = [ 1, 10, 25, 50, 75, 90, 100, 120, 150, 200, 300, 500, 1000, 2000 ]; - function setZoom(value, full_zoom) { if (value < 1 || value > 2000) @@ -495,13 +493,83 @@ vimperator.Buffer = function() //{{{ this.pageInfo = function(verbose) { - // to get the file size later (from pageInfo.js) (setup cacheEntryDescriptor) + // TODO: copied from firefox. Needs some review/work... + // const feedTypes = { + // "application/rss+xml": gBundle.getString("feedRss"), + // "application/atom+xml": gBundle.getString("feedAtom"), + // "text/xml": gBundle.getString("feedXML"), + // "application/xml": gBundle.getString("feedXML"), + // "application/rdf+xml": gBundle.getString("feedXML") + // }; + function isValidFeed(aData, aPrincipal, aIsFeed) + { + if (!aData || !aPrincipal) + return false; + + if (!aIsFeed) + { + var type = aData.type && aData.type.toLowerCase(); + type = type.replace(/^\s+|\s*(?:;.*)?$/g, ""); + + aIsFeed = (type == "application/rss+xml" || type == "application/atom+xml"); + if (!aIsFeed) + { + // really slimy: general XML types with magic letters in the title + const titleRegex = /(^|\s)rss($|\s)/i; + aIsFeed = ((type == "text/xml" || type == "application/rdf+xml" || + type == "application/xml") && titleRegex.test(aData.title)); + } + } + + if (aIsFeed) + { + try + { + urlSecurityCheck(aData.href, aPrincipal, + Components.interfaces.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL); + } + catch(ex) + { + aIsFeed = false; + } + } + + if (type) + aData.type = type; + + return aIsFeed; + } + + // TODO: could this be useful for other commands? + function createTable(data) + { + var ret = ""; + + if (data.length - 1) + { + for (var i = 0; i < data.length - 1 ; i++) + ret += ""; + } + else + { + ret += ""; + } + + return ret + "
" + + data[data.length -1][0] + "
" + data[i][0] + ": " + data[i][1] + "
(" + data[data.length - 1][1] + ")
"; + } + + 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); - httpCacheSession.doomEntriesIfExpired = false; var ftpCacheSession = cacheService.createSession("FTP", 0, true); + httpCacheSession.doomEntriesIfExpired = false; ftpCacheSession.doomEntriesIfExpired = false; var cacheKey = window.content.document.location.toString().replace(/#.*$/, ""); try @@ -517,49 +585,83 @@ vimperator.Buffer = function() //{{{ catch (ex2) { } } + var pageSize = []; // [0] bytes; [1] kbytes + if (cacheEntryDescriptor) + { + pageSize[0] = vimperator.util.formatNumber(cacheEntryDescriptor.dataSize); + pageSize[1] = vimperator.util.formatNumber(Math.round(cacheEntryDescriptor.dataSize / 1024 * 100) / 100); + } + + // put feeds rss into pageFeeds[] + var linkNodes = window.content.document.getElementsByTagName("link"); + var length = linkNodes.length; + for (var i = 0; i < length; i++) + { + var link = linkNodes[i]; + if (!link.href) + continue; + + var rel = link.rel && link.rel.toLowerCase(); + var rels = {}; + if (rel) + { + for each (let relVal in rel.split(/\s+/)) + rels[relVal] = true; + } + + if (rels.feed || (link.type && rels.alternate && !rels.stylesheet)) + { + var feed = { title: link.title, href: link.href, type: link.type || "" }; + if (isValidFeed(feed, window.content.document.nodePrincipal, rels.feed)) + { +// var type = feedTypes[feed.type] || feedTypes["application/rss+xml"]; // TODO: dig into that.. --calmar + var type = feed.type || "application/rss+xml"; + pageFeeds.push([feed.title, vimperator.util.highlightURL(feed.href, true)]); + } + } + } + + // Ctrl-g single line output if (!verbose) { - // TODO: strip off any component after & - var file = window.content.document.location.pathname.split('/').pop(); - if (!file) - file = "[No Name]"; - + var info = []; // tmp array for joining later + var file = window.content.document.location.pathname.split('/').pop() || "[No Name]"; var title = window.content.document.title || "[No Title]"; - if (cacheEntryDescriptor) - var pageSize = Math.round(cacheEntryDescriptor.dataSize / 1024 * 100) / 100 + "KB"; + if (pageSize[1]) + info.push(pageSize[1] + "KiB"); - var lastmod = window.content.document.lastModified.slice(0, -3); + var lastMod = window.content.document.lastModified.slice(0, -3); + if (lastMod) + info.push(lastMod); - var pageInfoText = '"' + file + '" [' + pageSize + ", " + lastmod + "] " + title; + var countFeeds = ""; + if (pageFeeds.length) + countFeeds = pageFeeds.length + (pageFeeds.length == 1 ? " feed" : " feeds"); + if (countFeeds) + info.push(countFeeds); + + var pageInfoText = '"' + file + '" [' + info.join(", ") + "] " + title; vimperator.echo(pageInfoText, vimperator.commandline.FORCE_SINGLELINE); return; } - var pageGeneral = []; // keeps general infos - var pageMeta = []; // keeps meta infos - // get general infos pageGeneral.push(["Title", window.content.document.title]); - pageGeneral.push(["URL", '' + - window.content.document.location.toString() + '']); - pageGeneral.push(["Referrer", ("referrer" in window.content.document && window.content.document.referrer)]); + pageGeneral.push(["URL", vimperator.util.highlightURL(window.content.document.location.toString(), true)]); + + var ref = "referrer" in window.content.document && window.content.document.referrer; + if (ref) + pageGeneral.push(["Referrer", vimperator.util.highlightURL(ref, true)]); + + if (pageSize[0]) + pageGeneral.push(["File Size", pageSize[1] + "KiB (" + pageSize[0] + " bytes)"]); + pageGeneral.push(["Mime-Type", window.content.document.contentType]); pageGeneral.push(["Encoding", window.content.document.characterSet]); - - if (cacheEntryDescriptor) - { - var pageSize = cacheEntryDescriptor.dataSize; - var bytes = pageSize + ''; - for (var u = bytes.length - 3; u > 0; u -= 3) // make a 1400 -> 1'400 - bytes = bytes.slice(0, u) + "," + bytes.slice(u, bytes.length); - pageGeneral.push(["File Size", (Math.round(pageSize / 1024 * 100) / 100) + "KB (" + bytes + " bytes)"]); - } - - pageGeneral.push(["Compatibility", content.document.compatMode == "BackCompat" ? - "Quirks Mode" : "Full/Almost Standards Mode"]); - pageGeneral.push(["Last Modified", window.content.document.lastModified]); + pageGeneral.push(["Compatibility", content.document.compatMode == "BackCompat" ? "Quirks Mode" : "Full/Almost Standards Mode"]); + pageGeneral.push(["Last Modified", window.content.document.lastModified]); //TODO: do not show bogus times (=current time) // get meta tag data, sort and put into pageMeta[] var metaNodes = window.content.document.getElementsByTagName("meta"); @@ -572,55 +674,55 @@ vimperator.Buffer = function() //{{{ for (var i = 0; i < length; i++) { var tmpTag = metaNodes[i].name || metaNodes[i].httpEquiv;// + - //'-eq'; // XXX: really important? - var tmpTagNr = tmpTag + "-" + i; // allows multiple (identical) meta names + var tmpTagNr = tmpTag + "-" + i; // allows multiple (identical) meta names tmpDict[tmpTagNr] = [tmpTag, metaNodes[i].content]; - tmpSort.push(tmpTagNr); // array for sorting + tmpSort.push(tmpTagNr); // array for sorting } // sort: ignore-case tmpSort.sort(function (a,b){return a.toLowerCase() > b.toLowerCase() ? 1 : -1;}); - for (var i=0; i < tmpSort.length; i++) - { - pageMeta.push([tmpDict[tmpSort[i]][0], tmpDict[tmpSort[i]][1]]); - } + pageMeta.push([tmpDict[tmpSort[i]][0], vimperator.util.highlightURL(tmpDict[tmpSort[i]][1], false)]); } + pageMeta.push(["Meta Tags", ""]); // add extra text to the end + pageGeneral.push(["General Info", ""]); + pageFeeds.push(["Feeds", ""]); + var pageInfoText = ""; var option = vimperator.options["pageinfo"]; + var br = ""; for (var z = 0; z < option.length; z++) { - var newLine = z > 0 ? "
" : ""; switch (option[z]) { - case "g": pageInfoText += newLine + ""; - for (var i = 0; i < pageGeneral.length; i++) + case "g": + if (pageGeneral.length > 1) { - if (pageGeneral[i][1]) - pageInfoText += ""; + pageInfoText += br + createTable(pageGeneral); + if (!br) + br = "
"; } - pageInfoText += "
General
" + pageGeneral[i][0] + ": " + pageGeneral[i][1] + "
"; break; - - case "m": pageInfoText += newLine + ""; - if (pageMeta.length) + case "f": + if (pageFeeds.length > 1) { - for (var i = 0; i < pageMeta.length; i++) - { - pageInfoText += ""; - } + pageInfoText += br + createTable(pageFeeds); + if (!br) + br = "
"; } - else + break; + case "m": + if (pageMeta.length > 1) { - pageInfoText += ""; + pageInfoText += br + createTable(pageMeta); + if (!br) + br = "
"; } - pageInfoText += "
Meta Tags
" + pageMeta[i][0] + ": " + pageMeta[i][1] + "
(no Meta-Tags on this page)
"; break; } } - vimperator.echo(pageInfoText, vimperator.commandline.FORCE_MULTILINE); } //}}} diff --git a/content/commands.js b/content/commands.js index 77e4c6b6..20b7accb 100644 --- a/content/commands.js +++ b/content/commands.js @@ -1495,8 +1495,8 @@ vimperator.Commands = function() //{{{ addDefaultCommand(new vimperator.Command(["pa[geinfo]"], function () { vimperator.buffer.pageInfo(true); }, { - short_help: "Show general and/or meta-content site informations", - help: "Show general and/or meta-content site informations" + short_help: "Show various page information", + help: "See :help 'pageinfo' for available options", } )); addDefaultCommand(new vimperator.Command(["pc[lose]"], diff --git a/content/mappings.js b/content/mappings.js index 1c3da53a..bd7ac07f 100644 --- a/content/mappings.js +++ b/content/mappings.js @@ -1973,6 +1973,18 @@ vimperator.Mappings = function() //{{{ function() { vimperator.editor.executeCommand("cmd_deleteCharBackward", 1); }, { } )); + addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.COMMAND_LINE], [""], + function() { vimperator.editor.executeCommand("cmd_deleteCharForward", 1); }, + { } + )); +// addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.COMMAND_LINE], [""], +// function() { vimperator.editor.executeCommand("cmd_charPrevious", 1); }, +// { } +// )); +// addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.COMMAND_LINE], [""], +// function() { vimperator.editor.executeCommand("cmd_charNext", 1); }, +// { } +// )); addDefaultMap(new vimperator.Map([vimperator.modes.INSERT, vimperator.modes.COMMAND_LINE], [""], function() { vimperator.editor.pasteClipboard(); }, { } diff --git a/content/options.js b/content/options.js index 0f0e125b..3a813841 100644 --- a/content/options.js +++ b/content/options.js @@ -590,12 +590,12 @@ vimperator.Options = function() //{{{ help: "Available items:
" + "
    " + "
  • g: general info
  • " + + "
  • f: feeds
  • " + "
  • m: meta tags
  • " + "
" + "The order matters", - default_value: "gm", - validator: function (value) { if (/[^gm]/.test(value) || value.length > 2 || - value.length < 1) return false; else return true; } + default_value: "gfm", + validator: function (value) { return !(/[^gfm]/.test(value) || value.length > 3 || value.length < 1) } } )); this.add(new vimperator.Option(["popups", "pps"], "number", diff --git a/content/util.js b/content/util.js index 0c009696..756a30f2 100644 --- a/content/util.js +++ b/content/util.js @@ -91,7 +91,7 @@ vimperator.util = { // takes a string like 'google bla, www.osnews.com' // and returns an array ['www.google.com/search?q=bla', 'www.osnews.com'] - stringToURLArray: function(str) // {{{ + stringToURLArray: function(str) { var urls = str.split(/\s*\,\s+/); @@ -164,8 +164,28 @@ vimperator.util = { } return urls; - } // }}} + }, + highlightURL: function(str, force) + { + if (force || /^[a-zA-Z]+:\/\/.*\//.test(str)) + return "" + vimperator.util.escapeHTML(str) + ""; + else + return str; + }, + + formatNumber: function(num) + { + var strNum = (num + "").split(".", 2); + + for (var u = strNum[0].length - 3; u > 0; u -= 3) + strNum[0] = strNum[0].substring(0, u) + "," + strNum[0].substring(u, strNum[0].length); + + if (strNum[1]) + strNum[0] += "." + strNum[1] + + return strNum[0]; + } } // vim: set fdm=marker sw=4 ts=4 et: