1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-21 22:17:59 +01:00

initial buffer implementation

This commit is contained in:
Doug Kearns
2007-08-07 14:19:20 +00:00
parent 4c919b8ea0
commit ad44a9160c
8 changed files with 369 additions and 266 deletions

View File

@@ -0,0 +1,272 @@
/***** BEGIN LICENSE BLOCK ***** {{{
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
(c) 2006-2007: Martin Stubenschrott <stubenschrott@gmx.net>
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/
function Buffer() //{{{
{
////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
var zoom_manager = ZoomManager.prototype.getInstance();
const ZOOM_INTERVAL = 25;
// initialise the zoom levels
zoom_manager.zoomFactors = [zoom_manager.MIN];
for (var i = ZOOM_INTERVAL; i <= zoom_manager.MAX; i += ZOOM_INTERVAL)
zoom_manager.zoomFactors.push(i);
// NOTE: this is only needed as there's currently no way to specify a
// {count} when calling ZM.reduce()/ZM.enlarge(). TODO: see if we can get
// this added to ZoomManager.
function bumpZoomLevel(steps)
{
var adjusted_zoom = zoom_manager.snap(zoom_manager.textZoom);
var current = zoom_manager.indexOf(adjusted_zoom);
var next = current + steps;
var start = 0, end = zoom_manager.zoomFactors.length - 1;
if ((current == start && steps < 0) || (current == end && steps > 0))
{
vimperator.beep();
return;
}
if (next < start)
next = start;
else if (next > end)
next = end;
zoom_manager.textZoom = zoom_manager.zoomFactors[next];
vimperator.hints.reshowHints();
}
/////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{
this.__defineGetter__("location", function()
{
return window.content.document.location.href;
});
this.__defineGetter__("textZoom", function()
{
return zoom_manager.textZoom;
});
this.__defineSetter__("textZoom", function(value)
{
try
{
zoom_manager.textZoom = value;
}
catch (e) // Components.results.NS_ERROR_INVALID_ARG
{
vimperator.echoerr("Zoom value out of range (" + zoom_manager.MIN + "-" + zoom_manager.MAX + ")");
}
// TODO: shouldn't this just recalculate hint coords, rather than
// unsuccessfully attempt to reshow hints? i.e. isn't it just relying
// on the recalculation side effect? -- djk
// NOTE: we could really do with a zoom event...
vimperator.hints.reshowHints();
});
this.__defineGetter__("title", function()
{
return window.content.document.title;
});
// both values are given in percent, -1 means no change
this.scrollAbsolute = function(horizontal, vertical)
{
var win = document.commandDispatcher.focusedWindow;
//var win = window.content;
var horiz, vert;
if (horizontal < 0)
horiz = win.scrollX;
else
horiz = win.scrollMaxX / 100 * horizontal;
if (vertical < 0)
vert = win.scrollY;
else
vert = win.scrollMaxY / 100 * vertical;
win.scrollTo(horiz, vert);
}
this.scrollRelative = function(right, down)
{
var win = window.document.commandDispatcher.focusedWindow;
//var win = window.content; // XXX: This would fix scrolling when the tab has focus, but breaks when it has frames --MST
// beep if we can't go there
if (down > 0)
{
if (win.scrollY == win.scrollMaxY)
vimperator.beep();
}
else if (down < 0)
{
if (win.scrollY == 0)
vimperator.beep();
}
if (right > 0)
{
if (win.scrollX == win.scrollMaxX)
vimperator.beep();
}
else if (right < 0)
{
if (win.scrollX == 0)
vimperator.beep();
}
win.scrollBy(right * 20, down * 20);
}
// TODO: allow callback for filtering out unwanted frames? User defined?
this.shiftFrameFocus = function(count, forward)
{
try
{
var frames = [];
// find all frames - depth-first search
(function(frame)
{
if (frame.document.body.localName.toLowerCase() == "body")
frames.push(frame);
for (var i = 0; i < frame.frames.length; i++)
arguments.callee(frame.frames[i])
})(window.content);
if (frames.length == 0) // currently top is always included
return;
// remove all unfocusable frames
// TODO: find a better way to do this
var start = document.commandDispatcher.focusedWindow;
frames = frames.filter(function(frame) {
frame.focus();
if (document.commandDispatcher.focusedWindow == frame)
return frame;
});
start.focus();
// find the currently focused frame index
// TODO: If the window is a frameset then the first _frame_ should be
// focused. Since this is not the current FF behaviour,
// we initalise current to -1 so the first call takes us to the
// first frame.
var current = -1;
for (var i = 0; i < frames.length; i++)
{
if (frames[i] == document.commandDispatcher.focusedWindow)
{
var current = i;
break;
}
}
// calculate the next frame to focus
var next = current;
if (forward)
{
if (count > 1)
next = current + count;
else
next++;
if (next > frames.length - 1)
next = frames.length - 1;
}
else
{
if (count > 1)
next = current - count;
else
next--;
if (next < 0)
next = 0;
}
// focus next frame and scroll into view
frames[next].focus();
if (frames[next] != window.content)
frames[next].frameElement.scrollIntoView(false);
// add the frame indicator
var doc = frames[next].document;
var indicator = doc.createElement("div");
indicator.id = "vimperator-frame-indicator";
// NOTE: need to set a high z-index - it's a crapshoot!
var style = "background-color: red; opacity: 0.5; z-index: 999;" +
"position: fixed; top: 0; bottom: 0; left: 0; right: 0;";
indicator.setAttribute("style", style);
doc.body.appendChild(indicator);
// remove the frame indicator
setTimeout(function() { doc.body.removeChild(indicator); }, 500);
}
catch (e)
{
//vimperator.echoerr(e);
// FIXME: fail silently here for now
}
}
// updates the buffer preview in place only if list is visible
this.updateBufferList = function()
{
if (!vimperator.bufferwindow.visible())
return false;
var items = get_buffer_completions("");
vimperator.bufferwindow.show(items);
vimperator.bufferwindow.selectItem(getBrowser().mTabContainer.selectedIndex);
}
this.zoomIn = function(steps)
{
bumpZoomLevel(steps);
}
this.zoomOut = function(steps)
{
bumpZoomLevel(-steps);
}
//}}}
} //}}}
// vim: set fdm=marker sw=4 ts=4 et:

View File

@@ -274,10 +274,10 @@ function Commands() //{{{
{ {
if (res.url == null) if (res.url == null)
{ {
res.url = getCurrentLocation(); res.url = vimperator.buffer.location;
// also guess title if the current url is :bmadded // also guess title if the current url is :bmadded
if (res.title == null) if (res.title == null)
res.title = getCurrentTitle(); res.title = vimperator.buffer.title;
} }
if (res.title == null) // title could still be null if (res.title == null) // title could still be null
@@ -309,7 +309,7 @@ function Commands() //{{{
if (res) if (res)
{ {
if (res.url == null) if (res.url == null)
res.url = getCurrentLocation(); res.url = vimperator.buffer.location;
var del = vimperator.bookmarks.remove(res.url); var del = vimperator.bookmarks.remove(res.url);
vimperator.echo(del + " bookmark(s) with url `" + res.url + "' deleted"); vimperator.echo(del + " bookmark(s) with url `" + res.url + "' deleted");
@@ -983,7 +983,7 @@ function Commands() //{{{
addDefaultCommand(new Command(["tabm[ove]"], addDefaultCommand(new Command(["tabm[ove]"],
function(args, special) { vimperator.tabs.move(getBrowser().mCurrentTab, args, special); }, function(args, special) { vimperator.tabs.move(getBrowser().mCurrentTab, args, special); },
{ {
usage: ["tabm[ove] [N]", "tabm[ove][!] [+|-N]"], usage: ["tabm[ove] [N]", "tabm[ove][!] +N | -N"],
short_help: "Move the current tab after tab N", short_help: "Move the current tab after tab N",
help: "When N is 0 the current tab is made the first one. Without N the current tab is made the last one. " + help: "When N is 0 the current tab is made the first one. Without N the current tab is made the last one. " +
"N can also be prefixed with '+' or '-' to indicate a relative movement. If <code class=\"command\">!</code> is specified the movement wraps around the start or end of the tab list." "N can also be prefixed with '+' or '-' to indicate a relative movement. If <code class=\"command\">!</code> is specified the movement wraps around the start or end of the tab list."
@@ -1053,7 +1053,7 @@ function Commands() //{{{
if (matches1 && matches1[1]) if (matches1 && matches1[1])
vimperator.quickmarks.add(matches1[1], matches1[2]); vimperator.quickmarks.add(matches1[1], matches1[2]);
else if (matches2 && matches2) else if (matches2 && matches2)
vimperator.quickmarks.add(matches2[1], getCurrentLocation()); vimperator.quickmarks.add(matches2[1], vimperator.buffer.location);
else else
vimperator.echoerr("E488: Trailing characters"); vimperator.echoerr("E488: Trailing characters");
}, },
@@ -1141,11 +1141,41 @@ function Commands() //{{{
} }
)); ));
addDefaultCommand(new Command(["zo[om]"], addDefaultCommand(new Command(["zo[om]"],
vimperator.zoom, function(args)
{ {
usage: ["zo[om] [+-]{value}[%]"], var level;
if (args.length == 0)
{
level = 100;
}
else if (/^\d+$/.test(args))
{
level = parseInt(args);
}
else if (/^[+-]\d+$/.test(args))
{
level = vimperator.buffer.textZoom + parseInt(args);
// relative args shouldn't take us out of range
if (level < 1)
level = 1;
if (level > 2000)
level = 2000;
}
else
{
vimperator.echoerr("E488: Trailing characters");
return;
}
vimperator.buffer.textZoom = level;
},
{
usage: ["zo[om] [value]", "zo[om] +{value} | -{value}"],
short_help: "Set zoom value of the web page", short_help: "Set zoom value of the web page",
help: "{value} can be an absolute value between 25 and 500% or a relative value if prefixed with - or +. If {value} is omitted, zoom is reset to 100%." help: "{value} can be an absolute value between 1 and 2000% or a relative value if prefixed with - or +. " +
"If {value} is omitted, zoom is reset to 100%."
} }
)); ));
//}}} //}}}
@@ -1163,7 +1193,7 @@ String.prototype.toURLArray = function()
// check for ./ and ../ (or even .../) to go to a file in the upper directory // check for ./ and ../ (or even .../) to go to a file in the upper directory
if (urls[url].match(/^(\.$|\.\/\S*)/)) if (urls[url].match(/^(\.$|\.\/\S*)/))
{ {
var newLocation = getCurrentLocation(); var newLocation = vimperator.buffer.location;
newLocation = newLocation.replace(/([\s\S]+\/)[^\/]*/, "$1"); newLocation = newLocation.replace(/([\s\S]+\/)[^\/]*/, "$1");
if (urls[url].match(/^\.(\/\S+)/)) if (urls[url].match(/^\.(\/\S+)/))
newLocation += urls[url].replace(/^\.(\/\S+)/, "$1"); newLocation += urls[url].replace(/^\.(\/\S+)/, "$1");
@@ -1173,7 +1203,7 @@ String.prototype.toURLArray = function()
} }
else if (urls[url].match(/^(\.\.$|\.\.\/[\S]*)/)) else if (urls[url].match(/^(\.\.$|\.\.\/[\S]*)/))
{ {
var newLocation = getCurrentLocation(); var newLocation = vimperator.buffer.location;
newLocation = newLocation.replace(/([\s\S]+\/)[^\/]*/, "$1/../"); newLocation = newLocation.replace(/([\s\S]+\/)[^\/]*/, "$1/../");
if (urls[url].match(/^\.\.(\/\S+)/)) if (urls[url].match(/^\.\.(\/\S+)/))
newLocation += urls[url].replace(/^\.\.\/(\S+)/, "$1"); newLocation += urls[url].replace(/^\.\.\/(\S+)/, "$1");
@@ -1183,7 +1213,7 @@ String.prototype.toURLArray = function()
} }
else if (urls[url].match(/^(\.\.\.$|\.\.\.\/[\S]*)/)) else if (urls[url].match(/^(\.\.\.$|\.\.\.\/[\S]*)/))
{ {
var newLocation = getCurrentLocation(); var newLocation = vimperator.buffer.location;
newLocation = newLocation.replace(/([\s\S]+):\/\/\/?(\S+?)\/\S*/, "$1://$2/"); newLocation = newLocation.replace(/([\s\S]+):\/\/\/?(\S+?)\/\S*/, "$1://$2/");
if (urls[url].match(/^\.\.\.(\/\S+)/)) if (urls[url].match(/^\.\.\.(\/\S+)/))
newLocation += urls[url].replace(/^\.\.\.\/(\S+)/, "$1"); newLocation += urls[url].replace(/^\.\.\.\/(\S+)/, "$1");
@@ -1252,74 +1282,6 @@ function isDirectory(url)
return false; return false;
} }
/////////////////////////////////////////////////////////////////////}}}
// location handling ///////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////{{{
function getCurrentLocation()
{
return window.content.document.location.href;
}
/* returns the current title or null */
function getCurrentTitle()
{
return window.content.document.title;
}
/////////////////////////////////////////////////////////////////////}}}
// scrolling ///////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////{{{
function scrollBufferRelative(right, down)
{
var win = window.document.commandDispatcher.focusedWindow;
//var win = window.content; // XXX: This would fix scrolling when the tab has focus, but breaks when it has frames --MST
if (vimperator.input.count < 1)
vimperator.input.count = 1;
// beep if we can't go there
if (down > 0)
{
if (win.scrollY == win.scrollMaxY) vimperator.beep();
}
else if (down < 0)
{
if (win.scrollY == 0) vimperator.beep();
}
if (right > 0)
{
if (win.scrollX == win.scrollMaxX) vimperator.beep();
}
else if (right < 0)
{
if (win.scrollX == 0) vimperator.beep();
}
win.scrollBy(vimperator.input.count * right * 20, vimperator.input.count * down * 20);
}
/* both values are given in percent, -1 means no change */
function scrollBufferAbsolute(horizontal, vertical)
{
var win = document.commandDispatcher.focusedWindow;
//var win = window.content;
var horiz, vert;
if (horizontal < 0)
horiz = win.scrollX;
else
horiz = win.scrollMaxX/100 * horizontal;
if (vertical < 0)
vert = win.scrollY;
else
vert = win.scrollMaxY/100 * vertical;
win.scrollTo(horiz, vert);
}
/////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////}}}
// misc helper functions /////////////////////////////////////////////// // misc helper functions ///////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////{{{

View File

@@ -41,21 +41,21 @@ function Events() //{{{
var tabcontainer = getBrowser().tabContainer; var tabcontainer = getBrowser().tabContainer;
tabcontainer.addEventListener("TabMove", function(event) { tabcontainer.addEventListener("TabMove", function(event) {
vimperator.statusline.updateTabCount() vimperator.statusline.updateTabCount()
vimperator.tabs.updateBufferList(); vimperator.buffer.updateBufferList();
}, false); }, false);
tabcontainer.addEventListener("TabOpen", function(event) { tabcontainer.addEventListener("TabOpen", function(event) {
vimperator.statusline.updateTabCount(); vimperator.statusline.updateTabCount();
vimperator.tabs.updateBufferList(); vimperator.buffer.updateBufferList();
vimperator.setMode(); // trick to reshow the mode in the command line vimperator.setMode(); // trick to reshow the mode in the command line
}, false); }, false);
tabcontainer.addEventListener("TabClose", function(event) { tabcontainer.addEventListener("TabClose", function(event) {
vimperator.statusline.updateTabCount() vimperator.statusline.updateTabCount()
vimperator.tabs.updateBufferList(); vimperator.buffer.updateBufferList();
vimperator.setMode(); // trick to reshow the mode in the command line vimperator.setMode(); // trick to reshow the mode in the command line
}, false); }, false);
tabcontainer.addEventListener("TabSelect", function(event) { tabcontainer.addEventListener("TabSelect", function(event) {
vimperator.statusline.updateTabCount(); vimperator.statusline.updateTabCount();
vimperator.tabs.updateBufferList(); vimperator.buffer.updateBufferList();
vimperator.setMode(); // trick to reshow the mode in the command line vimperator.setMode(); // trick to reshow the mode in the command line
vimperator.tabs.updateSelectionHistory(); vimperator.tabs.updateSelectionHistory();
}, false); }, false);
@@ -118,11 +118,11 @@ function Events() //{{{
} }
// code which should happen for all (also background) newly loaded tabs goes here: // code which should happen for all (also background) newly loaded tabs goes here:
vimperator.tabs.updateBufferList(); vimperator.buffer.updateBufferList();
//update history //update history
var url = getCurrentLocation(); var url = vimperator.buffer.location;
var title = getCurrentTitle(); // not perfect "- Vimperator" in the title var title = vimperator.buffer.title;
vimperator.history.add(url, title); vimperator.history.add(url, title);
// code which is only relevant if the page load is the current tab goes here: // code which is only relevant if the page load is the current tab goes here:

View File

@@ -296,7 +296,7 @@ function Mappings() //{{{
// {{{ // {{{
addDefaultMap(new Map(vimperator.modes.NORMAL, ["'", "`"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["'", "`"],
function(mark) { vimperator.marks.jumpTo(mark) }, function(arg) { vimperator.marks.jumpTo(arg) },
{ {
short_help: "Jump to the mark in the current buffer", short_help: "Jump to the mark in the current buffer",
usage: ["'{a-zA-Z0-9}"], usage: ["'{a-zA-Z0-9}"],
@@ -305,7 +305,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["]f"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["]f"],
function(count) { vimperator.shiftFrameFocus(count > 1 ? count : 1, true); }, function(count) { vimperator.buffer.shiftFrameFocus(count > 1 ? count : 1, true); },
{ {
short_help: "Focus next frame", short_help: "Focus next frame",
help: "Transfers keyboard focus to the [count]th next frame in order. The newly focused frame is briefly colored red.", help: "Transfers keyboard focus to the [count]th next frame in order. The newly focused frame is briefly colored red.",
@@ -313,7 +313,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["[f"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["[f"],
function(count) { vimperator.shiftFrameFocus(count > 1 ? count : 1, false); }, function(count) { vimperator.buffer.shiftFrameFocus(count > 1 ? count : 1, false); },
{ {
short_help: "Focus previous frame", short_help: "Focus previous frame",
help: "Transfers keyboard focus to the [count]th previous frame in order. The newly focused frame is briefly colored red.", help: "Transfers keyboard focus to the [count]th previous frame in order. The newly focused frame is briefly colored red.",
@@ -365,7 +365,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["go"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["go"],
function(mark) { vimperator.quickmarks.jumpTo(mark, vimperator.CURRENT_TAB) }, function(arg) { vimperator.quickmarks.jumpTo(arg, vimperator.CURRENT_TAB) },
{ {
short_help: "Jump to a QuickMark in the current tab", short_help: "Jump to a QuickMark in the current tab",
usage: ["go{a-zA-Z0-9}"], usage: ["go{a-zA-Z0-9}"],
@@ -375,7 +375,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["gn"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["gn"],
function(mark) function(arg)
{ {
vimperator.quickmarks.jumpTo(mark, vimperator.quickmarks.jumpTo(mark,
/\bquickmark\b/.test(vimperator.options["activate"]) ? /\bquickmark\b/.test(vimperator.options["activate"]) ?
@@ -446,7 +446,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["m"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["m"],
function(mark) { vimperator.marks.add(mark) }, function(arg) { vimperator.marks.add(arg) },
{ {
short_help: "Set mark at the cursor position", short_help: "Set mark at the cursor position",
usage: ["m{a-zA-Z0-9}"], usage: ["m{a-zA-Z0-9}"],
@@ -455,7 +455,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["M"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["M"],
function(mark) { vimperator.quickmarks.add(mark, getCurrentLocation()) }, function(arg) { vimperator.quickmarks.add(arg, vimperator.buffer.location) },
{ {
short_help: "Add new QuickMark for current URL", short_help: "Add new QuickMark for current URL",
usage: ["M{a-zA-Z0-9}"], usage: ["M{a-zA-Z0-9}"],
@@ -472,7 +472,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["O"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["O"],
function() { vimperator.commandline.open(":", "open " + getCurrentLocation(), vimperator.modes.EX); }, function() { vimperator.commandline.open(":", "open " + vimperator.buffer.location, vimperator.modes.EX); },
{ {
short_help: "Open one or more URLs in the current tab, based on current location", short_help: "Open one or more URLs in the current tab, based on current location",
help: "Works like <code class=\"mapping\">o</code>, but preselects current URL in the <code class=\"command\">:open</code> query." help: "Works like <code class=\"mapping\">o</code>, but preselects current URL in the <code class=\"command\">:open</code> query."
@@ -521,7 +521,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["T"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["T"],
function() { vimperator.commandline.open(":", "tabopen " + getCurrentLocation(), vimperator.modes.EX); }, function() { vimperator.commandline.open(":", "tabopen " + vimperator.buffer.location, vimperator.modes.EX); },
{ {
short_help: "Open one ore more URLs in a new tab, based on current location", short_help: "Open one ore more URLs in a new tab, based on current location",
help: "Works like <code class=\"mapping\">t</code>, but preselects current URL in the <code class=\"command\">:tabopen</code> query." help: "Works like <code class=\"mapping\">t</code>, but preselects current URL in the <code class=\"command\">:tabopen</code> query."
@@ -560,7 +560,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["zi", "+"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["zi", "+"],
function(count) { vimperator.zoom("+" + (count > 0 ? count * 25 : 25) + "%"); }, function(count) { vimperator.buffer.zoomIn(count > 0 ? count : 1); },
{ {
short_help: "Zoom in current web page by 25%", short_help: "Zoom in current web page by 25%",
help: "Currently no count supported.", help: "Currently no count supported.",
@@ -568,7 +568,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["zI"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["zI"],
function(count) { vimperator.zoom("+" + (count > 0 ? count * 100 : 100) + "%"); }, function(count) { vimperator.buffer.zoomIn((count > 0 ? count : 1) * 4); },
{ {
short_help: "Zoom in current web page by 100%", short_help: "Zoom in current web page by 100%",
help: "Currently no count supported.", help: "Currently no count supported.",
@@ -576,7 +576,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["zo", "-"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["zo", "-"],
function(count) { vimperator.zoom("-" + (count > 0 ? count * 25 : 25) + "%"); }, function(count) { vimperator.buffer.zoomOut(count > 0 ? count : 1); },
{ {
short_help: "Zoom out current web page by 25%", short_help: "Zoom out current web page by 25%",
help: "Currently no count supported.", help: "Currently no count supported.",
@@ -584,7 +584,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["zO"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["zO"],
function(count) { vimperator.zoom("-" + (count > 0 ? count * 100 : 100) + "%"); }, function(count) { vimperator.buffer.zoomOut((count > 0 ? count : 1) * 4); },
{ {
short_help: "Zoom out current web page by 100%", short_help: "Zoom out current web page by 100%",
help: "Currently no count supported.", help: "Currently no count supported.",
@@ -592,7 +592,8 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["zz"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["zz"],
function(count) { vimperator.zoom(count > 0 ? "" + count + "%" : "100%"); }, // FIXME: does it make sense to use count for this? Just use it for returning to 100%?
function(count) { vimperator.buffer.textZoom = count > 0 ? count : 100; },
{ {
short_help: "Set zoom value of the web page", short_help: "Set zoom value of the web page",
help: "Zoom value can be between 25 and 500%. If it is omitted, zoom is reset to 100%.", help: "Zoom value can be between 25 and 500%. If it is omitted, zoom is reset to 100%.",
@@ -617,20 +618,20 @@ function Mappings() //{{{
// scrolling commands // scrolling commands
addDefaultMap(new Map(vimperator.modes.NORMAL, ["0", "^"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["0", "^"],
function() { scrollBufferAbsolute(0, -1); }, function() { vimperator.buffer.scrollAbsolute(0, -1); },
{ {
short_help: "Scroll to the absolute left of the document", short_help: "Scroll to the absolute left of the document",
help: "Unlike in vim, <code class=\"mapping\">0</code> and <code class=\"mapping\">^</code> work exactly the same way." help: "Unlike in vim, <code class=\"mapping\">0</code> and <code class=\"mapping\">^</code> work exactly the same way."
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["$"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["$"],
function() { scrollBufferAbsolute(100, -1); }, function() { vimperator.buffer.scrollAbsolute(100, -1); },
{ {
short_help: "Scroll to the absolute right of the document" short_help: "Scroll to the absolute right of the document"
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["gg", "<Home>"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["gg", "<Home>"],
function(count) { scrollBufferAbsolute(-1, count > 0 ? count : 0); }, function(count) { vimperator.buffer.scrollAbsolute(-1, count > 0 ? count : 0); },
{ {
short_help: "Goto the top of the document", short_help: "Goto the top of the document",
help: "Count is supported, <code class=\"mapping\">35gg</code> vertically goes to 35% of the document.", help: "Count is supported, <code class=\"mapping\">35gg</code> vertically goes to 35% of the document.",
@@ -638,7 +639,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["G", "<End>"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["G", "<End>"],
function(count) { scrollBufferAbsolute(-1, count >= 0 ? count : 100); }, function(count) { vimperator.buffer.scrollAbsolute(-1, count >= 0 ? count : 100); },
{ {
short_help: "Goto the end of the document", short_help: "Goto the end of the document",
help: "Count is supported, <code class=\"mapping\">35G</code> vertically goes to 35% of the document.", help: "Count is supported, <code class=\"mapping\">35G</code> vertically goes to 35% of the document.",
@@ -646,7 +647,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["h", "<Left>"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["h", "<Left>"],
function(count) { scrollBufferRelative(-1, 0); }, function(count) { vimperator.buffer.scrollRelative(count > 1 ? -count : -1, 0); },
{ {
short_help: "Scroll document to the left", short_help: "Scroll document to the left",
help: "Count is supported: <code class=\"mapping\">10h</code> will move 10 times as much to the left.<br/>" + help: "Count is supported: <code class=\"mapping\">10h</code> will move 10 times as much to the left.<br/>" +
@@ -655,7 +656,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["j", "<Down>", "<C-e>"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["j", "<Down>", "<C-e>"],
function(count) { scrollBufferRelative(0, 1); }, function(count) { vimperator.buffer.scrollRelative(0, count > 1 ? count : 1); },
{ {
short_help: "Scroll document down", short_help: "Scroll document down",
help: "Count is supported: <code class=\"mapping\">10j</code> will move 10 times as much down.<br/>" + help: "Count is supported: <code class=\"mapping\">10j</code> will move 10 times as much down.<br/>" +
@@ -664,7 +665,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["k", "<Up>", "<C-y>"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["k", "<Up>", "<C-y>"],
function(count) { scrollBufferRelative(0, -1); }, function(count) { vimperator.buffer.scrollRelative(0, count > 1 ? -count : -1); },
{ {
short_help: "Scroll document up", short_help: "Scroll document up",
help: "Count is supported: <code class=\"mapping\">10k</code> will move 10 times as much up.<br/>" + help: "Count is supported: <code class=\"mapping\">10k</code> will move 10 times as much up.<br/>" +
@@ -673,7 +674,7 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.NORMAL, ["l", "<Right>"], addDefaultMap(new Map(vimperator.modes.NORMAL, ["l", "<Right>"],
function(count) { scrollBufferRelative(1, 0); }, function(count) { vimperator.buffer.scrollRelative(count > 1 ? count : 1, 0); },
{ {
short_help: "Scroll document to the right", short_help: "Scroll document to the right",
help: "Count is supported: <code class=\"mapping\">10l</code> will move 10 times as much to the right.<br/>" + help: "Count is supported: <code class=\"mapping\">10l</code> will move 10 times as much to the right.<br/>" +
@@ -733,7 +734,7 @@ function Mappings() //{{{
function(count) function(count)
{ {
var gocmd = ""; var gocmd = "";
if (isDirectory(getCurrentLocation())) if (isDirectory(vimperator.buffer.location))
gocmd = "../"; gocmd = "../";
else else
gocmd = "./"; gocmd = "./";
@@ -950,28 +951,28 @@ function Mappings() //{{{
// movement keys // movement keys
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-e>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-e>"],
function() { scrollBufferRelative(0, 1); }, function() { vimperator.buffer.scrollRelative(0, count > 1 ? count : 1); },
{ {
cancel_mode: false, cancel_mode: false,
always_active: true always_active: true
} }
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-y>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<C-y>"],
function() { scrollBufferRelative(0, -1); }, function() { vimperator.buffer.scrollRelative(0, count > 1 ? -count : -1); },
{ {
cancel_mode: false, cancel_mode: false,
always_active: true always_active: true
} }
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<Home>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<Home>"],
function() { scrollBufferAbsolute(-1, 0); }, function() { vimperator.buffer.scrollAbsolute(-1, 0); },
{ {
cancel_mode: false, cancel_mode: false,
always_active: true always_active: true
} }
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<End>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<End>"],
function() { scrollBufferAbsolute(-1, 100); }, function() { vimperator.buffer.scrollAbsolute(-1, 100); },
{ {
cancel_mode: false, cancel_mode: false,
always_active: true always_active: true
@@ -1006,28 +1007,28 @@ function Mappings() //{{{
} }
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<Left>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<Left>"],
function() { scrollBufferRelative(-1, 0); }, function() { vimperator.buffer.scrollRelative(count > 1 ? -count : -1, 0); },
{ {
cancel_mode: false, cancel_mode: false,
always_active: true always_active: true
} }
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<Down>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<Down>"],
function() { scrollBufferRelative(0, 1); }, function() { vimperator.buffer.scrollRelative(0, count > 1 ? count : 1); },
{ {
cancel_mode: false, cancel_mode: false,
always_active: true always_active: true
} }
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<Up>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<Up>"],
function() { scrollBufferRelative(0, -1); }, function() { vimperator.buffer.scrollRelative(0, count > 1 ? -count : -1); },
{ {
cancel_mode: false, cancel_mode: false,
always_active: true always_active: true
} }
)); ));
addDefaultMap(new Map(vimperator.modes.HINTS, ["<Right>"], addDefaultMap(new Map(vimperator.modes.HINTS, ["<Right>"],
function() { scrollBufferRelative(1, 0); }, function() { vimperator.buffer.scrollRelative(count > 1 ? count : 1, 0); },
{ {
cancel_mode: false, cancel_mode: false,
always_active: true always_active: true

View File

@@ -26,7 +26,8 @@ the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL. the terms of any one of the MPL, the GPL or the LGPL.
}}} ***** END LICENSE BLOCK *****/ }}} ***** END LICENSE BLOCK *****/
/** provides functions for working with tabs /**
* provides functions for working with tabs
* XXX: ATTENTION: We are planning to move to the FUEL API once we switch to * XXX: ATTENTION: We are planning to move to the FUEL API once we switch to
* Firefox 3.0, then this class should go away and their tab methods should be used * Firefox 3.0, then this class should go away and their tab methods should be used
* @deprecated * @deprecated
@@ -36,6 +37,7 @@ function Tabs() //{{{
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////// PRIVATE SECTION ///////////////////////////////////////// ////////////////////// PRIVATE SECTION /////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
/** @param spec can either be: /** @param spec can either be:
* - an absolute integer * - an absolute integer
* - "" for the current tab * - "" for the current tab
@@ -83,6 +85,7 @@ function Tabs() //{{{
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
////////////////////// PUBLIC SECTION ////////////////////////////////////////// ////////////////////// PUBLIC SECTION //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
// @returns the index of the currently selected tab starting with 0 // @returns the index of the currently selected tab starting with 0
this.index = function(tab) this.index = function(tab)
{ {
@@ -187,17 +190,6 @@ function Tabs() //{{{
this.alternate = this.getTab(); this.alternate = this.getTab();
// updates the buffer preview in place only if list is visible
this.updateBufferList = function()
{
if (!vimperator.bufferwindow.visible())
return false;
var items = get_buffer_completions("");
vimperator.bufferwindow.show(items);
vimperator.bufferwindow.selectItem(getBrowser().mTabContainer.selectedIndex);
}
this.reload = function(tab, bypass_cache) this.reload = function(tab, bypass_cache)
{ {
if (bypass_cache) if (bypass_cache)

View File

@@ -808,7 +808,7 @@ function StatusLine() //{{{
this.updateUrl = function(url) this.updateUrl = function(url)
{ {
if (!url || typeof url != "string") if (!url || typeof url != "string")
url = getCurrentLocation(); url = vimperator.buffer.location;
url_widget.value = url; url_widget.value = url;
}; };

View File

@@ -402,98 +402,6 @@ const vimperator = (function() //{{{
.quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit); .quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit);
}, },
// TODO: allow callback for filtering out unwanted frames? User defined?
shiftFrameFocus: function(count, forward)
{
try
{
var frames = [];
// find all frames - depth-first search
(function(frame)
{
if (frame.document.body.localName.toLowerCase() == "body")
frames.push(frame);
for (var i = 0; i < frame.frames.length; i++)
arguments.callee(frame.frames[i])
})(window.content);
if (frames.length == 0) // currently top is always included
return;
// remove all unfocusable frames
// TODO: find a better way to do this
var start = document.commandDispatcher.focusedWindow;
frames = frames.filter(function(frame) {
frame.focus();
if (document.commandDispatcher.focusedWindow == frame)
return frame;
});
start.focus();
// find the currently focused frame index
// TODO: If the window is a frameset then the first _frame_ should be
// focused. Since this is not the current FF behaviour,
// we initalise current to -1 so the first call takes us to the
// first frame.
var current = -1;
for (var i = 0; i < frames.length; i++)
{
if (frames[i] == document.commandDispatcher.focusedWindow)
{
var current = i;
break;
}
}
// calculate the next frame to focus
var next = current;
if (forward)
{
if (count > 1)
next = current + count;
else
next++;
if (next > frames.length - 1)
next = frames.length - 1;
}
else
{
if (count > 1)
next = current - count;
else
next--;
if (next < 0)
next = 0;
}
// focus next frame and scroll into view
frames[next].focus();
if (frames[next] != window.content)
frames[next].frameElement.scrollIntoView(false);
// add the frame indicator
var doc = frames[next].document;
var indicator = doc.createElement("div");
indicator.id = "vimperator-frame-indicator";
// NOTE: need to set a high z-index - it's a crapshoot!
var style = "background-color: red; opacity: 0.5; z-index: 999;" +
"position: fixed; top: 0; bottom: 0; left: 0; right: 0;";
indicator.setAttribute("style", style);
doc.body.appendChild(indicator);
// remove the frame indicator
setTimeout(function() { doc.body.removeChild(indicator); }, 500);
}
catch (e)
{
//vimperator.echoerr(e);
// FIXME: fail silently here for now
}
},
// files which end in .js are sourced as pure javascript files, // files which end in .js are sourced as pure javascript files,
// no need (actually forbidden) to add: js <<EOF ... EOF around those files // no need (actually forbidden) to add: js <<EOF ... EOF around those files
source: function(filename, silent) source: function(filename, silent)
@@ -607,6 +515,8 @@ const vimperator = (function() //{{{
vimperator.mappings = new Mappings(); vimperator.mappings = new Mappings();
vimperator.log("Loading module statusline...", 3); vimperator.log("Loading module statusline...", 3);
vimperator.statusline = new StatusLine(); vimperator.statusline = new StatusLine();
vimperator.log("Loading module buffer...", 3);
vimperator.buffer = new Buffer();
vimperator.log("Loading module tabs...", 3); vimperator.log("Loading module tabs...", 3);
vimperator.tabs = new Tabs(); vimperator.tabs = new Tabs();
vimperator.log("Loading module marks...", 3); vimperator.log("Loading module marks...", 3);
@@ -669,42 +579,7 @@ const vimperator = (function() //{{{
vimperator.events.destroy(); vimperator.events.destroy();
vimperator.options.destroy(); vimperator.options.destroy();
vimperator.quickmarks.destroy(); vimperator.quickmarks.destroy();
},
// @param value MUST be a string, it can have the following form: "+20%", "200%", "-30"
// @return false if argument could not be parsed or zoom level too high
zoom: function(value)
{
if (typeof value != "string")
return false;
var zoomMgr = ZoomManager.prototype.getInstance();
var new_zoom_value = 100;
var matches = value.match(/^\s*(\+|-)?(\d+)(%)?\s*/);
if (!matches || !matches[2])
return false;
if (matches[1] == "+")
new_zoom_value = zoomMgr.textZoom + parseInt(matches[2]);
else if (matches[1] == "-")
new_zoom_value = zoomMgr.textZoom - parseInt(matches[2]);
else
new_zoom_value = parseInt(matches[2]);
if (new_zoom_value < 25 || new_zoom_value > 500)
{
vimperator.echoerr("Zoom value must be between 25% and 500%");
vimperator.beep();
return false;
} }
zoomMgr.textZoom = new_zoom_value;
vimperator.hints.reshowHints();
vimperator.echo("Zoom value: " + new_zoom_value + "%");
}
} //}}} } //}}}
})(); //}}} })(); //}}}

View File

@@ -40,18 +40,19 @@ the terms of any one of the MPL, the GPL or the LGPL.
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript;version=1.7" src="vimperator.js"/> <script type="application/x-javascript;version=1.7" src="vimperator.js"/>
<script type="application/x-javascript;version=1.7" src="events.js"/>
<script type="application/x-javascript;version=1.7" src="tabs.js"/>
<script type="application/x-javascript;version=1.7" src="help.js"/>
<script type="application/x-javascript;version=1.7" src="commands.js"/>
<script type="application/x-javascript;version=1.7" src="ui.js"/>
<script type="application/x-javascript;version=1.7" src="options.js"/>
<script type="application/x-javascript;version=1.7" src="completion.js"/>
<script type="application/x-javascript;version=1.7" src="bookmarks.js"/> <script type="application/x-javascript;version=1.7" src="bookmarks.js"/>
<script type="application/x-javascript;version=1.7" src="hints.js"/> <script type="application/x-javascript;version=1.7" src="buffers.js"/>
<script type="application/x-javascript;version=1.7" src="commands.js"/>
<script type="application/x-javascript;version=1.7" src="completion.js"/>
<script type="application/x-javascript;version=1.7" src="events.js"/>
<script type="application/x-javascript;version=1.7" src="file.js"/> <script type="application/x-javascript;version=1.7" src="file.js"/>
<script type="application/x-javascript;version=1.7" src="find.js"/> <script type="application/x-javascript;version=1.7" src="find.js"/>
<script type="application/x-javascript;version=1.7" src="help.js"/>
<script type="application/x-javascript;version=1.7" src="hints.js"/>
<script type="application/x-javascript;version=1.7" src="mappings.js"/> <script type="application/x-javascript;version=1.7" src="mappings.js"/>
<script type="application/x-javascript;version=1.7" src="options.js"/>
<script type="application/x-javascript;version=1.7" src="tabs.js"/>
<script type="application/x-javascript;version=1.7" src="ui.js"/>
<window id="main-window"> <window id="main-window">
<toolbar id="vimperator-toolbar" hidden="false" align="center" fullscreentoolbar="true"> <toolbar id="vimperator-toolbar" hidden="false" align="center" fullscreentoolbar="true">
@@ -111,7 +112,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
<keyset id="mainKeyset"> <keyset id="mainKeyset">
<key id="key_open_vimbar" key=":" oncommand="vimperator.commandline.open(':', '', MODE_EX);" modifiers=""/> <key id="key_open_vimbar" key=":" oncommand="vimperator.commandline.open(':', '', MODE_EX);" modifiers=""/>
<key id="key_stop" keycode="VK_ESCAPE" oncommand="vimperator.events.onEscape();"/> <key id="key_stop" keycode="VK_ESCAPE" oncommand="vimperator.events.onEscape();"/>
<!--key id="key_a" key="a" oncommand="alert('a'); scrollBufferRelative(0, 1);"!/--> <!--key id="key_a" key="a" oncommand="alert('a'); vimperator.buffer.scrollRelative(0, 1);"!/-->
<!-- other keys are handled inside vimperator.js event loop --> <!-- other keys are handled inside vimperator.js event loop -->
</keyset> </keyset>
</window> </window>