From 61002641a35a6fafff69165d594ff01da9251ae5 Mon Sep 17 00:00:00 2001
From: Kris Maglione
{xml}>;
},
- // every item must have a .xml property which defines how to draw itself
- // @param headers is an array of strings, the text for the header columns
genericTable: function genericTable(items, format) {
completion.listCompleter(function (context) {
context.filterFunc = null;
diff --git a/common/locale/en-US/developer.xml b/common/locale/en-US/developer.xml
index 3e7a8052..5bf793a7 100644
--- a/common/locale/en-US/developer.xml
+++ b/common/locale/en-US/developer.xml
@@ -179,7 +179,7 @@
- - boolean
- can only be on or off
- - number
- has a numeric value
- - string
- has a string value
- - charlist
- like a string but with unique characters
- - stringlist
- a comma-separated list of strings
+ - boolean
- Can only be on or off
+ - number
- A numeric value
+ - string
- A string value
+ - charlist
- A string containing a discrete set of distinct characters
+ - stringlist
- A comma-separated list of strings
+ - stringmap
- A comma-separated list of key-value pairs, e.g.,
key=val,foo=bar
+ - regexlist
+ -
+ A comma-separated list of regular expressions. Expressions may be
+ prefixed with a !, in which case the match will be negated. A
+ literal ! at the begining of the expression may be matched with
+ [!]. Generally, the first matching regular expression is used.
+
+ - regexmap
+ -
+ A combination of a stringmap and a regexlist. Each key
+ in the key=value pair is a regexp. If the regexp begins with a
+ !, the sense match is negated, such that a non-matching
+ expression will be considered a match and
vice versa .
+ The first key to match yields value.
+
Setting options
@@ -293,6 +309,40 @@
+-
+
'au' 'autocomplete'
+ 'autocomplete' 'au'
+ regexlist
+ .*
+
+
+ A list of regexps defining which completion contexts should be
+ autocompleted. When the value is non-empty, the completion list is
+ automatically opened along with the commandline. Thereafter, any key
+ press triggers a completion update for the matching contexts.
+ Non-matching contexts will only be updated when the tab key is
+ pressed. This option is useful for disabling autocompletion for
+ computationally intense contexts that don't perform well on your
+ system under load.
+
+
+
+ To enable autocompletion for everything but :history or
+ :bmarks , you would choose a value such as,
+ !/ex/bmarks,.?
+
+
+
+ Completion contexts have names very much like Unix path names. This
+ denotes the tree in which they're called. A completer will never be
+ called unless every completer preceding it in the tree was also
+ called. For example, if your completer excludes /ex/ , it
+ will also exclude /ex/bmarks , and so on.
+
+
+ See also :contexts
+
+
-
$CDPATH
@@ -1249,41 +1299,50 @@
-
-
-
'wildcase' 'wic'
+ 'wic' 'wildcase'
'wildcase' 'wic'
- string
+ regexmap
smart
- Defines how completions are matched with regard to character case. Possible values:
+
+ Defines how completions are matched for a given completion context
+ with regard to character case.
+
+
+ Possible values:
smart - Case is significant when capital letters are typed
match - Case is always significant
ignore - Case is never significant
+
+ See also :contexts
-
-
'wildignore' 'wig'
'wildignore' 'wig'
- stringlist
+ regexlist
List of file patterns to ignore when completing files. E.g., to ignore object
files and Vim swap files
- :set wildignore=.\\.o,\\..\\.s[a-z]\\2
+ :set wildignore=\.o$ ,^\..*\.s[a-z]2$
+
Unlike Vim each pattern is a regex rather than a glob.
+
+ The only way to include a literal comma in a pattern is with the
+ escape \u0044 .
+
-
-
'wim' 'wildmode'
'wildmode' 'wim'
@@ -1318,25 +1377,23 @@
-
-
-
'wop' 'wildoptions'
- 'wildoptions' 'wop'
- stringlist
-
+ 'wis' 'wildsort'
+ 'wildsort' 'wis'
+ regexlist
+ .*
- A list of words that change how command-line completion is done.
+
+ A list of regexps defining which completion contexts
+ should be sorted. The main purpose of this option is to
+ prevent sorting of certain completion lists that don't
+ perform well under load.
+
- Possible words:
-
-
- - auto
- Automatically show completions while you are typing.
- - sort
- Always sort the completion list, overriding the
complete option.
-
+ See also :contexts
-
-
'wsp' 'wordseparators'
'wordseparators' 'wsp'
diff --git a/common/locale/en-US/various.xml b/common/locale/en-US/various.xml
index 9fc05efb..7f7f7327 100644
--- a/common/locale/en-US/various.xml
+++ b/common/locale/en-US/various.xml
@@ -17,16 +17,27 @@
:beep
:beep
- Play a system beep.
+
+ Play a system beep. This should not be used for any purpose other
+ than testing the visual bell.
+
-
-
CTRL-L :redr :redraw]]>
- :redraw
+ :contexts
+ :contexts ex-command
- Redraws the screen. Useful to update the screen halfway executing a script or function.
+
+ Lists the completion contexts used during the completion of its
+ arguments. These context names are used in options such as
+ autocomplete and wildcase . Note that completion must
+ be triggered in order for this command to be effective, so if
+ autocompletion is not active, you'll need to press the
+ key at least once. You should also be aware that
+ this command is only useful from the commandline.
+
@@ -46,6 +57,15 @@
+-
+
CTRL-L :redr :redraw]]>
+ :redraw
+
+ Redraws the screen. Useful to update the screen halfway executing a script or function.
+
+
+
+
-
:run :! :!cmd
:!cmd
From 03236cec0b69a5ce8275008b01337cf5558b4d85 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Tue, 24 Nov 2009 21:10:44 -0500
Subject: [PATCH 02/27] Fix toolbar completion.
--HG--
branch : testing
---
common/content/liberator.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/common/content/liberator.js b/common/content/liberator.js
index a4b00ded..189888d0 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -1729,6 +1729,7 @@ const Liberator = Module("liberator", {
context.completions = liberator.menuItems;
};
+ var toolbox = document.getElementById("navigator-toolbox");
completion.toolbar = function toolbar(context) {
context.title = ["Toolbar"];
context.keys = { text: function (item) item.getAttribute("toolbarname"), description: function () "" };
From 9d75ceb8c0847445120d3e89fe6f0380a59c4c8b Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Tue, 1 Dec 2009 07:00:38 -0500
Subject: [PATCH 03/27] Fix some crap.
--HG--
branch : testing
---
common/content/liberator.js | 1 +
common/content/options.js | 1 +
2 files changed, 2 insertions(+)
diff --git a/common/content/liberator.js b/common/content/liberator.js
index 189888d0..07380be7 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -1842,6 +1842,7 @@ const Liberator = Module("liberator", {
statusline.update();
liberator.log(config.name + " fully initialized", 0);
+ liberator.initialized = true;
}
});
diff --git a/common/content/options.js b/common/content/options.js
index 55430c8b..bbc7461b 100644
--- a/common/content/options.js
+++ b/common/content/options.js
@@ -407,6 +407,7 @@ const Option = Class("Option", {
},
stringlist: function (operator, values, scope, invert) {
+ const self = this;
values = Array.concat(values);
switch (operator) {
case "+":
From bf5fb6d44e7447381418d115e9ec4fe1e97af616 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Tue, 1 Dec 2009 07:08:05 -0500
Subject: [PATCH 04/27] Finish adding missing copyright notices.
--HG--
branch : testing
---
common/content/autocommands.js | 4 +++-
common/content/bookmarks.js | 4 +++-
common/content/browser.js | 2 +-
common/content/buffer.js | 2 +-
common/content/commandline.js | 4 +++-
common/content/commands.js | 2 +-
common/content/completion.js | 5 +++--
common/content/configbase.js | 4 +++-
common/content/events.js | 2 +-
common/content/finder.js | 4 +++-
common/content/hints.js | 4 +++-
common/content/history.js | 4 +++-
common/content/io.js | 4 +++-
common/content/liberator-overlay.js | 2 +-
common/content/liberator.js | 4 +++-
common/content/mappings.js | 2 +-
common/content/marks.js | 4 +++-
common/content/modes.js | 4 +++-
common/content/options.js | 4 +++-
common/content/quickmarks.js | 4 +++-
common/content/statusline.js | 4 +++-
common/content/tabs.js | 2 +-
common/content/template.js | 2 +-
common/content/util.js | 4 +++-
24 files changed, 56 insertions(+), 25 deletions(-)
diff --git a/common/content/autocommands.js b/common/content/autocommands.js
index 52ceecb6..1417e684 100644
--- a/common/content/autocommands.js
+++ b/common/content/autocommands.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js
index 207cb3b1..b822f7b7 100644
--- a/common/content/bookmarks.js
+++ b/common/content/bookmarks.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/browser.js b/common/content/browser.js
index aec8bf25..2f47a583 100644
--- a/common/content/browser.js
+++ b/common/content/browser.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
// Copyright (c) 2007-2009 by Doug Kearns
// Copyright (c) 2008-2009 by Kris Maglione
//
diff --git a/common/content/buffer.js b/common/content/buffer.js
index d70de3e5..a2424496 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
// Copyright (c) 2007-2009 by Doug Kearns
// Copyright (c) 2008-2009 by Kris Maglione
//
diff --git a/common/content/commandline.js b/common/content/commandline.js
index 16d06985..b4d027bc 100644
--- a/common/content/commandline.js
+++ b/common/content/commandline.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/commands.js b/common/content/commands.js
index f085507c..ab9cebbb 100644
--- a/common/content/commands.js
+++ b/common/content/commands.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
// Copyright (c) 2007-2009 by Doug Kearns
// Copyright (c) 2008-2009 by Kris Maglione
//
diff --git a/common/content/completion.js b/common/content/completion.js
index cd25a49a..c5beb117 100644
--- a/common/content/completion.js
+++ b/common/content/completion.js
@@ -1,5 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
-// Copyright (c) 2008-2009 by Kris Maglione
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/configbase.js b/common/content/configbase.js
index 7cb438b2..215695ef 100644
--- a/common/content/configbase.js
+++ b/common/content/configbase.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/events.js b/common/content/events.js
index cfab6641..e96a67bc 100644
--- a/common/content/events.js
+++ b/common/content/events.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
// Copyright (c) 2007-2009 by Doug Kearns
// Copyright (c) 2008-2009 by Kris Maglione
//
diff --git a/common/content/finder.js b/common/content/finder.js
index 158ce928..cf4ebba2 100644
--- a/common/content/finder.js
+++ b/common/content/finder.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/hints.js b/common/content/hints.js
index 48974c7e..4459c0b2 100644
--- a/common/content/hints.js
+++ b/common/content/hints.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/history.js b/common/content/history.js
index 8f3ae5c8..281d797d 100644
--- a/common/content/history.js
+++ b/common/content/history.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/io.js b/common/content/io.js
index 713423f5..2aa3f9e8 100644
--- a/common/content/io.js
+++ b/common/content/io.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
// Some code based on Venkman
//
// This work is licensed for reuse under an MIT license. Details are
diff --git a/common/content/liberator-overlay.js b/common/content/liberator-overlay.js
index 478ecd9e..ae32b8a2 100644
--- a/common/content/liberator-overlay.js
+++ b/common/content/liberator-overlay.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Kris Maglione
+// Copyright (c) 2008-2008 Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/liberator.js b/common/content/liberator.js
index 07380be7..5403ad16 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/mappings.js b/common/content/mappings.js
index af181120..7d1fa3fa 100644
--- a/common/content/mappings.js
+++ b/common/content/mappings.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
// Copyright (c) 2007-2009 by Doug Kearns
// Copyright (c) 2008-2009 by Kris Maglione
//
diff --git a/common/content/marks.js b/common/content/marks.js
index ab4c4789..44aadbc8 100644
--- a/common/content/marks.js
+++ b/common/content/marks.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/modes.js b/common/content/modes.js
index e6048bea..5a4948fc 100644
--- a/common/content/modes.js
+++ b/common/content/modes.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/options.js b/common/content/options.js
index bbc7461b..f34a721e 100644
--- a/common/content/options.js
+++ b/common/content/options.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/quickmarks.js b/common/content/quickmarks.js
index b6d6914b..20cb8b33 100644
--- a/common/content/quickmarks.js
+++ b/common/content/quickmarks.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/statusline.js b/common/content/statusline.js
index 9214b75d..d8fbfe05 100644
--- a/common/content/statusline.js
+++ b/common/content/statusline.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/tabs.js b/common/content/tabs.js
index 283c9262..6cd4083d 100644
--- a/common/content/tabs.js
+++ b/common/content/tabs.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
// Copyright (c) 2007-2009 by Doug Kearns
// Copyright (c) 2008-2009 by Kris Maglione
//
diff --git a/common/content/template.js b/common/content/template.js
index 26f0e512..7f8a1f09 100644
--- a/common/content/template.js
+++ b/common/content/template.js
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 by Kris Maglione
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
diff --git a/common/content/util.js b/common/content/util.js
index e313747d..d1c5656f 100644
--- a/common/content/util.js
+++ b/common/content/util.js
@@ -1,4 +1,6 @@
-// Copyright (c) 2006-2009 by Martin Stubenschrott
+// Copyright (c) 2006-2008 by Martin Stubenschrott
+// Copyright (c) 2007-2009 by Doug Kearns
+// Copyright (c) 2008-2009 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
From 7a3d35991cca325ac2caefb85ad034c798c5e25f Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Tue, 11 May 2010 06:01:02 -0400
Subject: [PATCH 05/27] Fix some general brokenness.
--HG--
branch : testing
---
common/content/bookmarks.js | 3 +--
common/content/buffer.js | 18 +++++++++++-------
common/content/commandline.js | 2 +-
common/skin/liberator.css | 4 ++++
4 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js
index b822f7b7..95ecdba9 100644
--- a/common/content/bookmarks.js
+++ b/common/content/bookmarks.js
@@ -366,7 +366,6 @@ const Bookmarks = Module("bookmarks", {
// ripped from Firefox
function getShortcutOrURI(url) {
- var shortcutURL = null;
var keyword = url;
var param = "";
var offset = url.indexOf(" ");
@@ -381,7 +380,7 @@ const Bookmarks = Module("bookmarks", {
return [submission.uri.spec, submission.postData];
}
- [shortcutURL, postData] = PlacesUtils.getURLAndPostDataForKeyword(keyword);
+ let [shortcutURL, postData] = PlacesUtils.getURLAndPostDataForKeyword(keyword);
if (!shortcutURL)
return [url, null];
diff --git a/common/content/buffer.js b/common/content/buffer.js
index a2424496..904d415f 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -19,9 +19,10 @@ const Point = Struct("x", "y");
* @instance buffer
*/
const Buffer = Module("buffer", {
- requires: ["config"],
+ requires: ["config", "util"],
init: function () {
+ this.evaluateXPath = util.evaluateXPath;
this.pageInfo = {};
this.addPageInfoSection("f", "Feeds", function (verbose) {
@@ -1470,16 +1471,19 @@ const Buffer = Module("buffer", {
if (count < 1 && buffer.lastInputField)
buffer.focusElement(buffer.lastInputField);
else {
- let xpath = ["input[not(@type) or @type='text' or @type='password' or @type='file']",
- "textarea[not(@disabled) and not(@readonly)]"];
+ let xpath = ["input", "textarea[not(@disabled) and not(@readonly)]"];
- let elements = [m for (m in util.evaluateXPath(xpath))].filter(function (match) {
- let computedStyle = util.computedStyle(match);
+ let elements = [m for (m in util.evaluateXPath(xpath))].filter(function (elem) {
+ if (elem.readOnly || elem instanceof HTMLInputElement && ["text", "password", "file"].indexOf(elem.type) < 0)
+ return false;
+ let computedStyle = util.computedStyle(elem);
return computedStyle.visibility != "hidden" && computedStyle.display != "none";
});
liberator.assert(elements.length > 0);
- buffer.focusElement(elements[util.Math.constrain(count, 1, elements.length) - 1]);
+ let elem = elements[util.Math.constrain(count, 1, elements.length) - 1];
+ elem.scrollIntoView();
+ buffer.focusElement(elem);
}
},
{ count: true });
@@ -1599,7 +1603,7 @@ const Buffer = Module("buffer", {
"Desired info in the :pageinfo output",
"charlist", "gfm",
{
- completer: function (context) [[k, v[1]] for ([k, v] in Iterator(this.pageInfo))]
+ completer: function (context) [[k, v[1]] for ([k, v] in Iterator(buffer.pageInfo))]
});
options.add(["scroll", "scr"],
diff --git a/common/content/commandline.js b/common/content/commandline.js
index b4d027bc..3d358b7c 100644
--- a/common/content/commandline.js
+++ b/common/content/commandline.js
@@ -1109,7 +1109,7 @@ const CommandLine = Module("commandline", {
*/
Completions: Class("Completions", {
init: function (input) {
- this.context = CompletionContext(input.editor);
+ this.context = CompletionContext(input.QueryInterface(Ci.nsIDOMNSEditableElement).editor);
this.context.onUpdate = this.closure._reset;
this.editor = input.editor;
this.selected = null;
diff --git a/common/skin/liberator.css b/common/skin/liberator.css
index 146619a1..ff67a8f5 100644
--- a/common/skin/liberator.css
+++ b/common/skin/liberator.css
@@ -1,4 +1,5 @@
@namespace liberator url("http://vimperator.org/namespaces/liberator");
+@namespace html url("http://www.w3.org/1999/xhtml");
/* Applied to all content */
[liberator|activeframe] {
@@ -122,6 +123,9 @@ statusbarpanel {
color: inherit;
margin: 0px;
}
+#liberator-commandline-command html|*:focus {
+ outline-width: 0px !important
+}
#liberator-message {
margin: 0px;
}
From ae1d7fe5ea7d40661668a7bfc544011589f50f52 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Fri, 14 May 2010 09:21:02 -0400
Subject: [PATCH 06/27] Get rid of silly zoom status messages.
--HG--
branch : testing
---
common/content/buffer.js | 42 +++++++++++++++++------------
common/content/liberator.xul | 3 ++-
common/content/statusline.js | 48 +++++++++++++++++++++++-----------
common/locale/en-US/buffer.xml | 20 +++++++-------
4 files changed, 70 insertions(+), 43 deletions(-)
diff --git a/common/content/buffer.js b/common/content/buffer.js
index 904d415f..cdcdba97 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -280,7 +280,10 @@ const Buffer = Module("buffer", {
autocommands.trigger("LocationChange", { url: buffer.URL });
// if this is not delayed we get the position of the old buffer
- setTimeout(function () { statusline.updateBufferPosition(); }, 500);
+ setTimeout(function () {
+ statusline.updateBufferPosition();
+ statusline.updateZoomLevel();
+ }, 500);
},
// called at the very end of a page load
asyncUpdateUI: function () {
@@ -385,19 +388,18 @@ const Buffer = Module("buffer", {
get pageHeight() window.content.innerHeight,
/**
- * @property {number} The current browser's text zoom level, as a
- * percentage with 100 as 'normal'. Only affects text size.
+ * @property {number} The current browser's zoom level, as a
+ * percentage with 100 as 'normal'.
*/
- get textZoom() config.browser.markupDocumentViewer.textZoom * 100,
- set textZoom(value) { Buffer.setZoom(value, false); },
+ get zoomLevel() config.browser.markupDocumentViewer[this.fullZoom ? "textZoom" : "fullZoom"] * 100,
+ set zoomLevel(value) { Buffer.setZoom(value, this.fullZoom); },
/**
- * @property {number} The current browser's text zoom level, as a
- * percentage with 100 as 'normal'. Affects text size, as well as
- * image size and block size.
+ * @property {boolean} Whether the current browser is using full
+ * zoom, as opposed to text zoom.
*/
- get fullZoom() config.browser.markupDocumentViewer.fullZoom * 100,
- set fullZoom(value) { Buffer.setZoom(value, true); },
+ get fullZoom() ZoomManager.useFullZoom,
+ set fullZoom(value) { Buffer.setZoom(this.zoomLevel, value); },
/**
* @property {string} The current document's title.
@@ -961,14 +963,20 @@ const Buffer = Module("buffer", {
liberator.assert(value >= Buffer.ZOOM_MIN || value <= Buffer.ZOOM_MAX,
"Zoom value out of range (" + Buffer.ZOOM_MIN + " - " + Buffer.ZOOM_MAX + "%)");
- ZoomManager.useFullZoom = fullZoom;
+ if (fullZoom !== undefined)
+ ZoomManager.useFullZoom = fullZoom;
ZoomManager.zoom = value / 100;
+
if ("FullZoom" in window)
FullZoom._applySettingToPref();
- liberator.echomsg((fullZoom ? "Full" : "Text") + " zoom: " + value + "%");
+
+ statusline.updateZoomLevel(value, ZoomManager.useFullZoom);
},
bumpZoomLevel: function bumpZoomLevel(steps, fullZoom) {
+ if (fullZoom === undefined)
+ fullZoom = ZoomManager.useFullZoom;
+
let values = ZoomManager.zoomValues;
let cur = values.indexOf(ZoomManager.snap(ZoomManager.zoom));
let i = util.Math.constrain(cur + steps, 0, values.length - 1);
@@ -1555,27 +1563,27 @@ const Buffer = Module("buffer", {
function (count) { buffer.textZoom = count > 1 ? count : 100; },
{ count: true });
- mappings.add(myModes, ["zI"],
+ mappings.add(myModes, ["ZI", "zI"],
"Enlarge full zoom of current web page",
function (count) { buffer.zoomIn(Math.max(count, 1), true); },
{ count: true });
- mappings.add(myModes, ["zM"],
+ mappings.add(myModes, ["ZM", "zM"],
"Enlarge full zoom of current web page by a larger amount",
function (count) { buffer.zoomIn(Math.max(count, 1) * 3, true); },
{ count: true });
- mappings.add(myModes, ["zO"],
+ mappings.add(myModes, ["ZO", "zO"],
"Reduce full zoom of current web page",
function (count) { buffer.zoomOut(Math.max(count, 1), true); },
{ count: true });
- mappings.add(myModes, ["zR"],
+ mappings.add(myModes, ["ZR", "zR"],
"Reduce full zoom of current web page by a larger amount",
function (count) { buffer.zoomOut(Math.max(count, 1) * 3, true); },
{ count: true });
- mappings.add(myModes, ["zZ"],
+ mappings.add(myModes, ["ZZ", "zZ"],
"Set full zoom value of current web page",
function (count) { buffer.fullZoom = count > 1 ? count : 100; },
{ count: true });
diff --git a/common/content/liberator.xul b/common/content/liberator.xul
index c1acf2bb..d2e9429d 100644
--- a/common/content/liberator.xul
+++ b/common/content/liberator.xul
@@ -86,12 +86,13 @@
+ id="liberator-statusline-field-status" flex="1" hidden="false" align="center">
+
diff --git a/common/content/statusline.js b/common/content/statusline.js
index d8fbfe05..57baac40 100644
--- a/common/content/statusline.js
+++ b/common/content/statusline.js
@@ -13,12 +13,8 @@ const StatusLine = Module("statusline", {
this._statusBar.collapsed = true; // it is later restored unless the user sets laststatus=0
// our status bar fields
- this._statuslineWidget = document.getElementById("liberator-statusline");
- this._urlWidget = document.getElementById("liberator-statusline-field-url");
- this._inputBufferWidget = document.getElementById("liberator-statusline-field-inputbuffer");
- this._progressWidget = document.getElementById("liberator-statusline-field-progress");
- this._tabCountWidget = document.getElementById("liberator-statusline-field-tabcount");
- this._bufferPositionWidget = document.getElementById("liberator-statusline-field-bufferposition");
+ this.widgets = dict(["status", "url", "inputbuffer", "progress", "tabcount", "bufferposition", "zoomlevel"].map(
+ function (field) [field, document.getElementById("liberator-statusline-field-" + field)]));
},
/**
@@ -49,6 +45,7 @@ const StatusLine = Module("statusline", {
this.updateProgress();
this.updateTabCount();
this.updateBufferPosition();
+ this.updateZoomLevel();
},
/**
@@ -116,7 +113,7 @@ const StatusLine = Module("statusline", {
if (modified)
url += " [" + modified + "]";
- this._urlWidget.value = url;
+ this.widgets.url.value = url;
},
/**
@@ -131,7 +128,7 @@ const StatusLine = Module("statusline", {
if (!buffer || typeof buffer != "string")
buffer = "";
- this._inputBufferWidget.value = buffer;
+ this.widgets.inputbuffer.value = buffer;
},
/**
@@ -148,7 +145,7 @@ const StatusLine = Module("statusline", {
progress = "";
if (typeof progress == "string")
- this._progressWidget.value = progress;
+ this.widgets.progress.value = progress;
else if (typeof progress == "number") {
let progressStr = "";
if (progress <= 0)
@@ -161,7 +158,7 @@ const StatusLine = Module("statusline", {
+ " ".substr(0, 19 - progress)
+ "]";
}
- this._progressWidget.value = progressStr;
+ this.widgets.progress.value = progressStr;
}
},
@@ -185,7 +182,7 @@ const StatusLine = Module("statusline", {
for (let [i, tab] in util.Array.iteritems(config.browser.mTabs))
tab.setAttribute("ordinal", i + 1);
- this._tabCountWidget.value = "[" + (tabs.index() + 1) + "/" + tabs.count + "]";
+ this.widgets.tabcount.value = "[" + (tabs.index() + 1) + "/" + tabs.count + "]";
}
},
@@ -196,7 +193,7 @@ const StatusLine = Module("statusline", {
* @param {number} percent The position, as a percentage. @optional
*/
updateBufferPosition: function updateBufferPosition(percent) {
- if (!percent || typeof percent != "number") {
+ if (typeof percent != "number") {
let win = document.commandDispatcher.focusedWindow;
if (!win)
return;
@@ -209,14 +206,35 @@ const StatusLine = Module("statusline", {
bufferPositionStr = "All";
else if (percent == 0)
bufferPositionStr = "Top";
- else if (percent < 10)
- bufferPositionStr = " " + percent + "%";
else if (percent >= 100)
bufferPositionStr = "Bot";
+ else if (percent < 10)
+ bufferPositionStr = " " + percent + "%";
else
bufferPositionStr = percent + "%";
- this._bufferPositionWidget.value = bufferPositionStr;
+ this.widgets.bufferposition.value = bufferPositionStr;
+ },
+
+ /**
+ * Display the main content's zoom level.
+ *
+ * @param {number} percent The zoom level, as a percentage. @optional
+ * @param {boolean} full True if full zoom is in operation. @optional
+ */
+ updateZoomLevel: function updateZoomLevel(percent, full) {
+ if (arguments.length == 0)
+ [percent, full] = [buffer.zoomLevel, buffer.fullZoom];
+
+ if (percent == 100)
+ this.widgets.zoomlevel.value = "";
+ else {
+ percent = (" " + percent).substr(-3);
+ if (full)
+ this.widgets.zoomlevel.value = " [" + percent + "%]";
+ else
+ this.widgets.zoomlevel.value = " (" + percent + "%)";
+ }
}
}, {
diff --git a/common/locale/en-US/buffer.xml b/common/locale/en-US/buffer.xml
index a0e96318..da56c7bb 100644
--- a/common/locale/en-US/buffer.xml
+++ b/common/locale/en-US/buffer.xml
@@ -417,8 +417,8 @@ preference.
-
-
zI
- count zI
+ ZI zI
+ count ZI
Enlarge full zoom of current web page. Mnemonic: zoom in.
@@ -426,8 +426,8 @@ preference.
-
-
zM
- count zM
+ ZM zM
+ count ZM
Enlarge full zoom of current web page by a larger amount. Mnemonic: zoom more.
@@ -435,8 +435,8 @@ preference.
-
-
zO
- count zO
+ ZO zO
+ count ZO
Reduce full zoom of current web page. Mnemonic: zoom out.
@@ -444,8 +444,8 @@ preference.
-
-
zR
- count zR
+ ZR zR
+ count ZR
Reduce full zoom of current web page by a larger amount. Mnemonic: zoom reduce.
@@ -453,8 +453,8 @@ preference.
-
-
zZ
- count zZ
+ ZZ zZ
+ count ZZ
Set full zoom value of current web page. Zoom value can be between 30 and
From 847dc6428d879a962c26afb41c33cfebfc81cc2c Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Fri, 14 May 2010 09:42:19 -0400
Subject: [PATCH 07/27] Collapse asinine search icon in the commandline.
--HG--
branch : testing
---
common/content/liberator.xul | 2 +-
common/skin/liberator.css | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/common/content/liberator.xul b/common/content/liberator.xul
index d2e9429d..674970d6 100644
--- a/common/content/liberator.xul
+++ b/common/content/liberator.xul
@@ -67,7 +67,7 @@
-
Date: Fri, 14 May 2010 14:37:56 -0400
Subject: [PATCH 08/27] Fix sanitizer.
--HG--
branch : testing
---
common/content/buffer.js | 2 +-
common/content/commandline.js | 2 +-
common/content/sanitizer.js | 1 +
common/content/util.js | 14 ++++++++++++++
4 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/common/content/buffer.js b/common/content/buffer.js
index cdcdba97..dda58534 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -1490,8 +1490,8 @@ const Buffer = Module("buffer", {
liberator.assert(elements.length > 0);
let elem = elements[util.Math.constrain(count, 1, elements.length) - 1];
- elem.scrollIntoView();
buffer.focusElement(elem);
+ util.scrollIntoView(elem);
}
},
{ count: true });
diff --git a/common/content/commandline.js b/common/content/commandline.js
index 3d358b7c..81e54619 100644
--- a/common/content/commandline.js
+++ b/common/content/commandline.js
@@ -1034,7 +1034,7 @@ const CommandLine = Module("commandline", {
sanitize: function (timespan) {
let range = [0, Number.MAX_VALUE];
if (liberator.has("sanitizer") && (timespan || options["sanitizetimespan"]))
- range = sanitizer.getClearRange(timespan || options["sanitizetimespan"]);
+ range = Sanitizer.getClearRange(timespan || options["sanitizetimespan"]);
const self = this;
this.store.mutate("filter", function (item) {
diff --git a/common/content/sanitizer.js b/common/content/sanitizer.js
index 1b3afcc4..146f6fa4 100644
--- a/common/content/sanitizer.js
+++ b/common/content/sanitizer.js
@@ -19,6 +19,7 @@ const Sanitizer = Module("sanitizer", {
init: function () {
const self = this;
liberator.loadScript("chrome://browser/content/sanitize.js", Sanitizer);
+ Sanitizer.getClearRange = Sanitizer.Sanitizer.getClearRange;
this.__proto__.__proto__ = new Sanitizer.Sanitizer; // Good enough.
// TODO: remove this version test
diff --git a/common/content/util.js b/common/content/util.js
index d1c5656f..77e74526 100644
--- a/common/content/util.js
+++ b/common/content/util.js
@@ -673,6 +673,20 @@ const Util = Module("util", {
return str;
},
+ /**
+ * Scrolls an element into view if and only if it's not already
+ * fully visible.
+ *
+ * @param {Node} elem The element to make visible.
+ */
+ scrollIntoView: function scrollIntoView(elem) {
+ let win = elem.ownerDocument.defaultView;
+ let rect = elem.getBoundingClientRect();
+ if (!(rect && rect.top < win.innerHeight && rect.bottom >= 0 && rect.left < win.innerWidth && rect.right >= 0))
+ elem.scrollIntoView();
+ },
+
+
/**
* Returns an array of URLs parsed from str.
*
From 3da3d903a87e9dccbde480ca090e742547608511 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Fri, 14 May 2010 18:46:10 -0400
Subject: [PATCH 09/27] Replace Finder with RangeFinder.
--HG--
branch : testing
---
common/content/finder.js | 557 ++++++---------------------------------
1 file changed, 82 insertions(+), 475 deletions(-)
diff --git a/common/content/finder.js b/common/content/finder.js
index cf4ebba2..3de2ddf9 100644
--- a/common/content/finder.js
+++ b/common/content/finder.js
@@ -1,467 +1,11 @@
-// Copyright (c) 2006-2008 by Martin Stubenschrott
-// Copyright (c) 2007-2009 by Doug Kearns
-// Copyright (c) 2008-2009 by Kris Maglione
+// Copyright (c) 2008-2010 by Kris Maglione
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
/** @scope modules */
-// TODO: proper backwards search - implement our own component?
-// : implement our own highlighter?
-// : should cancel search highlighting in 'incsearch' mode and jump
-// back to the presearch page location - can probably use the same
-// solution as marks
-// : 'linksearch' searches should highlight link matches only
-// : changing any search settings should also update the search state including highlighting
-// : incremental searches shouldn't permanently update search modifiers
-//
-// TODO: Clean up this rat's nest. --Kris
-
-/**
- * @instance finder
- */
-const Finder = Module("finder", {
- requires: ["config"],
-
- init: function () {
- const self = this;
-
- this._found = false; // true if the last search was successful
- this._backwards = false; // currently searching backwards
- this._searchString = ""; // current search string (without modifiers)
- this._searchPattern = ""; // current search string (includes modifiers)
- this._lastSearchPattern = ""; // the last searched pattern (includes modifiers)
- this._lastSearchString = ""; // the last searched string (without modifiers)
- this._lastSearchBackwards = false; // like "backwards", but for the last search, so if you cancel a search with this is not set
- this._caseSensitive = false; // search string is case sensitive
- this._linksOnly = false; // search is limited to link text only
-
- /* Stolen from toolkit.jar in Firefox, for the time being. The private
- * methods were unstable, and changed. The new version is not remotely
- * compatible with what we do.
- * The following only applies to this object, and may not be
- * necessary, or accurate, but, just in case:
- * The Original Code is mozilla.org viewsource frontend.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (c) 2003
- * by the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Blake Ross (Original Author)
- * Masayuki Nakano
- * Ben Basson
- * Jason Barnabe
- * Asaf Romano
- * Ehsan Akhgari
- * Graeme McCutcheon
- */
- this._highlighter = {
-
- doc: null,
-
- spans: [],
-
- search: function (aWord, matchCase) {
- var finder = services.create("find");
- if (matchCase !== undefined)
- self._caseSensitive = matchCase;
-
- var range;
- while ((range = finder.Find(aWord, this.searchRange, this.startPt, this.endPt)))
- yield range;
- },
-
- highlightDoc: function highlightDoc(win, aWord) {
- this.doc = content.document; // XXX
- Array.forEach(win.frames, function (frame) this.highlightDoc(frame, aWord), this);
-
- var doc = win.document;
- if (!doc || !(doc instanceof HTMLDocument))
- return;
-
- if (!aWord) {
- let elems = this._highlighter.spans;
- for (let i = elems.length; --i >= 0;) {
- let elem = elems[i];
- let docfrag = doc.createDocumentFragment();
- let next = elem.nextSibling;
- let parent = elem.parentNode;
-
- let child;
- while ((child = elem.firstChild))
- docfrag.appendChild(child);
-
- parent.removeChild(elem);
- parent.insertBefore(docfrag, next);
- parent.normalize();
- }
- return;
- }
-
- var baseNode = ;
- baseNode = util.xmlToDom(baseNode, window.content.document);
-
- var body = doc.body;
- var count = body.childNodes.length;
- this.searchRange = doc.createRange();
- this.startPt = doc.createRange();
- this.endPt = doc.createRange();
-
- this.searchRange.setStart(body, 0);
- this.searchRange.setEnd(body, count);
-
- this.startPt.setStart(body, 0);
- this.startPt.setEnd(body, 0);
- this.endPt.setStart(body, count);
- this.endPt.setEnd(body, count);
-
- liberator.interrupted = false;
- let n = 0;
- for (let retRange in this.search(aWord, this._caseSensitive)) {
- // Highlight
- var nodeSurround = baseNode.cloneNode(true);
- var node = this.highlight(retRange, nodeSurround);
- this.startPt = node.ownerDocument.createRange();
- this.startPt.setStart(node, node.childNodes.length);
- this.startPt.setEnd(node, node.childNodes.length);
- if (n++ % 20 == 0)
- liberator.threadYield(true);
- if (liberator.interrupted)
- break;
- }
- },
-
- highlight: function highlight(aRange, aNode) {
- var startContainer = aRange.startContainer;
- var startOffset = aRange.startOffset;
- var endOffset = aRange.endOffset;
- var docfrag = aRange.extractContents();
- var before = startContainer.splitText(startOffset);
- var parent = before.parentNode;
- aNode.appendChild(docfrag);
- parent.insertBefore(aNode, before);
- this.spans.push(aNode);
- return aNode;
- },
-
- /**
- * Clears all search highlighting.
- */
- clear: function () {
- this.spans.forEach(function (span) {
- if (span.parentNode) {
- let el = span.firstChild;
- while (el) {
- span.removeChild(el);
- span.parentNode.insertBefore(el, span);
- el = span.firstChild;
- }
- span.parentNode.removeChild(span);
- }
- });
- this.spans = [];
- },
-
- isHighlighted: function (doc) this.doc == doc && this.spans.length > 0
- };
- },
-
- // set searchString, searchPattern, caseSensitive, linksOnly
- _processUserPattern: function (pattern) {
- //// strip off pattern terminator and offset
- //if (backwards)
- // pattern = pattern.replace(/\?.*/, "");
- //else
- // pattern = pattern.replace(/\/.*/, "");
-
- this._searchPattern = pattern;
-
- // links only search - \l wins if both modifiers specified
- if (/\\l/.test(pattern))
- this._linksOnly = true;
- else if (/\L/.test(pattern))
- this._linksOnly = false;
- else if (options["linksearch"])
- this._linksOnly = true;
- else
- this._linksOnly = false;
-
- // strip links-only modifiers
- pattern = pattern.replace(/(\\)?\\[lL]/g, function ($0, $1) { return $1 ? $0 : ""; });
-
- // case sensitivity - \c wins if both modifiers specified
- if (/\c/.test(pattern))
- this._caseSensitive = false;
- else if (/\C/.test(pattern))
- this._caseSensitive = true;
- else if (options["ignorecase"] && options["smartcase"] && /[A-Z]/.test(pattern))
- this._caseSensitive = true;
- else if (options["ignorecase"])
- this._caseSensitive = false;
- else
- this._caseSensitive = true;
-
- // strip case-sensitive modifiers
- pattern = pattern.replace(/(\\)?\\[cC]/g, function ($0, $1) { return $1 ? $0 : ""; });
-
- // remove any modifier escape \
- pattern = pattern.replace(/\\(\\[cClL])/g, "$1");
-
- this._searchString = pattern;
- },
-
- /**
- * Called when the search dialog is requested.
- *
- * @param {number} mode The search mode, either modes.SEARCH_FORWARD or
- * modes.SEARCH_BACKWARD.
- * @default modes.SEARCH_FORWARD
- */
- openPrompt: function (mode) {
- this._backwards = mode == modes.SEARCH_BACKWARD;
- commandline.open(this._backwards ? "?" : "/", "", mode);
- // TODO: focus the top of the currently visible screen
- },
-
- // TODO: backwards seems impossible i fear
- /**
- * Searches the current buffer for str.
- *
- * @param {string} str The string to find.
- */
- find: function (str) {
- let fastFind = config.browser.fastFind;
-
- this._processUserPattern(str);
- fastFind.caseSensitive = this._caseSensitive;
- this._found = fastFind.find(this._searchString, this._linksOnly) != Ci.nsITypeAheadFind.FIND_NOTFOUND;
-
- if (!this._found)
- this.setTimeout(function () liberator.echoerr("E486: Pattern not found: " + this._searchPattern, commandline.FORCE_SINGLELINE), 0);
- },
-
- /**
- * Searches the current buffer again for the most recently used search
- * string.
- *
- * @param {boolean} reverse Whether to search forwards or backwards.
- * @default false
- */
- findAgain: function (reverse) {
- // This hack is needed to make n/N work with the correct string, if
- // we typed /foo after the original search. Since searchString is
- // readonly we have to call find() again to update it.
- if (config.browser.fastFind.searchString != this._lastSearchString)
- this.find(this._lastSearchString);
-
- let up = reverse ? !this._lastSearchBackwards : this._lastSearchBackwards;
- let result = config.browser.fastFind.findAgain(up, this._linksOnly);
-
- if (result == Ci.nsITypeAheadFind.FIND_NOTFOUND)
- liberator.echoerr("E486: Pattern not found: " + this._lastSearchPattern, commandline.FORCE_SINGLELINE);
- else if (result == Ci.nsITypeAheadFind.FIND_WRAPPED) {
- // hack needed, because wrapping causes a "scroll" event which clears
- // our command line
- setTimeout(function () {
- let msg = up ? "search hit TOP, continuing at BOTTOM" : "search hit BOTTOM, continuing at TOP";
- commandline.echo(msg, commandline.HL_WARNINGMSG, commandline.APPEND_TO_MESSAGES | commandline.FORCE_SINGLELINE);
- }, 0);
- }
- else {
- commandline.echo((up ? "?" : "/") + this._lastSearchPattern, null, commandline.FORCE_SINGLELINE);
-
- if (options["hlsearch"])
- this.highlight(this._lastSearchString);
- }
- },
-
- /**
- * Called when the user types a key in the search dialog. Triggers a
- * search attempt if 'incsearch' is set.
- *
- * @param {string} str The search string.
- */
- onKeyPress: function (str) {
- if (options["incsearch"])
- this.find(str);
- },
-
- /**
- * Called when the key is pressed to trigger a search.
- *
- * @param {string} str The search string.
- * @param {boolean} forcedBackward Whether to search forwards or
- * backwards. This overrides the direction set in
- * (@link #openPrompt).
- * @default false
- */
- onSubmit: function (str, forcedBackward) {
- if (typeof forcedBackward === "boolean")
- this._backwards = forcedBackward;
-
- if (str)
- var pattern = str;
- else {
- liberator.assert(this._lastSearchPattern, "E35: No previous search pattern");
- pattern = this._lastSearchPattern;
- }
-
- this.clear();
-
- if (!options["incsearch"] || !str || !this._found) {
- // prevent any current match from matching again
- if (!window.content.getSelection().isCollapsed)
- window.content.getSelection().getRangeAt(0).collapse(this._backwards);
-
- this.find(pattern);
- }
-
- this._lastSearchBackwards = this._backwards;
- //lastSearchPattern = pattern.replace(backwards ? /\?.*/ : /\/.*/, ""); // XXX
- this._lastSearchPattern = pattern;
- this._lastSearchString = this._searchString;
-
- // TODO: move to find() when reverse incremental searching is kludged in
- // need to find again for reverse searching
- if (this._backwards)
- this.setTimeout(function () { this.findAgain(false); }, 0);
-
- if (options["hlsearch"])
- this.highlight(this._searchString);
-
- modes.reset();
- },
-
- /**
- * Called when the search is canceled. For example, if someone presses
- * while typing a search.
- */
- onCancel: function () {
- // TODO: code to reposition the document to the place before search started
- },
-
- /**
- * Highlights all occurances of str in the buffer.
- *
- * @param {string} str The string to highlight.
- */
- highlight: function (str) {
- // FIXME: Thunderbird incompatible
- if (config.name == "Muttator")
- return;
-
- if (this._highlighter.isHighlighted(content.document))
- return;
-
- if (!str)
- str = this._lastSearchString;
-
- this._highlighter.highlightDoc(window.content, str);
-
- // recreate selection since highlightDoc collapses the selection
- if (window.content.getSelection().isCollapsed)
- config.browser.fastFind.findAgain(this._backwards, this._linksOnly);
-
- // TODO: remove highlighting from non-link matches (HTML - A/AREA with href attribute; XML - Xlink [type="simple"])
- },
-
- /**
- * Clears all search highlighting.
- */
- clear: function () {
- this._highlighter.clear();
- }
-}, {
-}, {
- commandline: function () {
- // Event handlers for search - closure is needed
- commandline.registerCallback("change", modes.SEARCH_FORWARD, this.closure.onKeyPress);
- commandline.registerCallback("submit", modes.SEARCH_FORWARD, this.closure.onSubmit);
- commandline.registerCallback("cancel", modes.SEARCH_FORWARD, this.closure.onCancel);
- // TODO: allow advanced myModes in register/triggerCallback
- commandline.registerCallback("change", modes.SEARCH_BACKWARD, this.closure.onKeyPress);
- commandline.registerCallback("submit", modes.SEARCH_BACKWARD, this.closure.onSubmit);
- commandline.registerCallback("cancel", modes.SEARCH_BACKWARD, this.closure.onCancel);
-
- },
- commands: function () {
- commands.add(["noh[lsearch]"],
- "Remove the search highlighting",
- function () { finder.clear(); },
- { argCount: "0" });
- },
- mappings: function () {
- var myModes = config.browserModes;
- myModes = myModes.concat([modes.CARET]);
-
- mappings.add(myModes,
- ["/"], "Search forward for a pattern",
- function () { finder.openPrompt(modes.SEARCH_FORWARD); });
-
- mappings.add(myModes,
- ["?"], "Search backwards for a pattern",
- function () { finder.openPrompt(modes.SEARCH_BACKWARD); });
-
- mappings.add(myModes,
- ["n"], "Find next",
- function () { finder.findAgain(false); });
-
- mappings.add(myModes,
- ["N"], "Find previous",
- function () { finder.findAgain(true); });
-
- mappings.add(myModes.concat([modes.CARET, modes.TEXTAREA]), ["*"],
- "Find word under cursor",
- function () {
- this._found = false;
- finder.onSubmit(buffer.getCurrentWord(), false);
- });
-
- mappings.add(myModes.concat([modes.CARET, modes.TEXTAREA]), ["#"],
- "Find word under cursor backwards",
- function () {
- this._found = false;
- finder.onSubmit(buffer.getCurrentWord(), true);
- });
- },
- options: function () {
- options.add(["hlsearch", "hls"],
- "Highlight previous search pattern matches",
- "boolean", "false", {
- setter: function (value) {
- try {
- if (value)
- finder.highlight();
- else
- finder.clear();
- }
- catch (e) {}
-
- return value;
- }
- });
-
- options.add(["ignorecase", "ic"],
- "Ignore case in search patterns",
- "boolean", true);
-
- options.add(["incsearch", "is"],
- "Show where the search pattern matches as it is typed",
- "boolean", true);
-
- options.add(["linksearch", "lks"],
- "Limit the search to hyperlink text",
- "boolean", false);
-
- options.add(["smartcase", "scs"],
- "Override the 'ignorecase' option if the pattern contains uppercase characters",
- "boolean", true);
- }
-});
-
+/** @instance rangefinder */
const RangeFinder = Module("rangefinder", {
requires: ["config"],
@@ -605,45 +149,81 @@ const RangeFinder = Module("rangefinder", {
},
commands: function () {
+ commands.add(["noh[lsearch]"],
+ "Remove the search highlighting",
+ function () { rangefinder.clear(); },
+ { argCount: "0" });
},
mappings: function () {
var myModes = config.browserModes.concat([modes.CARET]);
mappings.add(myModes,
- ["g/"], "Search forward for a pattern",
+ ["/"], "Search forward for a pattern",
function () { rangefinder.openPrompt(modes.FIND_FORWARD); });
mappings.add(myModes,
- ["g?"], "Search backwards for a pattern",
+ ["?"], "Search backwards for a pattern",
function () { rangefinder.openPrompt(modes.FIND_BACKWARD); });
mappings.add(myModes,
- ["g."], "Find next",
+ ["n"], "Find next",
function () { rangefinder.findAgain(false); });
mappings.add(myModes,
- ["g,"], "Find previous",
+ ["N"], "Find previous",
function () { rangefinder.findAgain(true); });
- mappings.add(myModes.concat([modes.CARET, modes.TEXTAREA]), ["g*"],
+ mappings.add(myModes.concat([modes.CARET, modes.TEXTAREA]), ["*"],
"Find word under cursor",
function () {
rangefinder._found = false;
rangefinder.onSubmit(buffer.getCurrentWord(), false);
});
- mappings.add(myModes.concat([modes.CARET, modes.TEXTAREA]), ["g#"],
+ mappings.add(myModes.concat([modes.CARET, modes.TEXTAREA]), ["#"],
"Find word under cursor backwards",
function () {
rangefinder._found = false;
rangefinder.onSubmit(buffer.getCurrentWord(), true);
});
+
},
modes: function () {
modes.addMode("FIND_FORWARD", true);
modes.addMode("FIND_BACKWARD", true);
},
options: function () {
+ options.add(["hlsearch", "hls"],
+ "Highlight previous search pattern matches",
+ "boolean", "false", {
+ setter: function (value) {
+ try {
+ if (value)
+ rangefinder.highlight();
+ else
+ rangefinder.clear();
+ }
+ catch (e) {}
+
+ return value;
+ }
+ });
+
+ options.add(["ignorecase", "ic"],
+ "Ignore case in search patterns",
+ "boolean", true);
+
+ options.add(["incsearch", "is"],
+ "Show where the search pattern matches as it is typed",
+ "boolean", true);
+
+ options.add(["linksearch", "lks"],
+ "Limit the search to hyperlink text",
+ "boolean", false);
+
+ options.add(["smartcase", "scs"],
+ "Override the 'ignorecase' option if the pattern contains uppercase characters",
+ "boolean", true);
}
});
@@ -657,20 +237,29 @@ const RangeFind = Class("RangeFind", {
this.finder.caseSensitive = this.matchCase;
this.ranges = this.makeFrameList(content);
- this.range = RangeFind.Range(tabs.localStore.focusedFrame || content);
- this.startRange = (this.range.selection.rangeCount ? this.range.selection.getRangeAt(0) : this.ranges[0].range).cloneRange();
- this.startRange.collapse(!backward);
- this.range = this.findRange(this.startRange);
- this.ranges.first = this.range;
+ this.reset();
this.highlighted = null;
this.lastString = "";
- this.lastRange = null;
this.forward = null;
this.found = false;
},
+ get selectedRange() {
+ let range = RangeFind.Range(tabs.localStore.focusedFrame || content);
+ range = (range.selection.rangeCount ? range.selection.getRangeAt(0) : this.ranges[0].range).cloneRange();
+ return range;
+ },
+
+ reset: function () {
+ this.startRange = this.selectedRange;
+ this.startRange.collapse(!this.reverse);
+ this.lastRange = this.selectedRange;
+ this.range = this.findRange(this.startRange);
+ this.ranges.first = this.range;
+ },
+
sameDocument: function (r1, r2) r1 && r2 && r1.endContainer.ownerDocument == r2.endContainer.ownerDocument,
compareRanges: function (r1, r2)
@@ -708,15 +297,21 @@ const RangeFind = Class("RangeFind", {
let backup = null;
function pushRange(start, end) {
+ function push(r) {
+ r = RangeFind.Range(r, frames.length);
+ if (r)
+ frames.push(r);
+ }
+
let range = start.startContainer.ownerDocument.createRange();
range.setStart(start.startContainer, start.startOffset);
range.setEnd(end.startContainer, end.startOffset);
if (!self.elementPath)
- frames.push(RangeFind.Range(range, frames.length));
+ push(range);
else
for (let r in self.findSubRanges(range))
- frames.push(RangeFind.Range(r, frames.length));
+ push(r);
}
function rec(win) {
let doc = win.document;
@@ -743,7 +338,7 @@ const RangeFind = Class("RangeFind", {
// This doesn't work yet.
resetCaret: function () {
- let equal = function (r1, r2) !r1.compareBoundaryPoints(Range.START_TO_START, r2) && !r1.compareBoundaryPoints(Range.END_TO_END, r2);
+ let equal = RangeFind.equal;
letselection = this.win.getSelection();
if (selection.rangeCount == 0)
selection.addRange(this.pageStart);
@@ -809,6 +404,8 @@ const RangeFind = Class("RangeFind", {
this.range.descroll();
this.lastRange = this.startRange;
this.range = this.ranges.first;
+ } else if (!private_ && this.lastRange && !RangeFind.equal(this.selectedRange, this.lastRange)) {
+ this.reset();
}
if (word == "")
@@ -954,6 +551,9 @@ const RangeFind = Class("RangeFind", {
this.window = this.document.defaultView;
this.range = range;
+ if (this.selection == null)
+ return false;
+
this.save();
},
@@ -991,13 +591,20 @@ const RangeFind = Class("RangeFind", {
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsISelectionDisplay)
.QueryInterface(Ci.nsISelectionController),
- get selection() this.selectionController.getSelection(Ci.nsISelectionController.SELECTION_NORMAL)
+ get selection() {
+ try {
+ return this.selectionController.getSelection(Ci.nsISelectionController.SELECTION_NORMAL)
+ } catch (e) {
+ return null;
+ }}
+
}),
endpoint: function (range, before) {
range = range.cloneRange();
range.collapse(before);
return range;
- }
+ },
+ equal: function (r1, r2) !r1.compareBoundaryPoints(Range.START_TO_START, r2) && !r1.compareBoundaryPoints(Range.END_TO_END, r2)
});
// vim: set fdm=marker sw=4 ts=4 et:
From b6267c4f19c4f2b2f37626cd666ceb09a818a6d7 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Fri, 14 May 2010 18:59:41 -0400
Subject: [PATCH 10/27] Add a docstring to RangeFind class.
--HG--
branch : testing
---
common/content/finder.js | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/common/content/finder.js b/common/content/finder.js
index 3de2ddf9..6af97a47 100644
--- a/common/content/finder.js
+++ b/common/content/finder.js
@@ -227,6 +227,28 @@ const RangeFinder = Module("rangefinder", {
}
});
+/**
+ * @class RangeFind
+ *
+ * A fairly sophisticated typeahead-find replacement. It supports
+ * incremental search very much as the builtin component.
+ * Additionally, it supports several features impossible to
+ * implement using the standard component. Incremental searching
+ * works both forwards and backwards. Erasing characters during an
+ * incremental search moves the selection back to the first
+ * available match for the shorter term. The selection and viewport
+ * are restored when the search is canceled.
+ *
+ * Also, in addition to full support for frames and iframes, this
+ * implementation will begin searching from the position of the
+ * caret in the last active frame. This is contrary to the behavior
+ * of the builtin component, which always starts a search from the
+ * begining of the first frame in the case of frameset documents,
+ * and cycles through all frames from begining to end. This makes it
+ * impossible to choose the starting point of a search for such
+ * documents, and represents a major detriment to productivity where
+ * large amounts of data are concerned (e.g., for API documents).
+ */
const RangeFind = Class("RangeFind", {
init: function (matchCase, backward, elementPath) {
this.window = Cu.getWeakReference(window);
@@ -485,6 +507,7 @@ const RangeFind = Class("RangeFind", {
parent.insertBefore(node, before);
range.selectNode(node);
}
+
function unhighlight(range) {
let elem = range.startContainer;
while (!(elem instanceof Element) && elem.parentNode)
@@ -512,7 +535,7 @@ const RangeFind = Class("RangeFind", {
else {
this.highlighted = this.lastString;
this.addListeners();
- this.search(null, false);
+ this.search(null, false); // Rehighlight collapsed range
}
},
From a6f90714e4320d057607d105b6acbf6509ba508c Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Thu, 3 Jun 2010 20:24:16 -0400
Subject: [PATCH 11/27] Fix broken JS completion.
--HG--
branch : testing
---
common/Makefile | 4 ++--
common/content/bookmarks.js | 7 +++++--
common/content/buffer.js | 3 ++-
common/content/finder.js | 10 ++++++++--
common/content/hints.js | 2 +-
common/content/javascript.js | 38 ++++++++++++++++++++++--------------
common/content/liberator.js | 4 ++--
common/content/util.js | 2 +-
common/make_jar.sh | 4 ++--
vimperator/TODO | 28 ++++----------------------
vimperator/install.rdf | 2 +-
11 files changed, 51 insertions(+), 53 deletions(-)
diff --git a/common/Makefile b/common/Makefile
index a918fc96..95441a2e 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -99,8 +99,8 @@ dist: $(XPI)
$(RDF): $(RDF_IN) Makefile
@echo "Preparing release..."
- $(SED) -e "s,###VERSION###,$(VERSION),g" \
- -e "s,###DATE###,$(BUILD_DATE),g" \
+ $(SED) -e "s,@VERSION@,$(VERSION),g" \
+ -e "s,@DATE@,$(BUILD_DATE),g" \
< $< > $@
@echo "SUCCESS: $@"
diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js
index 95ecdba9..7c7d47f0 100644
--- a/common/content/bookmarks.js
+++ b/common/content/bookmarks.js
@@ -656,8 +656,11 @@ const Bookmarks = Module("bookmarks", {
let rest = item.url.length - end.length;
let query = item.url.substring(begin.length, rest);
if (item.url.substr(rest) == end && query.indexOf("&") == -1) {
- item.url = decodeURIComponent(query.replace(/#.*/, ""));
- return item;
+ try {
+ item.url = decodeURIComponent(query.replace(/#.*/, ""));
+ return item;
+ }
+ catch (e) {}
}
return null;
}).filter(util.identity);
diff --git a/common/content/buffer.js b/common/content/buffer.js
index dda58534..4a6d4266 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -169,7 +169,7 @@ const Buffer = Module("buffer", {
// called when the active document is scrolled
_updateBufferPosition: function _updateBufferPosition() {
statusline.updateBufferPosition();
- modes.show();
+ modes.show(); // Clear the status line.
},
onDOMContentLoaded: function onDOMContentLoaded(event) {
@@ -283,6 +283,7 @@ const Buffer = Module("buffer", {
setTimeout(function () {
statusline.updateBufferPosition();
statusline.updateZoomLevel();
+ modes.show(); // Clear the status line.
}, 500);
},
// called at the very end of a page load
diff --git a/common/content/finder.js b/common/content/finder.js
index 6af97a47..aa78d3a7 100644
--- a/common/content/finder.js
+++ b/common/content/finder.js
@@ -361,7 +361,7 @@ const RangeFind = Class("RangeFind", {
// This doesn't work yet.
resetCaret: function () {
let equal = RangeFind.equal;
- letselection = this.win.getSelection();
+ let selection = this.win.getSelection();
if (selection.rangeCount == 0)
selection.addRange(this.pageStart);
function getLines() {
@@ -627,7 +627,13 @@ const RangeFind = Class("RangeFind", {
range.collapse(before);
return range;
},
- equal: function (r1, r2) !r1.compareBoundaryPoints(Range.START_TO_START, r2) && !r1.compareBoundaryPoints(Range.END_TO_END, r2)
+ equal: function (r1, r2) {
+ try {
+ return !r1.compareBoundaryPoints(Range.START_TO_START, r2) && !r1.compareBoundaryPoints(Range.END_TO_END, r2)
+ }
+ catch (e) {}
+ return false;
+ }
});
// vim: set fdm=marker sw=4 ts=4 et:
diff --git a/common/content/hints.js b/common/content/hints.js
index 4459c0b2..60babe15 100644
--- a/common/content/hints.js
+++ b/common/content/hints.js
@@ -268,7 +268,7 @@ const Hints = Module("hints", {
let hint = { elem: elem, showText: false };
// TODO: for iframes, this calculation is wrong
- rect = elem.getBoundingClientRect();
+ let rect = elem.getBoundingClientRect();
if (!rect || rect.top > height || rect.bottom < 0 || rect.left > width || rect.right < 0)
continue;
diff --git a/common/content/javascript.js b/common/content/javascript.js
index 98804f7c..cdc097ee 100644
--- a/common/content/javascript.js
+++ b/common/content/javascript.js
@@ -37,7 +37,10 @@ const JavaScript = Module("javascript", {
let seen = {};
let ret = {};
- try {
+ if(obj == null)
+ return;
+
+ if(options["jsdebugger"]) {
let orig = obj;
let top = services.get("debugger").wrapValue(obj);
@@ -56,13 +59,16 @@ const JavaScript = Module("javascript", {
}
// The debugger doesn't list some properties. I can't guess why.
for (let k in orig)
- if (k in orig && !('|' + k in seen) && obj.hasOwnProperty(k) == toplevel)
+ if (k in orig && !('|' + k in seen) && orig.hasOwnProperty(k) == toplevel)
yield [k, this.getKey(orig, k)]
}
- catch(e) {
+ else {
for (k in allkeys(obj))
- if (obj.hasOwnProperty(k) == toplevel)
- yield [k, this.getKey(obj, k)];
+ try {
+ if (obj.hasOwnProperty(k) == toplevel)
+ yield [k, this.getKey(obj, k)];
+ }
+ catch (e) {}
}
},
@@ -230,8 +236,6 @@ const JavaScript = Module("javascript", {
case "'":
case "/":
case "{":
- this._push(this._c);
- break;
case "[":
this._push(this._c);
break;
@@ -341,6 +345,10 @@ const JavaScript = Module("javascript", {
_complete: function (objects, key, compl, string, last) {
const self = this;
+
+ if(!options["jsdebugger"] && !this.context.message)
+ this.context.message = "For better completion data, please enable the JavaScript debugger (:set jsdebugger)";
+
let orig = compl;
if (!compl) {
compl = function (context, obj, recurse) {
@@ -427,7 +435,8 @@ const JavaScript = Module("javascript", {
// Okay, have parse stack. Figure out what we're completing.
// Find any complete statements that we can eval before we eval our object.
- // This allows for things like: let doc = window.content.document; let elem = doc.createElement...; elem.
+ // This allows for things like:
+ // let doc = window.content.document; let elem = doc.createEle ...
let prev = 0;
for (let [, v] in Iterator(this._get(0).fullStatements)) {
let key = this._str.substring(prev, v + 1);
@@ -437,14 +446,13 @@ const JavaScript = Module("javascript", {
prev = v + 1;
}
- // In a string. Check if we're dereferencing an object.
- // Otherwise, do nothing.
+ // In a string. Check if we're dereferencing an object or
+ // completing a function argument. Otherwise, do nothing.
if (this._last == "'" || this._last == '"') {
- //
+
// str = "foo[bar + 'baz"
// obj = "foo"
// key = "bar + ''"
- //
// The top of the stack is the sting we're completing.
// Wrap it in its delimiters and eval it to process escape sequences.
@@ -520,7 +528,7 @@ const JavaScript = Module("javascript", {
return null;
}
- //
+
// str = "foo.bar.baz"
// obj = "foo.bar"
// key = "baz"
@@ -528,11 +536,11 @@ const JavaScript = Module("javascript", {
// str = "foo"
// obj = [modules, window]
// key = "foo"
- //
+
let [offset, obj, key] = this._getObjKey(-1);
- // Wait for a keypress before completing the default objects.
+ // Wait for a keypress before completing when there's no key
if (!this.context.tabPressed && key == "" && obj.length > 1) {
this.context.waitingForTab = true;
this.context.message = "Waiting for key press";
diff --git a/common/content/liberator.js b/common/content/liberator.js
index 5403ad16..a4617b4c 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -136,7 +136,7 @@ const Liberator = Module("liberator", {
forceNewWindow: false,
/** @property {string} The Liberator version string. */
- version: "###VERSION### (created: ###DATE###)", // these VERSION and DATE tokens are replaced by the Makefile
+ version: "@VERSION@ (created: @DATE@)", // these VERSION and DATE tokens are replaced by the Makefile
/**
* @property {Object} The map of command-line options. These are
@@ -331,7 +331,7 @@ const Liberator = Module("liberator", {
// you don't like them you can set verbose=0, or use :silent when
// someone adds it. I reckon another flag and 'class' of messages
// is just going to unnecessarily complicate things. --djk
- flags |= commandline.APPEND_TO_MESSAGES | commandline.DISALLOW_MULTILINE;
+ flags |= commandline.APPEND_TO_MESSAGES; // | commandline.DISALLOW_MULTILINE;
if (verbosity == null)
verbosity = 0; // verbosity level is exclusionary
diff --git a/common/content/util.js b/common/content/util.js
index 77e74526..f5afd454 100644
--- a/common/content/util.js
+++ b/common/content/util.js
@@ -726,7 +726,7 @@ const Util = Module("util", {
// Ok, not a valid proto. If it looks like URL-ish (foo.com/bar),
// let Gecko figure it out.
- if (/[.\/]/.test(url) && !/\s/.test(url) || /^[\w-.]+:\d+(?:\/|$)/.test(url))
+ if (/^[a-zA-Z0-9-.]+(?:\/|$)/.test(url) && /[.\/]/.test(url) && !/\s/.test(url) || /^[a-zA-Z0-9-.]+:\d+(?:\/|$)/.test(url))
return url;
// TODO: it would be clearer if the appropriate call to
diff --git a/common/make_jar.sh b/common/make_jar.sh
index a0b04e79..2f4d9312 100644
--- a/common/make_jar.sh
+++ b/common/make_jar.sh
@@ -18,8 +18,8 @@ getfiles () {
find "$@" -not -path '*\.hg*' 2>/dev/null | grep -E "$filter" || true
}
copytext () {
- sed -e "s,###VERSION###,$VERSION,g" \
- -e "s,###DATE###,$BUILD_DATE,g" \
+ sed -e "s,@VERSION@,$VERSION,g" \
+ -e "s,@DATE@,$BUILD_DATE,g" \
<"$1" >"$2"
cmp -s "$1" "$2" ||
( echo "modified: $1"; diff -u "$1" "$2" | grep '^[-+][^-+]' )
diff --git a/vimperator/TODO b/vimperator/TODO
index 382ffc27..b3d08ca0 100644
--- a/vimperator/TODO
+++ b/vimperator/TODO
@@ -42,7 +42,6 @@ BUGS:
FEATURES:
8 Document Textarea, Caret and Visual modes.
-8 Incremental searches should retreat to their starting position on
8 Replace config.name tests in liberator with more specific feature
tests or overridable APIs where at all feasible.
8 change the extension ID to vimperator@vimperator.org rather than
@@ -65,25 +64,11 @@ FEATURES:
8 :redir and 'verbosefile'
8 middleclick in content == p, and if command line is open, paste there the clipboard buffer
8 all search commands should start searching from the top of the visible viewport
-8 :addsearch wikpedia http://en.wikipedia.org/wiki/Special:Search?search=%s to allow saving of
- quick searches in the RC file.
- Why not just add a bookmark? --Kris
- This would require performance tests, how fast it is to add 20 keywords that way, as we need
- to search all existing bookmarks to see if the keyword is already defined, and then just update
- that bookmark. --mst
-
- Wah? I don't see how that's especially relevant, since they only
- need to be added once, but, if you insist:
- :100time bookmarks.getKeywords().some(function(k) k.keyword == "wikipedia")
- Code execution summary
- Executed: 100 times
- Average time: 2.48 msec
- Total time: 0.25 sec
- --Kris
-
8 allow for multiple ex commands separated with | (see #24)
8 / should work as in vim (i.e., save page positions as well as
locations in the history list).
+8 jump to the next heading with ]h, next image ]i, previous textbox [t and so on
+8 pipe selected text/link/website to an external command
7 use ctrl-n/p in insert mode for word completion
7 implement QuickFix window based on ItemList
7 wherever possible: get rid of dialogs and ask console-like dialog questions
@@ -93,7 +78,7 @@ FEATURES:
opera's fast forward does something like this
7 make an option to disable session saving by default when you close Firefox
7 The output of the pageinfo-command should contain the security-information of ssl-encrypted sites
-7 Add :every command
+7 :grep support (needs location list)
6 :mksession
6 add [count] support to :b* and :tab* commands where missing
6 registers
@@ -101,12 +86,10 @@ FEATURES:
always be the default register. --Ted
6 check/correct spellings in insert mode with some mappings
6 add more autocommands (TabClose, TabOpen, TabChanged etc)
-6 jump to the next heading with ]h, next image ]i, previous textbox [t and so on
-6 :grep support (needs location list)
-6 pipe selected text/link/website to an external command
6 Use ctrl-w+j/k/w to switch between sidebar, content, preview window
6 Command :tags for getting a list of used tags
6 ;? should show more information
+6 Add information to liberator/HACKING file about testing and optimization
5 when looking at a zoomed out image (because it's large), zi should zoom in
maybe with this? : http://mxr.mozilla.org/seamonkey/source/content/html/document/public/nsIImageDocument.idl
5 make a command to search within google search results
@@ -117,8 +100,5 @@ FEATURES:
3 add a command-line window (:help cmdline-window in Vim).
3 Splitting Windows with [:sp :vsp ctrl-w,s ctrl-w,v] and closing with [ctrl-w,q], moving with [ctrl-w,w or tab]
have a look into the split browser extension
-1 Add information to liberator/HACKING file about testing and optimization
-1 Document remote branches in liberator/HACKING
1 Reformat liberator/HACKING so that git diff can find sections and report changes @ somewhere
-- many other ideas are listed in the wiki
diff --git a/vimperator/install.rdf b/vimperator/install.rdf
index 62c6cc5c..5e0bc867 100644
--- a/vimperator/install.rdf
+++ b/vimperator/install.rdf
@@ -4,7 +4,7 @@
vimperator@mozdev.org
Vimperator
- ###VERSION###
+ @VERSION@
Make Firefox behave like Vim
Martin Stubenschrott
http://vimperator.org
From a14e5127df0551806978dcbe181e9cbc2dd14363 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Thu, 10 Jun 2010 01:16:36 -0400
Subject: [PATCH 12/27] Lazy load help files. Store command names in a map.
--HG--
branch : testing
---
common/content/commands.js | 15 +++-
common/content/io.js | 3 +
common/content/liberator.js | 141 ++++++++++++++++++------------------
3 files changed, 86 insertions(+), 73 deletions(-)
diff --git a/common/content/commands.js b/common/content/commands.js
index ab9cebbb..8b59730a 100644
--- a/common/content/commands.js
+++ b/common/content/commands.js
@@ -73,9 +73,9 @@ const Command = Class("Command", {
modifiers = modifiers || {};
let self = this;
- function exec(args) {
+ function exec(command) {
// FIXME: Move to parseCommand?
- args = self.parseArgs(args);
+ args = self.parseArgs(command);
if (!args)
return;
args.count = count;
@@ -237,6 +237,7 @@ const ArgType = Struct("description", "parse");
const Commands = Module("commands", {
init: function () {
this._exCommands = [];
+ this._exMap = {};
},
// FIXME: remove later, when our option handler is better
@@ -304,7 +305,7 @@ const Commands = Module("commands", {
repeat: null,
_addCommand: function (command, replace) {
- if (this._exCommands.some(function (c) c.hasName(command.name))) {
+ if (command.name in this._exMap) {
if (command.user && replace)
commands.removeUserCommand(command.name);
else {
@@ -314,6 +315,8 @@ const Commands = Module("commands", {
}
this._exCommands.push(command);
+ for(let [,name] in Iterator(command.names))
+ this._exMap[name] = command;
return true;
},
@@ -387,7 +390,7 @@ const Commands = Module("commands", {
* @returns {Command}
*/
get: function (name) {
- return this._exCommands.filter(function (cmd) cmd.hasName(name))[0] || null;
+ return this._exMap[name] || this._exCommands.filter(function (cmd) cmd.hasName(name))[0] || null;
},
/**
@@ -762,6 +765,10 @@ const Commands = Module("commands", {
* any of the command's names.
*/
removeUserCommand: function (name) {
+ for(let [,cmd] in Iterator(this._exCommands))
+ if(cmd.user && cmd.hasName(name))
+ for(let [,name] in Iterator(cmd.names))
+ delete this._exMap[name];
this._exCommands = this._exCommands.filter(function (cmd) !(cmd.user && cmd.hasName(name)));
},
diff --git a/common/content/io.js b/common/content/io.js
index 2aa3f9e8..5b599215 100644
--- a/common/content/io.js
+++ b/common/content/io.js
@@ -597,6 +597,8 @@ lookup:
*/
source: function (filename, silent) {
let wasSourcing = this.sourcing;
+ liberator.dump("sourcing " + filename);
+ let time = Date.now();
try {
var file = File(filename);
this.sourcing = {
@@ -715,6 +717,7 @@ lookup:
liberator.echoerr(message);
}
finally {
+ liberator.dump("done sourcing " + filename + ": " + (Date.now() - time) + "ms");
this.sourcing = wasSourcing;
}
},
diff --git a/common/content/liberator.js b/common/content/liberator.js
index a4617b4c..6b2bc0a2 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -544,85 +544,88 @@ const Liberator = Module("liberator", {
* Initialize the help system.
*/
initHelp: function () {
- let namespaces = [config.name.toLowerCase(), "liberator"];
- services.get("liberator:").init({});
+ if(!this.helpInitialized) {
+ let namespaces = [config.name.toLowerCase(), "liberator"];
+ services.get("liberator:").init({});
- let tagMap = services.get("liberator:").HELP_TAGS;
- let fileMap = services.get("liberator:").FILE_MAP;
- let overlayMap = services.get("liberator:").OVERLAY_MAP;
+ let tagMap = services.get("liberator:").HELP_TAGS;
+ let fileMap = services.get("liberator:").FILE_MAP;
+ let overlayMap = services.get("liberator:").OVERLAY_MAP;
- // Left as an XPCOM instantiation so it can easilly be moved
- // into XPCOM code.
- function XSLTProcessor(sheet) {
- let xslt = Cc["@mozilla.org/document-transformer;1?type=xslt"].createInstance(Ci.nsIXSLTProcessor);
- xslt.importStylesheet(util.httpGet(sheet).responseXML);
- return xslt;
- }
-
- // Find help and overlay files with the given name.
- function findHelpFile(file) {
- let result = [];
- for (let [, namespace] in Iterator(namespaces)) {
- let url = ["chrome://", namespace, "/locale/", file, ".xml"].join("");
- let res = util.httpGet(url);
- if (res) {
- if (res.responseXML.documentElement.localName == "document")
- fileMap[file] = url;
- if (res.responseXML.documentElement.localName == "overlay")
- overlayMap[file] = url;
- result.push(res.responseXML);
- }
+ // Left as an XPCOM instantiation so it can easilly be moved
+ // into XPCOM code.
+ function XSLTProcessor(sheet) {
+ let xslt = Cc["@mozilla.org/document-transformer;1?type=xslt"].createInstance(Ci.nsIXSLTProcessor);
+ xslt.importStylesheet(util.httpGet(sheet).responseXML);
+ return xslt;
}
- return result;
- }
- // Find the tags in the document.
- function addTags(file, doc) {
- doc = XSLT.transformToDocument(doc);
- for (let elem in util.evaluateXPath("//xhtml:a/@id", doc))
- tagMap[elem.value] = file;
- }
- const XSLT = XSLTProcessor("chrome://liberator/content/help-single.xsl");
+ // Find help and overlay files with the given name.
+ function findHelpFile(file) {
+ let result = [];
+ for (let [, namespace] in Iterator(namespaces)) {
+ let url = ["chrome://", namespace, "/locale/", file, ".xml"].join("");
+ let res = util.httpGet(url);
+ if (res) {
+ if (res.responseXML.documentElement.localName == "document")
+ fileMap[file] = url;
+ if (res.responseXML.documentElement.localName == "overlay")
+ overlayMap[file] = url;
+ result.push(res.responseXML);
+ }
+ }
+ return result;
+ }
+ // Find the tags in the document.
+ function addTags(file, doc) {
+ doc = XSLT.transformToDocument(doc);
+ for (let elem in util.evaluateXPath("//xhtml:a/@id", doc))
+ tagMap[elem.value] = file;
+ }
- // Scrape the list of help files from all.xml
- // Always process main and overlay files, since XSLTProcessor and
- // XMLHttpRequest don't allow access to chrome documents.
- tagMap.all = "all";
- let files = findHelpFile("all").map(function (doc)
- [f.value for (f in util.evaluateXPath(
- "//liberator:include/@href", doc))]);
+ const XSLT = XSLTProcessor("chrome://liberator/content/help-single.xsl");
- // Scrape the tags from the rest of the help files.
- util.Array.flatten(files).forEach(function (file) {
- findHelpFile(file).forEach(function (doc) {
- addTags(file, doc);
+ // Scrape the list of help files from all.xml
+ // Always process main and overlay files, since XSLTProcessor and
+ // XMLHttpRequest don't allow access to chrome documents.
+ tagMap.all = "all";
+ let files = findHelpFile("all").map(function (doc)
+ [f.value for (f in util.evaluateXPath(
+ "//liberator:include/@href", doc))]);
+
+ // Scrape the tags from the rest of the help files.
+ util.Array.flatten(files).forEach(function (file) {
+ findHelpFile(file).forEach(function (doc) {
+ addTags(file, doc);
+ });
});
- });
- // Process plugin help entries.
- XML.ignoreWhiteSpace = false;
- XML.prettyPrinting = false;
- XML.prettyPrinting = true; // Should be false, but ignoreWhiteSpace=false doesn't work correctly. This is the lesser evil.
- XML.prettyIndent = 4;
+ // Process plugin help entries.
+ XML.ignoreWhiteSpace = false;
+ XML.prettyPrinting = false;
+ XML.prettyPrinting = true; // Should be false, but ignoreWhiteSpace=false doesn't work correctly. This is the lesser evil.
+ XML.prettyIndent = 4;
- let body = XML();
- for (let [, context] in Iterator(plugins.contexts))
- if (context.INFO instanceof XML)
- body += {context.INFO.@summary}
+
- context.INFO;
+ let body = XML();
+ for (let [, context] in Iterator(plugins.contexts))
+ if (context.INFO instanceof XML)
+ body += {context.INFO.@summary}
+
+ context.INFO;
- let help = '\n' +
- '\n' +
- '' +
-
- Using Plugins
+ let help = '\n' +
+ '\n' +
+ '' +
+
+ Using Plugins
- {body}
- .toXMLString();
- fileMap["plugins"] = function () ['text/xml;charset=UTF-8', help];
+ {body}
+ .toXMLString();
+ fileMap["plugins"] = function () ['text/xml;charset=UTF-8', help];
- addTags("plugins", util.httpGet("liberator://help/plugins").responseXML);
+ addTags("plugins", util.httpGet("liberator://help/plugins").responseXML);
+ this.helpInitialized = true;
+ }
},
/**
@@ -634,6 +637,7 @@ const Liberator = Module("liberator", {
* @returns {string}
*/
help: function (topic, unchunked) {
+ liberator.initHelp();
if (!topic) {
let helpFile = unchunked ? "all" : options["helpfile"];
if (helpFile in services.get("liberator:").FILE_MAP)
@@ -1717,6 +1721,7 @@ const Liberator = Module("liberator", {
};
completion.help = function help(context, unchunked) {
+ liberator.initHelp();
context.title = ["Help"];
context.anchored = false;
context.completions = services.get("liberator:").HELP_TAGS;
@@ -1820,8 +1825,6 @@ const Liberator = Module("liberator", {
if (options["loadplugins"])
liberator.loadPlugins();
- liberator.initHelp();
-
// after sourcing the initialization files, this function will set
// all gui options to their default values, if they have not been
// set before by any RC file
From 535293a53eb672dc31108f4d45e2c0e395ab68a5 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Thu, 10 Jun 2010 01:30:03 -0400
Subject: [PATCH 13/27] Fix finding from caret.
--HG--
branch : testing
---
common/content/finder.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/common/content/finder.js b/common/content/finder.js
index aa78d3a7..2cd391b4 100644
--- a/common/content/finder.js
+++ b/common/content/finder.js
@@ -270,8 +270,7 @@ const RangeFind = Class("RangeFind", {
get selectedRange() {
let range = RangeFind.Range(tabs.localStore.focusedFrame || content);
- range = (range.selection.rangeCount ? range.selection.getRangeAt(0) : this.ranges[0].range).cloneRange();
- return range;
+ return (range.selection.rangeCount ? range.selection.getRangeAt(0) : this.ranges[0].range).cloneRange();
},
reset: function () {
@@ -411,6 +410,9 @@ const RangeFind = Class("RangeFind", {
},
search: function (word, reverse, private_) {
+ if (!private_ && this.lastRange && !RangeFind.equal(this.selectedRange, this.lastRange))
+ this.reset();
+
this.wrapped = false;
this.finder.findBackwards = reverse ? !this.reverse : this.reverse;
let again = word == null;
@@ -426,8 +428,6 @@ const RangeFind = Class("RangeFind", {
this.range.descroll();
this.lastRange = this.startRange;
this.range = this.ranges.first;
- } else if (!private_ && this.lastRange && !RangeFind.equal(this.selectedRange, this.lastRange)) {
- this.reset();
}
if (word == "")
From 5bd7b6b0fc695d216af787d6ab1b5abb86d090b6 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Thu, 10 Jun 2010 02:19:35 -0400
Subject: [PATCH 14/27] Focus ancestor link (but not input boxes) of
rangefinder selections.
--HG--
branch : testing
---
common/content/finder.js | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/common/content/finder.js b/common/content/finder.js
index 2cd391b4..3322f12c 100644
--- a/common/content/finder.js
+++ b/common/content/finder.js
@@ -83,6 +83,7 @@ const RangeFinder = Module("rangefinder", {
if (options["hlsearch"])
this.highlight();
+ this.rangeFind.focus();
},
// Called when the user types a key in the search dialog. Triggers a find attempt if 'incsearch' is set
@@ -103,6 +104,7 @@ const RangeFinder = Module("rangefinder", {
if (options["hlsearch"])
this.highlight();
+ this.rangeFind.focus();
modes.reset();
},
@@ -311,6 +313,16 @@ const RangeFind = Class("RangeFind", {
}
},
+ focus: function() {
+ if(this.lastRange)
+ var node = util.evaluateXPath(RangeFind.selectNodePath, this.range.document,
+ this.lastRange.commonAncestorContainer).snapshotItem(0);
+ if(node) {
+ node.focus();
+ this.search(null, false); // Rehighlight collapsed range
+ }
+ },
+
makeFrameList: function (win) {
const self = this;
win = win.top;
@@ -622,6 +634,8 @@ const RangeFind = Class("RangeFind", {
}}
}),
+ selectNodePath: ["ancestor-or-self::" + s for ([i, s] in Iterator(
+ ["a", "xhtml:a", "*[@onclick]"]))].join(" | "),
endpoint: function (range, before) {
range = range.cloneRange();
range.collapse(before);
From a72c4af900ce44892dde49939b7dfe9c96aedf92 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Thu, 10 Jun 2010 02:35:27 -0400
Subject: [PATCH 15/27] Fix plugin help.
--HG--
branch : testing
---
common/content/io.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/common/content/io.js b/common/content/io.js
index 5b599215..75cb6054 100644
--- a/common/content/io.js
+++ b/common/content/io.js
@@ -628,8 +628,7 @@ lookup:
if (/\.js$/.test(filename)) {
try {
liberator.loadScript(uri.spec, Script(file));
- if (liberator.initialized)
- liberator.initHelp();
+ liberator.helpInitialized = false;
}
catch (e) {
let err = new Error();
From 05a3bcf1806d466e84173d3d52e0f8883db85f92 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Thu, 17 Jun 2010 08:25:41 -0400
Subject: [PATCH 16/27] Only echo the download complete message in the active
window.
--HG--
branch : testing
---
common/content/commandline.js | 9 +++++++--
common/content/io.js | 2 +-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/common/content/commandline.js b/common/content/commandline.js
index 81e54619..8ee48769 100644
--- a/common/content/commandline.js
+++ b/common/content/commandline.js
@@ -331,10 +331,11 @@ const CommandLine = Module("commandline", {
FORCE_MULTILINE : 1 << 0,
FORCE_SINGLELINE : 1 << 1,
- DISALLOW_MULTILINE : 1 << 2, // if an echo() should try to use the single line
+ DISALLOW_MULTILINE : 1 << 2, // If an echo() should try to use the single line
// but output nothing when the MOW is open; when also
// FORCE_MULTILINE is given, FORCE_MULTILINE takes precedence
- APPEND_TO_MESSAGES : 1 << 3, // add the string to the message this._history
+ APPEND_TO_MESSAGES : 1 << 3, // Add the string to the message this._history.
+ ACTIVE_WINDOW : 1 << 4, // Only echo in active window.
get completionContext() this._completions.context,
@@ -501,6 +502,10 @@ const CommandLine = Module("commandline", {
if (flags & this.APPEND_TO_MESSAGES)
this._messageHistory.add({ str: str, highlight: highlightGroup });
+ if ((flags & this.ACTIVE_WINDOW) &&
+ window != services.get("windowWatcher").activeWindow &&
+ services.get("windowWatcher").activeWindow.liberator)
+ return;
// The DOM isn't threadsafe. It must only be accessed from the main thread.
liberator.callInMainThread(function () {
diff --git a/common/content/io.js b/common/content/io.js
index 75cb6054..3350df4f 100644
--- a/common/content/io.js
+++ b/common/content/io.js
@@ -340,7 +340,7 @@ const IO = Module("io", {
let file = download.targetFile.path;
let size = download.size;
- liberator.echomsg("Download of " + title + " to " + file + " finished", 1);
+ liberator.echomsg("Download of " + title + " to " + file + " finished", 1, commandline.ACTIVE_WINDOW);
autocommands.trigger("DownloadPost", { url: url, title: title, file: file, size: size });
}
},
From 9589d33fd21f3e52395c84478a8b4103ef8a8ffe Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Thu, 17 Jun 2010 16:52:45 -0400
Subject: [PATCH 17/27] Fix JS completion bug.
--HG--
branch : testing
---
common/content/javascript.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/common/content/javascript.js b/common/content/javascript.js
index cdc097ee..e2c6a50d 100644
--- a/common/content/javascript.js
+++ b/common/content/javascript.js
@@ -59,7 +59,9 @@ const JavaScript = Module("javascript", {
}
// The debugger doesn't list some properties. I can't guess why.
for (let k in orig)
- if (k in orig && !('|' + k in seen) && orig.hasOwnProperty(k) == toplevel)
+ if (k in orig && !('|' + k in seen)
+ && callable(orig.hasOwnProperty)
+ && orig.hasOwnProperty(k) == toplevel)
yield [k, this.getKey(orig, k)]
}
else {
From 1210bc574ac8cd21066b9fbfdb4e320627434374 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Sun, 20 Jun 2010 11:25:50 -0400
Subject: [PATCH 18/27] Only open files rather than URLs for full or relative
path names.
--HG--
branch : testing
---
common/content/io.js | 5 +-
common/content/liberator.js | 91 +++++++++++++++++++++++++++----------
common/content/util.js | 59 ------------------------
3 files changed, 71 insertions(+), 84 deletions(-)
diff --git a/common/content/io.js b/common/content/io.js
index 3350df4f..8d5faf64 100644
--- a/common/content/io.js
+++ b/common/content/io.js
@@ -1065,7 +1065,10 @@ lookup:
};
};
- completion.addUrlCompleter("f", "Local files", completion.file);
+ completion.addUrlCompleter("f", "Local files", function (context, full) {
+ if (!/^\.?\//.test(context.filter))
+ completion.file(context, full);
+ });
},
options: function () {
var shell, shellcmdflag;
diff --git a/common/content/liberator.js b/common/content/liberator.js
index 6b2bc0a2..1390a84c 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -743,22 +743,12 @@ const Liberator = Module("liberator", {
*/
open: function (urls, params, force) {
// convert the string to an array of converted URLs
- // -> see util.stringToURLArray for more details
+ // -> see liberator.stringToURLArray for more details
//
// This is strange. And counterintuitive. Is it really
// necessary? --Kris
- if (typeof urls == "string") {
- // rather switch to the tab instead of opening a new url in case of "12: Tab Title" like "urls"
- if (liberator.has("tabs")) {
- let matches = urls.match(/^(\d+):/);
- if (matches) {
- tabs.select(parseInt(matches[1], 10) - 1, false); // make it zero-based
- return;
- }
- }
-
- urls = util.stringToURLArray(urls);
- }
+ if (typeof urls == "string")
+ urls = liberator.stringToURLArray(urls);
if (urls.length > 20 && !force) {
commandline.input("This will open " + urls.length + " new tabs. Would you like to continue? (yes/[no]) ",
@@ -771,7 +761,7 @@ const Liberator = Module("liberator", {
let flags = 0;
params = params || {};
- if (params instanceof Array)
+ if (isarray(params))
params = { where: params };
for (let [opt, flag] in Iterator({ replace: "REPLACE_HISTORY", hide: "BYPASS_HISTORY" }))
@@ -779,15 +769,11 @@ const Liberator = Module("liberator", {
flags |= Ci.nsIWebNavigation["LOAD_FLAGS_" + flag];
let where = params.where || liberator.CURRENT_TAB;
+ let background = ("background" in params) ? params.background : params.where == NEW_BACKGROUND_TAB;
if ("from" in params && liberator.has("tabs")) {
if (!('where' in params) && options.get("newtab").has("all", params.from))
- where = liberator.NEW_BACKGROUND_TAB;
- if (options.get("activate").has("all", params.from)) {
- if (where == liberator.NEW_TAB)
- where = liberator.NEW_BACKGROUND_TAB;
- else if (where == liberator.NEW_BACKGROUND_TAB)
- where = liberator.NEW_TAB;
- }
+ where = liberator.NEW_TAB;
+ background = !options.get("activate").has("all", params.from);
}
if (urls.length == 0)
@@ -805,7 +791,6 @@ const Liberator = Module("liberator", {
browser.loadURIWithFlags(url, flags, null, null, postdata);
break;
- case liberator.NEW_BACKGROUND_TAB:
case liberator.NEW_TAB:
if (!liberator.has("tabs")) {
open(urls, liberator.NEW_WINDOW);
@@ -814,7 +799,7 @@ const Liberator = Module("liberator", {
options.withContext(function () {
options.setPref("browser.tabs.loadInBackground", true);
- browser.loadOneTab(url, null, null, postdata, where == liberator.NEW_BACKGROUND_TAB);
+ browser.loadOneTab(url, null, null, postdata, background);
});
break;
@@ -838,7 +823,7 @@ const Liberator = Module("liberator", {
for (let [, url] in Iterator(urls)) {
open(url, where);
- where = liberator.NEW_BACKGROUND_TAB;
+ background = true;
}
},
@@ -871,6 +856,64 @@ const Liberator = Module("liberator", {
window.goQuitApplication();
},
+ /**
+ * Returns an array of URLs parsed from str.
+ *
+ * Given a string like 'google bla, www.osnews.com' return an array
+ * ['www.google.com/search?q=bla', 'www.osnews.com']
+ *
+ * @param {string} str
+ * @returns {string[]}
+ */
+ stringToURLArray: function stringToURLArray(str) {
+ let urls;
+
+ if (options["urlseparator"])
+ urls = util.splitLiteral(str, RegExp("\\s*" + options["urlseparator"] + "\\s*"));
+ else
+ urls = [str];
+
+ return urls.map(function (url) {
+ if (/^\.?\//.test(url)) {
+ try {
+ // Try to find a matching file.
+ let file = io.File(url);
+ if (file.exists() && file.isReadable())
+ return services.get("io").newFileURI(file).spec;
+ }
+ catch (e) {}
+ }
+
+ // strip each 'URL' - makes things simpler later on
+ url = url.replace(/^\s+|\s+$/, "");
+
+ // Look for a valid protocol
+ let proto = url.match(/^([-\w]+):/);
+ if (proto && Cc["@mozilla.org/network/protocol;1?name=" + proto[1]])
+ // Handle as URL, but remove spaces. Useful for copied/'p'asted URLs.
+ return url.replace(/\s*\n+\s*/g, "");
+
+ // Ok, not a valid proto. If it looks like URL-ish (foo.com/bar),
+ // let Gecko figure it out.
+ if (/^[a-zA-Z0-9-.]+(?:\/|$)/.test(url) && /[.\/]/.test(url) && !/\s/.test(url) || /^[a-zA-Z0-9-.]+:\d+(?:\/|$)/.test(url))
+ return url;
+
+ // TODO: it would be clearer if the appropriate call to
+ // getSearchURL was made based on whether or not the first word was
+ // indeed an SE alias rather than seeing if getSearchURL can
+ // process the call usefully and trying again if it fails
+
+ // check for a search engine match in the string, then try to
+ // search for the whole string in the default engine
+ let searchURL = bookmarks.getSearchURL(url, false) || bookmarks.getSearchURL(url, true);
+ if (searchURL)
+ return searchURL;
+
+ // Hmm. No defsearch? Let the host app deal with it, then.
+ return url;
+ });
+ },
+
/*
* Tests a condition and throws a FailedAssertion error on
* failure.
diff --git a/common/content/util.js b/common/content/util.js
index f5afd454..172bbed6 100644
--- a/common/content/util.js
+++ b/common/content/util.js
@@ -686,65 +686,6 @@ const Util = Module("util", {
elem.scrollIntoView();
},
-
- /**
- * Returns an array of URLs parsed from str.
- *
- * Given a string like 'google bla, www.osnews.com' return an array
- * ['www.google.com/search?q=bla', 'www.osnews.com']
- *
- * @param {string} str
- * @returns {string[]}
- */
- stringToURLArray: function stringToURLArray(str) {
- let urls;
-
- if (options["urlseparator"])
- urls = util.splitLiteral(str, RegExp("\\s*" + options["urlseparator"] + "\\s*"));
- else
- urls = [str];
-
- return urls.map(function (url) {
- if (url.substr(0, 5) != "file:") {
- try {
- // Try to find a matching file.
- let file = io.File(url);
- if (file.exists() && file.isReadable())
- return services.get("io").newFileURI(file).spec;
- }
- catch (e) {}
- }
-
- // strip each 'URL' - makes things simpler later on
- url = url.replace(/^\s+|\s+$/, "");
-
- // Look for a valid protocol
- let proto = url.match(/^([-\w]+):/);
- if (proto && Cc["@mozilla.org/network/protocol;1?name=" + proto[1]])
- // Handle as URL, but remove spaces. Useful for copied/'p'asted URLs.
- return url.replace(/\s*\n+\s*/g, "");
-
- // Ok, not a valid proto. If it looks like URL-ish (foo.com/bar),
- // let Gecko figure it out.
- if (/^[a-zA-Z0-9-.]+(?:\/|$)/.test(url) && /[.\/]/.test(url) && !/\s/.test(url) || /^[a-zA-Z0-9-.]+:\d+(?:\/|$)/.test(url))
- return url;
-
- // TODO: it would be clearer if the appropriate call to
- // getSearchURL was made based on whether or not the first word was
- // indeed an SE alias rather than seeing if getSearchURL can
- // process the call usefully and trying again if it fails
-
- // check for a search engine match in the string, then try to
- // search for the whole string in the default engine
- let searchURL = bookmarks.getSearchURL(url, false) || bookmarks.getSearchURL(url, true);
- if (searchURL)
- return searchURL;
-
- // Hmm. No defsearch? Let the host app deal with it, then.
- return url;
- });
- },
-
/**
* Converts an E4X XML literal to a DOM node.
*
From 0e3b5ca121dd6f569da3355b54af1b61b4181720 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Sun, 8 Aug 2010 22:03:42 -0400
Subject: [PATCH 19/27] Some Gecko 2 fixes.
--HG--
branch : testing
---
common/components/protocols.js | 7 +-
common/content/buffer.js | 2 +-
common/content/commandline.js | 2 +-
common/content/hints.js | 25 +--
common/content/liberator.js | 195 +++++++++++++------
common/content/services.js | 3 +
common/content/tabs.js | 9 +-
common/content/util.js | 2 +-
vimperator/chrome.manifest | 13 ++
vimperator/components/about-handler.js | 5 +-
vimperator/components/commandline-handler.js | 5 +-
11 files changed, 175 insertions(+), 93 deletions(-)
diff --git a/common/components/protocols.js b/common/components/protocols.js
index 450c346e..2dd50338 100644
--- a/common/components/protocols.js
+++ b/common/components/protocols.js
@@ -152,8 +152,9 @@ Liberator.prototype = {
}
};
-var components = [ChromeData, Liberator];
-
-function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule(components)
+if (XPCOMUtils.generateNSGetFactory)
+ const NSGetFactory = XPCOMUtils.generateNSGetFactory([ChromeData, Liberator]);
+else
+ const NSGetModule = XPCOMUtils.generateNSGetModule([ChromeData, Liberator]);
// vim: set fdm=marker sw=4 ts=4 et:
diff --git a/common/content/buffer.js b/common/content/buffer.js
index 4a6d4266..b73e718f 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -1517,7 +1517,7 @@ const Buffer = Module("buffer", {
function () {
let url = util.readFromClipboard();
liberator.assert(url);
- liberator.open(url, { from: "activate", where: liberator.NEW_TAB });
+ liberator.open(url, { from: "paste", where: liberator.NEW_TAB });
});
// reloading
diff --git a/common/content/commandline.js b/common/content/commandline.js
index 8ee48769..78db2968 100644
--- a/common/content/commandline.js
+++ b/common/content/commandline.js
@@ -1134,7 +1134,7 @@ const CommandLine = Module("commandline", {
let str = commandline.command;
return str.substring(this.prefix.length, str.length - this.suffix.length);
},
- set completion set_completion(completion) {
+ set completion(completion) {
this.previewClear();
// Change the completion text.
diff --git a/common/content/hints.js b/common/content/hints.js
index 60babe15..ca0037f4 100644
--- a/common/content/hints.js
+++ b/common/content/hints.js
@@ -47,7 +47,7 @@ const Hints = Module("hints", {
t: Mode("Follow hint in a new tab", function (elem) buffer.followLink(elem, liberator.NEW_TAB)),
b: Mode("Follow hint in a background tab", function (elem) buffer.followLink(elem, liberator.NEW_BACKGROUND_TAB)),
w: Mode("Follow hint in a new window", function (elem) buffer.followLink(elem, liberator.NEW_WINDOW), extended),
- F: Mode("Open multiple hints in tabs", followAndReshow),
+ F: Mode("Open multiple hints in tabs", function (elem) { buffer.followLink(elem, liberator.NEW_BACKGROUND_TAB); hints.show("F") }),
O: Mode("Generate an ':open URL' using hint", function (elem, loc) commandline.open(":", "open " + loc, modes.EX)),
T: Mode("Generate a ':tabopen URL' using hint", function (elem, loc) commandline.open(":", "tabopen " + loc, modes.EX)),
W: Mode("Generate a ':winopen URL' using hint", function (elem, loc) commandline.open(":", "winopen " + loc, modes.EX)),
@@ -59,21 +59,6 @@ const Hints = Module("hints", {
i: Mode("Show image", function (elem) liberator.open(elem.src), images),
I: Mode("Show image in a new tab", function (elem) liberator.open(elem.src, liberator.NEW_TAB), images)
};
-
- /**
- * Follows the specified hint and then reshows all hints. Used to open
- * multiple hints in succession.
- *
- * @param {Node} elem The selected hint.
- */
- function followAndReshow(elem) {
- buffer.followLink(elem, liberator.NEW_BACKGROUND_TAB);
-
- // TODO: Maybe we find a *simple* way to keep the hints displayed rather than
- // showing them again, or is this short flash actually needed as a "usability
- // feature"? --mst
- hints.show("F");
- }
},
/**
@@ -129,7 +114,7 @@ const Hints = Module("hints", {
let type = elem.type;
- if (elem instanceof HTMLInputElement && /(submit|button|this._reset)/.test(type))
+ if (elem instanceof HTMLInputElement && /(submit|button|reset)/.test(type))
return [elem.value, false];
else {
for (let [, option] in Iterator(options["hintinputs"].split(","))) {
@@ -272,10 +257,6 @@ const Hints = Module("hints", {
if (!rect || rect.top > height || rect.bottom < 0 || rect.left > width || rect.right < 0)
continue;
- rect = elem.getClientRects()[0];
- if (!rect)
- continue;
-
let computedStyle = doc.defaultView.getComputedStyle(elem, null);
if (computedStyle.getPropertyValue("visibility") != "visible" || computedStyle.getPropertyValue("display") == "none")
continue;
@@ -396,7 +377,7 @@ const Hints = Module("hints", {
}
}
- if (config.browser.markupDocumentViewer.authorStyleDisabled) {
+ if (options["usermode"]) {
let css = [];
// FIXME: Broken for imgspans.
for (let [, { doc: doc }] in Iterator(this._docs)) {
diff --git a/common/content/liberator.js b/common/content/liberator.js
index 1390a84c..60d68847 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -270,7 +270,7 @@ const Liberator = Module("liberator", {
let stack = Error().stack.replace(/(?:.*\n){2}/, "");
if (frames != null)
[stack] = stack.match(RegExp("(?:.*\n){0," + frames + "}"));
- liberator.dump((msg || "Stack") + "\n" + stack);
+ liberator.dump((msg || "Stack") + "\n" + stack + "\n");
},
/**
@@ -769,7 +769,7 @@ const Liberator = Module("liberator", {
flags |= Ci.nsIWebNavigation["LOAD_FLAGS_" + flag];
let where = params.where || liberator.CURRENT_TAB;
- let background = ("background" in params) ? params.background : params.where == NEW_BACKGROUND_TAB;
+ let background = ("background" in params) ? params.background : params.where == liberator.NEW_BACKGROUND_TAB;
if ("from" in params && liberator.has("tabs")) {
if (!('where' in params) && options.get("newtab").has("all", params.from))
where = liberator.NEW_TAB;
@@ -1380,19 +1380,89 @@ const Liberator = Module("liberator", {
}
});
+ ///////////////////////////////////////////////////////////////////////////
+
+ if (typeof AddonManager == "undefined") {
+ modules.AddonManager = {
+ getInstallForFile: function (file, callback, mimetype) {
+ callback({
+ install: function () {
+ services.get("extensionManager").installItemFromFile(file, "app-profile");
+ }
+ });
+ },
+ getAddonById: function (id, callback) {
+ let addon = id;
+ if (!isobject(addon))
+ addon = services.get("extensionManager").getItemForID(id);
+ if (!addon)
+ return callback(null);
+
+ function getRdfProperty(item, property) {
+ let resource = services.get("rdf").GetResource("urn:mozilla:item:" + item.id);
+ let value = "";
+
+ if (resource) {
+ let target = services.get("extensionManager").datasource.GetTarget(resource,
+ services.get("rdf").GetResource("http://www.mozilla.org/2004/em-rdf#" + property), true);
+ if (target && target instanceof Ci.nsIRDFLiteral)
+ value = target.Value;
+ }
+
+ return value;
+ }
+
+ ["aboutURL", "creator", "description", "developers",
+ "homepageURL", "iconURL", "installDate", "name",
+ "optionsURL", "releaseNotesURI", "updateDate"].forEach(function (item) {
+ addon[item] = getRdfProperty(addon, item);
+ });
+ addon.isActive = getRdfProperty(addon, "isDisabled") != "true";
+
+ addon.uninstall = function () {
+ services.get("extensionManager").uninstallItem(this.id);
+ };
+ addon.appDisabled = false;
+ addon.__defineGetter("userDisabled", function() getRdfProperty("userDisabled") == "true");
+ addon.__defineSetter__("userDisabled", function(val) {
+ services.get("extensionManager")[val ? "enableItem" : "disableItem"](this.id);
+ });
+
+ return callback(addon);
+ },
+ getAddonsByTypes: function (types, callback) {
+ let res = [];
+ for (let [,type] in Iterator(types))
+ for (let [,item] in Iterator(services.get("extensionManager")
+ .getItemList(Ci.nsIUpdateItem["TYPE_" + type.toUpperCase()], {})))
+ res.append(this.getAddonById(item));
+ return res;
+ }
+ };
+
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ function callResult(method) {
+ let args = Array.slice(arguments, 1);
+ return function (result) { result[method].apply(result, args) };
+ }
+
commands.add(["exta[dd]"],
"Install an extension",
function (args) {
- let file = io.File(args[0]);
-
- if (file.exists() && file.isReadable() && file.isFile())
- services.get("extensionManager").installItemFromFile(file, "app-profile");
- else {
- if (file.exists() && file.isDirectory())
- liberator.echomsg("Cannot install a directory: \"" + file.path + "\"", 0);
+ let url = args[0];
+ let file = io.File(url);
+ if (!file.exists())
+ AddonManager.getInstallForURL(url, callResult("install"), "application/x-xpinstall");
+ else if (file.isReadable() && file.isFile())
+ AddonManager.getInstallForFile(file, callResult("install"), "application/x-xpinstall");
+ else if (file.isDirectory())
+ liberator.echomsg("Cannot install a directory: \"" + file.path + "\"", 0);
+ else
liberator.echoerr("E484: Can't open file " + file.path);
- }
}, {
argCount: "1",
completer: function (context) {
@@ -1406,38 +1476,35 @@ const Liberator = Module("liberator", {
{
name: "extde[lete]",
description: "Uninstall an extension",
- action: "uninstallItem"
+ action: callResult("uninstall")
},
{
name: "exte[nable]",
description: "Enable an extension",
- action: "enableItem",
- filter: function ({ item: e }) !e.enabled
+ action: function (addon) addon.userDisabled = false,
+ filter: function ({ item: e }) e.userDisabled
},
{
name: "extd[isable]",
description: "Disable an extension",
- action: "disableItem",
- filter: function ({ item: e }) e.enabled
+ action: function (addon) addon.userDisabled = true,
+ filter: function ({ item: e }) !e.userDisabled
}
].forEach(function (command) {
commands.add([command.name],
command.description,
function (args) {
let name = args[0];
- function action(e) { services.get("extensionManager")[command.action](e.id); };
-
if (args.bang)
- liberator.extensions.forEach(function (e) { action(e); });
- else {
- liberator.assert(name, "E471: Argument required"); // XXX
+ liberator.assert(!name, "E488: Trailing characters");
+ else
+ liberator.assert(name, "E471: Argument required");
- let extension = liberator.getExtension(name);
- if (extension)
- action(extension);
- else
- liberator.echoerr("E474: Invalid argument");
- }
+ AddonManager.getAddonsByTypes(["extension"], function (list) {
+ if (!args.bang)
+ list = list.filter(function (extension) extension.name == name);
+ list.forEach(command.action);
+ });
}, {
argCount: "?", // FIXME: should be "1"
bang: true,
@@ -1453,19 +1520,21 @@ const Liberator = Module("liberator", {
commands.add(["exto[ptions]", "extp[references]"],
"Open an extension's preference dialog",
function (args) {
- let extension = liberator.getExtension(args[0]);
- liberator.assert(extension && extension.options,
- "E474: Invalid argument");
- if (args.bang)
- window.openDialog(extension.options, "_blank", "chrome");
- else
- liberator.open(extension.options, { from: "extoptions" });
+ AddonManager.getAddonsByTypes(["extension"], function (list) {
+ list = list.filter(function (extension) extension.name == args[0]);
+ if (!list.length || !list[0].optionsURL)
+ liberator.echoerr("E474: Invalid argument");
+ else if (args.bang)
+ window.openDialog(list[0].optionsURL, "_blank", "chrome");
+ else
+ liberator.open(list[0].optionsURL, { from: "extoptions" });
+ });
}, {
argCount: "1",
bang: true,
completer: function (context) {
completion.extension(context);
- context.filters.push(function ({ item: e }) e.options);
+ context.filters.push(function ({ item: e }) e.isActive && e.optionsURL);
},
literal: 0
});
@@ -1474,30 +1543,42 @@ const Liberator = Module("liberator", {
commands.add(["extens[ions]"],
"List available extensions",
function (args) {
- let filter = args[0] || "";
- let extensions = liberator.extensions.filter(function (e) e.name.indexOf(filter) >= 0);
+ AddonManager.getAddonsByTypes(["extension"], function (extensions) {
+ liberator.dump(extensions);
+ if (args[0])
+ extensions = extensions.filter(function (extension) extension.name.indexOf(args[0]) >= 0);
- if (extensions.length > 0) {
- let list = template.tabular(
- ["Name", "Version", "Status", "Description"], [],
- ([template.icon(e, e.name),
- e.version,
- e.enabled ? enabled
- : disabled,
- e.description] for ([, e] in Iterator(extensions)))
- );
+ liberator.dump(extensions);
+ if (extensions.length > 0) {
+ let list = template.tabular(
+ ["Name", "Version", "Status", "Description"], [],
+ ([template.icon({ icon: e.iconURL }, e.name),
+ e.version,
+ (e.isActive ? enabled
+ : disabled) +
+ ((e.userDisabled || e.appDisabled) == !e.isActive ? XML() :
+ <> ({e.userDisabled || e.appDisabled
+ ? disabled
+ : enabled}
+ on restart)
+ >),
+ e.description] for ([, e] in Iterator(extensions)))
+ );
- commandline.echo(list, commandline.HL_NORMAL, commandline.FORCE_MULTILINE);
- }
- else {
- if (filter)
- liberator.echoerr("Exxx: No extension matching \"" + filter + "\"");
- else
- liberator.echoerr("No extensions installed");
- }
+ commandline.echo(list, commandline.HL_NORMAL, commandline.FORCE_MULTILINE);
+ }
+ else {
+ if (filter)
+ liberator.echoerr("Exxx: No extension matching \"" + filter + "\"");
+ else
+ liberator.echoerr("No extensions installed");
+ }
+ });
},
{ argCount: "?" });
+ ///////////////////////////////////////////////////////////////////////////
+
commands.add(["exu[sage]"],
"List all Ex commands with a short description",
function (args) { Liberator.showHelpIndex("ex-cmd-index", commands, args.bang); }, {
@@ -1759,8 +1840,12 @@ const Liberator = Module("liberator", {
completion.extension = function extension(context) {
context.title = ["Extension"];
context.anchored = false;
- context.keys = { text: "name", description: "description", icon: "icon" },
- context.completions = liberator.extensions;
+ context.keys = { text: "name", description: "description", icon: "iconURL" },
+ context.incomplete = true;
+ AddonManager.getAddonsByTypes(["extension"], function (addons) {
+ context.incomplete = false;
+ context.completions = addons;
+ });
};
completion.help = function help(context, unchunked) {
diff --git a/common/content/services.js b/common/content/services.js
index 20e73b48..ad056221 100644
--- a/common/content/services.js
+++ b/common/content/services.js
@@ -47,6 +47,9 @@ const Services = Module("services", {
this.addClass("file:", "@mozilla.org/network/protocol;1?name=file", Ci.nsIFileProtocolHandler);
this.addClass("find", "@mozilla.org/embedcomp/rangefind;1", Ci.nsIFind);
this.addClass("process", "@mozilla.org/process/util;1", Ci.nsIProcess);
+
+ if (!this.get("extensionManager"))
+ Components.utils.import("resource://gre/modules/AddonManager.jsm", modules);
},
_create: function (classes, ifaces, meth) {
diff --git a/common/content/tabs.js b/common/content/tabs.js
index 6cd4083d..8373b858 100644
--- a/common/content/tabs.js
+++ b/common/content/tabs.js
@@ -797,14 +797,7 @@ const Tabs = Module("tabs", {
commands.add(["tabopen", "t[open]", "tabnew"],
"Open one or more URLs in a new tab",
function (args) {
- let special = args.bang;
- args = args.string;
-
- let where = special ? liberator.NEW_TAB : liberator.NEW_BACKGROUND_TAB;
- if (args)
- liberator.open(args, { from: "tabopen", where: where });
- else
- liberator.open("about:blank", { from: "tabopen", where: where });
+ liberator.open(args.string || "about:blank", { from: "tabopen", where: liberator.NEW_TAB, background: args.bang });
}, {
bang: true,
completer: function (context) completion.url(context),
diff --git a/common/content/util.js b/common/content/util.js
index 172bbed6..a328ae20 100644
--- a/common/content/util.js
+++ b/common/content/util.js
@@ -779,7 +779,7 @@ const Util = Module("util", {
* @param {Array} ary
* @returns {Array}
*/
- flatten: function flatten(ary) Array.concat.apply([], ary),
+ flatten: function flatten(ary) ary.length ? Array.concat.apply([], ary) : [],
/**
* Returns an Iterator for an array's values.
diff --git a/vimperator/chrome.manifest b/vimperator/chrome.manifest
index 57ebfae3..4890933b 100644
--- a/vimperator/chrome.manifest
+++ b/vimperator/chrome.manifest
@@ -14,3 +14,16 @@ override chrome://liberator/content/config.js chrome://vimperator/content/conf
overlay chrome://browser/content/browser.xul chrome://liberator/content/liberator.xul
overlay chrome://browser/content/browser.xul chrome://vimperator/content/vimperator.xul
+component components/
+
+component {81495d80-89ee-4c36-a88d-ea7c4e5ac63f} components/about-handler.js
+contract @mozilla.org/network/protocol/about;1?what=vimperator {81495d80-89ee-4c36-a88d-ea7c4e5ac63f}
+
+component {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69} components/commandline-handler.js
+contract @mozilla.org/commandlinehandler/general-startup;1?type=vimperator {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69}
+
+component {c1b67a07-18f7-4e13-b361-2edcc35a5a0d} components/protocols.js
+contract @mozilla.org/network/protocol;1?name=chrome-data {c1b67a07-18f7-4e13-b361-2edcc35a5a0d}
+component {9c8f2530-51c8-4d41-b356-319e0b155c44} components/protocols.js
+contract @mozilla.org/network/protocol;1?name=liberator {9c8f2530-51c8-4d41-b356-319e0b155c44}
+
diff --git a/vimperator/components/about-handler.js b/vimperator/components/about-handler.js
index f6a386c0..25dbd492 100644
--- a/vimperator/components/about-handler.js
+++ b/vimperator/components/about-handler.js
@@ -38,6 +38,9 @@ AboutHandler.prototype = {
getURIFlags: function (uri) Ci.nsIAboutModule.ALLOW_SCRIPT,
};
-function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([AboutHandler])
+if (XPCOMUtils.generateNSGetFactory)
+ const NSGetFactory = XPCOMUtils.generateNSGetFactory([AboutHandler]);
+else
+ const NSGetModule = XPCOMUtils.generateNSGetModule([AboutHandler]);
// vim: set fdm=marker sw=4 ts=4 et:
diff --git a/vimperator/components/commandline-handler.js b/vimperator/components/commandline-handler.js
index 5ddb6713..8c23f36d 100644
--- a/vimperator/components/commandline-handler.js
+++ b/vimperator/components/commandline-handler.js
@@ -43,6 +43,9 @@ CommandLineHandler.prototype = {
}
};
-function NSGetModule(compMgr, fileSpec) XPCOMUtils.generateModule([CommandLineHandler])
+if (XPCOMUtils.generateNSGetFactory)
+ const NSGetFactory = XPCOMUtils.generateNSGetFactory([CommandLineHandler]);
+else
+ const NSGetModule = XPCOMUtils.generateNSGetModule([CommandLineHandler]);
// vim: set ft=javascript fdm=marker sw=4 ts=4 et:
From 3fa5bb5cea1e96d83318abe16bf5f8583ddfe0de Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Tue, 10 Aug 2010 01:40:58 -0400
Subject: [PATCH 20/27] More Gecko 2 fixes.
--HG--
branch : testing
---
common/content/util.js | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/common/content/util.js b/common/content/util.js
index a328ae20..6f8857be 100644
--- a/common/content/util.js
+++ b/common/content/util.js
@@ -417,11 +417,12 @@ const Util = Module("util", {
null
);
- result.__iterator__ = asIterator
+ return {
+ __proto__: result,
+ __iterator__: asIterator
? function () { let elem; while ((elem = this.iterateNext())) yield elem; }
- : function () { for (let i = 0; i < this.snapshotLength; i++) yield this.snapshotItem(i); };
-
- return result;
+ : function () { for (let i = 0; i < this.snapshotLength; i++) yield this.snapshotItem(i); }
+ }
},
/**
From 59b79928617c75a5bf5903cf688d0c66dece8dfb Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Wed, 11 Aug 2010 01:12:01 -0400
Subject: [PATCH 21/27] Remove leftover debugging statements.
--HG--
branch : testing
---
common/content/liberator.js | 2 --
1 file changed, 2 deletions(-)
diff --git a/common/content/liberator.js b/common/content/liberator.js
index 60d68847..86d6e108 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -1544,11 +1544,9 @@ const Liberator = Module("liberator", {
"List available extensions",
function (args) {
AddonManager.getAddonsByTypes(["extension"], function (extensions) {
- liberator.dump(extensions);
if (args[0])
extensions = extensions.filter(function (extension) extension.name.indexOf(args[0]) >= 0);
- liberator.dump(extensions);
if (extensions.length > 0) {
let list = template.tabular(
["Name", "Version", "Status", "Description"], [],
From f3c32988f12b725988ce86ff55d98d0b1ac3ccb6 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Wed, 11 Aug 2010 01:14:18 -0400
Subject: [PATCH 22/27] Re-add missing class to services.
--HG--
branch : testing
---
common/content/services.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/common/content/services.js b/common/content/services.js
index ad056221..29a76e80 100644
--- a/common/content/services.js
+++ b/common/content/services.js
@@ -47,6 +47,7 @@ const Services = Module("services", {
this.addClass("file:", "@mozilla.org/network/protocol;1?name=file", Ci.nsIFileProtocolHandler);
this.addClass("find", "@mozilla.org/embedcomp/rangefind;1", Ci.nsIFind);
this.addClass("process", "@mozilla.org/process/util;1", Ci.nsIProcess);
+ this.addClass("zipWriter", "@mozilla.org/zipwriter;1", Ci.nsIZipWriter);
if (!this.get("extensionManager"))
Components.utils.import("resource://gre/modules/AddonManager.jsm", modules);
From daa2d5dcc53d648db012f01cd879c29f280d52fa Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Sun, 15 Aug 2010 07:49:52 -0400
Subject: [PATCH 23/27] Use JS5's strict mode. But, alas! it outlaws octal! Oh
the inanity...
--HG--
branch : testing
---
common/components/protocols.js | 2 +-
common/content/autocommands.js | 2 +-
common/content/base.js | 1 +
common/content/bookmarks.js | 2 +-
common/content/browser.js | 2 +-
common/content/buffer.js | 2 +-
common/content/commandline.js | 3 ++-
common/content/commands.js | 2 +-
common/content/completion.js | 6 +++---
common/content/configbase.js | 1 +
common/content/editor.js | 2 +-
common/content/events.js | 2 +-
common/content/finder.js | 1 +
common/content/help.js | 2 +-
common/content/hints.js | 2 +-
common/content/history.js | 1 +
common/content/io.js | 6 +++---
common/content/javascript.js | 3 ++-
common/content/liberator-overlay.js | 1 +
common/content/liberator.js | 2 +-
common/content/mappings.js | 2 +-
common/content/marks.js | 1 +
common/content/modes.js | 1 +
common/content/modules.js | 1 +
common/content/options.js | 1 +
common/content/quickmarks.js | 1 +
common/content/sanitizer.js | 1 +
common/content/services.js | 1 +
common/content/statusline.js | 1 +
common/content/style.js | 1 +
common/content/tabs.js | 2 +-
common/content/template.js | 2 +-
common/content/util.js | 4 +++-
common/modules/storage.jsm | 1 +
vimperator/components/about-handler.js | 1 +
vimperator/components/commandline-handler.js | 1 +
36 files changed, 44 insertions(+), 23 deletions(-)
diff --git a/common/components/protocols.js b/common/components/protocols.js
index 2dd50338..29cff951 100644
--- a/common/components/protocols.js
+++ b/common/components/protocols.js
@@ -2,7 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/* Adds support for data: URIs with chrome privileges
* and fragment identifiers.
diff --git a/common/content/autocommands.js b/common/content/autocommands.js
index 1417e684..36750b75 100644
--- a/common/content/autocommands.js
+++ b/common/content/autocommands.js
@@ -4,7 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
diff --git a/common/content/base.js b/common/content/base.js
index 16a6422d..4eab72e7 100644
--- a/common/content/base.js
+++ b/common/content/base.js
@@ -2,6 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js
index 7c7d47f0..eea59c69 100644
--- a/common/content/bookmarks.js
+++ b/common/content/bookmarks.js
@@ -4,7 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
const DEFAULT_FAVICON = "chrome://mozapps/skin/places/defaultFavicon.png";
diff --git a/common/content/browser.js b/common/content/browser.js
index 2f47a583..1ceb716c 100644
--- a/common/content/browser.js
+++ b/common/content/browser.js
@@ -4,7 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
diff --git a/common/content/buffer.js b/common/content/buffer.js
index b73e718f..7bceb5f1 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -4,7 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
diff --git a/common/content/commandline.js b/common/content/commandline.js
index 78db2968..f0e057c9 100644
--- a/common/content/commandline.js
+++ b/common/content/commandline.js
@@ -4,6 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
/** @scope modules */
@@ -971,7 +972,7 @@ const CommandLine = Module("commandline", {
let doc = this._multilineOutputWidget.contentDocument;
- availableHeight = config.outputHeight;
+ let availableHeight = config.outputHeight;
if (!this._outputContainer.collapsed)
availableHeight += parseFloat(this._outputContainer.height);
doc.body.style.minWidth = this._commandlineWidget.scrollWidth + "px";
diff --git a/common/content/commands.js b/common/content/commands.js
index 8b59730a..c774bc28 100644
--- a/common/content/commands.js
+++ b/common/content/commands.js
@@ -4,7 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
diff --git a/common/content/completion.js b/common/content/completion.js
index c5beb117..bccd4052 100644
--- a/common/content/completion.js
+++ b/common/content/completion.js
@@ -4,7 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
@@ -412,12 +412,12 @@ const CompletionContext = Class("CompletionContext", {
let filter = fixCase(this.filter);
if (this.anchored) {
var compare = function compare(text, s) text.substr(0, s.length) == s;
- substrings = util.map(util.range(filter.length, text.length + 1),
+ var substrings = util.map(util.range(filter.length, text.length + 1),
function (end) text.substring(0, end));
}
else {
var compare = function compare(text, s) text.indexOf(s) >= 0;
- substrings = [];
+ var substrings = [];
let start = 0;
let idx;
let length = filter.length;
diff --git a/common/content/configbase.js b/common/content/configbase.js
index 215695ef..478a1417 100644
--- a/common/content/configbase.js
+++ b/common/content/configbase.js
@@ -4,6 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
const ConfigBase = Class(ModuleBase, {
/**
diff --git a/common/content/editor.js b/common/content/editor.js
index 70414226..0307c98a 100644
--- a/common/content/editor.js
+++ b/common/content/editor.js
@@ -2,7 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
diff --git a/common/content/events.js b/common/content/events.js
index e96a67bc..dbfe3c90 100644
--- a/common/content/events.js
+++ b/common/content/events.js
@@ -4,7 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
diff --git a/common/content/finder.js b/common/content/finder.js
index 3322f12c..71283c2c 100644
--- a/common/content/finder.js
+++ b/common/content/finder.js
@@ -2,6 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
/** @scope modules */
diff --git a/common/content/help.js b/common/content/help.js
index 67fbba37..ed1dd22a 100644
--- a/common/content/help.js
+++ b/common/content/help.js
@@ -2,7 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
function checkFragment() {
document.title = document.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "title")[0].textContent;
diff --git a/common/content/hints.js b/common/content/hints.js
index ca0037f4..977765a9 100644
--- a/common/content/hints.js
+++ b/common/content/hints.js
@@ -4,7 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
/** @instance hints */
diff --git a/common/content/history.js b/common/content/history.js
index 281d797d..dbab5522 100644
--- a/common/content/history.js
+++ b/common/content/history.js
@@ -4,6 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
const History = Module("history", {
requires: ["config"],
diff --git a/common/content/io.js b/common/content/io.js
index 8d5faf64..4ca6174f 100644
--- a/common/content/io.js
+++ b/common/content/io.js
@@ -5,7 +5,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
@@ -162,7 +162,7 @@ const File = Class("File", {
mode = File.MODE_WRONLY | File.MODE_CREATE | File.MODE_TRUNCATE;
if (!perms)
- perms = 0644;
+ perms = parseInt('0644', 8);
ofstream.init(this, mode, perms, 0);
let ocstream = getStream(0);
@@ -487,7 +487,7 @@ const IO = Module("io", {
let file = services.get("directory").get("TmpD", Ci.nsIFile);
file.append(config.tempFile);
- file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
+ file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt('0600', 8));
return File(file);
},
diff --git a/common/content/javascript.js b/common/content/javascript.js
index e2c6a50d..4880e6d0 100644
--- a/common/content/javascript.js
+++ b/common/content/javascript.js
@@ -2,6 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
// TODO: Clean this up.
@@ -109,7 +110,7 @@ const JavaScript = Module("javascript", {
return completions;
},
- eval: function eval(arg, key, tmp) {
+ eval: function evalstr(arg, key, tmp) {
let cache = this.context.cache.eval;
let context = this.context.cache.evalContext;
diff --git a/common/content/liberator-overlay.js b/common/content/liberator-overlay.js
index ae32b8a2..e9461df4 100644
--- a/common/content/liberator-overlay.js
+++ b/common/content/liberator-overlay.js
@@ -2,6 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
(function () {
const modules = {};
diff --git a/common/content/liberator.js b/common/content/liberator.js
index 86d6e108..02878811 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -4,7 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
diff --git a/common/content/mappings.js b/common/content/mappings.js
index 7d1fa3fa..5e02bba5 100644
--- a/common/content/mappings.js
+++ b/common/content/mappings.js
@@ -4,7 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
diff --git a/common/content/marks.js b/common/content/marks.js
index 44aadbc8..d6c7b908 100644
--- a/common/content/marks.js
+++ b/common/content/marks.js
@@ -4,6 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
/**
* @scope modules
diff --git a/common/content/modes.js b/common/content/modes.js
index 5a4948fc..16d660b5 100644
--- a/common/content/modes.js
+++ b/common/content/modes.js
@@ -4,6 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
/** @scope modules */
diff --git a/common/content/modules.js b/common/content/modules.js
index e3c8b5eb..bc934815 100644
--- a/common/content/modules.js
+++ b/common/content/modules.js
@@ -2,6 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
/**
* @class ModuleBase
diff --git a/common/content/options.js b/common/content/options.js
index f34a721e..59070bb6 100644
--- a/common/content/options.js
+++ b/common/content/options.js
@@ -4,6 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
/** @scope modules */
diff --git a/common/content/quickmarks.js b/common/content/quickmarks.js
index 20cb8b33..3c02dfd5 100644
--- a/common/content/quickmarks.js
+++ b/common/content/quickmarks.js
@@ -4,6 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
/** @scope modules */
diff --git a/common/content/sanitizer.js b/common/content/sanitizer.js
index 146f6fa4..85b8c4ea 100644
--- a/common/content/sanitizer.js
+++ b/common/content/sanitizer.js
@@ -2,6 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
// TODO:
// - fix Sanitize autocommand
diff --git a/common/content/services.js b/common/content/services.js
index 29a76e80..3311bf4c 100644
--- a/common/content/services.js
+++ b/common/content/services.js
@@ -2,6 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
/** @scope modules */
diff --git a/common/content/statusline.js b/common/content/statusline.js
index 57baac40..7b619beb 100644
--- a/common/content/statusline.js
+++ b/common/content/statusline.js
@@ -4,6 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
/** @scope modules */
diff --git a/common/content/style.js b/common/content/style.js
index dc206c5f..155416ab 100644
--- a/common/content/style.js
+++ b/common/content/style.js
@@ -2,6 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
/** @scope modules */
diff --git a/common/content/tabs.js b/common/content/tabs.js
index 8373b858..12bc8399 100644
--- a/common/content/tabs.js
+++ b/common/content/tabs.js
@@ -4,7 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
diff --git a/common/content/template.js b/common/content/template.js
index 7f8a1f09..c6e822f5 100644
--- a/common/content/template.js
+++ b/common/content/template.js
@@ -2,7 +2,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-
+"use strict";
/** @scope modules */
diff --git a/common/content/util.js b/common/content/util.js
index 6f8857be..07dfc162 100644
--- a/common/content/util.js
+++ b/common/content/util.js
@@ -4,6 +4,7 @@
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
+"use strict";
/** @scope modules */
@@ -267,8 +268,9 @@ const Util = Module("util", {
const PATH = FILE.leafName.replace(/\..*/, "") + "/";
const TIME = Date.now();
+ liberator.initHelp();
let zip = services.create("zipWriter");
- zip.open(FILE, io.MODE_CREATE | io.MODE_WRONLY | io.MODE_TRUNCATE);
+ zip.open(FILE, File.MODE_CREATE | File.MODE_WRONLY | File.MODE_TRUNCATE);
function addURIEntry(file, uri)
zip.addEntryChannel(PATH + file, TIME, 9,
services.get("io").newChannel(uri, null, null), false);
diff --git a/common/modules/storage.jsm b/common/modules/storage.jsm
index 287c6189..264ce186 100644
--- a/common/modules/storage.jsm
+++ b/common/modules/storage.jsm
@@ -19,6 +19,7 @@
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
}}} ***** END LICENSE BLOCK *****/
+"use strict";
var EXPORTED_SYMBOLS = ["storage", "Timer"];
diff --git a/vimperator/components/about-handler.js b/vimperator/components/about-handler.js
index 25dbd492..fc82098a 100644
--- a/vimperator/components/about-handler.js
+++ b/vimperator/components/about-handler.js
@@ -1,4 +1,5 @@
// Header:
+"use strict";
const Name = "Vimperator";
/*
* We can't load our modules here, so the following code is sadly
diff --git a/vimperator/components/commandline-handler.js b/vimperator/components/commandline-handler.js
index 8c23f36d..7d8501ad 100644
--- a/vimperator/components/commandline-handler.js
+++ b/vimperator/components/commandline-handler.js
@@ -1,4 +1,5 @@
// Header:
+"use strict";
const Name = "Vimperator";
/*
* We can't load our modules here, so the following code is sadly
From cb4cc8727249405f4cea09ed153454680b6a4e91 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Sun, 15 Aug 2010 08:57:18 -0400
Subject: [PATCH 24/27] Fix xmlToDom in Gecko 2.
--HG--
branch : testing
---
common/content/util.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/content/util.js b/common/content/util.js
index 07dfc162..41c512cd 100644
--- a/common/content/util.js
+++ b/common/content/util.js
@@ -708,7 +708,7 @@ const Util = Module("util", {
}
switch (node.nodeKind()) {
case "text":
- return doc.createTextNode(node);
+ return doc.createTextNode(String(node));
case "element":
let domnode = doc.createElementNS(node.namespace(), node.localName());
for each (let attr in node.@*)
From a0cb07e7d737907d934a63b38703525f1c8b8b73 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Thu, 26 Aug 2010 11:40:59 -0400
Subject: [PATCH 25/27] Some smallish fixes.
--HG--
branch : testing
---
common/components/protocols.js | 2 +-
common/content/buffer.js | 10 ++---
common/content/commandline.js | 4 +-
common/content/completion.js | 2 +-
common/content/events.js | 6 ++-
common/content/hints.js | 10 ++---
common/content/javascript.js | 23 +++++-----
common/content/liberator.js | 18 +++-----
common/content/style.js | 6 +--
common/content/util.js | 68 +++++++++++++++++++++++++++++-
common/modules/storage.jsm | 4 +-
vimperator/chrome.manifest | 11 +++--
vimperator/content/config.js | 77 ++++++++++++++++++----------------
13 files changed, 152 insertions(+), 89 deletions(-)
diff --git a/common/components/protocols.js b/common/components/protocols.js
index 29cff951..fd6378d1 100644
--- a/common/components/protocols.js
+++ b/common/components/protocols.js
@@ -27,7 +27,7 @@ let channel = Components.classesByID["{61ba33c0-3031-11d3-8cd0-0060b0fc14a3}"]
.QueryInterface(Ci.nsIRequest);
const systemPrincipal = channel.owner;
channel.cancel(NS_BINDING_ABORTED);
-delete channel;
+channel = null;
function dataURL(type, data) "data:" + (type || "application/xml;encoding=UTF-8") + "," + escape(data);
function makeChannel(url, orig) {
diff --git a/common/content/buffer.js b/common/content/buffer.js
index 7bceb5f1..a656ff6f 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -1148,8 +1148,8 @@ const Buffer = Module("buffer", {
},
{
argCount: "?",
- literal: 0,
- bang: true
+ bang: true,
+ literal: 0
});
commands.add(["pa[geinfo]"],
@@ -1188,8 +1188,8 @@ const Buffer = Module("buffer", {
"Reload the current web page",
function (args) { tabs.reload(config.browser.mCurrentTab, args.bang); },
{
- bang: true,
- argCount: "0"
+ argCount: "0",
+ bang: true
});
// TODO: we're prompted if download.useDownloadDir isn't set and no arg specified - intentional?
@@ -1483,7 +1483,7 @@ const Buffer = Module("buffer", {
let xpath = ["input", "textarea[not(@disabled) and not(@readonly)]"];
let elements = [m for (m in util.evaluateXPath(xpath))].filter(function (elem) {
- if (elem.readOnly || elem instanceof HTMLInputElement && ["text", "password", "file"].indexOf(elem.type) < 0)
+ if (elem.readOnly || elem instanceof HTMLInputElement && ["file", "search", "text", "password"].indexOf(elem.type) < 0)
return false;
let computedStyle = util.computedStyle(elem);
return computedStyle.visibility != "hidden" && computedStyle.display != "none";
diff --git a/common/content/commandline.js b/common/content/commandline.js
index f0e057c9..e4c29de2 100644
--- a/common/content/commandline.js
+++ b/common/content/commandline.js
@@ -762,12 +762,12 @@ const CommandLine = Module("commandline", {
case "":
case "":
case "":
- openLink(liberator.NEW_BACKGROUND_TAB);
+ openLink({ where: liberator.NEW_TAB, background: true });
break;
case "":
case "":
case "":
- openLink(liberator.NEW_TAB);
+ openLink({ where: liberator.NEW_TAB, background: false });
break;
case "":
openLink(liberator.NEW_WINDOW);
diff --git a/common/content/completion.js b/common/content/completion.js
index bccd4052..e838734f 100644
--- a/common/content/completion.js
+++ b/common/content/completion.js
@@ -251,7 +251,7 @@ const CompletionContext = Class("CompletionContext", {
get completions() this._completions || [],
set completions(items) {
// Accept a generator
- if ({}.toString.call(items) != '[object Array]')
+ if (!isarray(items))
items = [x for (x in Iterator(items))];
delete this.cache.filtered;
delete this.cache.filter;
diff --git a/common/content/events.js b/common/content/events.js
index dbfe3c90..a22785eb 100644
--- a/common/content/events.js
+++ b/common/content/events.js
@@ -671,7 +671,7 @@ const Events = Module("events", {
if (elem && elem.readOnly)
return;
- if ((elem instanceof HTMLInputElement && /^(text|password)$/.test(elem.type)) ||
+ if ((elem instanceof HTMLInputElement && /^(search|text|password)$/.test(elem.type)) ||
(elem instanceof HTMLSelectElement)) {
liberator.mode = modes.INSERT;
if (hasHTMLDocument(win))
@@ -1022,7 +1022,9 @@ const Events = Module("events", {
if (liberator.mode == modes.COMMAND_LINE) {
if (!(modes.extended & modes.INPUT_MULTILINE))
- commandline.onEvent(event); // reroute event in command line mode
+ liberator.trapErrors(function () {
+ commandline.onEvent(event); // reroute event in command line mode
+ });
}
else if (!modes.mainMode.input)
liberator.beep();
diff --git a/common/content/hints.js b/common/content/hints.js
index 977765a9..ed4b4e9c 100644
--- a/common/content/hints.js
+++ b/common/content/hints.js
@@ -42,7 +42,7 @@ const Hints = Module("hints", {
"?": Mode("Show information for hint", function (elem) buffer.showElementInfo(elem), extended),
s: Mode("Save hint", function (elem) buffer.saveLink(elem, true)),
a: Mode("Save hint with prompt", function (elem) buffer.saveLink(elem, false)),
- f: Mode("Focus frame", function (elem) elem.ownerDocument.defaultView.focus(), function () util.makeXPath(["body"])),
+ f: Mode("Focus frame", function (elem) elem.ownerDocument.defaultView.focus(), function () ["body"]),
o: Mode("Follow hint", function (elem) buffer.followLink(elem, liberator.CURRENT_TAB)),
t: Mode("Follow hint in a new tab", function (elem) buffer.followLink(elem, liberator.NEW_TAB)),
b: Mode("Follow hint in a background tab", function (elem) buffer.followLink(elem, liberator.NEW_BACKGROUND_TAB)),
@@ -353,7 +353,7 @@ const Hints = Module("hints", {
if (hint.text == "" && hint.elem.firstChild && hint.elem.firstChild instanceof HTMLImageElement) {
if (!hint.imgSpan) {
- rect = hint.elem.firstChild.getBoundingClientRect();
+ var rect = hint.elem.firstChild.getBoundingClientRect();
if (!rect)
continue;
@@ -381,7 +381,7 @@ const Hints = Module("hints", {
let css = [];
// FIXME: Broken for imgspans.
for (let [, { doc: doc }] in Iterator(this._docs)) {
- for (let elem in util.evaluateXPath(" {//*[@liberator:highlight and @number]", doc)) {
+ for (let elem in util.evaluateXPath("//*[@liberator:highlight and @number]", doc)) {
let group = elem.getAttributeNS(NS.uri, "highlight");
css.push(highlight.selector(group) + "[number=" + elem.getAttribute("number").quote() + "] { " + elem.style.cssText + " }");
}
@@ -1041,8 +1041,8 @@ const Hints = Module("hints", {
},
options: function () {
const DEFAULT_HINTTAGS =
- util.makeXPath(["input[not(@type='hidden')]", "a", "area", "iframe", "textarea", "button", "select"])
- + " | //*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @role='link']";
+ util.makeXPath(["input[not(@type='hidden')]", "a", "area", "iframe", "textarea", "button", "select",
+ "*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @role='link']"]);
function checkXPath(val) {
try {
diff --git a/common/content/javascript.js b/common/content/javascript.js
index 4880e6d0..a5f0f6ce 100644
--- a/common/content/javascript.js
+++ b/common/content/javascript.js
@@ -34,6 +34,7 @@ const JavaScript = Module("javascript", {
},
iter: function iter(obj, toplevel) {
+ "use strict";
toplevel = !!toplevel;
let seen = {};
let ret = {};
@@ -45,9 +46,6 @@ const JavaScript = Module("javascript", {
let orig = obj;
let top = services.get("debugger").wrapValue(obj);
- if (!toplevel)
- obj = obj.__proto__;
-
for (; obj; obj = !toplevel && obj.__proto__) {
services.get("debugger").wrapValue(obj).getProperties(ret, {});
for (let prop in values(ret.value)) {
@@ -55,20 +53,21 @@ const JavaScript = Module("javascript", {
if (name in seen)
continue;
seen[name] = 1;
- yield [prop.name.stringValue, top.getProperty(prop.name.stringValue).value.getWrappedValue()]
+ if (toplevel || obj !== orig)
+ yield [prop.name.stringValue, top.getProperty(prop.name.stringValue).value.getWrappedValue()]
}
}
// The debugger doesn't list some properties. I can't guess why.
+ // This only lists ENUMERABLE properties.
for (let k in orig)
if (k in orig && !('|' + k in seen)
- && callable(orig.hasOwnProperty)
- && orig.hasOwnProperty(k) == toplevel)
+ && Object.hasOwnProperty(orig, k) == toplevel)
yield [k, this.getKey(orig, k)]
}
else {
- for (k in allkeys(obj))
+ for (let k in allkeys(obj))
try {
- if (obj.hasOwnProperty(k) == toplevel)
+ if (Object.hasOwnProperty(obj, k) == toplevel)
yield [k, this.getKey(obj, k)];
}
catch (e) {}
@@ -508,15 +507,15 @@ const JavaScript = Module("javascript", {
// Split up the arguments
let prev = this._get(-2).offset;
let args = [];
- for (let [, idx] in Iterator(this._get(-2).comma)) {
+ for (let [i, idx] in Iterator(this._get(-2).comma)) {
let arg = this._str.substring(prev + 1, idx);
prev = idx;
- util.memoize(args, this._i, function () self.eval(arg));
+ util.memoize(args, i, function () self.eval(arg));
}
let key = this._getKey();
args.push(key + string);
- compl = function (context, obj) {
+ let compl = function (context, obj) {
let res = completer.call(self, context, func, obj, args);
if (res)
context.completions = res;
@@ -600,7 +599,7 @@ const JavaScript = Module("javascript", {
let completer = completers[args.length - 1];
if (!completer)
return [];
- return completer.call(this, context, obj, args);
+ return completer.call(obj, context, obj, args);
};
}
}
diff --git a/common/content/liberator.js b/common/content/liberator.js
index 02878811..8214b461 100644
--- a/common/content/liberator.js
+++ b/common/content/liberator.js
@@ -1320,17 +1320,8 @@ const Liberator = Module("liberator", {
let arg = args[0];
try {
- // TODO: why are these sorts of properties arrays? --djk
- let dialogs = config.dialogs;
-
- for (let [, dialog] in Iterator(dialogs)) {
- if (util.compareIgnoreCase(arg, dialog[0]) == 0) {
- dialog[2]();
- return;
- }
- }
-
- liberator.echoerr("E475: Invalid argument: " + arg);
+ liberator.assert(args[0] in config.dialogs, "E475: Invalid argument: " + arg);
+ config.dialogs[args[0]][1]();
}
catch (e) {
liberator.echoerr("Error opening " + arg.quote() + ": " + e);
@@ -1540,12 +1531,13 @@ const Liberator = Module("liberator", {
});
// TODO: maybe indicate pending status too?
- commands.add(["extens[ions]"],
+ commands.add(["extens[ions]", "exts"],
"List available extensions",
function (args) {
AddonManager.getAddonsByTypes(["extension"], function (extensions) {
if (args[0])
extensions = extensions.filter(function (extension) extension.name.indexOf(args[0]) >= 0);
+ extensions.sort(function (a, b) String.localeCompare(a.name, b.name));
if (extensions.length > 0) {
let list = template.tabular(
@@ -1832,7 +1824,7 @@ const Liberator = Module("liberator", {
completion: function () {
completion.dialog = function dialog(context) {
context.title = ["Dialog"];
- context.completions = config.dialogs;
+ context.completions = [[k, v[0]] for ([k, v] in Iterator(config.dialogs))];
};
completion.extension = function extension(context) {
diff --git a/common/content/style.js b/common/content/style.js
index 155416ab..3fc6824a 100644
--- a/common/content/style.js
+++ b/common/content/style.js
@@ -702,10 +702,10 @@ Module("styles", {
JavaScript.setCompleter(["get", "addSheet", "removeSheet", "findSheets"].map(function (m) styles[m]),
[ // Prototype: (system, name, filter, css, index)
null,
- function (context, obj, args) args[0] ? styles.systemNames : styles.userNames,
- function (context, obj, args) styles.completeSite(context, content),
+ function (context, obj, args) args[0] ? this.systemNames : this.userNames,
+ function (context, obj, args) this.completeSite(context, content),
null,
- function (context, obj, args) args[0] ? styles.systemSheets : styles.userSheets
+ function (context, obj, args) args[0] ? this.systemSheets : this.userSheets
]);
}
});
diff --git a/common/content/util.js b/common/content/util.js
index 41c512cd..97e3e888 100644
--- a/common/content/util.js
+++ b/common/content/util.js
@@ -102,6 +102,55 @@ const Util = Module("util", {
return fixup.createFixupURI(str, fixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP);
},
+ /**
+ * Expands brace globbing patterns in a string.
+ *
+ * Example:
+ * "a{b,c}d" => ["abd", "acd"]
+ *
+ * @param {string} pattern The pattern to deglob.
+ * @returns [string] The resulting strings.
+ */
+ debrace: function deglobBrace(pattern) {
+ function split(pattern, re, fn, dequote) {
+ let end = 0, match, res = [];
+ while (match = re.exec(pattern)) {
+ end = match.index + match[0].length;
+ res.push(match[1]);
+ if (fn)
+ fn(match);
+ }
+ res.push(pattern.substr(end));
+ return res.map(function (s) util.dequote(s, dequote));
+ }
+ let patterns = [], res = [];
+ let substrings = split(pattern, /((?:[^\\{]|\\.)*)\{((?:[^\\}]|\\.)*)\}/gy,
+ function (match) {
+ patterns.push(split(match[2], /((?:[^\\,]|\\.)*),/gy,
+ null, ",{}"));
+ }, "{}");
+ function rec(acc) {
+ if (acc.length == patterns.length)
+ res.push(util.Array.zip(substrings, acc).join(""));
+ else
+ for (let [, pattern] in Iterator(patterns[acc.length]))
+ rec(acc.concat(pattern));
+ }
+ rec([]);
+ return res;
+ },
+
+ /**
+ * Removes certain backslash-quoted characters while leaving other
+ * backslash-quoting sequences untouched.
+ *
+ * @param {string} pattern The string to unquote.
+ * @param {string} chars The characters to unquote.
+ * @returns {string}
+ */
+ dequote: function dequote(pattern, chars)
+ pattern.replace(/\\(.)/, function (m0, m1) chars.indexOf(m1) >= 0 ? m1 : m0),
+
/**
* Converts HTML special characters in str to the equivalent HTML
* entities.
@@ -169,7 +218,8 @@ const Util = Module("util", {
* @returns {string}
*/
makeXPath: function makeXPath(nodes) {
- return util.Array(nodes).map(function (node) [node, "xhtml:" + node]).flatten()
+ return util.Array(nodes).map(util.debrace).flatten()
+ .map(function (node) [node, "xhtml:" + node]).flatten()
.map(function (node) "//" + node).join(" | ");
},
@@ -832,6 +882,22 @@ const Util = Module("util", {
}
}
return ret;
+ },
+
+ /**
+ * Zips the contents of two arrays. The resulting array is twice the
+ * length of ary1, with any shortcomings of ary2 replaced with null
+ * strings.
+ *
+ * @param {Array} ary1
+ * @param {Array} ary2
+ * @returns {Array}
+ */
+ zip: function zip(ary1, ary2) {
+ let res = []
+ for(let [i, item] in Iterator(ary1))
+ res.push(item, i in ary2 ? ary2[i] : "");
+ return res;
}
})
});
diff --git a/common/modules/storage.jsm b/common/modules/storage.jsm
index 264ce186..d749ecbf 100644
--- a/common/modules/storage.jsm
+++ b/common/modules/storage.jsm
@@ -103,12 +103,12 @@ function readFile(file) {
function writeFile(file, data) {
if (!file.exists())
- file.create(file.NORMAL_FILE_TYPE, 0600);
+ file.create(file.NORMAL_FILE_TYPE, parseInt('0600', 8));
let fileStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
let stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
- fileStream.init(file, 0x20 | 0x08 | 0x02, 0600, 0); // PR_TRUNCATE | PR_CREATE | PR_WRITE
+ fileStream.init(file, 0x20 | 0x08 | 0x02, parseInt('0600', 8), 0); // PR_TRUNCATE | PR_CREATE | PR_WRITE
stream.init(fileStream, "UTF-8", 0, 0);
stream.writeString(data);
diff --git a/vimperator/chrome.manifest b/vimperator/chrome.manifest
index 4890933b..276496d7 100644
--- a/vimperator/chrome.manifest
+++ b/vimperator/chrome.manifest
@@ -1,26 +1,25 @@
# Firefox
content vimperator content/
skin vimperator classic/1.0 skin/
-locale vimperator en-US locale/en-US/
-locale liberator en-US ../common/locale/en-US/
+locale vimperator en-US locale/en-US/
+locale liberator en-US ../common/locale/en-US/
content liberator ../common/content/
resource liberator ../common/modules/
skin liberator classic/1.0 ../common/skin/
-override chrome://liberator/content/liberator.dtd chrome://vimperator/content/liberator.dtd
-override chrome://liberator/content/config.js chrome://vimperator/content/config.js
+override chrome://liberator/content/liberator.dtd chrome://vimperator/content/liberator.dtd
+override chrome://liberator/content/config.js chrome://vimperator/content/config.js
overlay chrome://browser/content/browser.xul chrome://liberator/content/liberator.xul
overlay chrome://browser/content/browser.xul chrome://vimperator/content/vimperator.xul
-component components/
-
component {81495d80-89ee-4c36-a88d-ea7c4e5ac63f} components/about-handler.js
contract @mozilla.org/network/protocol/about;1?what=vimperator {81495d80-89ee-4c36-a88d-ea7c4e5ac63f}
component {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69} components/commandline-handler.js
contract @mozilla.org/commandlinehandler/general-startup;1?type=vimperator {16dc34f7-6d22-4aa4-a67f-2921fb5dcb69}
+category command-line-handler m-vimperator @mozilla.org/commandlinehandler/general-startup;1?type=vimperator
component {c1b67a07-18f7-4e13-b361-2edcc35a5a0d} components/protocols.js
contract @mozilla.org/network/protocol;1?name=chrome-data {c1b67a07-18f7-4e13-b361-2edcc35a5a0d}
diff --git a/vimperator/content/config.js b/vimperator/content/config.js
index 6988d5a6..29446ee4 100644
--- a/vimperator/content/config.js
+++ b/vimperator/content/config.js
@@ -46,58 +46,58 @@ const Config = Module("config", ConfigBase, {
["VimperatorLeavePre", "Triggered before exiting Firefox, just before destroying each module"],
["VimperatorLeave", "Triggered before exiting Firefox"]],
- dialogs: [
- ["about", "About Firefox",
+ dialogs: {
+ about: ["About Firefox",
function () { window.openDialog("chrome://browser/content/aboutDialog.xul", "_blank", "chrome,dialog,modal,centerscreen"); }],
- ["addbookmark", "Add bookmark for the current page",
+ addbookmark: ["Add bookmark for the current page",
function () { PlacesCommandHook.bookmarkCurrentPage(true, PlacesUtils.bookmarksRootId); }],
- ["addons", "Manage Add-ons",
+ addons: ["Manage Add-ons",
function () { window.BrowserOpenAddonsMgr(); }],
- ["bookmarks", "List your bookmarks",
+ bookmarks: ["List your bookmarks",
function () { window.openDialog("chrome://browser/content/bookmarks/bookmarksPanel.xul", "Bookmarks", "dialog,centerscreen,width=600,height=600"); }],
- ["checkupdates", "Check for updates",
+ checkupdates: ["Check for updates",
function () { window.checkForUpdates(); }],
- ["cleardata", "Clear private data",
+ cleardata: ["Clear private data",
function () { Cc[GLUE_CID].getService(Ci.nsIBrowserGlue).sanitize(window || null); }],
- ["cookies", "List your cookies",
+ cookies: ["List your cookies",
function () { window.toOpenWindowByType("Browser:Cookies", "chrome://browser/content/preferences/cookies.xul", "chrome,dialog=no,resizable"); }],
- ["console", "JavaScript console",
+ console: ["JavaScript console",
function () { window.toJavaScriptConsole(); }],
- ["customizetoolbar", "Customize the Toolbar",
+ customizetoolbar: ["Customize the Toolbar",
function () { window.BrowserCustomizeToolbar(); }],
- ["dominspector", "DOM Inspector",
+ dominspector: ["DOM Inspector",
function () { try { window.inspectDOMDocument(content.document); } catch (e) { liberator.echoerr("DOM Inspector extension not installed"); } }],
- ["downloads", "Manage Downloads",
+ downloads: ["Manage Downloads",
function () { window.toOpenWindowByType("Download:Manager", "chrome://mozapps/content/downloads/downloads.xul", "chrome,dialog=no,resizable"); }],
- ["history", "List your history",
+ history: ["List your history",
function () { window.openDialog("chrome://browser/content/history/history-panel.xul", "History", "dialog,centerscreen,width=600,height=600"); }],
- ["import", "Import Preferences, Bookmarks, History, etc. from other browsers",
+ import: ["Import Preferences, Bookmarks, History, etc. from other browsers",
function () { window.BrowserImport(); }],
- ["openfile", "Open the file selector dialog",
+ openfile: ["Open the file selector dialog",
function () { window.BrowserOpenFileWindow(); }],
- ["pageinfo", "Show information about the current page",
+ pageinfo: ["Show information about the current page",
function () { window.BrowserPageInfo(); }],
- ["pagesource", "View page source",
+ pagesource: ["View page source",
function () { window.BrowserViewSourceOfDocument(content.document); }],
- ["places", "Places Organizer: Manage your bookmarks and history",
+ places: ["Places Organizer: Manage your bookmarks and history",
function () { PlacesCommandHook.showPlacesOrganizer(ORGANIZER_ROOT_BOOKMARKS); }],
- ["preferences", "Show Firefox preferences dialog",
+ preferences: ["Show Firefox preferences dialog",
function () { window.openPreferences(); }],
- ["printpreview", "Preview the page before printing",
+ printpreview: ["Preview the page before printing",
function () { PrintUtils.printPreview(onEnterPrintPreview, onExitPrintPreview); }],
- ["printsetup", "Setup the page size and orientation before printing",
+ printsetup: ["Setup the page size and orientation before printing",
function () { PrintUtils.showPageSetup(); }],
- ["print", "Show print dialog",
+ print: ["Show print dialog",
function () { PrintUtils.print(); }],
- ["saveframe", "Save frame to disk",
+ saveframe: ["Save frame to disk",
function () { window.saveFrameDocument(); }],
- ["savepage", "Save page to disk",
+ savepage: ["Save page to disk",
function () { window.saveDocument(window.content.document); }],
- ["searchengines", "Manage installed search engines",
+ searchengines: ["Manage installed search engines",
function () { window.openDialog("chrome://browser/content/search/engineManager.xul", "_blank", "chrome,dialog,modal,centerscreen"); }],
- ["selectionsource", "View selection source",
+ selectionsource: ["View selection source",
function () { buffer.viewSelectionSource(); }]
- ],
+ },
hasTabbrowser: true,
@@ -232,13 +232,20 @@ const Config = Module("config", ConfigBase, {
return;
context.anchored = false;
- context.title = ["Smart Completions"];
- context.keys.icon = 2;
- context.incomplete = true;
- context.hasItems = context.completions.length > 0; // XXX
- context.filterFunc = null;
- context.cancel = function () { if (searchRunning) { services.get("autoCompleteSearch").stopSearch(); searchRunning = false; } };
context.compare = CompletionContext.Sort.unsorted;
+ context.filterFunc = null;
+ context.hasItems = context.completions.length > 0; // XXX
+ context.incomplete = true;
+ context.keys.icon = 2;
+ context.title = ["Smart Completions"];
+ context.cancel = function () {
+ if (searchRunning) {
+ services.get("autoCompleteSearch").stopSearch();
+ searchRunning = false;
+ }
+ };
+ if (searchRunning)
+ services.get("autoCompleteSearch").stopSearch();
let timer = new Timer(50, 100, function (result) {
context.incomplete = result.searchResult >= result.RESULT_NOMATCH_ONGOING;
context.completions = [
@@ -246,9 +253,6 @@ const Config = Module("config", ConfigBase, {
for (i in util.range(0, result.matchCount))
];
});
- if (searchRunning)
- services.get("autoCompleteSearch").stopSearch();
- searchRunning = true;
services.get("autoCompleteSearch").startSearch(context.filter, "", context.result, {
onSearchResult: function onSearchResult(search, result) {
timer.tell(result);
@@ -258,6 +262,7 @@ const Config = Module("config", ConfigBase, {
}
}
});
+ searchRunning = true;
};
completion.sidebar = function sidebar(context) {
From 89633538c811f0187ff235d0408c00f9afaf4d77 Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Thu, 26 Aug 2010 12:19:21 -0400
Subject: [PATCH 26/27] Fix some finder quirks.
--HG--
branch : testing
---
common/content/finder.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/common/content/finder.js b/common/content/finder.js
index 71283c2c..b8bad27e 100644
--- a/common/content/finder.js
+++ b/common/content/finder.js
@@ -18,6 +18,7 @@ const RangeFinder = Module("rangefinder", {
let backwards = mode == modes.FIND_BACKWARD;
commandline.open(backwards ? "?" : "/", "", mode);
+ this.rangeFind = null;
this.find("", backwards);
},
From 2375a00fb41455a8581b6e8cad45414829eb714f Mon Sep 17 00:00:00 2001
From: Kris Maglione
Date: Thu, 26 Aug 2010 13:26:34 -0400
Subject: [PATCH 27/27] Replace 'focuscontent' with 'strictfocus'.
--HG--
branch : testing
---
.hgignore | 2 +
common/content/autocommands.js | 6 +-
common/content/buffer.js | 31 ++--
common/content/events.js | 250 +++++++++++++++++---------------
common/content/javascript.js | 11 +-
common/locale/en-US/gui.xml | 3 +-
common/locale/en-US/index.xml | 2 +-
common/locale/en-US/options.xml | 15 +-
vimperator/NEWS | 20 +--
9 files changed, 183 insertions(+), 157 deletions(-)
diff --git a/.hgignore b/.hgignore
index 40d211a3..93349ece 100644
--- a/.hgignore
+++ b/.hgignore
@@ -11,6 +11,8 @@ syntax: glob
*/locale/*/*.html
*/chrome
*/contrib/vim/*.vba
+*/bak/*
+downloads/*
## Editor backup and swap files
*~
diff --git a/common/content/autocommands.js b/common/content/autocommands.js
index 36750b75..a273b16b 100644
--- a/common/content/autocommands.js
+++ b/common/content/autocommands.js
@@ -271,9 +271,9 @@ const AutoCommands = Module("autocommands", {
completer: function () config.autocommands.concat([["all", "All events"]])
});
- options.add(["focuscontent", "fc"],
- "Try to stay in normal mode after loading a web page",
- "boolean", false);
+ options.add(["strictfocus", "sf"],
+ "Prevent scripts from focusing input elements without user intervention",
+ "boolean", true);
}
});
diff --git a/common/content/buffer.js b/common/content/buffer.js
index a656ff6f..be2362bf 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -200,19 +200,7 @@ const Buffer = Module("buffer", {
// any buffer, even in a background tab
doc.pageIsFullyLoaded = 1;
- // code which is only relevant if the page load is the current tab goes here:
- if (doc == config.browser.contentDocument) {
- // we want to stay in command mode after a page has loaded
- // TODO: move somewhere else, as focusing can already happen earlier than on "load"
- if (options["focuscontent"]) {
- setTimeout(function () {
- let focused = liberator.focus;
- if (focused && (focused.value != null) && focused.value.length == 0)
- focused.blur();
- }, 0);
- }
- }
- else // background tab
+ if (doc != config.browser.contentDocument)
liberator.echomsg("Background tab loaded: " + doc.title || doc.location.href, 3);
this._triggerLoadAutocmd("PageLoad", doc);
@@ -474,6 +462,18 @@ const Buffer = Module("buffer", {
return String(selection);
},
+ /**
+ * Returns true if a scripts are allowed to focus the given input
+ * element or input elements in the given window.
+ *
+ * @param {Node|Window}
+ * @returns {boolean}
+ */
+ focusAllowed: function (elem) {
+ let win = elem.ownerDocument && elem.ownerDocument.defaultView || elem;
+ return !options["strictfocus"] || elem.liberatorFocusAllowed;
+ },
+
/**
* Focuses the given element. In contrast to a simple
* elem.focus() call, this function works for iframes and
@@ -483,7 +483,10 @@ const Buffer = Module("buffer", {
*/
focusElement: function (elem) {
let doc = window.content.document;
- if (elem instanceof HTMLFrameElement || elem instanceof HTMLIFrameElement)
+ let win = elem.ownerDocument && elem.ownerDocument.defaultView || elem;
+ win.liberatorFocusAllowed = true;
+
+ if (isinstance(elem, [HTMLFrameElement, HTMLIFrameElement]))
elem.contentWindow.focus();
else if (elem instanceof HTMLInputElement && elem.type == "file") {
Buffer.openUploadPrompt(elem);
diff --git a/common/content/events.js b/common/content/events.js
index a22785eb..4ec214d2 100644
--- a/common/content/events.js
+++ b/common/content/events.js
@@ -103,32 +103,16 @@ const Events = Module("events", {
}
}, 100);
- function wrapListener(method) {
- return function (event) {
- try {
- self[method](event);
- }
- catch (e) {
- if (e.message == "Interrupted")
- liberator.echoerr("Interrupted");
- else
- liberator.echoerr("Processing " + event.type + " event: " + (e.echoerr || e));
- liberator.reportError(e);
- }
- };
- }
-
- this._wrappedOnKeyPress = wrapListener("onKeyPress");
- this._wrappedOnKeyUpOrDown = wrapListener("onKeyUpOrDown");
- this.addSessionListener(window, "keypress", this.closure._wrappedOnKeyPress, true);
- this.addSessionListener(window, "keydown", this.closure._wrappedOnKeyUpOrDown, true);
- this.addSessionListener(window, "keyup", this.closure._wrappedOnKeyUpOrDown, true);
-
this._activeMenubar = false;
- this.addSessionListener(window, "popupshown", this.closure.onPopupShown, true);
- this.addSessionListener(window, "popuphidden", this.closure.onPopupHidden, true);
this.addSessionListener(window, "DOMMenuBarActive", this.closure.onDOMMenuBarActive, true);
this.addSessionListener(window, "DOMMenuBarInactive", this.closure.onDOMMenuBarInactive, true);
+ this.addSessionListener(window, "focus", this.wrapListener(this.closure.onFocus), true);
+ this.addSessionListener(window, "keydown", this.wrapListener(this.closure.onKeyUpOrDown), true);
+ this.addSessionListener(window, "keypress", this.wrapListener(this.closure.onKeyPress), true);
+ this.addSessionListener(window, "keyup", this.wrapListener(this.closure.onKeyUpOrDown), true);
+ this.addSessionListener(window, "mousedown", this.wrapListener(this.closure.onMouseDown), true);
+ this.addSessionListener(window, "popuphidden", this.closure.onPopupHidden, true);
+ this.addSessionListener(window, "popupshown", this.closure.onPopupShown, true);
this.addSessionListener(window, "resize", this.closure.onResize, true);
},
@@ -151,10 +135,28 @@ const Events = Module("events", {
*/
addSessionListener: function (target, event, callback, capture) {
let args = Array.slice(arguments, 0);
- target.addEventListener.apply(target, args.slice(1));
+ target.addEventListener.apply(args[0], args.slice(1));
this.sessionListeners.push(args);
},
+ /**
+ * Wraps an event listener to ensure that errors are reported.
+ */
+ wrapListener: function wrapListener(method, self) {
+ return function (event) {
+ try {
+ method.apply(self, arguments);
+ }
+ catch (e) {
+ if (e.message == "Interrupted")
+ liberator.echoerr("Interrupted");
+ else
+ liberator.echoerr("Processing " + event.type + " event: " + (e.echoerr || e));
+ liberator.reportError(e);
+ }
+ };
+ },
+
/**
* @property {boolean} Whether synthetic key events are currently being
* processed.
@@ -651,89 +653,14 @@ const Events = Module("events", {
return ret;
},
- // argument "event" is deliberately not used, as i don't seem to have
- // access to the real focus target
- // Huh? --djk
- onFocusChange: function (event) {
- // command line has it's own focus change handler
- if (liberator.mode == modes.COMMAND_LINE)
- return;
-
- function hasHTMLDocument(win) win && win.document && win.document instanceof HTMLDocument
-
- let win = window.document.commandDispatcher.focusedWindow;
- let elem = window.document.commandDispatcher.focusedElement;
-
- if (win && win.top == content && liberator.has("tabs"))
- tabs.localStore.focusedFrame = win;
-
- try {
- if (elem && elem.readOnly)
- return;
-
- if ((elem instanceof HTMLInputElement && /^(search|text|password)$/.test(elem.type)) ||
- (elem instanceof HTMLSelectElement)) {
- liberator.mode = modes.INSERT;
- if (hasHTMLDocument(win))
- buffer.lastInputField = elem;
- return;
- }
- if (elem instanceof HTMLEmbedElement || elem instanceof HTMLObjectElement) {
- liberator.mode = modes.EMBED;
- return;
- }
-
- if (elem instanceof HTMLTextAreaElement || (elem && elem.contentEditable == "true")) {
- if (options["insertmode"])
- modes.set(modes.INSERT);
- else if (elem.selectionEnd - elem.selectionStart > 0)
- modes.set(modes.VISUAL, modes.TEXTAREA);
- else
- modes.main = modes.TEXTAREA;
- if (hasHTMLDocument(win))
- buffer.lastInputField = elem;
- return;
- }
-
- if (config.focusChange) {
- config.focusChange(win);
- return;
- }
-
- let urlbar = document.getElementById("urlbar");
- if (elem == null && urlbar && urlbar.inputField == this._lastFocus)
- liberator.threadYield(true);
-
- if (liberator.mode & (modes.EMBED | modes.INSERT | modes.TEXTAREA | modes.VISUAL))
- modes.reset();
- }
- finally {
- this._lastFocus = elem;
- }
+ onDOMMenuBarActive: function () {
+ this._activeMenubar = true;
+ modes.add(modes.MENU);
},
- onSelectionChange: function (event) {
- let couldCopy = false;
- let controller = document.commandDispatcher.getControllerForCommand("cmd_copy");
- if (controller && controller.isCommandEnabled("cmd_copy"))
- couldCopy = true;
-
- if (liberator.mode != modes.VISUAL) {
- if (couldCopy) {
- if ((liberator.mode == modes.TEXTAREA ||
- (modes.extended & modes.TEXTAREA))
- && !options["insertmode"])
- modes.set(modes.VISUAL, modes.TEXTAREA);
- else if (liberator.mode == modes.CARET)
- modes.set(modes.VISUAL, modes.CARET);
- }
- }
- // XXX: disabled, as i think automatically starting visual caret mode does more harm than help
- // else
- // {
- // if (!couldCopy && modes.extended & modes.CARET)
- // liberator.mode = modes.CARET;
- // }
+ onDOMMenuBarInactive: function () {
+ this._activeMenubar = false;
+ modes.remove(modes.MENU);
},
/**
@@ -808,6 +735,78 @@ const Events = Module("events", {
}
},
+ onFocus: function (event) {
+ function hasHTMLDocument(win) win && win.document && win.document instanceof HTMLDocument
+
+ let elem = event.originalTarget;
+ let win = elem.ownerDocument && elem.ownerDocument.defaultView || elem;
+
+ if (hasHTMLDocument(win) && !buffer.focusAllowed(win))
+ elem.blur();
+ },
+
+ // argument "event" is deliberately not used, as i don't seem to have
+ // access to the real focus target
+ // Huh? --djk
+ onFocusChange: function (event) {
+ // command line has it's own focus change handler
+ if (liberator.mode == modes.COMMAND_LINE)
+ return;
+
+ function hasHTMLDocument(win) win && win.document && win.document instanceof HTMLDocument
+
+ let win = window.document.commandDispatcher.focusedWindow;
+ let elem = window.document.commandDispatcher.focusedElement;
+
+ if (win && win.top == content && liberator.has("tabs"))
+ tabs.localStore.focusedFrame = win;
+
+ try {
+ if (elem && elem.readOnly)
+ return;
+
+ if ((elem instanceof HTMLInputElement && /^(search|text|password)$/.test(elem.type)) ||
+ (elem instanceof HTMLSelectElement)) {
+ liberator.mode = modes.INSERT;
+ if (hasHTMLDocument(win))
+ buffer.lastInputField = elem;
+ return;
+ }
+
+ if(isinstance(elem, [HTMLEmbedElement, HTMLEmbedElement])) {
+ liberator.mode = modes.EMBED;
+ return;
+ }
+
+ if (elem instanceof HTMLTextAreaElement || (elem && elem.contentEditable == "true")) {
+ if (options["insertmode"])
+ modes.set(modes.INSERT);
+ else if (elem.selectionEnd - elem.selectionStart > 0)
+ modes.set(modes.VISUAL, modes.TEXTAREA);
+ else
+ modes.main = modes.TEXTAREA;
+ if (hasHTMLDocument(win))
+ buffer.lastInputField = elem;
+ return;
+ }
+
+ if (config.focusChange) {
+ config.focusChange(win);
+ return;
+ }
+
+ let urlbar = document.getElementById("urlbar");
+ if (elem == null && urlbar && urlbar.inputField == this._lastFocus)
+ liberator.threadYield(true);
+
+ if (liberator.mode & (modes.EMBED | modes.INSERT | modes.TEXTAREA | modes.VISUAL))
+ modes.reset();
+ }
+ finally {
+ this._lastFocus = elem;
+ }
+ },
+
// this keypress handler gets always called first, even if e.g.
// the commandline has focus
// TODO: ...help me...please...
@@ -1052,6 +1051,13 @@ const Events = Module("events", {
event.stopPropagation();
},
+ onMouseDown: function (event) {
+ let elem = event.target;
+ let win = elem.ownerDocument && elem.ownerDocument.defaultView || elem;
+ for(; win; win = win != win.parent && win.parent)
+ win.liberatorFocusAllowed = true;
+ },
+
onPopupShown: function (event) {
if (event.originalTarget.localName == "tooltip" || event.originalTarget.id == "liberator-visualbell")
return;
@@ -1064,22 +1070,36 @@ const Events = Module("events", {
modes.remove(modes.MENU);
},
- onDOMMenuBarActive: function () {
- this._activeMenubar = true;
- modes.add(modes.MENU);
- },
-
- onDOMMenuBarInactive: function () {
- this._activeMenubar = false;
- modes.remove(modes.MENU);
- },
-
onResize: function (event) {
if (window.fullScreen != this._fullscreen) {
this._fullscreen = window.fullScreen;
liberator.triggerObserver("fullscreen", this._fullscreen);
autocommands.trigger("Fullscreen", { state: this._fullscreen });
}
+ },
+
+ onSelectionChange: function (event) {
+ let couldCopy = false;
+ let controller = document.commandDispatcher.getControllerForCommand("cmd_copy");
+ if (controller && controller.isCommandEnabled("cmd_copy"))
+ couldCopy = true;
+
+ if (liberator.mode != modes.VISUAL) {
+ if (couldCopy) {
+ if ((liberator.mode == modes.TEXTAREA ||
+ (modes.extended & modes.TEXTAREA))
+ && !options["insertmode"])
+ modes.set(modes.VISUAL, modes.TEXTAREA);
+ else if (liberator.mode == modes.CARET)
+ modes.set(modes.VISUAL, modes.CARET);
+ }
+ }
+ // XXX: disabled, as i think automatically starting visual caret mode does more harm than help
+ // else
+ // {
+ // if (!couldCopy && modes.extended & modes.CARET)
+ // liberator.mode = modes.CARET;
+ // }
}
}, {
isInputElemFocused: function () {
diff --git a/common/content/javascript.js b/common/content/javascript.js
index a5f0f6ce..1c337424 100644
--- a/common/content/javascript.js
+++ b/common/content/javascript.js
@@ -59,10 +59,13 @@ const JavaScript = Module("javascript", {
}
// The debugger doesn't list some properties. I can't guess why.
// This only lists ENUMERABLE properties.
- for (let k in orig)
- if (k in orig && !('|' + k in seen)
- && Object.hasOwnProperty(orig, k) == toplevel)
- yield [k, this.getKey(orig, k)]
+ try {
+ for (let k in orig)
+ if (k in orig && !('|' + k in seen)
+ && Object.hasOwnProperty(orig, k) == toplevel)
+ yield [k, this.getKey(orig, k)]
+ }
+ catch(e) {}
}
else {
for (let k in allkeys(obj))
diff --git a/common/locale/en-US/gui.xml b/common/locale/en-US/gui.xml
index 2250027a..4affd063 100644
--- a/common/locale/en-US/gui.xml
+++ b/common/locale/en-US/gui.xml
@@ -151,8 +151,9 @@
-
-
:extens :extensions
+ :exts :extens :extensions
:extensions
+ :exts
List all installed extensions.
diff --git a/common/locale/en-US/index.xml b/common/locale/en-US/index.xml
index 2482ad84..0546ff9a 100644
--- a/common/locale/en-US/index.xml
+++ b/common/locale/en-US/index.xml
@@ -393,7 +393,6 @@ This file contains a list of all available commands, mappings and options.
exrc Allow reading of an RC file in the current directory
extendedhinttags XPath string of hintable elements activated by ;
fileencoding Changes the character encoding that &liberator.appname; uses to read and write files
- focuscontent Try to stay in Normal mode after loading a web page
followhints Change the behaviour of in Hints mode
fullscreen Show the current window fullscreen
guioptions Show or hide certain GUI elements like the menu or toolbar
@@ -430,6 +429,7 @@ This file contains a list of all available commands, mappings and options.
showstatuslinks Show the destination of the link under the cursor in the status bar
showtabline Control when to show the tab bar of opened web pages
smartcase Override the ignorecase option if the pattern contains uppercase characters
+ strictfocus Prevent scripts from focusing input elements without user intervention
suggestengines Engine Alias which has a feature of suggest
titlestring Change the title of the window
urlseparator Set the separator regex used to separate multiple URL args
diff --git a/common/locale/en-US/options.xml b/common/locale/en-US/options.xml
index e75c5847..5b7ca1f3 100644
--- a/common/locale/en-US/options.xml
+++ b/common/locale/en-US/options.xml
@@ -519,19 +519,14 @@
-
-
'nofc' 'nofocuscontent'
- 'fc' 'focuscontent'
- 'focuscontent' 'fc'
+ 'nosf' 'nostrictfocus'
+ 'sf' 'strictfocus'
+ 'strictfocus' 'sf'
boolean
- off
+ on
- Focus the content after a page has loaded. This is useful if you
- always want to stay in Normal mode when browsing between web sites.
- When on , it blurs any textbox which often is
- automatically focused on page load. If you usually like
- focuscontent but sometimes you'd like to focus the first
- input field, you can use gi to jump to it.
+ Prevent scripts from focusing input elements without user intervention.
diff --git a/vimperator/NEWS b/vimperator/NEWS
index f55c9bf3..dc078e95 100644
--- a/vimperator/NEWS
+++ b/vimperator/NEWS
@@ -1,11 +1,15 @@
2009-XX-XX:
- * version 2.3a1pre
- * add basic plugin authorship documentation
- * plugins may now provide full-fleged ':help' documentation
- * asciidoc is no longer required to build Vimperator
- * the help system is newly modularized
- * remove [c]:edit[c], [c]:tabedit[c], and [c]:winedit[c]
- * add 'jsdebugger' option - switch on/off javascript debugger service
+ * Replaced 'focuscontent' with 'strictfocus'
+ * Replaced previous incremental search implementation
+ * :open now only opens files begining with / or ./
+ * Page zoom information is now shown in the status bar
+ * Added ZO, ZI, ZM, and ZR as aliases for zO, zI, zM, and zR
+ * Add basic plugin authorship documentation
+ * Plugins may now provide full-fleged ':help' documentation
+ * The help system is newly modularized
+ * Asciidoc is no longer for building
+ * Remove [c]:edit[c], [c]:tabedit[c], and [c]:winedit[c]
+ * Add 'jsdebugger' option - switch on/off javascript debugger service
2009-10-28:
* version 2.2
@@ -26,8 +30,6 @@
...................................
* IMPORTANT: shifted key notation now matches Vim's behaviour. E.g.
and are equivalent, to map the uppercase character use .
- (this might change again, as this is REALLY inconsistent, and i don't
- know if I like copying bugs)
* IMPORTANT: 'popups' now takes a stringlist rather than a number.
* add [c]:winonly[c]