mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-21 13:07:59 +01:00
Merge branch 'master' into vimperator-2.1
Conflicts: common/content/io.js common/content/style.js
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,3 +2,7 @@
|
||||
*/locale/*/*.html
|
||||
*/chrome
|
||||
*~
|
||||
.*.swp
|
||||
.*.swo
|
||||
.swp
|
||||
.DS_Store
|
||||
|
||||
148
HACKING
Normal file
148
HACKING
Normal file
@@ -0,0 +1,148 @@
|
||||
= Hacking =
|
||||
|
||||
If you've taken to hacking Vimperator source code, we hope that you'll share
|
||||
your changes. In case you do, please keep the following in mind, and we'll be
|
||||
happy to accept your patches.
|
||||
|
||||
== Documentation ==
|
||||
|
||||
First of all, all new features and all user-visible changes to existing
|
||||
features need to be documented. That means editing the appropriate help files
|
||||
and adding a NEWS entry where appropriate. When editing the NEWS file, you
|
||||
should add your change to the top of the list of changes. If your change
|
||||
alters an interface (key binding, command) and is likely to cause trouble,
|
||||
prefix it with 'IMPORTANT:', otherwise, place it below the other 'IMPORTANT'
|
||||
entries. If you're not sure if your change merits a news entry, or if it's
|
||||
important, please ask.
|
||||
|
||||
== Coding Style ==
|
||||
|
||||
In general: Just look at the existing source code!
|
||||
We try to be quite consistent, but of course, that's not always possible.
|
||||
|
||||
=== The most important style issues are: ===
|
||||
|
||||
* Use 4 spaces to indent things, no tabs, not 2, nor 8 spaces. If you use Vim,
|
||||
this should be taken care of automatically by the modeline (like the
|
||||
one below).
|
||||
|
||||
* No trailing whitespace.
|
||||
|
||||
* Use " for enclosing strings instead of ', unless using ' avoids escaping of lots of "
|
||||
Example: alert("foo") instead of alert('foo');
|
||||
|
||||
* Exactly one space after if/for/while/catch etc. and after a comma, but none
|
||||
after a parenthesis or after a function call:
|
||||
for (pre; condition; post)
|
||||
but:
|
||||
alert("foo");
|
||||
|
||||
* Opening curly brackets { must be on a new line, unless it is used in a closure:
|
||||
function myFunction ()
|
||||
{
|
||||
if (foo)
|
||||
{
|
||||
baz = false;
|
||||
return bar;
|
||||
}
|
||||
else
|
||||
{
|
||||
return baz;
|
||||
}
|
||||
}
|
||||
but:
|
||||
setTimeout(function () {
|
||||
...
|
||||
});
|
||||
|
||||
* No braces for one-line conditional statements:
|
||||
Right:
|
||||
if (foo)
|
||||
frob();
|
||||
else
|
||||
unfrob();
|
||||
|
||||
* Prefer lambda-style functions where suitable:
|
||||
Right: list.filter(function (elem) elem.good != elem.BAD);
|
||||
Wrong: list.filter(function (elem) { return elem.good != elem.BAD });
|
||||
|
||||
* Anonymous function definitions should be formatted with a space after the
|
||||
keyword "function". Example: function () {}, not function() {}.
|
||||
|
||||
* Prefer the use of let over var i.e. only use var when required.
|
||||
For more details, see
|
||||
https://developer.mozilla.org/en/New_in_JavaScript_1.7#Block_scope_with_let
|
||||
|
||||
* Reuse common local variable names E.g. "elem" is generally used for element,
|
||||
"win" for windows etc.
|
||||
|
||||
* Prefer // over /* */ comments (exceptions for big comments are usually OK)
|
||||
Right: if (HACK) // TODO: remove hack
|
||||
Wrong: if (HACK) /* TODO: remove hack */
|
||||
Documentation comment blocks use /** ... */
|
||||
|
||||
* Only wrap lines if it makes the code obviously clearer. Lines longer than 132
|
||||
characters should probably be broken up rather than wrapped anyway.
|
||||
|
||||
* Use UNIX new lines (\n), not windows (\r\n) or old Mac ones (\r)
|
||||
|
||||
* Use Iterators, Array#forEach, or for (let i = 0; i < ary.length; i++)
|
||||
to iterate over arrays. for (let i in ary) and for each (let i in ary)
|
||||
include members in an Array.prototype, which some extensions alter.
|
||||
Right:
|
||||
for (let [,elem] in Iterator(ary))
|
||||
for (let [k, v] in Iterator(obj))
|
||||
ary.forEach(function (elem) { ...
|
||||
Wrong:
|
||||
for each (let elem in ary)
|
||||
|
||||
The exceptions to this rule are for objects with __iterator__ set,
|
||||
and for XML objects (see README.E4X).
|
||||
|
||||
* Avoid using 'new' with constructors where possible, and use [] and
|
||||
{} rather than new Array/new Object.
|
||||
Right:
|
||||
RegExp("^" + foo + "$")
|
||||
Function(code)
|
||||
new Date
|
||||
Wrong:
|
||||
new RegExp("^" + foo + "$")
|
||||
new Function(code)
|
||||
Date() // Right if you want a string-representation of the date
|
||||
|
||||
NOTE by mst: That one is debateable, actually I like the "new" as one
|
||||
immediately sees that a new object of a class is created which is not
|
||||
so obvious by var x = CompletionContext(); which could also mean that
|
||||
CompletionContext() could return a cached object. What's thesnowdog's
|
||||
opinion and why do you, Kris, think it's better/cleaner?
|
||||
|
||||
I don't think it's better/cleaner, it just seemed to be a consensus.
|
||||
--Kris
|
||||
|
||||
I don't like unnecessary use of 'new', I don't like 'new'. --djk
|
||||
|
||||
== Testing/Optimization ==
|
||||
|
||||
TODO: Add some information here about testing/validation/etc.
|
||||
Information about how/when to use :regressions might be nice.
|
||||
Additionally, maybe there should be some benchmark information here --
|
||||
something to let a developer know what's "too" slow...? Or general
|
||||
guidelines about optimization?
|
||||
|
||||
== Source Code Management ==
|
||||
|
||||
TODO: Document the existence of remote branches and discuss when and how
|
||||
to push to them. At least provide an index so that devs know where
|
||||
to look if an old branch needs to be maintained or a feature needs
|
||||
to be added to a new branch. Keep in mind that git is not the most
|
||||
intuitive SCM.
|
||||
|
||||
I don't agree. git is about as intuitive as any other SCM, but,
|
||||
regardless, it's by far one of the most popular. There are
|
||||
countless git walkthroughs, FAQs, tips pages (not to mention 'git
|
||||
help') that I don't see the need to duplicate them here. As for
|
||||
branches, 'git branch' should be sufficient, and, if not, there's
|
||||
a list on gitweb.
|
||||
--Kris
|
||||
|
||||
# vim: set fdm=marker sw=4 ts=4 et ai:
|
||||
@@ -32,7 +32,7 @@ const Point = new Struct("x", "y");
|
||||
|
||||
/**
|
||||
* A class to manage the primary web content buffer. The name comes
|
||||
* from vim's term, 'buffer', which signifies instances of open
|
||||
* from Vim's term, 'buffer', which signifies instances of open
|
||||
* files.
|
||||
* @instance buffer
|
||||
*/
|
||||
@@ -41,7 +41,8 @@ function Buffer() //{{{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
/* FIXME: This doesn't belong here. */
|
||||
|
||||
// FIXME: This doesn't belong here.
|
||||
let mainWindowID = config.mainWindowID || "main-window";
|
||||
let fontSize = util.computedStyle(document.getElementById(mainWindowID)).fontSize;
|
||||
|
||||
@@ -197,7 +198,7 @@ function Buffer() //{{{
|
||||
{
|
||||
if (mappings.repeat)
|
||||
{
|
||||
for (let i in util.interruptableRange(0, Math.max(count, 1), 100))
|
||||
for (let i in util.interruptibleRange(0, Math.max(count, 1), 100))
|
||||
mappings.repeat();
|
||||
}
|
||||
},
|
||||
@@ -330,7 +331,7 @@ function Buffer() //{{{
|
||||
"//xhtml:input[not(@type) or @type='text' or @type='password'] | //xhtml:textarea[not(@disabled) and not(@readonly)]"
|
||||
);
|
||||
|
||||
for (match in matches)
|
||||
for (let match in matches)
|
||||
{
|
||||
let computedStyle = util.computedStyle(match);
|
||||
if (computedStyle.visibility != "hidden" && computedStyle.display != "none")
|
||||
@@ -339,11 +340,7 @@ function Buffer() //{{{
|
||||
|
||||
if (elements.length > 0)
|
||||
{
|
||||
if (count > elements.length)
|
||||
count = elements.length;
|
||||
else if (count < 1)
|
||||
count = 1;
|
||||
|
||||
count = Math.min(Math.max(count, 1), elements.length);
|
||||
elements[count - 1].focus();
|
||||
}
|
||||
else
|
||||
@@ -482,7 +479,7 @@ function Buffer() //{{{
|
||||
if (arg && (liberator.has("Win32") || arg[0] != ">"))
|
||||
return liberator.echoerr("E488: Trailing characters");
|
||||
|
||||
options.temporaryContext(function () {
|
||||
options.withContext(function () {
|
||||
if (arg)
|
||||
{
|
||||
options.setPref("print.print_to_file", "true");
|
||||
@@ -570,12 +567,9 @@ function Buffer() //{{{
|
||||
let file = io.getFile(filename);
|
||||
|
||||
if (file.exists() && !args.bang)
|
||||
{
|
||||
liberator.echoerr("E13: File exists (add ! to override)");
|
||||
return;
|
||||
}
|
||||
return void liberator.echoerr("E13: File exists (add ! to override)");
|
||||
|
||||
chosenData = { file: file, uri: makeURI(doc.location.href, doc.characterSet) };
|
||||
chosenData = { file: file, uri: window.makeURI(doc.location.href, doc.characterSet) };
|
||||
}
|
||||
|
||||
// if browser.download.useDownloadDir = false then the "Save As"
|
||||
@@ -682,7 +676,7 @@ function Buffer() //{{{
|
||||
|
||||
if (!isFeed)
|
||||
{
|
||||
let type = data.type && data.type.toLowerCase();
|
||||
var type = data.type && data.type.toLowerCase();
|
||||
type = type.replace(/^\s+|\s*(?:;.*)?$/g, "");
|
||||
|
||||
isFeed = (type == "application/rss+xml" || type == "application/atom+xml");
|
||||
@@ -817,8 +811,8 @@ function Buffer() //{{{
|
||||
return {
|
||||
|
||||
/**
|
||||
* The alternative stylesheets for the current buffer. Only
|
||||
* returns stylesheets for the 'screen' media type.
|
||||
* @property {Array} The alternative style sheets for the current
|
||||
* buffer. Only returns style sheets for the 'screen' media type.
|
||||
*/
|
||||
get alternateStyleSheets()
|
||||
{
|
||||
@@ -836,7 +830,8 @@ function Buffer() //{{{
|
||||
get pageInfo() pageInfo,
|
||||
|
||||
/**
|
||||
* Returns whether the buffer is loaded. Values may be:
|
||||
* @property {number} A value indicating whether the buffer is loaded.
|
||||
* Values may be:
|
||||
* 0 - Loading.
|
||||
* 1 - Fully loaded.
|
||||
* 2 - Load failed.
|
||||
@@ -854,8 +849,8 @@ function Buffer() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* The last focused input field in the buffer. Used by the
|
||||
* "gi" key binding.
|
||||
* @property {Object} The last focused input field in the buffer. Used
|
||||
* by the "gi" key binding.
|
||||
*/
|
||||
get lastInputField()
|
||||
{
|
||||
@@ -870,21 +865,24 @@ function Buffer() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* The current top-level document's URL.
|
||||
* @property {string} The current top-level document's URL.
|
||||
*/
|
||||
get URL()
|
||||
{
|
||||
return window.content.document.location.href;
|
||||
},
|
||||
|
||||
/**
|
||||
* @property {number} The buffer's height in pixels.
|
||||
*/
|
||||
get pageHeight()
|
||||
{
|
||||
return window.content.innerHeight;
|
||||
},
|
||||
|
||||
/**
|
||||
* The current browser's text zoom level, as a percentage with
|
||||
* 100 as 'normal'. Only affects text size.
|
||||
* @property {number} The current browser's text zoom level, as a
|
||||
* percentage with 100 as 'normal'. Only affects text size.
|
||||
*/
|
||||
get textZoom()
|
||||
{
|
||||
@@ -896,9 +894,9 @@ function Buffer() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* 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 {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.
|
||||
*/
|
||||
get fullZoom()
|
||||
{
|
||||
@@ -910,7 +908,7 @@ function Buffer() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* The current document's title.
|
||||
* @property {string} The current document's title.
|
||||
*/
|
||||
get title()
|
||||
{
|
||||
@@ -918,6 +916,7 @@ function Buffer() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a new section to the page information output.
|
||||
*
|
||||
* @param {string} option The section's value in 'pageinfo'.
|
||||
* @param {string} title The heading for this section's
|
||||
@@ -972,6 +971,8 @@ function Buffer() //{{{
|
||||
* positioned in.
|
||||
*
|
||||
* NOTE: might change the selection
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
// FIXME: getSelection() doesn't always preserve line endings, see:
|
||||
// https://www.mozdev.org/bugs/show_bug.cgi?id=19303
|
||||
@@ -1026,9 +1027,8 @@ function Buffer() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Try to guess links the like of "next" and "prev". Though it
|
||||
* has a singularly horrendous name, it turns out to be quite
|
||||
* useful.
|
||||
* Tries to guess links the like of "next" and "prev". Though it has a
|
||||
* singularly horrendous name, it turns out to be quite useful.
|
||||
*
|
||||
* @param {string} rel The relationship to look for. Looks for
|
||||
* links with matching @rel or @rev attributes, and,
|
||||
@@ -1083,12 +1083,12 @@ function Buffer() //{{{
|
||||
return false;
|
||||
}
|
||||
|
||||
let retVal = followFrame(window.content);
|
||||
if (!retVal)
|
||||
// only loop through frames if the main content didnt match
|
||||
retVal = Array.some(window.content.frames, followFrame);
|
||||
let ret = followFrame(window.content);
|
||||
if (!ret)
|
||||
// only loop through frames if the main content didn't match
|
||||
ret = Array.some(window.content.frames, followFrame);
|
||||
|
||||
if (!retVal)
|
||||
if (!ret)
|
||||
liberator.beep();
|
||||
},
|
||||
|
||||
@@ -1125,7 +1125,7 @@ function Buffer() //{{{
|
||||
case liberator.NEW_TAB:
|
||||
case liberator.NEW_BACKGROUND_TAB:
|
||||
ctrlKey = true;
|
||||
shiftKey = (where == liberator.NEW_BACKGROUND_TAB);
|
||||
shiftKey = (where != liberator.NEW_BACKGROUND_TAB);
|
||||
break;
|
||||
case liberator.NEW_WINDOW:
|
||||
shiftKey = true;
|
||||
@@ -1147,13 +1147,19 @@ function Buffer() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* The current document's selection controller.
|
||||
* @property {Object} The current document's selection controller.
|
||||
*/
|
||||
get selectionController() getBrowser().docShell
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsISelectionDisplay)
|
||||
.QueryInterface(Ci.nsISelectionController),
|
||||
|
||||
/**
|
||||
* Saves a page link to disk.
|
||||
*
|
||||
* @param {Object} elem The page link to save.
|
||||
* @param {boolean} skipPrompt Whether to open the "Save Link As..." dialog
|
||||
*/
|
||||
saveLink: function (elem, skipPrompt)
|
||||
{
|
||||
let doc = elem.ownerDocument;
|
||||
@@ -1229,7 +1235,13 @@ function Buffer() //{{{
|
||||
win.scrollByPages(pages);
|
||||
},
|
||||
|
||||
scrollByScrollSize: function (count, direction)
|
||||
/**
|
||||
* Scrolls the buffer vertically <b>count</b> * 'scroll' rows.
|
||||
*
|
||||
* @param {number} count The multiple of 'scroll' lines to scroll.
|
||||
* @param {number} direction The direction to scroll, down if 1 and up if -1.
|
||||
*/
|
||||
scrollByScrollSize: function (count, direction) // XXX: boolean
|
||||
{
|
||||
if (count > 0)
|
||||
options["scroll"] = count;
|
||||
@@ -1244,7 +1256,9 @@ function Buffer() //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Scrolls the current buffer vertically to <b>percentage</b>
|
||||
* Scrolls the current buffer vertically to <b>percentage</b>.
|
||||
*
|
||||
* @param {number} percentage The page percentile to scroll the buffer to.
|
||||
*/
|
||||
scrollToPercentile: function (percentage)
|
||||
{
|
||||
@@ -1279,9 +1293,16 @@ function Buffer() //{{{
|
||||
},
|
||||
|
||||
// TODO: allow callback for filtering out unwanted frames? User defined?
|
||||
/**
|
||||
* Shifts the focus to another frame within the buffer. Each buffer
|
||||
* contains at least one frame.
|
||||
*
|
||||
* @param {number} count The number of frames to skip through.
|
||||
* @param {boolean} forward The direction of motion.
|
||||
*/
|
||||
shiftFrameFocus: function (count, forward)
|
||||
{
|
||||
if (!window.content.document instanceof HTMLDocument)
|
||||
if (!(window.content.document instanceof HTMLDocument))
|
||||
return;
|
||||
|
||||
count = Math.max(count, 1);
|
||||
@@ -1357,11 +1378,23 @@ function Buffer() //{{{
|
||||
|
||||
// similar to pageInfo
|
||||
// TODO: print more useful information, just like the DOM inspector
|
||||
/**
|
||||
* Displays information about the specified element.
|
||||
*
|
||||
* @param {Object} elem
|
||||
*/
|
||||
showElementInfo: function (elem)
|
||||
{
|
||||
liberator.echo(<>Element:<br/>{util.objectToString(elem, true)}</>, commandline.FORCE_MULTILINE);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays information about the current buffer.
|
||||
*
|
||||
* @param {boolean} verbose Display more verbose information.
|
||||
* @param {string} sections A string limiting the displayed sections.
|
||||
* @default The value of 'pageinfo'.
|
||||
*/
|
||||
showPageInfo: function (verbose, sections)
|
||||
{
|
||||
// Ctrl-g single line output
|
||||
@@ -1391,6 +1424,9 @@ function Buffer() //{{{
|
||||
liberator.echo(list, commandline.FORCE_MULTILINE);
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens a viewer to inspect the source of the currently selected range.
|
||||
*/
|
||||
viewSelectionSource: function ()
|
||||
{
|
||||
// copied (and tuned somebit) from browser.jar -> nsContextMenu.js
|
||||
@@ -1411,6 +1447,15 @@ function Buffer() //{{{
|
||||
docUrl, docCharset, reference, "selection");
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens a viewer to inspect the source of the current buffer or the
|
||||
* specified <b>url</b>. Either the default viewer or the configured
|
||||
* external editor is used.
|
||||
*
|
||||
* @param {string} url The URL of the source.
|
||||
* @default The current buffer.
|
||||
* @param {boolean} useExternalEditor View the source in the external editor.
|
||||
*/
|
||||
viewSource: function (url, useExternalEditor)
|
||||
{
|
||||
url = url || buffer.URL;
|
||||
@@ -1421,11 +1466,23 @@ function Buffer() //{{{
|
||||
liberator.open("view-source:" + url);
|
||||
},
|
||||
|
||||
/**
|
||||
* Increases the zoom level of the current buffer.
|
||||
*
|
||||
* @param {number} steps The number of zoom levels to jump.
|
||||
* @param {boolean} fullZoom Whether to use full zoom or text zoom.
|
||||
*/
|
||||
zoomIn: function (steps, fullZoom)
|
||||
{
|
||||
bumpZoomLevel(steps, fullZoom);
|
||||
},
|
||||
|
||||
/**
|
||||
* Decreases the zoom level of the current buffer.
|
||||
*
|
||||
* @param {number} steps The number of zoom levels to jump.
|
||||
* @param {boolean} fullZoom Whether to use full zoom or text zoom.
|
||||
*/
|
||||
zoomOut: function (steps, fullZoom)
|
||||
{
|
||||
bumpZoomLevel(-steps, fullZoom);
|
||||
@@ -1443,8 +1500,8 @@ function Marks() //{{{
|
||||
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
var localMarks = storage.newMap('local-marks', true);
|
||||
var urlMarks = storage.newMap('url-marks', true);
|
||||
var localMarks = storage.newMap("local-marks", true);
|
||||
var urlMarks = storage.newMap("url-marks", true);
|
||||
|
||||
var pendingJumps = [];
|
||||
var appContent = document.getElementById("appcontent");
|
||||
@@ -1471,7 +1528,7 @@ function Marks() //{{{
|
||||
return name + ", " + mark.location +
|
||||
", (" + Math.round(mark.position.x * 100) +
|
||||
"%, " + Math.round(mark.position.y * 100) + "%)" +
|
||||
(('tab' in mark) ? ", tab: " + tabs.index(mark.tab) : "");
|
||||
(("tab" in mark) ? ", tab: " + tabs.index(mark.tab) : "");
|
||||
}
|
||||
|
||||
function removeLocalMark(mark)
|
||||
|
||||
@@ -28,14 +28,14 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
/** @scope modules */
|
||||
|
||||
// Do NOT create instances of this class yourself, use the helper method
|
||||
// commands.add() instead
|
||||
/**
|
||||
* A class representing EX commands. Instances are created by
|
||||
* A class representing Ex commands. Instances are created by
|
||||
* the {@link Commands} class.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
// Do NOT create instances of this class yourself, use the helper method
|
||||
// commands.add() instead
|
||||
function Command(specs, description, action, extraInfo) //{{{
|
||||
{
|
||||
if (!specs || !action)
|
||||
@@ -86,7 +86,7 @@ function Command(specs, description, action, extraInfo) //{{{
|
||||
/** @property {string[]} All of this command's long names, e.g., "command" */
|
||||
this.longNames = expandedSpecs.longNames;
|
||||
|
||||
/** @property {string} The command's cannonical name. */
|
||||
/** @property {string} The command's canonical name. */
|
||||
this.name = this.longNames[0];
|
||||
/** @property {string[]} All of this command's long and short names. */
|
||||
this.names = expandedSpecs.names; // return all command name aliases
|
||||
@@ -112,7 +112,7 @@ function Command(specs, description, action, extraInfo) //{{{
|
||||
* arguments begin. For instance, with a value of 2, all arguments
|
||||
* starting with the third are parsed as a single string, with all
|
||||
* quoting characters passed literally. This is especially useful for
|
||||
* commands which take key mappings or ex command lines as
|
||||
* commands which take key mappings or Ex command lines as
|
||||
* arguments.
|
||||
*/
|
||||
this.literal = extraInfo.literal == null ? null : extraInfo.literal;
|
||||
@@ -133,7 +133,7 @@ function Command(specs, description, action, extraInfo) //{{{
|
||||
this.isUserCommand = extraInfo.isUserCommand || false;
|
||||
/**
|
||||
* @property {string} For commands defined via :command, contains
|
||||
* the EX command line to be executed upon invocation.
|
||||
* the Ex command line to be executed upon invocation.
|
||||
*/
|
||||
this.replacementText = extraInfo.replacementText || null;
|
||||
};
|
||||
@@ -148,7 +148,7 @@ Command.prototype = {
|
||||
* @param {boolean} bang @deprecated Whether this command was
|
||||
* executed with a trailing !.
|
||||
* @param {number} count @deprecated Whether this command was
|
||||
* executed a leading count.
|
||||
* executed with a leading count.
|
||||
* @param modifiers Any modifiers to be passed to
|
||||
* {@link action}
|
||||
*/
|
||||
@@ -189,6 +189,7 @@ Command.prototype = {
|
||||
* Returns whether this command may be invoked via <b>name</b>.
|
||||
*
|
||||
* @param {string} name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasName: function (name)
|
||||
{
|
||||
@@ -214,7 +215,7 @@ Command.prototype = {
|
||||
* purposes.
|
||||
* @param {Object} extra Extra keys to be spliced into the
|
||||
* returned Args object.
|
||||
* @returns Args
|
||||
* @returns {Args}
|
||||
* @see Commands#parseArgs
|
||||
*/
|
||||
parseArgs: function (args, complete, extra) commands.parseArgs(args, this.options, this.argCount, false, this.literal, complete, extra)
|
||||
@@ -306,7 +307,7 @@ function Commands() //{{{
|
||||
completion.setFunctionCompleter(commands.get, [function () ([c.name, c.description] for (c in commands))]);
|
||||
});
|
||||
|
||||
var commandManager = {
|
||||
const self = {
|
||||
|
||||
// FIXME: remove later, when our option handler is better
|
||||
OPTION_ANY: 0, // can be given no argument or an argument of any type,
|
||||
@@ -717,27 +718,18 @@ function Commands() //{{{
|
||||
return args;
|
||||
},
|
||||
|
||||
// return [null, null, null, null, heredoc_tag || false];
|
||||
// [count, cmd, special, args] = match;
|
||||
parseCommand: function (str, tag)
|
||||
parseCommand: function (str)
|
||||
{
|
||||
// remove comments
|
||||
str.replace(/\s*".*$/, "");
|
||||
|
||||
if (tag) // we already have a multiline heredoc construct
|
||||
{
|
||||
if (str == tag)
|
||||
return [null, null, null, null, false];
|
||||
else
|
||||
return [null, null, null, str, tag];
|
||||
}
|
||||
|
||||
// 0 - count, 1 - cmd, 2 - special, 3 - args, 4 - heredoc tag
|
||||
// 0 - count, 1 - cmd, 2 - special, 3 - args
|
||||
let matches = str.match(/^:*(\d+|%)?([a-zA-Z]+|!)(!)?(?:\s*(.*?))?$/);
|
||||
//var matches = str.match(/^:*(\d+|%)?([a-zA-Z]+|!)(!)?(?:\s*(.*?)\s*)?$/);
|
||||
if (!matches)
|
||||
return [null, null, null, null, null];
|
||||
let [, count, cmd, special, args, heredoc] = matches;
|
||||
return [null, null, null, null];
|
||||
|
||||
let [, count, cmd, special, args] = matches;
|
||||
|
||||
// parse count
|
||||
if (count)
|
||||
@@ -745,14 +737,7 @@ function Commands() //{{{
|
||||
else
|
||||
count = this.COUNT_NONE;
|
||||
|
||||
if (args)
|
||||
{
|
||||
tag = args.match(/<<\s*(\w+)\s*$/);
|
||||
if (tag && tag[1])
|
||||
heredoc = tag[1];
|
||||
}
|
||||
|
||||
return [count, cmd, !!special, args || "", heredoc];
|
||||
return [count, cmd, !!special, args || ""];
|
||||
},
|
||||
|
||||
get complQuote() complQuote,
|
||||
@@ -769,7 +754,7 @@ function Commands() //{{{
|
||||
{
|
||||
return str.replace(/<((?:q-)?)([a-zA-Z]+)?>/g, function (match, quote, token)
|
||||
{
|
||||
if (token == "lt") // Don't quote, as in vim (but, why so in vim? You'd think people wouldn't say <q-lt> if they didn't want it)
|
||||
if (token == "lt") // Don't quote, as in Vim (but, why so in Vim? You'd think people wouldn't say <q-lt> if they didn't want it)
|
||||
return "<";
|
||||
let res = tokens[token];
|
||||
if (res == undefined) // Ignore anything undefined
|
||||
@@ -811,7 +796,7 @@ function Commands() //{{{
|
||||
|
||||
// TODO: Vim allows commands to be defined without {rep} if there are {attr}s
|
||||
// specified - useful?
|
||||
commandManager.add(["com[mand]"],
|
||||
self.add(["com[mand]"],
|
||||
"List and define commands",
|
||||
function (args)
|
||||
{
|
||||
@@ -918,13 +903,13 @@ function Commands() //{{{
|
||||
bang: true,
|
||||
completer: function (context) completion.userCommand(context),
|
||||
options: [
|
||||
[["-nargs"], commandManager.OPTION_STRING,
|
||||
[["-nargs"], self.OPTION_STRING,
|
||||
function (arg) /^[01*?+]$/.test(arg), ["0", "1", "*", "?", "+"]],
|
||||
[["-bang"], commandManager.OPTION_NOARG],
|
||||
[["-count"], commandManager.OPTION_NOARG],
|
||||
[["-complete"], commandManager.OPTION_STRING,
|
||||
[["-bang"], self.OPTION_NOARG],
|
||||
[["-count"], self.OPTION_NOARG],
|
||||
[["-complete"], self.OPTION_STRING,
|
||||
function (arg) arg in completeOptionMap || /custom,\w+/.test(arg),
|
||||
function (context) [[k, ''] for ([k, v] in Iterator(completeOptionMap))]]
|
||||
function (context) [[k, ""] for ([k, v] in Iterator(completeOptionMap))]]
|
||||
],
|
||||
literal: 1,
|
||||
serial: function () [
|
||||
@@ -945,7 +930,7 @@ function Commands() //{{{
|
||||
]
|
||||
});
|
||||
|
||||
commandManager.add(["comc[lear]"],
|
||||
self.add(["comc[lear]"],
|
||||
"Delete all user-defined commands",
|
||||
function ()
|
||||
{
|
||||
@@ -953,7 +938,7 @@ function Commands() //{{{
|
||||
},
|
||||
{ argCount: "0" });
|
||||
|
||||
commandManager.add(["delc[ommand]"],
|
||||
self.add(["delc[ommand]"],
|
||||
"Delete the specified user-defined command",
|
||||
function (args)
|
||||
{
|
||||
@@ -971,7 +956,7 @@ function Commands() //{{{
|
||||
|
||||
//}}}
|
||||
|
||||
return commandManager;
|
||||
return self;
|
||||
|
||||
}; //}}}
|
||||
|
||||
|
||||
@@ -66,7 +66,8 @@ function CompletionContext(editor, name, offset) //{{{
|
||||
self.contexts[name] = this;
|
||||
|
||||
/**
|
||||
* @property {CompletionContext} This context's parent. {null} when this is a top-level context.
|
||||
* @property {CompletionContext} This context's parent. {null} when
|
||||
* this is a top-level context.
|
||||
*/
|
||||
self.parent = parent;
|
||||
|
||||
@@ -111,6 +112,12 @@ function CompletionContext(editor, name, offset) //{{{
|
||||
this.editor = editor;
|
||||
this.compare = function (a, b) String.localeCompare(a.text, b.text);
|
||||
|
||||
/**
|
||||
* @property {function} This function is called when we close
|
||||
* a completion window with Esc or Ctrl-c. Usually this callback
|
||||
* is only needed for long, asynchronous completions
|
||||
*/
|
||||
this.cancel = null;
|
||||
/**
|
||||
* @property {function} The function used to filter the results.
|
||||
* @default Selects all results which match every predicate in the
|
||||
@@ -141,16 +148,18 @@ function CompletionContext(editor, name, offset) //{{{
|
||||
}];
|
||||
/**
|
||||
* @property {boolean} Specifies whether this context results must
|
||||
* match the filter at the begining of the string.
|
||||
* match the filter at the beginning of the string.
|
||||
* @default true
|
||||
*/
|
||||
this.anchored = true;
|
||||
/**
|
||||
* @property {Object} A map of all contexts, keyed on their names.
|
||||
* Names are assigned when a context is forked, with its specified
|
||||
* name appended, after a '/', to its parent's name.
|
||||
* name appended, after a '/', to its parent's name. May
|
||||
* contain inactive contexts. For active contexts, see
|
||||
* {@link #contextList}.
|
||||
*/
|
||||
this.contexts = { name: this };
|
||||
this.contexts = { "/": this };
|
||||
/**
|
||||
* @property {Object} A mapping of keys, for {@link #getKey}. Given
|
||||
* { key: value }, getKey(item, key) will return values as such:
|
||||
@@ -159,7 +168,7 @@ function CompletionContext(editor, name, offset) //{{{
|
||||
*/
|
||||
this.keys = { text: 0, description: 1, icon: "icon" };
|
||||
/**
|
||||
* @property {number} This context's offset from the begining of
|
||||
* @property {number} This context's offset from the beginning of
|
||||
* {@link #editor}'s value.
|
||||
*/
|
||||
this.offset = offset || 0;
|
||||
@@ -519,6 +528,15 @@ CompletionContext.prototype = {
|
||||
this._filter = this._filter.substr(count);
|
||||
},
|
||||
|
||||
cancelAll: function ()
|
||||
{
|
||||
for (let [,context] in Iterator(this.contextList))
|
||||
{
|
||||
if (context.cancel)
|
||||
context.cancel();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a key from {@link #cache}, setting it to <b>defVal</b> if it
|
||||
* doesn't already exists.
|
||||
@@ -622,6 +640,11 @@ CompletionContext.prototype = {
|
||||
for (let type in this.selectionTypes)
|
||||
this.highlight(0, 0, type);
|
||||
|
||||
/**
|
||||
* @property {[CompletionContext]} A list of active
|
||||
* completion contexts, in the order in which they were
|
||||
* instantiated.
|
||||
*/
|
||||
this.contextList = [];
|
||||
this.offset = 0;
|
||||
this.process = [];
|
||||
@@ -631,6 +654,8 @@ CompletionContext.prototype = {
|
||||
this.updateAsync = false;
|
||||
this.waitingForTab = false;
|
||||
|
||||
this.cancelAll();
|
||||
|
||||
if (this.editor)
|
||||
{
|
||||
this.value = this.editor.selection.focusNode.textContent;
|
||||
@@ -653,7 +678,7 @@ CompletionContext.prototype = {
|
||||
/**
|
||||
* Wait for all subcontexts to complete.
|
||||
*
|
||||
* @param {boolean} interruptable When true, the call may be interrupted
|
||||
* @param {boolean} interruptible When true, the call may be interrupted
|
||||
* via <C-c>. In this case, "Interrupted" may be thrown.
|
||||
* @param {number} timeout The maximum time, in milliseconds, to wait.
|
||||
*/
|
||||
@@ -682,10 +707,10 @@ function Completion() //{{{
|
||||
const OFFSET = 0, CHAR = 1, STATEMENTS = 2, DOTS = 3, FULL_STATEMENTS = 4, COMMA = 5, FUNCTIONS = 6;
|
||||
let stack = [];
|
||||
let functions = [];
|
||||
let top = []; /* The element on the top of the stack. */
|
||||
let last = ""; /* The last opening char pushed onto the stack. */
|
||||
let lastNonwhite = ""; /* Last non-whitespace character we saw. */
|
||||
let lastChar = ""; /* Last character we saw, used for \ escaping quotes. */
|
||||
let top = []; // The element on the top of the stack.
|
||||
let last = ""; // The last opening char pushed onto the stack.
|
||||
let lastNonwhite = ""; // Last non-whitespace character we saw.
|
||||
let lastChar = ""; // Last character we saw, used for \ escaping quotes.
|
||||
let compl = [];
|
||||
let str = "";
|
||||
|
||||
@@ -732,11 +757,10 @@ function Completion() //{{{
|
||||
return iterator;
|
||||
}
|
||||
|
||||
/* Search the object for strings starting with @key.
|
||||
* If @last is defined, key is a quoted string, it's
|
||||
* wrapped in @last after @offset characters are sliced
|
||||
* off of it and it's quoted.
|
||||
*/
|
||||
// Search the object for strings starting with @key.
|
||||
// If @last is defined, key is a quoted string, it's
|
||||
// wrapped in @last after @offset characters are sliced
|
||||
// off of it and it's quoted.
|
||||
this.objectKeys = function objectKeys(obj)
|
||||
{
|
||||
// Things we can dereference
|
||||
@@ -808,11 +832,10 @@ function Completion() //{{{
|
||||
}
|
||||
}
|
||||
|
||||
/* Get an element from the stack. If @n is negative,
|
||||
* count from the top of the stack, otherwise, the bottom.
|
||||
* If @m is provided, return the @mth value of element @o
|
||||
* of the stack entey at @n.
|
||||
*/
|
||||
// Get an element from the stack. If @n is negative,
|
||||
// count from the top of the stack, otherwise, the bottom.
|
||||
// If @m is provided, return the @mth value of element @o
|
||||
// of the stack entey at @n.
|
||||
let get = function get(n, m, o)
|
||||
{
|
||||
let a = stack[n >= 0 ? n : stack.length + n];
|
||||
@@ -826,7 +849,7 @@ function Completion() //{{{
|
||||
function buildStack(filter)
|
||||
{
|
||||
let self = this;
|
||||
/* Push and pop the stack, maintaining references to 'top' and 'last'. */
|
||||
// Push and pop the stack, maintaining references to 'top' and 'last'.
|
||||
let push = function push(arg)
|
||||
{
|
||||
top = [i, arg, [i], [], [], [], []];
|
||||
@@ -854,7 +877,7 @@ function Completion() //{{{
|
||||
return ret;
|
||||
}
|
||||
|
||||
let i = 0, c = ""; /* Current index and character, respectively. */
|
||||
let i = 0, c = ""; // Current index and character, respectively.
|
||||
|
||||
// Reuse the old stack.
|
||||
if (str && filter.substr(0, str.length) == str)
|
||||
@@ -870,11 +893,10 @@ function Completion() //{{{
|
||||
push("#root");
|
||||
}
|
||||
|
||||
/* Build a parse stack, discarding entries as opening characters
|
||||
* match closing characters. The stack is walked from the top entry
|
||||
* and down as many levels as it takes us to figure out what it is
|
||||
* that we're completing.
|
||||
*/
|
||||
// Build a parse stack, discarding entries as opening characters
|
||||
// match closing characters. The stack is walked from the top entry
|
||||
// and down as many levels as it takes us to figure out what it is
|
||||
// that we're completing.
|
||||
str = filter;
|
||||
let length = str.length;
|
||||
for (; i < length; lastChar = c, i++)
|
||||
@@ -906,7 +928,7 @@ function Completion() //{{{
|
||||
switch (c)
|
||||
{
|
||||
case "(":
|
||||
/* Function call, or if/while/for/... */
|
||||
// Function call, or if/while/for/...
|
||||
if (/[\w$]/.test(lastNonwhite))
|
||||
{
|
||||
functions.push(i);
|
||||
@@ -927,7 +949,7 @@ function Completion() //{{{
|
||||
break;
|
||||
case ")": pop("("); break;
|
||||
case "]": pop("["); break;
|
||||
case "}": pop("{"); /* Fallthrough */
|
||||
case "}": pop("{"); // Fallthrough
|
||||
case ";":
|
||||
top[FULL_STATEMENTS].push(i);
|
||||
break;
|
||||
@@ -972,7 +994,7 @@ function Completion() //{{{
|
||||
this.context.getCache("eval", Object);
|
||||
this.context.getCache("evalContext", function () ({ __proto__: userContext }));
|
||||
|
||||
/* Okay, have parse stack. Figure out what we're completing. */
|
||||
// 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.<Tab>
|
||||
@@ -1039,7 +1061,7 @@ function Completion() //{{{
|
||||
cacheKey = null;
|
||||
let obj = [[cache.evalContext, "Local Variables"], [userContext, "Global Variables"],
|
||||
[modules, "modules"], [window, "window"]]; // Default objects;
|
||||
/* Is this an object dereference? */
|
||||
// Is this an object dereference?
|
||||
if (dot < statement) // No.
|
||||
dot = statement - 1;
|
||||
else // Yes. Set the object to the string before the dot.
|
||||
@@ -1073,7 +1095,7 @@ function Completion() //{{{
|
||||
compl = function (context, obj)
|
||||
{
|
||||
context.process = [null, function highlight(item, v) template.highlight(v, true)];
|
||||
// Sort in a logical fasion for object keys:
|
||||
// Sort in a logical fashion for object keys:
|
||||
// Numbers are sorted as numbers, rather than strings, and appear first.
|
||||
// Constants are unsorted, and appear before other non-null strings.
|
||||
// Other strings are sorted in the default manner.
|
||||
@@ -1112,11 +1134,11 @@ function Completion() //{{{
|
||||
// Otherwise, do nothing.
|
||||
if (last == "'" || last == '"')
|
||||
{
|
||||
/*
|
||||
* str = "foo[bar + 'baz"
|
||||
* obj = "foo"
|
||||
* key = "bar + ''"
|
||||
*/
|
||||
//
|
||||
// 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.
|
||||
@@ -1133,21 +1155,20 @@ function Completion() //{{{
|
||||
return this.eval(key);
|
||||
}
|
||||
|
||||
/* Is this an object accessor? */
|
||||
// Is this an object accessor?
|
||||
if (get(-2)[CHAR] == "[") // Are we inside of []?
|
||||
{
|
||||
/* Stack:
|
||||
* [-1]: "...
|
||||
* [-2]: [...
|
||||
* [-3]: base statement
|
||||
*/
|
||||
// Stack:
|
||||
// [-1]: "...
|
||||
// [-2]: [...
|
||||
// [-3]: base statement
|
||||
|
||||
// Yes. If the [ starts at the begining of a logical
|
||||
// Yes. If the [ starts at the beginning of a logical
|
||||
// statement, we're in an array literal, and we're done.
|
||||
if (get(-3, 0, STATEMENTS) == get(-2)[OFFSET])
|
||||
return;
|
||||
|
||||
// Begining of the statement upto the opening [
|
||||
// Beginning of the statement upto the opening [
|
||||
let obj = getObj(-3, get(-2)[OFFSET]);
|
||||
|
||||
return complete.call(this, obj, getKey(), null, string, last);
|
||||
@@ -1156,11 +1177,10 @@ function Completion() //{{{
|
||||
// Is this a function call?
|
||||
if (get(-2)[CHAR] == "(")
|
||||
{
|
||||
/* Stack:
|
||||
* [-1]: "...
|
||||
* [-2]: (...
|
||||
* [-3]: base statement
|
||||
*/
|
||||
// Stack:
|
||||
// [-1]: "...
|
||||
// [-2]: (...
|
||||
// [-3]: base statement
|
||||
|
||||
// Does the opening "(" mark a function call?
|
||||
if (get(-3, 0, FUNCTIONS) != get(-2)[OFFSET])
|
||||
@@ -1209,15 +1229,15 @@ function Completion() //{{{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* str = "foo.bar.baz"
|
||||
* obj = "foo.bar"
|
||||
* key = "baz"
|
||||
*
|
||||
* str = "foo"
|
||||
* obj = [modules, window]
|
||||
* key = "foo"
|
||||
*/
|
||||
//
|
||||
// str = "foo.bar.baz"
|
||||
// obj = "foo.bar"
|
||||
// key = "baz"
|
||||
//
|
||||
// str = "foo"
|
||||
// obj = [modules, window]
|
||||
// key = "foo"
|
||||
//
|
||||
|
||||
let [offset, obj, key] = getObjKey(-1);
|
||||
|
||||
@@ -1230,7 +1250,7 @@ function Completion() //{{{
|
||||
}
|
||||
|
||||
if (!/^(?:[a-zA-Z_$][\w$]*)?$/.test(key))
|
||||
return; /* Not a word. Forget it. Can this even happen? */
|
||||
return; // Not a word. Forget it. Can this even happen?
|
||||
|
||||
try
|
||||
{ // FIXME
|
||||
@@ -1250,7 +1270,7 @@ function Completion() //{{{
|
||||
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
let self = {
|
||||
const self = {
|
||||
|
||||
setFunctionCompleter: function setFunctionCompleter(funcs, completers)
|
||||
{
|
||||
@@ -1338,6 +1358,7 @@ function Completion() //{{{
|
||||
context.completions = config.autocommands;
|
||||
},
|
||||
|
||||
// TODO: shouldn't these app-specific completers be moved to config.js? --djk
|
||||
bookmark: function bookmark(context, tags, extra)
|
||||
{
|
||||
context.title = ["Bookmark", "Title"];
|
||||
@@ -1552,13 +1573,15 @@ function Completion() //{{{
|
||||
location: function location(context)
|
||||
{
|
||||
if (!services.get("autoCompleteSearch"))
|
||||
return
|
||||
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 () services.get("autoCompleteSearch").stopSearch();
|
||||
context.compare = null;
|
||||
let timer = new Timer(50, 100, function (result) {
|
||||
context.incomplete = result.searchResult >= result.RESULT_NOMATCH_ONGOING;
|
||||
@@ -1627,9 +1650,8 @@ function Completion() //{{{
|
||||
let completions = completer(context);
|
||||
if (!completions)
|
||||
return;
|
||||
/* Not vim compatible, but is a significant enough improvement
|
||||
* that it's worth breaking compatibility.
|
||||
*/
|
||||
// Not Vim compatible, but is a significant enough improvement
|
||||
// that it's worth breaking compatibility.
|
||||
if (newValues instanceof Array)
|
||||
{
|
||||
completions = completions.filter(function (val) newValues.indexOf(val[0]) == -1);
|
||||
|
||||
@@ -217,7 +217,7 @@ function Editor() //{{{
|
||||
|
||||
var myModes = [modes.INSERT, modes.COMMAND_LINE];
|
||||
|
||||
/* KEYS COUNT CARET TEXTAREA VISUAL_TEXTAREA */
|
||||
// KEYS COUNT CARET TEXTAREA VISUAL_TEXTAREA
|
||||
addMovementMap(["k", "<Up>"], true, "lineMove", false, "cmd_linePrevious", selectPreviousLine);
|
||||
addMovementMap(["j", "<Down>", "<Return>"], true, "lineMove", true, "cmd_lineNext", selectNextLine);
|
||||
addMovementMap(["h", "<Left>", "<BS>"], true, "characterMove", false, "cmd_charPrevious", "cmd_selectCharPrevious");
|
||||
@@ -371,10 +371,14 @@ function Editor() //{{{
|
||||
{ flags: Mappings.flags.COUNT });
|
||||
|
||||
// visual mode
|
||||
mappings.add([modes.CARET, modes.TEXTAREA, modes.VISUAL],
|
||||
mappings.add([modes.CARET, modes.TEXTAREA],
|
||||
["v"], "Start visual mode",
|
||||
function (count) { modes.set(modes.VISUAL, liberator.mode); });
|
||||
|
||||
mappings.add([modes.VISUAL],
|
||||
["v"], "End visual mode",
|
||||
function (count) { events.onEscape() });
|
||||
|
||||
mappings.add([modes.TEXTAREA],
|
||||
["V"], "Start visual line mode",
|
||||
function (count)
|
||||
@@ -557,9 +561,9 @@ function Editor() //{{{
|
||||
|
||||
unselectText: function ()
|
||||
{
|
||||
let elt = window.document.commandDispatcher.focusedElement;
|
||||
if (elt && elt.selectionEnd)
|
||||
elt.selectionEnd = elt.selectionStart;
|
||||
let elem = window.document.commandDispatcher.focusedElement;
|
||||
if (elem && elem.selectionEnd)
|
||||
elem.selectionEnd = elem.selectionStart;
|
||||
},
|
||||
|
||||
selectedText: function ()
|
||||
@@ -570,20 +574,20 @@ function Editor() //{{{
|
||||
|
||||
pasteClipboard: function ()
|
||||
{
|
||||
let elt = window.document.commandDispatcher.focusedElement;
|
||||
let elem = window.document.commandDispatcher.focusedElement;
|
||||
|
||||
if (elt.setSelectionRange && util.readFromClipboard())
|
||||
if (elem.setSelectionRange && util.readFromClipboard())
|
||||
// readFromClipboard would return 'undefined' if not checked
|
||||
// dunno about .setSelectionRange
|
||||
{
|
||||
let rangeStart = elt.selectionStart; // caret position
|
||||
let rangeEnd = elt.selectionEnd;
|
||||
let tempStr1 = elt.value.substring(0, rangeStart);
|
||||
let rangeStart = elem.selectionStart; // caret position
|
||||
let rangeEnd = elem.selectionEnd;
|
||||
let tempStr1 = elem.value.substring(0, rangeStart);
|
||||
let tempStr2 = util.readFromClipboard();
|
||||
let tempStr3 = elt.value.substring(rangeEnd);
|
||||
elt.value = tempStr1 + tempStr2 + tempStr3;
|
||||
elt.selectionStart = rangeStart + tempStr2.length;
|
||||
elt.selectionEnd = elt.selectionStart;
|
||||
let tempStr3 = elem.value.substring(rangeEnd);
|
||||
elem.value = tempStr1 + tempStr2 + tempStr3;
|
||||
elem.selectionStart = rangeStart + tempStr2.length;
|
||||
elem.selectionEnd = elem.selectionStart;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -709,7 +713,7 @@ function Editor() //{{{
|
||||
|
||||
// This function will move/select up to given "pos"
|
||||
// Simple setSelectionRange() would be better, but we want to maintain the correct
|
||||
// order of selectionStart/End (a firefox bug always makes selectionStart <= selectionEnd)
|
||||
// order of selectionStart/End (a Firefox bug always makes selectionStart <= selectionEnd)
|
||||
// Use only for small movements!
|
||||
moveToPosition: function (pos, forward, select)
|
||||
{
|
||||
@@ -809,7 +813,7 @@ function Editor() //{{{
|
||||
}
|
||||
|
||||
args.push(path);
|
||||
liberator.callFunctionInThread(null, io.run, args.shift(), args, true);
|
||||
liberator.callFunctionInThread(null, io.run, io.expandPath(args.shift()), args, true);
|
||||
},
|
||||
|
||||
// TODO: clean up with 2 functions for textboxes and currentEditor?
|
||||
@@ -900,7 +904,7 @@ function Editor() //{{{
|
||||
//
|
||||
// if filter == ! remove all and add it as only END
|
||||
//
|
||||
// variant 1: rhs matches anywere in loop
|
||||
// variant 1: rhs matches anywhere in loop
|
||||
//
|
||||
// 1 mod matches anywhere in loop
|
||||
// a) simple replace and
|
||||
|
||||
@@ -4,7 +4,7 @@ catch (e)
|
||||
{
|
||||
__liberator_eval_error = e;
|
||||
}
|
||||
// Important: The eval statement *must* remain on the first line
|
||||
// IMPORTANT: The eval statement *must* remain on the first line
|
||||
// in order for line numbering in any errors to remain correct.
|
||||
//
|
||||
// vim: set fdm=marker sw=4 ts=4 et:
|
||||
|
||||
@@ -37,13 +37,12 @@ function AutoCommands() //{{{
|
||||
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
const AutoCommand = new Struct("event", "pattern", "command");
|
||||
var store = [];
|
||||
var lastFocus = null;
|
||||
|
||||
function matchAutoCmd(autoCmd, event, regex)
|
||||
{
|
||||
return (!event || autoCmd.event == event) &&
|
||||
(!regex || autoCmd.pattern.source == regex);
|
||||
return (!event || autoCmd.event == event) && (!regex || autoCmd.pattern.source == regex);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////}}}
|
||||
@@ -72,6 +71,7 @@ function AutoCommands() //{{{
|
||||
{
|
||||
let [event, regex, cmd] = args;
|
||||
let events = null;
|
||||
|
||||
if (event)
|
||||
{
|
||||
// NOTE: event can only be a comma separated list for |:au {event} {pat} {cmd}|
|
||||
@@ -96,6 +96,7 @@ function AutoCommands() //{{{
|
||||
{
|
||||
if (event == "*")
|
||||
event = null;
|
||||
|
||||
if (args.bang)
|
||||
{
|
||||
// TODO: "*" only appears to work in Vim when there is a {group} specified
|
||||
@@ -181,6 +182,16 @@ function AutoCommands() //{{{
|
||||
|
||||
__iterator__: function () util.Array.iterator(store),
|
||||
|
||||
/**
|
||||
* Adds a new autocommand. <b>cmd</b> will be executed when one of the
|
||||
* specified <b>events</b> occurs and the URL of the applicable buffer
|
||||
* matches <b>regex</b>.
|
||||
*
|
||||
* @param {Array} events The array of event names for which this
|
||||
* autocommand should be executed.
|
||||
* @param {string} regex The URL pattern to match against the buffer URL
|
||||
* @param {string} cmd The Ex command to run
|
||||
*/
|
||||
add: function (events, regex, cmd)
|
||||
{
|
||||
if (typeof events == "string")
|
||||
@@ -188,20 +199,43 @@ function AutoCommands() //{{{
|
||||
events = events.split(",");
|
||||
liberator.log("DEPRECATED: the events list arg to autocommands.add() should be an array of event names");
|
||||
}
|
||||
events.forEach(function (event)
|
||||
store.push({ event: event, pattern: RegExp(regex), command: cmd }));
|
||||
events.forEach(function (event) {
|
||||
store.push(new AutoCommand(event, RegExp(regex), cmd));
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns all autocommands with a matching <b>event</b> and
|
||||
* <b>regex</b>.
|
||||
*
|
||||
* @param {string} event The event name filter.
|
||||
* @param {string} regex The URL pattern filter.
|
||||
* @returns {AutoCommand[]}
|
||||
*/
|
||||
get: function (event, regex)
|
||||
{
|
||||
return store.filter(function (autoCmd) matchAutoCmd(autoCmd, event, regex));
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes all autocommands with a matching <b>event</b> and
|
||||
* <b>regex</b>.
|
||||
*
|
||||
* @param {string} event The event name filter.
|
||||
* @param {string} regex The URL pattern filter.
|
||||
*/
|
||||
remove: function (event, regex)
|
||||
{
|
||||
store = store.filter(function (autoCmd) !matchAutoCmd(autoCmd, event, regex));
|
||||
},
|
||||
|
||||
/**
|
||||
* Lists all autocommands with a matching <b>event</b> and
|
||||
* <b>regex</b>.
|
||||
*
|
||||
* @param {string} event The event name filter.
|
||||
* @param {string} regex The URL pattern filter.
|
||||
*/
|
||||
list: function (event, regex)
|
||||
{
|
||||
let cmds = {};
|
||||
@@ -237,6 +271,14 @@ function AutoCommands() //{{{
|
||||
commandline.echo(list, commandline.HL_NORMAL, commandline.FORCE_MULTILINE);
|
||||
},
|
||||
|
||||
/**
|
||||
* Triggers the execution of all autocommands registered for
|
||||
* <b>event</b>. A map of <b>args</b> is passed to each autocommand
|
||||
* when it is being executed.
|
||||
*
|
||||
* @param {string} event The event to fire.
|
||||
* @param {Object} args The args to pass to each autocommand.
|
||||
*/
|
||||
trigger: function (event, args)
|
||||
{
|
||||
if (options.get("eventignore").has("all", event))
|
||||
@@ -273,7 +315,7 @@ function AutoCommands() //{{{
|
||||
}
|
||||
else
|
||||
{
|
||||
liberator.execute(commands.replaceTokens(autoCmd.command, args));
|
||||
liberator.execute(commands.replaceTokens(autoCmd.command, args), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,10 +337,12 @@ function Events() //{{{
|
||||
|
||||
var fullscreen = window.fullScreen;
|
||||
|
||||
var lastFocus = null;
|
||||
|
||||
var inputBufferLength = 0; // count the number of keys in v.input.buffer (can be different from v.input.buffer.length)
|
||||
var skipMap = false; // while feeding the keys (stored in v.input.buffer | no map found) - ignore mappings
|
||||
|
||||
var macros = storage.newMap('macros', true);
|
||||
var macros = storage.newMap("macros", true);
|
||||
|
||||
var currentMacro = "";
|
||||
var lastMacro = "";
|
||||
@@ -457,14 +501,14 @@ function Events() //{{{
|
||||
|
||||
function isFormElemFocused()
|
||||
{
|
||||
let elt = window.document.commandDispatcher.focusedElement;
|
||||
if (elt == null)
|
||||
let elem = window.document.commandDispatcher.focusedElement;
|
||||
if (elem == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{ // sometimes the elt doesn't have .localName
|
||||
let tagname = elt.localName.toLowerCase();
|
||||
let type = elt.type.toLowerCase();
|
||||
{ // sometimes the elem doesn't have .localName
|
||||
let tagname = elem.localName.toLowerCase();
|
||||
let type = elem.type.toLowerCase();
|
||||
|
||||
if ((tagname == "input" && (type != "image")) ||
|
||||
tagname == "textarea" ||
|
||||
@@ -524,7 +568,7 @@ function Events() //{{{
|
||||
{
|
||||
// hacky way to get rid of "Transfering data from ..." on sites with frames
|
||||
// when you click on a link inside a frameset, because asyncUpdateUI
|
||||
// is not triggered there (firefox bug?)
|
||||
// is not triggered there (Firefox bug?)
|
||||
setTimeout(statusline.updateUrl, 10);
|
||||
return;
|
||||
}
|
||||
@@ -568,7 +612,7 @@ function Events() //{{{
|
||||
{
|
||||
try
|
||||
{
|
||||
eventManager[method](event);
|
||||
self[method](event);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
@@ -587,7 +631,6 @@ function Events() //{{{
|
||||
// load all macros inside ~/.vimperator/macros/
|
||||
// setTimeout needed since io. is loaded after events.
|
||||
setTimeout (function () {
|
||||
// FIXME: largely duplicated for loading plugins
|
||||
try
|
||||
{
|
||||
let dirs = io.getRuntimeDirectories("macros");
|
||||
@@ -715,7 +758,7 @@ function Events() //{{{
|
||||
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
var eventManager = {
|
||||
const self = {
|
||||
|
||||
feedingKeys: false,
|
||||
|
||||
@@ -805,7 +848,7 @@ function Events() //{{{
|
||||
{
|
||||
if (lastMacro.length == 1)
|
||||
// TODO: ignore this like Vim?
|
||||
liberator.echoerr("Exxx: Register " + lastMacro + " not set");
|
||||
liberator.echoerr("Exxx: Register '" + lastMacro + "' not set");
|
||||
else
|
||||
liberator.echoerr("Exxx: Named macro '" + lastMacro + "' not set");
|
||||
}
|
||||
@@ -832,12 +875,18 @@ function Events() //{{{
|
||||
}
|
||||
},
|
||||
|
||||
// This method pushes keys into the event queue from liberator
|
||||
// it is similar to vim's feedkeys() method, but cannot cope with
|
||||
// 2 partially-fed strings, you have to feed one parsable string
|
||||
//
|
||||
// @param keys: a string like "2<C-f>" to pass
|
||||
// if you want < to be taken literally, prepend it with a \\
|
||||
/**
|
||||
* Pushes keys into the event queue from liberator it is similar to
|
||||
* Vim's feedkeys() method, but cannot cope with 2 partially-fed
|
||||
* strings, you have to feed one parsable string.
|
||||
*
|
||||
* @param {string} keys A string like "2<C-f>" to pass if you want "<"
|
||||
* to be taken literally, prepend it with a "\\".
|
||||
* @param {boolean} noremap Allow recursive mappings.
|
||||
* @param {boolean} silent Whether the command should be echoed to the
|
||||
* command-line.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
feedkeys: function (keys, noremap, silent)
|
||||
{
|
||||
let doc = window.document;
|
||||
@@ -965,7 +1014,7 @@ function Events() //{{{
|
||||
if (event.metaKey)
|
||||
modifier += "M-";
|
||||
|
||||
if (event.type == "keypress")
|
||||
if (/^key/.test(event.type))
|
||||
{
|
||||
if (event.charCode == 0)
|
||||
{
|
||||
@@ -1043,8 +1092,9 @@ function Events() //{{{
|
||||
if (buffer.loaded == 1)
|
||||
return true;
|
||||
|
||||
const maxWaitTime = 25;
|
||||
let start = Date.now();
|
||||
let end = start + 25000; // maximum time to wait - TODO: add option
|
||||
let end = start + (maxWaitTime * 1000); // maximum time to wait - TODO: add option
|
||||
let now;
|
||||
while (now = Date.now(), now < end)
|
||||
{
|
||||
@@ -1061,14 +1111,14 @@ function Events() //{{{
|
||||
break;
|
||||
}
|
||||
else
|
||||
liberator.echomsg("Waiting for page to load...");
|
||||
liberator.echo("Waiting for page to load...", commandline.DISALLOW_MULTILINE);
|
||||
}
|
||||
modes.show();
|
||||
|
||||
// TODO: allow macros to be continued when page does not fully load with an option
|
||||
let ret = (buffer.loaded == 1);
|
||||
if (!ret)
|
||||
liberator.echoerr("Page did not load completely in " + ms + " milliseconds. Macro stopped.");
|
||||
liberator.echoerr("Page did not load completely in " + maxWaitTime + " seconds. Macro stopped.");
|
||||
liberator.dump("done waiting: " + ret);
|
||||
|
||||
// sometimes the input widget had focus when replaying a macro
|
||||
@@ -1078,10 +1128,10 @@ function Events() //{{{
|
||||
return ret;
|
||||
},
|
||||
|
||||
// argument "event" is delibarately not used, as i don't seem to have
|
||||
// argument "event" is deliberately not used, as i don't seem to have
|
||||
// access to the real focus target
|
||||
//
|
||||
// the ugly wantsModeReset is needed, because firefox generates a massive
|
||||
// the ugly wantsModeReset is needed, because Firefox generates a massive
|
||||
// amount of focus changes for things like <C-v><C-k> (focusing the search field)
|
||||
onFocusChange: function (event)
|
||||
{
|
||||
@@ -1128,7 +1178,7 @@ function Events() //{{{
|
||||
|
||||
if (config.name == "Muttator")
|
||||
{
|
||||
// we switch to -- MESSAGE -- mode for muttator, when the main HTML widget gets focus
|
||||
// we switch to -- MESSAGE -- mode for Muttator, when the main HTML widget gets focus
|
||||
if (hasHTMLDocument(win) || elem instanceof HTMLAnchorElement)
|
||||
{
|
||||
if (config.isComposeWindow)
|
||||
@@ -1334,7 +1384,7 @@ function Events() //{{{
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX: ugly hack for now pass certain keys to firefox as they are without beeping
|
||||
// XXX: ugly hack for now pass certain keys to Firefox as they are without beeping
|
||||
// also fixes key navigation in combo boxes, submitting forms, etc.
|
||||
// FIXME: breaks iabbr for now --mst
|
||||
if ((config.name == "Vimperator" && liberator.mode == modes.NORMAL)
|
||||
@@ -1373,7 +1423,7 @@ function Events() //{{{
|
||||
return false;
|
||||
}
|
||||
|
||||
// others are left to generate the 'input' event or handled by firefox
|
||||
// others are left to generate the 'input' event or handled by Firefox
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1503,7 +1553,7 @@ function Events() //{{{
|
||||
|
||||
if (key != "<Esc>" && key != "<C-[>")
|
||||
{
|
||||
// allow key to be passed to firefox if we can't handle it
|
||||
// allow key to be passed to Firefox if we can't handle it
|
||||
stop = false;
|
||||
|
||||
if (liberator.mode == modes.COMMAND_LINE)
|
||||
@@ -1673,7 +1723,7 @@ function Events() //{{{
|
||||
}
|
||||
}; //}}}
|
||||
|
||||
window.XULBrowserWindow = eventManager.progressListener;
|
||||
window.XULBrowserWindow = self.progressListener;
|
||||
window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
|
||||
@@ -1682,21 +1732,21 @@ function Events() //{{{
|
||||
.XULBrowserWindow = window.XULBrowserWindow;
|
||||
try
|
||||
{
|
||||
getBrowser().addProgressListener(eventManager.progressListener, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
getBrowser().addProgressListener(self.progressListener, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
eventManager.prefObserver.register();
|
||||
self.prefObserver.register();
|
||||
liberator.registerObserver("shutdown", function () {
|
||||
eventManager.destroy();
|
||||
eventManager.prefObserver.unregister();
|
||||
self.destroy();
|
||||
self.prefObserver.unregister();
|
||||
});
|
||||
|
||||
window.addEventListener("keypress", wrapListener("onKeyPress"), true);
|
||||
window.addEventListener("keydown", wrapListener("onKeyUpOrDown"), true);
|
||||
window.addEventListener("keyup", wrapListener("onKeyUpOrDown"), true);
|
||||
|
||||
return eventManager;
|
||||
return self;
|
||||
|
||||
}; //}}}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ function Search() //{{{
|
||||
// strip case-sensitive modifiers
|
||||
pattern = pattern.replace(/(\\)?\\[cC]/g, function ($0, $1) { return $1 ? $0 : ""; });
|
||||
|
||||
// remove any modifer escape \
|
||||
// remove any modifier escape \
|
||||
pattern = pattern.replace(/\\(\\[cClL])/g, "$1");
|
||||
|
||||
searchString = pattern;
|
||||
@@ -440,7 +440,7 @@ function Search() //{{{
|
||||
// TODO: code to reposition the document to the place before search started
|
||||
},
|
||||
|
||||
// FIXME: thunderbird incompatible
|
||||
// FIXME: Thunderbird incompatible
|
||||
// this is not dependent on the value of 'hlsearch'
|
||||
highlight: function (text)
|
||||
{
|
||||
@@ -469,7 +469,6 @@ function Search() //{{{
|
||||
// highlighted
|
||||
getBrowser().fastFind.collapseSelection();
|
||||
}
|
||||
|
||||
};
|
||||
//}}}
|
||||
}; //}}}
|
||||
|
||||
@@ -9,3 +9,4 @@ let url = page ? "chrome://liberator/locale/" + page : content.history.previous;
|
||||
|
||||
win.getBrowser().loadURIWithFlags(url, Components.interfaces.nsIWebNavigation.LOAD_FLAGS_REPLACE_HISTORY, null, null, null);
|
||||
|
||||
// vim: set fdm=marker sw=4 ts=4 et:
|
||||
|
||||
@@ -47,7 +47,7 @@ function Hints() //{{{
|
||||
var hintNumber = 0; // only the numerical part of the hint
|
||||
var usedTabKey = false; // when we used <Tab> to select an element
|
||||
var prevInput = ""; // record previous user input type, "text" || "number"
|
||||
var extendedhintCount; // for the count arugument of Mode#action (extended hint only)
|
||||
var extendedhintCount; // for the count argument of Mode#action (extended hint only)
|
||||
|
||||
// hints[] = [elem, text, span, imgspan, elem.style.backgroundColor, elem.style.color]
|
||||
var pageHints = [];
|
||||
@@ -65,24 +65,42 @@ function Hints() //{{{
|
||||
function extended() options.extendedhinttags;
|
||||
const hintModes = {
|
||||
";": Mode("Focus hint", function (elem) buffer.focusElement(elem), extended),
|
||||
"?": 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 () "//body | //xhtml:body"),
|
||||
s: Mode("Save hint", function (elem) buffer.saveLink(elem, true)),
|
||||
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)),
|
||||
v: Mode("View hint source", function (elem, loc) buffer.viewSource(loc, false), extended),
|
||||
V: Mode("View hint source", function (elem, loc) buffer.viewSource(loc, true), extended),
|
||||
w: Mode("Follow hint in a new window", function (elem) buffer.followLink(elem, liberator.NEW_WINDOW), extended),
|
||||
|
||||
"?": Mode("Show information for hint", function (elem) buffer.showElementInfo(elem), extended),
|
||||
O: Mode("Open location based on hint", function (elem, loc) commandline.open(":", "open " + loc, modes.EX)),
|
||||
T: Mode("Open new tab based on hint", function (elem, loc) commandline.open(":", "tabopen " + loc, modes.EX)),
|
||||
W: Mode("Open new window based on hint", function (elem, loc) commandline.open(":", "winopen " + loc, modes.EX)),
|
||||
F: Mode("Follow hint sequence in tabs", hintSequenceElement),
|
||||
O: Mode("Preselect hint in an :open query", function (elem, loc) commandline.open(":", "open " + loc, modes.EX)),
|
||||
T: Mode("Preselect hint in a :tabopen query", function (elem, loc) commandline.open(":", "tabopen " + loc, modes.EX)),
|
||||
W: Mode("Preselect hint in a :winopen query", function (elem, loc) commandline.open(":", "winopen " + loc, modes.EX)),
|
||||
v: Mode("View hint source", function (elem, loc) buffer.viewSource(loc, false), extended),
|
||||
V: Mode("View hint source in external editor", function (elem, loc) buffer.viewSource(loc, true), extended),
|
||||
y: Mode("Yank hint location", function (elem, loc) util.copyToClipboard(loc, true)),
|
||||
Y: Mode("Yank hint description", function (elem) util.copyToClipboard(elem.textContent || "", true), extended)
|
||||
};
|
||||
|
||||
// Used to open multiple hints
|
||||
function hintSequenceElement(elem)
|
||||
{
|
||||
// Want to always open sequence hints in background
|
||||
// (remember: NEW_BACKGROUND_TAB and NEW_TAB semantics assume
|
||||
// that loadInBackground=true)
|
||||
if (options.getPref("browser.tabs.loadInBackground"))
|
||||
buffer.followLink(elem, liberator.NEW_BACKGROUND_TAB);
|
||||
else
|
||||
buffer.followLink(elem, liberator.NEW_TAB);
|
||||
|
||||
// Move to next element in sequence
|
||||
// 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");
|
||||
}
|
||||
|
||||
// reset all important variables
|
||||
function reset()
|
||||
{
|
||||
@@ -209,7 +227,7 @@ function Hints() //{{{
|
||||
let scrollY = doc.defaultView.scrollY;
|
||||
|
||||
inner:
|
||||
for (let i in (util.interruptableRange(start, end + 1, 500)))
|
||||
for (let i in (util.interruptibleRange(start, end + 1, 500)))
|
||||
{
|
||||
let hint = pageHints[i];
|
||||
[elem, text, span, imgspan] = hint;
|
||||
@@ -340,7 +358,7 @@ function Hints() //{{{
|
||||
removeHints(timeout);
|
||||
|
||||
if (timeout == 0)
|
||||
// force a possible mode change, based on wheter an input field has focus
|
||||
// force a possible mode change, based on whether an input field has focus
|
||||
events.onFocusChange();
|
||||
setTimeout(function () {
|
||||
if (modes.extended & modes.HINTS)
|
||||
|
||||
@@ -108,10 +108,10 @@ function IO() //{{{
|
||||
|
||||
function joinPaths(head, tail)
|
||||
{
|
||||
let path = ioManager.getFile(head);
|
||||
let path = self.getFile(head);
|
||||
try
|
||||
{
|
||||
path.appendRelativePath(ioManager.expandPath(tail, true)); // FIXME: should only expand env vars and normalise path separators
|
||||
path.appendRelativePath(self.expandPath(tail, true)); // FIXME: should only expand env vars and normalise path separators
|
||||
if (path.exists() && path.normalize)
|
||||
path.normalize();
|
||||
}
|
||||
@@ -379,14 +379,14 @@ function IO() //{{{
|
||||
|
||||
liberator.registerObserver("load_completion", function ()
|
||||
{
|
||||
completion.setFunctionCompleter([ioManager.getFile, ioManager.expandPath],
|
||||
completion.setFunctionCompleter([self.getFile, self.expandPath],
|
||||
[function (context, obj, args) {
|
||||
context.quote[2] = "";
|
||||
completion.file(context, true);
|
||||
}]);
|
||||
});
|
||||
|
||||
var ioManager = {
|
||||
const self = {
|
||||
|
||||
MODE_RDONLY: 0x01,
|
||||
MODE_WRONLY: 0x02,
|
||||
@@ -405,7 +405,7 @@ function IO() //{{{
|
||||
// Firefox's CWD - see // https://bugzilla.mozilla.org/show_bug.cgi?id=280953
|
||||
getCurrentDirectory: function ()
|
||||
{
|
||||
let dir = ioManager.getFile(cwd.path);
|
||||
let dir = self.getFile(cwd.path);
|
||||
|
||||
// NOTE: the directory could have been deleted underneath us so
|
||||
// fallback to Firefox's CWD
|
||||
@@ -425,7 +425,7 @@ function IO() //{{{
|
||||
}
|
||||
else
|
||||
{
|
||||
let dir = ioManager.getFile(newdir);
|
||||
let dir = self.getFile(newdir);
|
||||
|
||||
if (!dir.exists() || !dir.isDirectory())
|
||||
{
|
||||
@@ -436,7 +436,7 @@ function IO() //{{{
|
||||
[cwd, oldcwd] = [dir, this.getCurrentDirectory()];
|
||||
}
|
||||
|
||||
return ioManager.getCurrentDirectory();
|
||||
return self.getCurrentDirectory();
|
||||
},
|
||||
|
||||
getRuntimeDirectories: function (specialDirectory)
|
||||
@@ -482,10 +482,10 @@ function IO() //{{{
|
||||
}
|
||||
else
|
||||
{
|
||||
let expandedPath = ioManager.expandPath(path);
|
||||
let expandedPath = self.expandPath(path);
|
||||
|
||||
if (!isAbsolutePath(expandedPath) && !noCheckPWD)
|
||||
file = joinPaths(ioManager.getCurrentDirectory().path, expandedPath);
|
||||
file = joinPaths(self.getCurrentDirectory().path, expandedPath);
|
||||
else
|
||||
file.initWithPath(expandedPath);
|
||||
}
|
||||
@@ -502,7 +502,7 @@ function IO() //{{{
|
||||
switch (EXTENSION_NAME)
|
||||
{
|
||||
case "muttator":
|
||||
tmpName = "mutt-ator-mail"; // to allow vim to :set ft=mail automatically
|
||||
tmpName = "mutt-ator-mail"; // to allow Vim to :set ft=mail automatically
|
||||
break;
|
||||
case "vimperator":
|
||||
try
|
||||
@@ -529,7 +529,7 @@ function IO() //{{{
|
||||
readDirectory: function (file, sort)
|
||||
{
|
||||
if (typeof file == "string")
|
||||
file = ioManager.getFile(file);
|
||||
file = self.getFile(file);
|
||||
else if (!(file instanceof Ci.nsILocalFile))
|
||||
throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined
|
||||
|
||||
@@ -543,11 +543,12 @@ function IO() //{{{
|
||||
array.push(entry.QueryInterface(Ci.nsIFile));
|
||||
}
|
||||
if (sort)
|
||||
return array.sort(function (a, b) b.isDirectory() - a.isDirectory() || String.localeCompare(a.path, b.path));
|
||||
array.sort(function (a, b) b.isDirectory() - a.isDirectory() || String.localeCompare(a.path, b.path));
|
||||
return array;
|
||||
}
|
||||
else
|
||||
return []; // XXX: or should it throw an error, probably yes?
|
||||
// Yes --djk
|
||||
},
|
||||
|
||||
// file is either a full pathname or an instance of file instanceof nsILocalFile
|
||||
@@ -559,7 +560,7 @@ function IO() //{{{
|
||||
|
||||
let toCharset = "UTF-8";
|
||||
if (typeof file == "string")
|
||||
file = ioManager.getFile(file);
|
||||
file = self.getFile(file);
|
||||
else if (!(file instanceof Ci.nsILocalFile))
|
||||
throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined
|
||||
|
||||
@@ -587,14 +588,14 @@ function IO() //{{{
|
||||
|
||||
let charset = "UTF-8"; // Can be any character encoding name that Mozilla supports
|
||||
if (typeof file == "string")
|
||||
file = ioManager.getFile(file);
|
||||
file = self.getFile(file);
|
||||
else if (!(file instanceof Ci.nsILocalFile))
|
||||
throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined
|
||||
|
||||
if (mode == ">>")
|
||||
mode = ioManager.MODE_WRONLY | ioManager.MODE_CREATE | ioManager.MODE_APPEND;
|
||||
mode = self.MODE_WRONLY | self.MODE_CREATE | self.MODE_APPEND;
|
||||
else if (!mode || mode == ">")
|
||||
mode = ioManager.MODE_WRONLY | ioManager.MODE_CREATE | ioManager.MODE_TRUNCATE;
|
||||
mode = self.MODE_WRONLY | self.MODE_CREATE | self.MODE_TRUNCATE;
|
||||
|
||||
if (!perms)
|
||||
perms = 0644;
|
||||
@@ -616,12 +617,12 @@ function IO() //{{{
|
||||
|
||||
if (isAbsolutePath(program))
|
||||
{
|
||||
file = ioManager.getFile(program, true);
|
||||
file = self.getFile(program, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
let dirs = services.get("environment").get("PATH").split(WINDOWS ? ";" : ":");
|
||||
// Windows tries the cwd first TODO: desirable?
|
||||
// Windows tries the CWD first TODO: desirable?
|
||||
if (WINDOWS)
|
||||
dirs = [io.getCurrentDirectory().path].concat(dirs);
|
||||
|
||||
@@ -693,9 +694,9 @@ lookup:
|
||||
}
|
||||
|
||||
if (res > 0) // FIXME: Is this really right? Shouldn't we always show both?
|
||||
var output = ioManager.readFile(stderr) + "\nshell returned " + res;
|
||||
var output = self.readFile(stderr) + "\nshell returned " + res;
|
||||
else
|
||||
output = ioManager.readFile(stdout);
|
||||
output = self.readFile(stdout);
|
||||
|
||||
// if there is only one \n at the end, chop it off
|
||||
if (output && output.indexOf("\n") == output.length - 1)
|
||||
@@ -740,15 +741,15 @@ lookup:
|
||||
return found;
|
||||
},
|
||||
|
||||
// files which end in .js are sourced as pure javascript files,
|
||||
// files which end in .js are sourced as pure JavaScript files,
|
||||
// no need (actually forbidden) to add: js <<EOF ... EOF around those files
|
||||
source: function (filename, silent)
|
||||
{
|
||||
let wasSourcing = ioManager.sourcing;
|
||||
let wasSourcing = self.sourcing;
|
||||
try
|
||||
{
|
||||
var file = ioManager.getFile(filename);
|
||||
ioManager.sourcing = {
|
||||
var file = self.getFile(filename);
|
||||
self.sourcing = {
|
||||
file: file.path,
|
||||
line: 0
|
||||
};
|
||||
@@ -770,10 +771,10 @@ lookup:
|
||||
|
||||
liberator.echomsg("sourcing " + filename.quote(), 2);
|
||||
|
||||
let str = ioManager.readFile(file);
|
||||
let str = self.readFile(file);
|
||||
let uri = ioService.newFileURI(file);
|
||||
|
||||
// handle pure javascript files specially
|
||||
// handle pure JavaScript files specially
|
||||
if (/\.js$/.test(filename))
|
||||
{
|
||||
try
|
||||
@@ -797,7 +798,7 @@ lookup:
|
||||
{
|
||||
let heredoc = "";
|
||||
let heredocEnd = null; // the string which ends the heredoc
|
||||
let lines = str.split("\n");
|
||||
let lines = str.split(/\r\n|[\r\n]/);
|
||||
|
||||
for (let [i, line] in Iterator(lines))
|
||||
{
|
||||
@@ -816,7 +817,7 @@ lookup:
|
||||
}
|
||||
else
|
||||
{
|
||||
ioManager.sourcing.line = i + 1;
|
||||
self.sourcing.line = i + 1;
|
||||
// skip line comments and blank lines
|
||||
line = line.replace(/\r$/, "");
|
||||
|
||||
@@ -891,7 +892,7 @@ lookup:
|
||||
}
|
||||
finally
|
||||
{
|
||||
ioManager.sourcing = wasSourcing;
|
||||
self.sourcing = wasSourcing;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -911,7 +912,7 @@ lookup:
|
||||
}
|
||||
}; //}}}
|
||||
|
||||
return ioManager;
|
||||
return self;
|
||||
|
||||
}; //}}}
|
||||
|
||||
@@ -921,8 +922,16 @@ IO.PATH_SEP = (function () {
|
||||
return file.path[0];
|
||||
})();
|
||||
|
||||
IO.__defineGetter__("runtimePath", function () services.get("environment").get(config.name.toUpperCase() + "_RUNTIME") ||
|
||||
"~/" + (liberator.has("Win32") ? "" : ".") + config.name.toLowerCase());
|
||||
IO.__defineGetter__("runtimePath", function () {
|
||||
const rtpvar = config.name.toUpperCase() + "_RUNTIME";
|
||||
let rtp = services.get("environment").get(rtpvar);
|
||||
if (!rtp)
|
||||
{
|
||||
rtp = "~/" + (liberator.has("Win32") ? "" : ".") + config.name.toLowerCase();
|
||||
services.get("environment").set(rtpvar, rtp);
|
||||
}
|
||||
return rtp;
|
||||
});
|
||||
|
||||
IO.expandPath = function (path, relative)
|
||||
{
|
||||
@@ -947,7 +956,7 @@ IO.expandPath = function (path, relative)
|
||||
// Try $HOME first, on all systems
|
||||
let home = services.get("environment").get("HOME");
|
||||
|
||||
// Windows has its own ideosyncratic $HOME variables.
|
||||
// Windows has its own idiosyncratic $HOME variables.
|
||||
if (!home && WINDOWS)
|
||||
home = services.get("environment").get("USERPROFILE") ||
|
||||
services.get("environment").get("HOMEDRIVE") + services.get("environment").get("HOMEPATH");
|
||||
|
||||
@@ -57,11 +57,14 @@ const liberator = (function () //{{{
|
||||
run: function () { this.func.apply(this.self, this.args); }
|
||||
};
|
||||
|
||||
var callbacks = [];
|
||||
var observers = [];
|
||||
const callbacks = {};
|
||||
const observers = {};
|
||||
|
||||
function registerObserver(type, callback)
|
||||
{
|
||||
observers.push([type, callback]);
|
||||
if (!(type in observers))
|
||||
observers[type] = [];
|
||||
observers[type].push(callback);
|
||||
}
|
||||
|
||||
let nError = 0;
|
||||
@@ -83,7 +86,7 @@ const liberator = (function () //{{{
|
||||
}
|
||||
}
|
||||
|
||||
// Only general options are added here, which are valid for all vimperator like extensions
|
||||
// Only general options are added here, which are valid for all Vimperator like extensions
|
||||
registerObserver("load_options", function ()
|
||||
{
|
||||
options.add(["errorbells", "eb"],
|
||||
@@ -364,7 +367,7 @@ const liberator = (function () //{{{
|
||||
"Run a JavaScript command through eval()",
|
||||
function (args)
|
||||
{
|
||||
if (args.bang) // open javascript console
|
||||
if (args.bang) // open JavaScript console
|
||||
{
|
||||
liberator.open("chrome://global/content/console.xul",
|
||||
(options["newtab"] && options.get("newtab").has("all", "javascript"))
|
||||
@@ -449,7 +452,7 @@ const liberator = (function () //{{{
|
||||
let each, eachUnits, totalUnits;
|
||||
let total = 0;
|
||||
|
||||
for (let i in util.interruptableRange(0, count, 500))
|
||||
for (let i in util.interruptibleRange(0, count, 500))
|
||||
{
|
||||
let now = Date.now();
|
||||
method();
|
||||
@@ -605,6 +608,11 @@ const liberator = (function () //{{{
|
||||
// ###VERSION### and ###DATE### are replaced by the Makefile
|
||||
version: "###VERSION### (created: ###DATE###)",
|
||||
|
||||
// NOTE: services.get("profile").selectedProfile.name is not rightness.
|
||||
// If default profile Firefox runs without arguments,
|
||||
// then selectedProfile returns last selected profile! (not current one!)
|
||||
profileName: services.get("directory").get("ProfD", Ci.nsIFile).leafName.replace(/^.+?\./, ""),
|
||||
|
||||
// TODO: move to events.js?
|
||||
input: {
|
||||
buffer: "", // partial command storage
|
||||
@@ -622,19 +630,15 @@ const liberator = (function () //{{{
|
||||
// TODO: move to ui.js?
|
||||
registerCallback: function (type, mode, func)
|
||||
{
|
||||
// TODO: check if callback is already registered
|
||||
callbacks.push([type, mode, func]);
|
||||
if (!(type in callbacks))
|
||||
callbacks[type] = {};
|
||||
callbacks[type][mode] = func;
|
||||
},
|
||||
|
||||
triggerCallback: function (type, mode, data)
|
||||
{
|
||||
// liberator.dump("type: " + type + " mode: " + mode + "data: " + data + "\n");
|
||||
for (let i = 0; i < callbacks.length; i++)
|
||||
{
|
||||
let [thistype, thismode, thisfunc] = callbacks[i];
|
||||
if (mode == thismode && type == thistype)
|
||||
return thisfunc.call(this, data);
|
||||
}
|
||||
if (callbacks[type] && callbacks[type][mode])
|
||||
return callbacks[type][mode].call(this, data);
|
||||
return false;
|
||||
},
|
||||
|
||||
@@ -642,16 +646,14 @@ const liberator = (function () //{{{
|
||||
|
||||
unregisterObserver: function (type, callback)
|
||||
{
|
||||
observers = observers.filter(function ([t, c]) t != type || c != callback);
|
||||
if (type in observers)
|
||||
observers[type] = observers[type].filter(function (c) c != callback);
|
||||
},
|
||||
|
||||
triggerObserver: function (type)
|
||||
{
|
||||
for (let [,[thistype, callback]] in Iterator(observers))
|
||||
{
|
||||
if (thistype == type)
|
||||
callback.apply(null, Array.slice(arguments, 1));
|
||||
}
|
||||
for (let [,fn] in Iterator(observers[type] || []))
|
||||
fn.apply(null, Array.slice(arguments, 1));
|
||||
},
|
||||
|
||||
beep: function ()
|
||||
@@ -988,27 +990,17 @@ const liberator = (function () //{{{
|
||||
|
||||
loadPlugins: function ()
|
||||
{
|
||||
// FIXME: largely duplicated for loading macros
|
||||
try
|
||||
function sourceDirectory(dir)
|
||||
{
|
||||
let dirs = io.getRuntimeDirectories("plugin");
|
||||
|
||||
if (dirs.length == 0)
|
||||
if (!dir.isReadable())
|
||||
{
|
||||
liberator.log("No user plugin directory found", 3);
|
||||
liberator.echoerr("E484: Can't open file " + dir.path);
|
||||
return;
|
||||
}
|
||||
for (let [,dir] in Iterator(dirs))
|
||||
{
|
||||
// TODO: search plugins/**/* for plugins
|
||||
liberator.echomsg('Searching for "plugin/*.{js,vimp}" in ' + dir.path.quote(), 2);
|
||||
|
||||
liberator.log("Sourcing plugin directory: " + dir.path + "...", 3);
|
||||
|
||||
let files = io.readDirectory(dir.path, true);
|
||||
|
||||
files.forEach(function (file) {
|
||||
if (!file.isDirectory() && /\.(js|vimp)$/i.test(file.path) && !(file.path in liberator.pluginFiles))
|
||||
io.readDirectory(dir.path, true).forEach(function (file) {
|
||||
if (file.isFile() && /\.(js|vimp)$/i.test(file.path) && !(file.path in liberator.pluginFiles))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1020,17 +1012,31 @@ const liberator = (function () //{{{
|
||||
liberator.reportError(e);
|
||||
}
|
||||
}
|
||||
else if (file.isDirectory())
|
||||
{
|
||||
sourceDirectory(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
|
||||
let dirs = io.getRuntimeDirectories("plugin");
|
||||
|
||||
if (dirs.length == 0)
|
||||
{
|
||||
// thrown if directory does not exist
|
||||
liberator.log("Error sourcing plugin directory: " + e, 9);
|
||||
liberator.log("No user plugin directory found", 3);
|
||||
return;
|
||||
}
|
||||
|
||||
liberator.echomsg('Searching for "plugin/**/*.{js,vimp}" in '
|
||||
+ [dir.path.replace(/.plugin$/, "") for each (dir in dirs)].join(",").quote(), 2);
|
||||
|
||||
dirs.forEach(function (dir) {
|
||||
liberator.echomsg("Searching for " + (dir.path + "/**/*.{js,vimp}").quote(), 3);
|
||||
sourceDirectory(dir);
|
||||
});
|
||||
},
|
||||
|
||||
// logs a message to the javascript error console
|
||||
// logs a message to the JavaScript error console
|
||||
// if msg is an object, it is beautified
|
||||
// TODO: add proper level constants
|
||||
log: function (msg, level)
|
||||
@@ -1049,20 +1055,24 @@ const liberator = (function () //{{{
|
||||
if (typeof msg == "object")
|
||||
msg = util.objectToString(msg, false);
|
||||
|
||||
const consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
|
||||
consoleService.logStringMessage(config.name.toLowerCase() + ": " + msg);
|
||||
services.get("console").logStringMessage(config.name.toLowerCase() + ": " + msg);
|
||||
},
|
||||
|
||||
// open one or more URLs
|
||||
//
|
||||
// @param urls: either a string or an array of urls
|
||||
// The array can look like this:
|
||||
// ["url1", "url2", "url3", ...] or:
|
||||
// [["url1", postdata1], ["url2", postdata2], ...]
|
||||
// @param where: if ommited, CURRENT_TAB is assumed
|
||||
// but NEW_TAB is set when liberator.forceNewTab is true.
|
||||
// @param force: Don't prompt whether to open more than 20 tabs.
|
||||
// @returns true when load was initiated, or false on error
|
||||
/**
|
||||
* Opens one or more URLs. Returns true when load was initiated, or
|
||||
* false on error.
|
||||
*
|
||||
* @param {FIXME} urls Either a URL string or an array of URLs.
|
||||
* The array can look like this:
|
||||
* ["url1", "url2", "url3", ...]
|
||||
* or:
|
||||
* [["url1", postdata1], ["url2", postdata2], ...]
|
||||
* @param {number} where If ommited, CURRENT_TAB is assumed but NEW_TAB
|
||||
* is set when liberator.forceNewTab is true.
|
||||
* @param {boolean} force Don't prompt whether to open more than 20
|
||||
* tabs.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
open: function (urls, where, force)
|
||||
{
|
||||
// convert the string to an array of converted URLs
|
||||
@@ -1083,6 +1093,8 @@ const liberator = (function () //{{{
|
||||
if (urls.length == 0)
|
||||
return false;
|
||||
|
||||
let browser = window.getBrowser();
|
||||
|
||||
function open(urls, where)
|
||||
{
|
||||
let url = Array.concat(urls)[0];
|
||||
@@ -1092,7 +1104,7 @@ const liberator = (function () //{{{
|
||||
switch (where)
|
||||
{
|
||||
case liberator.CURRENT_TAB:
|
||||
getBrowser().loadURIWithFlags(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, postdata);
|
||||
browser.loadURIWithFlags(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, postdata);
|
||||
break;
|
||||
|
||||
case liberator.NEW_BACKGROUND_TAB:
|
||||
@@ -1100,21 +1112,21 @@ const liberator = (function () //{{{
|
||||
if (!liberator.has("tabs"))
|
||||
return open(urls, liberator.NEW_WINDOW);
|
||||
|
||||
let tab = getBrowser().addTab(url, null, null, postdata);
|
||||
|
||||
if (where == liberator.NEW_TAB)
|
||||
getBrowser().selectedTab = tab;
|
||||
options.withContext(function () {
|
||||
options.setPref("browser.tabs.loadInBackground", true);
|
||||
browser.loadOneTab(url, null, null, postdata, where == liberator.NEW_BACKGROUND_TAB);
|
||||
});
|
||||
break;
|
||||
|
||||
case liberator.NEW_WINDOW:
|
||||
window.open();
|
||||
services.get("windowMediator").getMostRecentWindow("navigator:browser")
|
||||
.loadURI(url, null, postdata);
|
||||
let win = services.get("windowMediator").getMostRecentWindow("navigator:browser");
|
||||
win.loadURI(url, null, postdata);
|
||||
browser = win.getBrowser();
|
||||
break;
|
||||
|
||||
default:
|
||||
liberator.echoerr("Exxx: Invalid 'where' directive in liberator.open(...)");
|
||||
return false;
|
||||
throw Error("Invalid 'where' directive in liberator.open(...)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1123,7 +1135,7 @@ const liberator = (function () //{{{
|
||||
else if (!where)
|
||||
where = liberator.CURRENT_TAB;
|
||||
|
||||
for (let [i, url] in Iterator(urls))
|
||||
for (let [,url] in Iterator(urls))
|
||||
{
|
||||
open(url, where);
|
||||
where = liberator.NEW_BACKGROUND_TAB;
|
||||
@@ -1227,7 +1239,7 @@ const liberator = (function () //{{{
|
||||
let infoPath = services.create("file");
|
||||
infoPath.initWithPath(IO.expandPath(IO.runtimePath.replace(/,.*/, "")));
|
||||
infoPath.append("info");
|
||||
infoPath.append(services.get("profile").selectedProfile.name);
|
||||
infoPath.append(liberator.profileName);
|
||||
storage.infoPath = infoPath;
|
||||
}
|
||||
catch (e)
|
||||
@@ -1235,8 +1247,6 @@ const liberator = (function () //{{{
|
||||
liberator.reportError(e);
|
||||
}
|
||||
|
||||
liberator.triggerObserver("load");
|
||||
|
||||
// commands must always be the first module to be initialized
|
||||
loadModule("commands", Commands);
|
||||
loadModule("options", Options);
|
||||
@@ -1254,6 +1264,8 @@ const liberator = (function () //{{{
|
||||
if (config.init)
|
||||
config.init();
|
||||
|
||||
liberator.triggerObserver("load");
|
||||
|
||||
liberator.log("All modules loaded", 3);
|
||||
|
||||
// first time intro message
|
||||
@@ -1404,6 +1416,21 @@ const liberator = (function () //{{{
|
||||
|
||||
window.liberator = liberator;
|
||||
|
||||
// FIXME: Ugly, etc.
|
||||
window.addEventListener("liberatorHelpLink", function (event) {
|
||||
let elem = event.target;
|
||||
liberator.dump(String(elem));
|
||||
if (/^(option|mapping|command)$/.test(elem.className))
|
||||
var tag = elem.textContent.replace(/\s.*/, "");
|
||||
if (elem.className == "command")
|
||||
tag = tag.replace(/\[.*?\]/g, "");
|
||||
if (tag)
|
||||
var page = liberator.findHelp(tag);
|
||||
if (page)
|
||||
elem.href = "chrome://liberator/locale/" + page;
|
||||
},
|
||||
true, true);
|
||||
|
||||
// called when the chrome is fully loaded and before the main window is shown
|
||||
window.addEventListener("load", liberator.startup, false);
|
||||
window.addEventListener("unload", liberator.shutdown, false);
|
||||
|
||||
@@ -85,6 +85,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
<label class="plain" id="liberator-commandline-prompt" flex="0" crop="end" value="" collapsed="true"/>
|
||||
<textbox class="plain" id="liberator-commandline-command" flex="1" type="timed" timeout="100"
|
||||
oninput="liberator.modules.commandline.onEvent(event);"
|
||||
onkeyup="liberator.modules.commandline.onEvent(event);"
|
||||
onfocus="liberator.modules.commandline.onEvent(event);"
|
||||
onblur="liberator.modules.commandline.onEvent(event);"/>
|
||||
</hbox>
|
||||
|
||||
@@ -283,7 +283,7 @@ function Mappings() //{{{
|
||||
|
||||
// FIXME:
|
||||
Mappings.flags = {
|
||||
ALLOW_EVENT_ROUTING: 1 << 0, // if set, return true inside the map command to pass the event further to firefox
|
||||
ALLOW_EVENT_ROUTING: 1 << 0, // if set, return true inside the map command to pass the event further to Firefox
|
||||
MOTION: 1 << 1,
|
||||
COUNT: 1 << 2,
|
||||
ARGUMENT: 1 << 3
|
||||
|
||||
@@ -126,7 +126,8 @@ const modes = (function () //{{{
|
||||
////////////////////// PUBLIC SECTION //////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
var self = {
|
||||
const self = {
|
||||
|
||||
NONE: 0,
|
||||
|
||||
__iterator__: function () util.Array.iterator(this.all),
|
||||
|
||||
@@ -125,7 +125,7 @@ Option.prototype = {
|
||||
aValue = this.globalvalue;
|
||||
|
||||
if (this.getter)
|
||||
this.getter.call(this, aValue);
|
||||
return this.getter.call(this, aValue);
|
||||
|
||||
return aValue;
|
||||
},
|
||||
@@ -393,167 +393,7 @@ function Options() //{{{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// firefox preferences which need to be changed to work well with vimperator
|
||||
//
|
||||
|
||||
// work around firefox popup blocker
|
||||
// TODO: Make this work like safeSetPref
|
||||
var popupAllowedEvents = loadPreference("dom.popup_allowed_events", "change click dblclick mouseup reset submit");
|
||||
if (!/keypress/.test(popupAllowedEvents))
|
||||
{
|
||||
storePreference("dom.popup_allowed_events", popupAllowedEvents + " keypress");
|
||||
liberator.registerObserver("shutdown", function ()
|
||||
{
|
||||
if (loadPreference("dom.popup_allowed_events", "")
|
||||
== popupAllowedEvents + " keypress")
|
||||
storePreference("dom.popup_allowed_events", popupAllowedEvents);
|
||||
});
|
||||
}
|
||||
|
||||
// safeSetPref might try to echomsg. Need commandline.
|
||||
liberator.registerObserver("load_commandline", function () {
|
||||
// TODO: maybe reset in .destroy()?
|
||||
// TODO: move to buffer.js
|
||||
// we have our own typeahead find implementation
|
||||
options.safeSetPref("accessibility.typeaheadfind.autostart", false);
|
||||
options.safeSetPref("accessibility.typeaheadfind", false); // actually the above setting should do it, but has no effect in firefox
|
||||
});
|
||||
|
||||
// start with saved session
|
||||
storePreference("browser.startup.page", 3);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////}}}
|
||||
////////////////////// COMMANDS ////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
commands.add(["let"],
|
||||
"Set or list a variable",
|
||||
function (args)
|
||||
{
|
||||
args = args.string;
|
||||
|
||||
if (!args)
|
||||
{
|
||||
let str =
|
||||
<table>
|
||||
{
|
||||
template.map(liberator.globalVariables, function ([i, value]) {
|
||||
let prefix = typeof value == "number" ? "#" :
|
||||
typeof value == "function" ? "*" :
|
||||
" ";
|
||||
return <tr>
|
||||
<td style="width: 200px;">{i}</td>
|
||||
<td>{prefix}{value}</td>
|
||||
</tr>
|
||||
})
|
||||
}
|
||||
</table>;
|
||||
if (str.*.length())
|
||||
liberator.echo(str, commandline.FORCE_MULTILINE);
|
||||
else
|
||||
liberator.echomsg("No variables found");
|
||||
return;
|
||||
}
|
||||
|
||||
let matches;
|
||||
// 1 - type, 2 - name, 3 - +-., 4 - expr
|
||||
if (matches = args.match(/([$@&])?([\w:]+)\s*([-+.])?=\s*(.+)/))
|
||||
{
|
||||
if (!matches[1])
|
||||
{
|
||||
let reference = liberator.variableReference(matches[2]);
|
||||
if (!reference[0] && matches[3])
|
||||
{
|
||||
liberator.echoerr("E121: Undefined variable: " + matches[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
let expr = liberator.evalExpression(matches[4]);
|
||||
if (expr === undefined)
|
||||
{
|
||||
liberator.echoerr("E15: Invalid expression: " + matches[4]);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!reference[0])
|
||||
{
|
||||
if (reference[2] == "g")
|
||||
reference[0] = liberator.globalVariables;
|
||||
else
|
||||
return; // for now
|
||||
}
|
||||
|
||||
if (matches[3])
|
||||
{
|
||||
if (matches[3] == "+")
|
||||
reference[0][reference[1]] += expr;
|
||||
else if (matches[3] == "-")
|
||||
reference[0][reference[1]] -= expr;
|
||||
else if (matches[3] == ".")
|
||||
reference[0][reference[1]] += expr.toString();
|
||||
}
|
||||
else
|
||||
reference[0][reference[1]] = expr;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 1 - name
|
||||
else if (matches = args.match(/^\s*([\w:]+)\s*$/))
|
||||
{
|
||||
let reference = liberator.variableReference(matches[1]);
|
||||
if (!reference[0])
|
||||
{
|
||||
liberator.echoerr("E121: Undefined variable: " + matches[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
let value = reference[0][reference[1]];
|
||||
let prefix = typeof value == "number" ? "#" :
|
||||
typeof value == "function" ? "*" :
|
||||
" ";
|
||||
liberator.echo(reference[1] + "\t\t" + prefix + value);
|
||||
}
|
||||
});
|
||||
|
||||
commands.add(["setl[ocal]"],
|
||||
"Set local option",
|
||||
function (args)
|
||||
{
|
||||
commands.get("set").execute(args.string, args.bang, args.count, { scope: options.OPTION_SCOPE_LOCAL });
|
||||
},
|
||||
{
|
||||
bang: true,
|
||||
count: true,
|
||||
completer: function (context, args)
|
||||
{
|
||||
return commands.get("set").completer(context.filter, args.bang, args.count, { scope: options.OPTION_SCOPE_LOCAL });
|
||||
},
|
||||
literal: 0
|
||||
}
|
||||
);
|
||||
|
||||
commands.add(["setg[lobal]"],
|
||||
"Set global option",
|
||||
function (args)
|
||||
{
|
||||
commands.get("set").execute(args.string, args.bang, args.count, { scope: options.OPTION_SCOPE_GLOBAL });
|
||||
},
|
||||
{
|
||||
bang: true,
|
||||
count: true,
|
||||
completer: function (context, args)
|
||||
{
|
||||
return commands.get("set").completer(context.filter, args.bang, args.count, { scope: options.OPTION_SCOPE_GLOBAL });
|
||||
},
|
||||
literal: 0
|
||||
}
|
||||
);
|
||||
|
||||
commands.add(["se[t]"],
|
||||
"Set an option",
|
||||
function (args, modifiers)
|
||||
function setAction(args, modifiers)
|
||||
{
|
||||
let bang = args.bang;
|
||||
if (!args.length)
|
||||
@@ -675,10 +515,9 @@ function Options() //{{{
|
||||
liberator.echoerr(res);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
bang: true,
|
||||
completer: function (context, args, modifiers)
|
||||
}
|
||||
|
||||
function setCompleter(context, args, modifiers)
|
||||
{
|
||||
let filter = context.filter;
|
||||
|
||||
@@ -737,6 +576,177 @@ function Options() //{{{
|
||||
}
|
||||
|
||||
completion.optionValue(context, opt.name, opt.operator);
|
||||
}
|
||||
|
||||
//
|
||||
// Firefox preferences which need to be changed to work well with Vimperator
|
||||
//
|
||||
|
||||
// work around Firefox popup blocker
|
||||
// TODO: Make this work like safeSetPref
|
||||
var popupAllowedEvents = loadPreference("dom.popup_allowed_events", "change click dblclick mouseup reset submit");
|
||||
if (!/keypress/.test(popupAllowedEvents))
|
||||
{
|
||||
storePreference("dom.popup_allowed_events", popupAllowedEvents + " keypress");
|
||||
liberator.registerObserver("shutdown", function ()
|
||||
{
|
||||
if (loadPreference("dom.popup_allowed_events", "")
|
||||
== popupAllowedEvents + " keypress")
|
||||
storePreference("dom.popup_allowed_events", popupAllowedEvents);
|
||||
});
|
||||
}
|
||||
|
||||
// safeSetPref might try to echomsg. Need commandline.
|
||||
liberator.registerObserver("load_commandline", function () {
|
||||
// TODO: maybe reset in .destroy()?
|
||||
// TODO: move to buffer.js
|
||||
// we have our own typeahead find implementation
|
||||
options.safeSetPref("accessibility.typeaheadfind.autostart", false);
|
||||
options.safeSetPref("accessibility.typeaheadfind", false); // actually the above setting should do it, but has no effect in Firefox
|
||||
});
|
||||
|
||||
// start with saved session
|
||||
storePreference("browser.startup.page", 3);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////}}}
|
||||
////////////////////// COMMANDS ////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
commands.add(["let"],
|
||||
"Set or list a variable",
|
||||
function (args)
|
||||
{
|
||||
args = args.string;
|
||||
|
||||
if (!args)
|
||||
{
|
||||
let str =
|
||||
<table>
|
||||
{
|
||||
template.map(liberator.globalVariables, function ([i, value]) {
|
||||
let prefix = typeof value == "number" ? "#" :
|
||||
typeof value == "function" ? "*" :
|
||||
" ";
|
||||
return <tr>
|
||||
<td style="width: 200px;">{i}</td>
|
||||
<td>{prefix}{value}</td>
|
||||
</tr>
|
||||
})
|
||||
}
|
||||
</table>;
|
||||
if (str.*.length())
|
||||
liberator.echo(str, commandline.FORCE_MULTILINE);
|
||||
else
|
||||
liberator.echomsg("No variables found");
|
||||
return;
|
||||
}
|
||||
|
||||
let matches;
|
||||
// 1 - type, 2 - name, 3 - +-., 4 - expr
|
||||
if (matches = args.match(/([$@&])?([\w:]+)\s*([-+.])?=\s*(.+)/))
|
||||
{
|
||||
if (!matches[1])
|
||||
{
|
||||
let reference = liberator.variableReference(matches[2]);
|
||||
if (!reference[0] && matches[3])
|
||||
{
|
||||
liberator.echoerr("E121: Undefined variable: " + matches[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
let expr = liberator.evalExpression(matches[4]);
|
||||
if (expr === undefined)
|
||||
{
|
||||
liberator.echoerr("E15: Invalid expression: " + matches[4]);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!reference[0])
|
||||
{
|
||||
if (reference[2] == "g")
|
||||
reference[0] = liberator.globalVariables;
|
||||
else
|
||||
return; // for now
|
||||
}
|
||||
|
||||
if (matches[3])
|
||||
{
|
||||
if (matches[3] == "+")
|
||||
reference[0][reference[1]] += expr;
|
||||
else if (matches[3] == "-")
|
||||
reference[0][reference[1]] -= expr;
|
||||
else if (matches[3] == ".")
|
||||
reference[0][reference[1]] += expr.toString();
|
||||
}
|
||||
else
|
||||
reference[0][reference[1]] = expr;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 1 - name
|
||||
else if (matches = args.match(/^\s*([\w:]+)\s*$/))
|
||||
{
|
||||
let reference = liberator.variableReference(matches[1]);
|
||||
if (!reference[0])
|
||||
{
|
||||
liberator.echoerr("E121: Undefined variable: " + matches[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
let value = reference[0][reference[1]];
|
||||
let prefix = typeof value == "number" ? "#" :
|
||||
typeof value == "function" ? "*" :
|
||||
" ";
|
||||
liberator.echo(reference[1] + "\t\t" + prefix + value);
|
||||
}
|
||||
});
|
||||
|
||||
commands.add(["setl[ocal]"],
|
||||
"Set local option",
|
||||
function (args)
|
||||
{
|
||||
return setAction(args, { scope: options.OPTION_SCOPE_LOCAL });
|
||||
},
|
||||
{
|
||||
bang: true,
|
||||
count: true,
|
||||
completer: function (context, args)
|
||||
{
|
||||
return setCompleter(context, args, { scope: options.OPTION_SCOPE_LOCAL });
|
||||
},
|
||||
literal: 0
|
||||
}
|
||||
);
|
||||
|
||||
commands.add(["setg[lobal]"],
|
||||
"Set global option",
|
||||
function (args)
|
||||
{
|
||||
return setAction(args, { scope: options.OPTION_SCOPE_GLOBAL });
|
||||
},
|
||||
{
|
||||
bang: true,
|
||||
count: true,
|
||||
completer: function (context, args)
|
||||
{
|
||||
return setCompleter(context, args, { scope: options.OPTION_SCOPE_GLOBAL });
|
||||
},
|
||||
literal: 0
|
||||
}
|
||||
);
|
||||
|
||||
commands.add(["se[t]"],
|
||||
"Set an option",
|
||||
function (args)
|
||||
{
|
||||
return setAction(args);
|
||||
},
|
||||
{
|
||||
bang: true,
|
||||
completer: function (context, args)
|
||||
{
|
||||
return setCompleter(context, args);
|
||||
},
|
||||
serial: function () [
|
||||
{
|
||||
@@ -760,7 +770,6 @@ function Options() //{{{
|
||||
//for (let i = 0, name = names[i]; i < length; name = names[++i])
|
||||
for (let [,name] in args)
|
||||
{
|
||||
let name = args[i];
|
||||
let reference = liberator.variableReference(name);
|
||||
if (!reference[0])
|
||||
{
|
||||
@@ -857,7 +866,7 @@ function Options() //{{{
|
||||
isDefault: opt.value == opt.defaultValue,
|
||||
name: opt.name,
|
||||
default: opt.defaultValue,
|
||||
pre: "\u00a0\u00a0", /* Unicode nonbreaking space. */
|
||||
pre: "\u00a0\u00a0", // Unicode nonbreaking space.
|
||||
value: <></>
|
||||
};
|
||||
|
||||
@@ -905,7 +914,7 @@ function Options() //{{{
|
||||
default: loadPreference(pref, null, true),
|
||||
value: <>={template.highlight(value, true, 100)}</>,
|
||||
name: pref,
|
||||
pre: "\u00a0\u00a0" /* Unicode nonbreaking space. */
|
||||
pre: "\u00a0\u00a0" // Unicode nonbreaking space.
|
||||
};
|
||||
|
||||
yield option;
|
||||
@@ -982,14 +991,14 @@ function Options() //{{{
|
||||
|
||||
setPref: function (name, value)
|
||||
{
|
||||
return storePreference(name, value);
|
||||
storePreference(name, value);
|
||||
},
|
||||
|
||||
resetPref: function (name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return services.get("pref").clearUserPref(name);
|
||||
services.get("pref").clearUserPref(name);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
@@ -1017,7 +1026,7 @@ function Options() //{{{
|
||||
storePreference(k, v);
|
||||
},
|
||||
|
||||
temporaryContext: function (fn, self)
|
||||
withContext: function (fn, self)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -45,6 +45,7 @@ function Services()
|
||||
get: function (name) services[name],
|
||||
create: function (name) classes[name]()
|
||||
};
|
||||
|
||||
self.add("appStartup", "@mozilla.org/toolkit/app-startup;1", Ci.nsIAppStartup);
|
||||
self.add("autoCompleteSearch", "@mozilla.org/browser/global-history;2", Ci.nsIAutoCompleteSearch);
|
||||
self.add("browserSearch", "@mozilla.org/browser/search-service;1", Ci.nsIBrowserSearchService);
|
||||
@@ -55,6 +56,7 @@ function Services()
|
||||
self.add("extensionManager", "@mozilla.org/extensions/manager;1", Ci.nsIExtensionManager);
|
||||
self.add("json", "@mozilla.org/dom/json;1", Ci.nsIJSON, "createInstance");
|
||||
self.add("observer", "@mozilla.org/observer-service;1", Ci.nsIObserverService);
|
||||
self.add("io", "@mozilla.org/network/io-service;1", Ci.nsIIOService);
|
||||
self.add("pref", "@mozilla.org/preferences-service;1", [Ci.nsIPrefService, Ci.nsIPrefBranch, Ci.nsIPrefBranch2]);
|
||||
self.add("profile", "@mozilla.org/toolkit/profile-service;1", Ci.nsIToolkitProfileService);
|
||||
self.add("sessionStore", "@mozilla.org/browser/sessionstore;1", Ci.nsISessionStore);
|
||||
@@ -66,8 +68,10 @@ function Services()
|
||||
self.addClass("file", "@mozilla.org/file/local;1", Ci.nsILocalFile);
|
||||
self.addClass("find", "@mozilla.org/embedcomp/rangefind;1", Ci.nsIFind);
|
||||
self.addClass("process", "@mozilla.org/process/util;1", Ci.nsIProcess);
|
||||
|
||||
return self;
|
||||
};
|
||||
|
||||
var services = Services();
|
||||
|
||||
// vim: set fdm=marker sw=4 ts=4 et:
|
||||
|
||||
@@ -72,8 +72,8 @@ Highlights.prototype.CSS = <![CDATA[
|
||||
Question color: green; background: white; font-weight: bold;
|
||||
|
||||
StatusLine color: white; background: black;
|
||||
StatusLineBroken color: black; background: #FF6060; /* light-red */
|
||||
StatusLineSecure color: black; background: #B0FF00; /* light-green */
|
||||
StatusLineBroken color: black; background: #FF6060 /* light-red */
|
||||
StatusLineSecure color: black; background: #B0FF00 /* light-green */
|
||||
|
||||
TabClose
|
||||
TabIcon
|
||||
@@ -129,7 +129,7 @@ Highlights.prototype.CSS = <![CDATA[
|
||||
|
||||
/**
|
||||
* A class to manage highlighting rules. The parameters are the
|
||||
* standard paramaters for any {@link Storage} object.
|
||||
* standard parameters for any {@link Storage} object.
|
||||
*
|
||||
* @author Kris Maglione <maglione.k@gmail.com>
|
||||
*/
|
||||
@@ -178,17 +178,22 @@ function Highlights(name, store, serial)
|
||||
|
||||
let css = newStyle.replace(/(?:!\s*important\s*)?(?:;?\s*$|;)/g, "!important;")
|
||||
.replace(";!important;", ";", "g"); // Seeming Spidermonkey bug
|
||||
if (!/^\s*(?:!\s*important\s*)?;*\s*$/.test(css))
|
||||
{
|
||||
css = style.selector + " { " + css + " }";
|
||||
|
||||
let error = styles.addSheet(true, style.selector, style.filter, css);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
style.value = newStyle;
|
||||
highlight[style.class] = style;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a CSS selector given a highlight group.
|
||||
*
|
||||
* @param {string} class
|
||||
*/
|
||||
this.selector = function (class)
|
||||
{
|
||||
@@ -235,28 +240,26 @@ function Highlights(name, store, serial)
|
||||
/**
|
||||
* Manages named and unnamed user style sheets, which apply to both
|
||||
* chrome and content pages. The parameters are the standard
|
||||
* paramaters for any {@link Storage} object.
|
||||
* parameters for any {@link Storage} object.
|
||||
*
|
||||
* @author Kris Maglione <maglione.k@gmail.com>
|
||||
*/
|
||||
function Styles(name, store, serial)
|
||||
{
|
||||
/* Can't reference liberator or Components inside Styles --
|
||||
* they're members of the window object, which disappear
|
||||
* with this window.
|
||||
*/
|
||||
// Can't reference liberator or Components inside Styles --
|
||||
// they're members of the window object, which disappear
|
||||
// with this window.
|
||||
const util = modules.util;
|
||||
const sleep = liberator.sleep;
|
||||
const storage = modules.storage;
|
||||
const consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
|
||||
const ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
const ios = services.get("io");
|
||||
const sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
|
||||
const namespace = '@namespace html "' + XHTML + '";\n' +
|
||||
'@namespace xul "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";\n' +
|
||||
'@namespace liberator "' + NS.uri + '";\n';
|
||||
const Sheet = new Struct("name", "sites", "css", "ref");
|
||||
|
||||
let cssUri = function (css) "chrome-data:text/css," + encodeURI(css);
|
||||
let cssUri = function (css) "chrome-data:text/css," + window.encodeURI(css);
|
||||
|
||||
let userSheets = [];
|
||||
let systemSheets = [];
|
||||
@@ -275,7 +278,6 @@ function Styles(name, store, serial)
|
||||
* @param {boolean} system Declares whether this is a system or
|
||||
* user sheet. System sheets are used internally by
|
||||
* @liberator.
|
||||
>>>>>>> master:common/content/style.js
|
||||
* @param {string} name The name given to the style sheet by
|
||||
* which it may be later referenced.
|
||||
* @param {string} filter The sites to which this sheet will
|
||||
@@ -335,6 +337,12 @@ function Styles(name, store, serial)
|
||||
/**
|
||||
* Find sheets matching the parameters. See {@link #addSheet}
|
||||
* for parameters.
|
||||
*
|
||||
* @param {boolean} system
|
||||
* @param {string} name
|
||||
* @param {string} filter
|
||||
* @param {string} css
|
||||
* @param {number} index
|
||||
*/
|
||||
this.findSheets = function (system, name, filter, css, index)
|
||||
{
|
||||
@@ -359,6 +367,12 @@ function Styles(name, store, serial)
|
||||
* In cases where <b>filter</b> is supplied, the given filters
|
||||
* are removed from matching sheets. If any remain, the sheet is
|
||||
* left in place.
|
||||
*
|
||||
* @param {boolean} system
|
||||
* @param {string} name
|
||||
* @param {string} filter
|
||||
* @param {string} css
|
||||
* @param {number} index
|
||||
*/
|
||||
this.removeSheet = function (system, name, filter, css, index)
|
||||
{
|
||||
@@ -405,7 +419,7 @@ function Styles(name, store, serial)
|
||||
/**
|
||||
* Register a user style sheet at the given URI.
|
||||
*
|
||||
* @param {string} uri The UrI of the sheet to register.
|
||||
* @param {string} uri The URI of the sheet to register.
|
||||
* @param {boolean} reload Whether to reload any sheets that are
|
||||
* already registered.
|
||||
*/
|
||||
@@ -420,6 +434,8 @@ function Styles(name, store, serial)
|
||||
|
||||
/**
|
||||
* Unregister a sheet at the given URI.
|
||||
*
|
||||
* @param {string} uri The URI of the sheet to unregister.
|
||||
*/
|
||||
this.unregisterSheet = function (uri)
|
||||
{
|
||||
@@ -431,6 +447,8 @@ function Styles(name, store, serial)
|
||||
// FIXME
|
||||
/**
|
||||
* Register an agent style sheet.
|
||||
*
|
||||
* @param {string} uri The URI of the sheet to register.
|
||||
* @deprecated
|
||||
*/
|
||||
this.registerAgentSheet = function (uri)
|
||||
@@ -442,6 +460,8 @@ function Styles(name, store, serial)
|
||||
|
||||
/**
|
||||
* Unregister an agent style sheet.
|
||||
*
|
||||
* @param {string} uri The URI of the sheet to unregister.
|
||||
* @deprecated
|
||||
*/
|
||||
this.unregisterAgentSheet = function (uri)
|
||||
@@ -514,7 +534,6 @@ liberator.registerObserver("load_completion", function ()
|
||||
|
||||
liberator.registerObserver("load_commands", function ()
|
||||
{
|
||||
// TODO: :colo default needs :hi clear
|
||||
commands.add(["colo[rscheme]"],
|
||||
"Load a color scheme",
|
||||
function (args)
|
||||
|
||||
@@ -44,12 +44,12 @@ function Tabs() //{{{
|
||||
{
|
||||
if (!tabmail)
|
||||
{
|
||||
tabmail = document.getElementById('tabmail');
|
||||
tabmail.__defineGetter__('mTabContainer', function () this.tabContainer);
|
||||
tabmail.__defineGetter__('mTabs', function () this.tabContainer.childNodes);
|
||||
tabmail.__defineGetter__('mCurrentTab', function () this.tabContainer.selectedItem);
|
||||
tabmail.__defineGetter__('mStrip', function () this.tabStrip);
|
||||
tabmail.__defineGetter__('browsers', function () [browser for (browser in Iterator(this.mTabs))] );
|
||||
tabmail = document.getElementById("tabmail");
|
||||
tabmail.__defineGetter__("mTabContainer", function () this.tabContainer);
|
||||
tabmail.__defineGetter__("mTabs", function () this.tabContainer.childNodes);
|
||||
tabmail.__defineGetter__("mCurrentTab", function () this.tabContainer.selectedItem);
|
||||
tabmail.__defineGetter__("mStrip", function () this.tabStrip);
|
||||
tabmail.__defineGetter__("browsers", function () [browser for (browser in Iterator(this.mTabs))] );
|
||||
}
|
||||
return tabmail;
|
||||
};
|
||||
@@ -123,7 +123,7 @@ function Tabs() //{{{
|
||||
let tabStrip = tabs.tabStrip;
|
||||
|
||||
if (!tabStrip)
|
||||
return options['showtabline']; // XXX
|
||||
return options["showtabline"]; // XXX
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
@@ -677,9 +677,9 @@ function Tabs() //{{{
|
||||
return store.options;
|
||||
},
|
||||
|
||||
getLocalStore: function (tab)
|
||||
getLocalStore: function (tabIndex)
|
||||
{
|
||||
let tab = this.getTab(tab);
|
||||
let tab = this.getTab(tabIndex);
|
||||
if (!tab.liberatorStore)
|
||||
tab.liberatorStore = {};
|
||||
return tab.liberatorStore;
|
||||
@@ -737,7 +737,7 @@ function Tabs() //{{{
|
||||
{
|
||||
if (index != undefined)
|
||||
return getBrowser().mTabs[index];
|
||||
|
||||
else
|
||||
return getBrowser().mCurrentTab;
|
||||
},
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ const template = {
|
||||
|
||||
map: function map(iter, fn, sep, interruptable)
|
||||
{
|
||||
if (iter.length) /* Kludge? */
|
||||
if (iter.length) // FIXME: Kludge?
|
||||
iter = util.Array.iterator(iter);
|
||||
let ret = <></>;
|
||||
let n = 0;
|
||||
@@ -287,7 +287,7 @@ const template = {
|
||||
|
||||
tabular: function tabular(headings, style, iter)
|
||||
{
|
||||
/* This might be mind-bogglingly slow. We'll see. */
|
||||
// TODO: This might be mind-bogglingly slow. We'll see.
|
||||
// <e4x>
|
||||
return this.commandOutput(
|
||||
<table>
|
||||
|
||||
@@ -28,7 +28,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
/** @scope modules */
|
||||
|
||||
/*
|
||||
/**
|
||||
* This class is used for prompting of user input and echoing of messages
|
||||
*
|
||||
* it consists of a prompt and command field
|
||||
@@ -75,6 +75,12 @@ function CommandLine() //{{{
|
||||
var keepCommand = false;
|
||||
var lastEcho = null;
|
||||
|
||||
/**
|
||||
* A class for managing the history of an inputField
|
||||
*
|
||||
* @param {Object} inputField
|
||||
* @param {string} mode
|
||||
*/
|
||||
function History(inputField, mode)
|
||||
{
|
||||
if (!(this instanceof arguments.callee))
|
||||
@@ -85,27 +91,42 @@ function CommandLine() //{{{
|
||||
this.reset();
|
||||
}
|
||||
History.prototype = {
|
||||
/**
|
||||
* Empties the history.
|
||||
*/
|
||||
reset: function ()
|
||||
{
|
||||
this.index = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Permanently save the history
|
||||
*/
|
||||
save: function ()
|
||||
{
|
||||
let str = this.input.value;
|
||||
if (/^\s*$/.test(str))
|
||||
return;
|
||||
this.store.mutate('filter', function (line) line != str);
|
||||
this.store.mutate("filter", function (line) line != str);
|
||||
this.store.push(str);
|
||||
this.store.truncate(options["history"], true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the current match to val
|
||||
*
|
||||
* @param {string} val
|
||||
*/
|
||||
replace: function (val)
|
||||
{
|
||||
this.input.value = val;
|
||||
liberator.triggerCallback("change", currentExtendedMode, val);
|
||||
},
|
||||
|
||||
/**
|
||||
* move up or (if backward) down in the history
|
||||
*
|
||||
* @param {boolean} backward
|
||||
* @param {boolean} matchCurrent XXX: what?
|
||||
*/
|
||||
select: function (backward, matchCurrent)
|
||||
{
|
||||
// always reset the tab completion if we use up/down keys
|
||||
@@ -154,6 +175,11 @@ function CommandLine() //{{{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A class for tab completions on an input field
|
||||
*
|
||||
* @param {Object} input
|
||||
*/
|
||||
function Completions(input)
|
||||
{
|
||||
if (!(this instanceof arguments.callee))
|
||||
@@ -326,7 +352,7 @@ function CommandLine() //{{{
|
||||
{
|
||||
case this.UP:
|
||||
if (this.selected == null)
|
||||
idx = this.items.length - 1;
|
||||
idx = -2
|
||||
else
|
||||
idx = this.selected - 1;
|
||||
break;
|
||||
@@ -343,8 +369,8 @@ function CommandLine() //{{{
|
||||
idx = Math.max(0, Math.min(this.items.length - 1, idx));
|
||||
break;
|
||||
}
|
||||
this.itemList.selectItem(idx);
|
||||
if (idx < 0 || idx >= this.items.length || idx == null)
|
||||
|
||||
if (idx == -1 || this.items.length && idx >= this.items.length || idx == null)
|
||||
{
|
||||
// Wrapped. Start again.
|
||||
this.selected = null;
|
||||
@@ -352,28 +378,41 @@ function CommandLine() //{{{
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for contexts to complete if necessary.
|
||||
// FIXME: Need to make idx relative to individual contexts.
|
||||
let list = this.context.contextList.reverse();
|
||||
if (idx == -2)
|
||||
list = list.slice().reverse();
|
||||
let n = 0;
|
||||
for (let [,context] in Iterator(list))
|
||||
{
|
||||
function done() !(idx >= n + context.items.length || idx == -2 && !context.items.length);
|
||||
while (context.incomplete && !done())
|
||||
liberator.threadYield(true, true);
|
||||
if (done())
|
||||
break;
|
||||
n += context.items.length;
|
||||
}
|
||||
|
||||
// See previous FIXME. This will break if new items in
|
||||
// a previous context come in.
|
||||
if (idx < 0)
|
||||
idx = this.items.length - 1;
|
||||
|
||||
this.selected = idx;
|
||||
this.completion = this.items[idx].text;
|
||||
}
|
||||
|
||||
this.itemList.selectItem(idx);
|
||||
},
|
||||
|
||||
tab: function tab(reverse)
|
||||
{
|
||||
autocompleteTimer.flush();
|
||||
// Check if we need to run the completer.
|
||||
if (this.context.waitingForTab || this.wildIndex == -1)
|
||||
this.complete(true, true);
|
||||
|
||||
if (this.items.length == 0)
|
||||
{
|
||||
// No items. Wait for any unfinished completers.
|
||||
let end = Date.now() + 5000;
|
||||
while (this.context.incomplete && this.items.length == 0 && Date.now() < end)
|
||||
liberator.threadYield();
|
||||
|
||||
if (this.items.length == 0)
|
||||
return liberator.beep();
|
||||
}
|
||||
|
||||
switch (this.wildtype.replace(/.*:/, ""))
|
||||
{
|
||||
case "":
|
||||
@@ -392,6 +431,9 @@ function CommandLine() //{{{
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.items.length == 0)
|
||||
return void liberator.beep();
|
||||
|
||||
if (this.type.list)
|
||||
completionList.show();
|
||||
|
||||
@@ -511,16 +553,28 @@ function CommandLine() //{{{
|
||||
var multilineRegexp = null;
|
||||
var multilineCallback = null;
|
||||
|
||||
/**
|
||||
* @private - highlight the messageBox according to group
|
||||
*/
|
||||
function setHighlightGroup(group)
|
||||
{
|
||||
messageBox.setAttributeNS(NS.uri, "highlight", group);
|
||||
}
|
||||
|
||||
// Whether the command line must be open.
|
||||
/**
|
||||
* @private - Determines whether the command line should be visible.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
function commandShown() modes.main == modes.COMMAND_LINE &&
|
||||
!(modes.extended & (modes.INPUT_MULTILINE | modes.OUTPUT_MULTILINE));
|
||||
|
||||
// sets the prompt - for example, : or /
|
||||
/**
|
||||
* @private - set the prompt to val styled with highlightGroup
|
||||
*
|
||||
* @param {string} val
|
||||
* @param {string} highlightGroup
|
||||
*/
|
||||
function setPrompt(val, highlightGroup)
|
||||
{
|
||||
promptWidget.value = val;
|
||||
@@ -529,7 +583,11 @@ function CommandLine() //{{{
|
||||
promptWidget.setAttributeNS(NS.uri, "highlight", highlightGroup || commandline.HL_NORMAL);
|
||||
}
|
||||
|
||||
// sets the command - e.g. 'tabopen', 'open http://example.com/'
|
||||
/**
|
||||
* @private - set the command to cmd and move the user's cursor to the end.
|
||||
*
|
||||
* @param {string} cmd
|
||||
*/
|
||||
function setCommand(cmd)
|
||||
{
|
||||
commandWidget.value = cmd;
|
||||
@@ -537,6 +595,14 @@ function CommandLine() //{{{
|
||||
commandWidget.selectionEnd = cmd.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private - display a message styled with highlightGroup
|
||||
* and, if forceSingle is true, ensure it takes only one line.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} highlightGroup
|
||||
* @param {boolean} forceSingle
|
||||
*/
|
||||
function echoLine(str, highlightGroup, forceSingle)
|
||||
{
|
||||
setHighlightGroup(highlightGroup);
|
||||
@@ -552,7 +618,14 @@ function CommandLine() //{{{
|
||||
echoMultiline(<span highlight="Message">{str}</span>, highlightGroup);
|
||||
}
|
||||
|
||||
// TODO: resize upon a window resize
|
||||
/**
|
||||
* Display a multiline message, possible through a "more" like interface
|
||||
*
|
||||
* TODO: resize upon a window resize
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} highlightGroup
|
||||
*/
|
||||
function echoMultiline(str, highlightGroup)
|
||||
{
|
||||
let doc = multilineOutputWidget.contentDocument;
|
||||
@@ -560,11 +633,10 @@ function CommandLine() //{{{
|
||||
|
||||
liberator.triggerObserver("echoMultiline", str, highlightGroup);
|
||||
|
||||
/* If it's already XML, assume it knows what it's doing.
|
||||
* Otherwise, white space is significant.
|
||||
* The problem elsewhere is that E4X tends to insert new lines
|
||||
* after interpolated data.
|
||||
*/
|
||||
// If it's already XML, assume it knows what it's doing.
|
||||
// Otherwise, white space is significant.
|
||||
// The problem elsewhere is that E4X tends to insert new lines
|
||||
// after interpolated data.
|
||||
XML.ignoreWhitespace = typeof str != "xml";
|
||||
lastMowOutput = <div class="ex-command-output" style="white-space: nowrap" highlight={highlightGroup}>{template.maybeXML(str)}</div>;
|
||||
let output = util.xmlToDom(lastMowOutput, doc);
|
||||
@@ -598,6 +670,10 @@ function CommandLine() //{{{
|
||||
commandline.updateMorePrompt();
|
||||
}
|
||||
|
||||
/**
|
||||
* @private - ensure that the Multiline input widget is the
|
||||
* correct size.
|
||||
*/
|
||||
function autosizeMultilineInputWidget()
|
||||
{
|
||||
let lines = multilineInputWidget.value.split("\n").length - 1;
|
||||
@@ -605,7 +681,16 @@ function CommandLine() //{{{
|
||||
multilineInputWidget.setAttribute("rows", Math.max(lines, 1));
|
||||
}
|
||||
|
||||
// used for the :echo[err] commands
|
||||
/**
|
||||
* @private - eval()s a javascript expression
|
||||
* and returns a string suitable to be echo'd.
|
||||
*
|
||||
* If useColor is true, util.objectToString will
|
||||
* colorize object output.
|
||||
*
|
||||
* @param {string} arg
|
||||
* @param {boolean} useColor
|
||||
*/
|
||||
function echoArgumentToString(arg, useColor)
|
||||
{
|
||||
if (!arg)
|
||||
@@ -885,6 +970,9 @@ function CommandLine() //{{{
|
||||
storage.styles.removeSheet(true, "silent-mode");
|
||||
},
|
||||
|
||||
/**
|
||||
* XXX: This function is not used!
|
||||
*/
|
||||
runSilently: function (fn, self)
|
||||
{
|
||||
let wasSilent = this.silent;
|
||||
@@ -912,6 +1000,16 @@ function CommandLine() //{{{
|
||||
|
||||
get message() messageBox.value,
|
||||
|
||||
/**
|
||||
* Changes the command line to display the following prompt (usually ":")
|
||||
* followed by the command, in the given mode. Valid modes are
|
||||
* attributes of the "modes" variable, and modes.EX is probably
|
||||
* a good choice.
|
||||
*
|
||||
* @param {string} prompt
|
||||
* @param {string} cmd
|
||||
* @param {number} mode
|
||||
*/
|
||||
open: function open(prompt, cmd, extendedMode)
|
||||
{
|
||||
// save the current prompts, we need it later if the command widget
|
||||
@@ -936,7 +1034,11 @@ function CommandLine() //{{{
|
||||
liberator.triggerCallback("change", currentExtendedMode, cmd);
|
||||
},
|
||||
|
||||
// normally used when pressing esc, does not execute a command
|
||||
/**
|
||||
* Removes any input from the command line, without executing its
|
||||
* contents. Removes any "More" windows or other such output.
|
||||
* Pressing <ESC> in EX mode normally has this effect.
|
||||
*/
|
||||
close: function close()
|
||||
{
|
||||
let mode = currentExtendedMode;
|
||||
@@ -946,6 +1048,7 @@ function CommandLine() //{{{
|
||||
if (history)
|
||||
history.save();
|
||||
|
||||
this.resetCompletions(); // cancels any asynchronous completion still going on, must be before completions = null
|
||||
completions = null;
|
||||
history = null;
|
||||
|
||||
@@ -969,14 +1072,33 @@ function CommandLine() //{{{
|
||||
keepCommand = false;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Hide any auto-completion/More-ing that is happening.
|
||||
*/
|
||||
hide: function hide()
|
||||
{
|
||||
commandlineWidget.collapsed = true;
|
||||
},
|
||||
|
||||
// liberator.echo uses different order of flags as it omits the hightlight group, change v.commandline.echo argument order? --mst
|
||||
/**
|
||||
* Output the given string onto the command line coloured
|
||||
* using the rules according to highlightGroup. If not
|
||||
* given higlightGroup defaults to commandline.HL_NORMAL
|
||||
* and other possibe values are at commandline.HL_[A-Z]*.
|
||||
*
|
||||
* Flags can be any of:
|
||||
* commandline.APPEND_TO_MESSAGES (causes message to be added to the messagesHistory)
|
||||
* commandline.FORCE_SINGLELINE | commandline.DISALLOW_MULTILINE
|
||||
* commandline.FORCE_MULTILINE
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} highlightGroup
|
||||
* @param {number} flags
|
||||
*/
|
||||
echo: function echo(str, highlightGroup, flags)
|
||||
{
|
||||
// liberator.echo uses different order of flags as it omits the highlight group, change v.commandline.echo argument order? --mst
|
||||
if (silent)
|
||||
return false;
|
||||
|
||||
@@ -1021,8 +1143,23 @@ function CommandLine() //{{{
|
||||
return true;
|
||||
},
|
||||
|
||||
// this will prompt the user for a string
|
||||
// commandline.input("(s)ave or (o)pen the file?")
|
||||
/**
|
||||
* Prompt the user for a string and execute the given
|
||||
* callback with that as the only argument on <CR>
|
||||
* extra can have any of the following attributes:
|
||||
*
|
||||
* onChange: A function to be called with the current input every time it changes
|
||||
* completer: A function called with a ?context? when the user tries to tabcomplete
|
||||
* promptHighlight: The HighlightGroup to use (default commandline.HL_QUESTION, others
|
||||
* can be found at commandline.HL_[A-Z]*)
|
||||
*
|
||||
* This function sets the mode to modes.COMMAND_LINE, and thus popping the mode will
|
||||
* stop further input from being waited for (useful for stopping onChange)
|
||||
*
|
||||
* @param {string} prompt
|
||||
* @param {function(string)} callback
|
||||
* @param {Object} extra
|
||||
*/
|
||||
input: function input(prompt, callback, extra)
|
||||
{
|
||||
extra = extra || {};
|
||||
@@ -1042,8 +1179,14 @@ function CommandLine() //{{{
|
||||
completions = Completions(commandWidget.inputField);
|
||||
},
|
||||
|
||||
// reads a multi line input and returns the string once the last line matches
|
||||
// @param untilRegexp
|
||||
/**
|
||||
* Get a multiline input from a user, up to but not including
|
||||
* the line which matches the given regular expression. Then
|
||||
* execute the callback with that string as a parameter.
|
||||
*
|
||||
* @param {RegExp} untilRegexp
|
||||
* @param {function(string)} callbackFunc
|
||||
*/
|
||||
inputMultiline: function inputMultiline(untilRegexp, callbackFunc)
|
||||
{
|
||||
// Kludge.
|
||||
@@ -1063,6 +1206,13 @@ function CommandLine() //{{{
|
||||
setTimeout(function () { multilineInputWidget.focus(); }, 10);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle events, the come from liberator when liberator.mode = modes.COMMAND_LINE
|
||||
* but also takes blur/focus/input events raw from #liberator-commandline-command
|
||||
* in the XUL
|
||||
*
|
||||
* @param {Event} event
|
||||
*/
|
||||
onEvent: function onEvent(event)
|
||||
{
|
||||
let command = this.command;
|
||||
@@ -1085,7 +1235,7 @@ function CommandLine() //{{{
|
||||
}
|
||||
else if (event.type == "input")
|
||||
{
|
||||
this.resetCompletions();
|
||||
//this.resetCompletions(); -> already handled by "keypress" below (hopefully), so don't do it twice
|
||||
liberator.triggerCallback("change", currentExtendedMode, command);
|
||||
}
|
||||
else if (event.type == "keypress")
|
||||
@@ -1150,11 +1300,18 @@ function CommandLine() //{{{
|
||||
}
|
||||
else if (event.type == "keyup")
|
||||
{
|
||||
let key = events.toString(event);
|
||||
if (key == "<Tab>" || key == "<S-Tab>")
|
||||
tabTimer.flush();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Multiline input events, they will come straight from
|
||||
* #liberator-multiline-input in the XUL.
|
||||
*
|
||||
* @param {Event} event
|
||||
*/
|
||||
onMultilineInputEvent: function onMultilineInputEvent(event)
|
||||
{
|
||||
if (event.type == "keypress")
|
||||
@@ -1189,8 +1346,16 @@ function CommandLine() //{{{
|
||||
return true;
|
||||
},
|
||||
|
||||
// FIXME: if 'more' is set and the MOW is not scrollable we should still
|
||||
// allow a down motion after an up rather than closing
|
||||
/**
|
||||
* Handle events when we are in multiline output mode,
|
||||
* these come from liberator when modes.extended & modes.MULTILINE_OUTPUT
|
||||
* and also from #liberator-multiline-output in the XUL
|
||||
*
|
||||
* FIXME: if 'more' is set and the MOW is not scrollable we should still
|
||||
* allow a down motion after an up rather than closing
|
||||
*
|
||||
* @param {Event} event
|
||||
*/
|
||||
onMultilineOutputEvent: function onMultilineOutputEvent(event)
|
||||
{
|
||||
let win = multilineOutputWidget.contentWindow;
|
||||
@@ -1298,7 +1463,7 @@ function CommandLine() //{{{
|
||||
}
|
||||
break;
|
||||
|
||||
// let firefox handle those to select table cells or show a context menu
|
||||
// let Firefox handle those to select table cells or show a context menu
|
||||
case "<C-LeftMouse>":
|
||||
case "<RightMouse>":
|
||||
case "<C-S-LeftMouse>":
|
||||
@@ -1400,6 +1565,15 @@ function CommandLine() //{{{
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Refresh or remove the prompt that displays when in multiline mode.
|
||||
* showHelp will cause the possible key-options to be displayed,
|
||||
* force will cause a display of the default message even if it
|
||||
* could be at the end of the output.
|
||||
*
|
||||
* @param {boolean} force
|
||||
* @param {boolean} showHelp
|
||||
*/
|
||||
updateMorePrompt: function updateMorePrompt(force, showHelp)
|
||||
{
|
||||
if (outputContainer.collapsed)
|
||||
@@ -1417,6 +1591,14 @@ function CommandLine() //{{{
|
||||
echoLine("Press ENTER or type command to continue", this.HL_QUESTION, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the height of the multilineOutputWidget to fit
|
||||
* its contents, if <b>open</b> is true, it will cause the
|
||||
* widget to uncollapse, if not it will leave the widget
|
||||
* closed.
|
||||
*
|
||||
* @param {boolean} open
|
||||
*/
|
||||
updateOutputHeight: function updateOutputHeight(open)
|
||||
{
|
||||
if (!open && outputContainer.collapsed)
|
||||
@@ -1439,11 +1621,18 @@ function CommandLine() //{{{
|
||||
outputContainer.collapsed = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Disable any active completion functions by calling their cancelFunc's
|
||||
* Will also remove the completions preview window.
|
||||
*/
|
||||
resetCompletions: function resetCompletions()
|
||||
{
|
||||
autocompleteTimer.reset();
|
||||
|
||||
// liberator.dump("Resetting completions...");
|
||||
if (completions)
|
||||
{
|
||||
completions.context.cancelAll();
|
||||
completions.wildIndex = -1;
|
||||
completions.previewClear();
|
||||
}
|
||||
@@ -1457,9 +1646,9 @@ function CommandLine() //{{{
|
||||
/**
|
||||
* The list which is used for the completion box (and QuickFix window in future)
|
||||
*
|
||||
* @param id: the id of the the XUL <iframe> which we want to fill
|
||||
* it MUST be inside a <vbox> (or any other html element,
|
||||
* because otherwise setting the height does not work properly
|
||||
* @param {string} id The id of the XUL <iframe> which we want to fill it
|
||||
* MUST be inside a <vbox> (or any other html element, because otherwise
|
||||
* setting the height does not work properly
|
||||
*/
|
||||
function ItemList(id) //{{{
|
||||
{
|
||||
@@ -1505,7 +1694,7 @@ function ItemList(id) //{{{
|
||||
minHeight = Math.max(minHeight, divNodes.completions.getBoundingClientRect().bottom);
|
||||
container.height = minHeight;
|
||||
if (container.collapsed)
|
||||
div.style.minWidth = undefined;
|
||||
div.style.minWidth = "";
|
||||
// FIXME: Belongs elsewhere.
|
||||
commandline.updateOutputHeight(false);
|
||||
}
|
||||
@@ -1550,10 +1739,10 @@ function ItemList(id) //{{{
|
||||
}
|
||||
|
||||
/**
|
||||
* uses the entries in "items" to fill the listbox
|
||||
* does incremental filling to speed up things
|
||||
* Uses the entries in "items" to fill the listbox and
|
||||
* does incremental filling to speed up things.
|
||||
*
|
||||
* @param offset: start at this index and show maxItems
|
||||
* @param {number} offset Start at this index and show maxItems
|
||||
*/
|
||||
function fill(offset)
|
||||
{
|
||||
@@ -1671,7 +1860,7 @@ function ItemList(id) //{{{
|
||||
// select index, refill list if necessary
|
||||
selectItem: function selectItem(index)
|
||||
{
|
||||
//if (container.collapsed) // fixme
|
||||
//if (container.collapsed) // FIXME
|
||||
// return;
|
||||
|
||||
//let now = Date.now();
|
||||
@@ -1773,6 +1962,14 @@ function StatusLine() //{{{
|
||||
|
||||
return {
|
||||
|
||||
/**
|
||||
* Update the status bar to indicate how secure the website is
|
||||
* secure => https:// with valid certificate
|
||||
* broken => https:// with invalid certificate
|
||||
* insecure => http://
|
||||
*
|
||||
* @param {'secure'|'broken'|'insecure'} type
|
||||
*/
|
||||
setClass: function setClass(type)
|
||||
{
|
||||
const highlightGroup = {
|
||||
@@ -1794,7 +1991,14 @@ function StatusLine() //{{{
|
||||
this.updateBufferPosition();
|
||||
},
|
||||
|
||||
// if "url" is ommited, build a usable string for the URL
|
||||
/**
|
||||
* Update which URL is displayed on the status line,
|
||||
* if url is omitted then buffer.URL is used instead and
|
||||
* status icons [+-â¤] are updated to match whether one can
|
||||
* go back/forwards in history/have bookmarked the page.
|
||||
*
|
||||
* @param {string} url
|
||||
*/
|
||||
updateUrl: function updateUrl(url)
|
||||
{
|
||||
if (typeof url == "string")
|
||||
@@ -1805,7 +2009,7 @@ function StatusLine() //{{{
|
||||
|
||||
url = buffer.URL;
|
||||
|
||||
// make it even more vim-like
|
||||
// make it even more Vim-like
|
||||
if (url == "about:blank")
|
||||
{
|
||||
if (!buffer.title)
|
||||
@@ -1837,6 +2041,13 @@ function StatusLine() //{{{
|
||||
urlWidget.value = url;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the contents of the status line's input buffer
|
||||
* to the given string.
|
||||
*
|
||||
* Used for displaying partial key combinations in
|
||||
* normal mode.
|
||||
*/
|
||||
updateInputBuffer: function updateInputBuffer(buffer)
|
||||
{
|
||||
if (!buffer || typeof buffer != "string")
|
||||
@@ -1845,6 +2056,17 @@ function StatusLine() //{{{
|
||||
inputBufferWidget.value = buffer;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the display of the progress bar.
|
||||
* If the parameter is a string, it will be
|
||||
* displayed literally. Otherwise it must be a number
|
||||
* less than one.
|
||||
* Negative numbers cause a "Loading..." status,
|
||||
* Positive (< 1) numbers cause an arrow ==> of length
|
||||
* proportional to the arrow.
|
||||
*
|
||||
* @param {string|number} progress
|
||||
*/
|
||||
updateProgress: function updateProgress(progress)
|
||||
{
|
||||
if (!progress)
|
||||
@@ -1872,7 +2094,13 @@ function StatusLine() //{{{
|
||||
}
|
||||
},
|
||||
|
||||
// you can omit either of the 2 arguments
|
||||
/**
|
||||
* Display the correct tabcount (e.g. [1/5]) on the status bar.
|
||||
* If either parameter is omitted, they will be calculated.
|
||||
*
|
||||
* @param {number} currentIndex
|
||||
* @param {number} totalTabs
|
||||
*/
|
||||
updateTabCount: function updateTabCount(currentIndex, totalTabs)
|
||||
{
|
||||
if (!liberator.has("tabs"))
|
||||
@@ -1897,7 +2125,16 @@ function StatusLine() //{{{
|
||||
tabCountWidget.value = "[" + currentIndex + "/" + totalTabs + "]";
|
||||
},
|
||||
|
||||
// percent is given between 0 and 1
|
||||
/**
|
||||
* Display the correct position on the status bar, if the
|
||||
* percent parameter is omitted it will be calculated.
|
||||
*
|
||||
* Negative numbers are set to "All", Zero implies "Top"
|
||||
* One or above is "Bot", and anything else is multiplied by
|
||||
* a hundred and displayed as a percentage.
|
||||
*
|
||||
* @param {number} percent
|
||||
*/
|
||||
updateBufferPosition: function updateBufferPosition(percent)
|
||||
{
|
||||
if (!percent || typeof percent != "number")
|
||||
|
||||
@@ -57,15 +57,19 @@ const util = { //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Flatten an array, such that all elements of the array are
|
||||
* Flattens an array, such that all elements of the array are
|
||||
* joined into a single array:
|
||||
* [["foo", ["bar"]], ["baz"], "quux"] -> ["foo", ["bar"], "baz", "quux"]
|
||||
*
|
||||
* @param {Array} ary
|
||||
* @returns {Array}
|
||||
*/
|
||||
flatten: function flatten(ary) Array.concat.apply([], ary),
|
||||
|
||||
/**
|
||||
* Returns an Iterator for an array's values.
|
||||
*
|
||||
* @param {Array} ary
|
||||
* @returns {Iterator(Object)}
|
||||
*/
|
||||
iterator: function iterator(ary)
|
||||
@@ -76,8 +80,9 @@ const util = { //{{{
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the arrays indices and values.
|
||||
* Returns an Iterator for an array's indices and values.
|
||||
*
|
||||
* @param {Array} ary
|
||||
* @returns {Iterator([{number}, {Object}])}
|
||||
*/
|
||||
iterator2: function (ary)
|
||||
@@ -94,6 +99,7 @@ const util = { //{{{
|
||||
*
|
||||
* @param {Array} ary
|
||||
* @param {boolean} unsorted
|
||||
* @returns {Array}
|
||||
*/
|
||||
uniq: function uniq(ary, unsorted)
|
||||
{
|
||||
@@ -135,10 +141,10 @@ const util = { //{{{
|
||||
|
||||
/**
|
||||
* Clips a string to a given length. If the input string is longer
|
||||
* than <b>length</b>, an elipsis is appended.
|
||||
* than <b>length</b>, an ellipsis is appended.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {number} length
|
||||
* @param {string} str The string to truncate.
|
||||
* @param {number} length The length of the returned string.
|
||||
* @returns {string}
|
||||
*/
|
||||
clip: function clip(str, length)
|
||||
@@ -169,6 +175,13 @@ const util = { //{{{
|
||||
return node.ownerDocument.defaultView.getComputedStyle(node, null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Copies a string to the system clipboard. If <b>verbose</b> is specified
|
||||
* the copied string is also echoed to the command-line.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {boolean} verbose
|
||||
*/
|
||||
copyToClipboard: function copyToClipboard(str, verbose)
|
||||
{
|
||||
const clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
|
||||
@@ -178,12 +191,26 @@ const util = { //{{{
|
||||
liberator.echo("Yanked " + str, commandline.FORCE_SINGLELINE);
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts any arbitrary string into an URI object.
|
||||
*
|
||||
* @param {string} str
|
||||
* @returns {Object}
|
||||
*/
|
||||
// FIXME: newURI needed too?
|
||||
createURI: function createURI(str)
|
||||
{
|
||||
const fixup = Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci.nsIURIFixup);
|
||||
return fixup.createFixupURI(str, fixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP);
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts HTML special characters in <b>str</b> to the equivalent HTML
|
||||
* entities.
|
||||
*
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
escapeHTML: function escapeHTML(str)
|
||||
{
|
||||
// XXX: the following code is _much_ slower than a simple .replace()
|
||||
@@ -195,11 +222,26 @@ const util = { //{{{
|
||||
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
},
|
||||
|
||||
/**
|
||||
* Escapes Regular Expression special characters in <b>str</b>.
|
||||
*
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
escapeRegex: function escapeRegex(str)
|
||||
{
|
||||
return str.replace(/([\\{}()[\].?*+])/g, "\\$1");
|
||||
},
|
||||
|
||||
/**
|
||||
* Escapes quotes, newline and tab characters in <b>str</b>. The returned
|
||||
* string is delimited by <b>delimiter</b> or " if <b>delimiter</b> is not
|
||||
* specified.
|
||||
*
|
||||
* @param {string} str
|
||||
* @param {string} delimiter
|
||||
* @returns {string}
|
||||
*/
|
||||
escapeString: function escapeString(str, delimiter)
|
||||
{
|
||||
if (delimiter == undefined)
|
||||
@@ -207,11 +249,20 @@ const util = { //{{{
|
||||
return delimiter + str.replace(/([\\'"])/g, "\\$1").replace("\n", "\\n", "g").replace("\t", "\\t", "g") + delimiter;
|
||||
},
|
||||
|
||||
formatBytes: function formatBytes(num, decimalPlaces, humanReadable)
|
||||
/**
|
||||
* Converts <b>bytes</b> to a pretty printed data size string.
|
||||
*
|
||||
* @param {number} bytes The number of bytes.
|
||||
* @param {string} decimalPlaces The number of decimal places to use if
|
||||
* <b>humanReadable</b> is true.
|
||||
* @param {boolean} humanReadable Use byte multiples.
|
||||
* @returns {string}
|
||||
*/
|
||||
formatBytes: function formatBytes(bytes, decimalPlaces, humanReadable)
|
||||
{
|
||||
const unitVal = ["Bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
|
||||
let unitIndex = 0;
|
||||
let tmpNum = parseInt(num, 10) || 0;
|
||||
let tmpNum = parseInt(bytes, 10) || 0;
|
||||
let strNum = [tmpNum + ""];
|
||||
|
||||
if (humanReadable)
|
||||
@@ -242,33 +293,40 @@ const util = { //{{{
|
||||
return strNum[0] + " " + unitVal[unitIndex];
|
||||
},
|
||||
|
||||
// generates an Asciidoc help entry, "command" can also be a mapping
|
||||
generateHelp: function generateHelp(command, extraHelp)
|
||||
/**
|
||||
* Generates an Asciidoc help entry.
|
||||
*
|
||||
* @param {Object} obj A liberator <b>Command</b>, <b>Mapping</b> or
|
||||
* <b>Option</b> object
|
||||
* @param {string} extraHelp Extra help text beyond the description.
|
||||
* @returns {string}
|
||||
*/
|
||||
generateHelp: function generateHelp(obj, extraHelp)
|
||||
{
|
||||
let start = "", end = "";
|
||||
if (command instanceof liberator.Command)
|
||||
if (obj instanceof Command)
|
||||
start = ":";
|
||||
else if (command instanceof liberator.Option)
|
||||
else if (obj instanceof Option)
|
||||
start = end = "'";
|
||||
|
||||
let ret = "";
|
||||
let longHelp = false;
|
||||
if ((command.help && command.description) && (command.help.length + command.description.length) > 50)
|
||||
if ((obj.help && obj.description) && (obj.help.length + obj.description.length) > 50)
|
||||
longHelp = true;
|
||||
|
||||
// the tags which are printed on the top right
|
||||
for (let j = command.names.length - 1; j >= 0; j--)
|
||||
ret += "|" + start + command.names[j] + end + "| ";
|
||||
for (let j = obj.names.length - 1; j >= 0; j--)
|
||||
ret += "|" + start + obj.names[j] + end + "| ";
|
||||
|
||||
if (longHelp)
|
||||
ret += "+";
|
||||
|
||||
ret += "\n";
|
||||
|
||||
// the usage information for the command
|
||||
let usage = command.names[0];
|
||||
if (command.specs) // for :commands
|
||||
usage = command.specs[0];
|
||||
// the usage information
|
||||
let usage = obj.names[0];
|
||||
if (obj.specs) // for :commands
|
||||
usage = obj.specs[0];
|
||||
|
||||
usage = usage.replace(/{/, "\\\\{").replace(/}/, "\\\\}");
|
||||
usage = usage.replace(/'/, "\\'").replace(/`/, "\\`");
|
||||
@@ -279,9 +337,9 @@ const util = { //{{{
|
||||
ret += "\n________________________________________________________________________________\n";
|
||||
|
||||
// the actual help text
|
||||
if (command.description)
|
||||
if (obj.description)
|
||||
{
|
||||
ret += command.description + "."; // the help description
|
||||
ret += obj.description + "."; // the help description
|
||||
if (extraHelp)
|
||||
ret += " +\n" + extraHelp;
|
||||
}
|
||||
@@ -294,6 +352,16 @@ const util = { //{{{
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends a synchronous HTTP request to <b>url</b> and returns the
|
||||
* XMLHttpRequest object. If <b>callback</b> is specified the request is
|
||||
* asynchronous and the <b>callback</b> is invoked with the object as its
|
||||
* argument.
|
||||
*
|
||||
* @param {string} url
|
||||
* @param {function} callback
|
||||
* @returns {Object}
|
||||
*/
|
||||
httpGet: function httpGet(url, callback)
|
||||
{
|
||||
try
|
||||
@@ -317,8 +385,21 @@ const util = { //{{{
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The identity function.
|
||||
*
|
||||
* @param {Object} k
|
||||
* @returns {Object}
|
||||
*/
|
||||
identity: function identity(k) k,
|
||||
|
||||
/**
|
||||
* Returns the intersection of two rectangles.
|
||||
*
|
||||
* @param {Object} r1
|
||||
* @param {Object} r2
|
||||
* @returns {Object}
|
||||
*/
|
||||
intersection: function (r1, r2) ({
|
||||
get width() this.right - this.left,
|
||||
get height() this.bottom - this.top,
|
||||
@@ -328,6 +409,14 @@ const util = { //{{{
|
||||
bottom: Math.min(r1.bottom, r2.bottom)
|
||||
}),
|
||||
|
||||
/**
|
||||
* Returns the array that results from applying <b>fn</b> to each property
|
||||
* of <b>obj</b>.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @param {function} fn
|
||||
* @returns {Array}
|
||||
*/
|
||||
map: function map(obj, fn)
|
||||
{
|
||||
let ary = [];
|
||||
@@ -336,20 +425,32 @@ const util = { //{{{
|
||||
return ary;
|
||||
},
|
||||
|
||||
newURI: function (url)
|
||||
/**
|
||||
* Converts a URI string into an URI object.
|
||||
*
|
||||
* @param {string} uri
|
||||
* @returns {Object}
|
||||
*/
|
||||
// FIXME: createURI needed too?
|
||||
newURI: function (uri)
|
||||
{
|
||||
const ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
return ioService.newURI(url, null, null);
|
||||
return services.get("io").newURI(uri, null, null);
|
||||
},
|
||||
|
||||
// if color = true it uses HTML markup to color certain items
|
||||
/**
|
||||
* Pretty print a JavaScript object. Use HTML markup to color certain items
|
||||
* if <b>color</b> is true.
|
||||
*
|
||||
* @param {Object} object The object to pretty print.
|
||||
* @param {boolean} color Whether the output should be colored.
|
||||
* @returns {string}
|
||||
*/
|
||||
objectToString: function objectToString(object, color)
|
||||
{
|
||||
/* Use E4X literals so html is automatically quoted
|
||||
* only when it's asked for. Noone wants to see <
|
||||
* on their console or :map :foo in their buffer
|
||||
* when they expect :map <C-f> :foo.
|
||||
*/
|
||||
// Use E4X literals so html is automatically quoted
|
||||
// only when it's asked for. Noone wants to see <
|
||||
// on their console or :map :foo in their buffer
|
||||
// when they expect :map <C-f> :foo.
|
||||
XML.prettyPrinting = false;
|
||||
XML.ignoreWhitespace = false;
|
||||
|
||||
@@ -417,6 +518,15 @@ const util = { //{{{
|
||||
return color ? string : [s for each (s in string)].join("");
|
||||
},
|
||||
|
||||
/**
|
||||
* A generator that returns the values between <b>start</b> and <b>end</b>.
|
||||
* If <b>reverse</b> is true then the values are returned in reverse order.
|
||||
*
|
||||
* @param {number} start The interval's start value.
|
||||
* @param {number} end The interval's end value.
|
||||
* @param {boolean} reverse Reverse the order in which the values are produced.
|
||||
* @returns {Iterator(Object)}
|
||||
*/
|
||||
range: function range(start, end, reverse)
|
||||
{
|
||||
if (!reverse)
|
||||
@@ -431,7 +541,16 @@ const util = { //{{{
|
||||
}
|
||||
},
|
||||
|
||||
interruptableRange: function interruptableRange(start, end, time)
|
||||
/**
|
||||
* An interruptible generator that returns all values between <b>start</b>
|
||||
* and <b>end</b>. The thread yields every <b>time</b> milliseconds.
|
||||
*
|
||||
* @param {number} start The interval's start value.
|
||||
* @param {number} end The interval's end value.
|
||||
* @param {number} time The time in milliseconds between thread yields.
|
||||
* @returns {Iterator(Object)}
|
||||
*/
|
||||
interruptibleRange: function interruptibleRange(start, end, time)
|
||||
{
|
||||
let endTime = Date.now() + time;
|
||||
while (start < end)
|
||||
@@ -445,15 +564,22 @@ const util = { //{{{
|
||||
}
|
||||
},
|
||||
|
||||
// same as Firefox's readFromClipboard function, but needed for apps like Thunderbird
|
||||
/**
|
||||
* Reads a string from the system clipboard.
|
||||
*
|
||||
* This is same as Firefox's readFromClipboard function, but is needed for
|
||||
* apps like Thunderbird which do not provide it.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
readFromClipboard: function readFromClipboard()
|
||||
{
|
||||
let url;
|
||||
|
||||
try
|
||||
{
|
||||
const clipboard = Cc['@mozilla.org/widget/clipboard;1'].getService(Ci.nsIClipboard);
|
||||
const transferable = Cc['@mozilla.org/widget/transferable;1'].createInstance(Ci.nsITransferable);
|
||||
const clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
|
||||
const transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
|
||||
|
||||
transferable.addDataFlavor("text/unicode");
|
||||
|
||||
@@ -478,11 +604,18 @@ const util = { //{{{
|
||||
return url;
|
||||
},
|
||||
|
||||
// takes a string like 'google bla, www.osnews.com'
|
||||
// and returns an array ['www.google.com/search?q=bla', 'www.osnews.com']
|
||||
/**
|
||||
* Returns an array of URLs parsed from <b>str</b>.
|
||||
*
|
||||
* 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 {Array}
|
||||
*/
|
||||
stringToURLArray: function stringToURLArray(str)
|
||||
{
|
||||
let urls = str.split(RegExp("\s*" + options["urlseparator"] + "\s*"));
|
||||
let urls = str.split(RegExp("\\s*" + options["urlseparator"] + "\\s*"));
|
||||
|
||||
return urls.map(function (url) {
|
||||
try
|
||||
@@ -525,6 +658,14 @@ const util = { //{{{
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts an E4X XML literal to a DOM node.
|
||||
*
|
||||
* @param {Node} node
|
||||
* @param {Document} doc
|
||||
* @param {Object} nodes
|
||||
* @returns {Node}
|
||||
*/
|
||||
xmlToDom: function xmlToDom(node, doc, nodes)
|
||||
{
|
||||
XML.prettyPrinting = false;
|
||||
|
||||
@@ -34,6 +34,7 @@ const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
// XXX: does not belong here
|
||||
function Timer(minInterval, maxInterval, callback)
|
||||
{
|
||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
@@ -57,7 +58,7 @@ function Timer(minInterval, maxInterval, callback)
|
||||
};
|
||||
this.tell = function (arg)
|
||||
{
|
||||
if (arg !== undefined)
|
||||
if (arguments.length > 0)
|
||||
this.arg = arg;
|
||||
|
||||
let now = Date.now();
|
||||
|
||||
@@ -31,7 +31,7 @@ const config = { //{{{
|
||||
name: "Muttator",
|
||||
hostApplication: "Thunderbird", // TODO: can this be found out otherwise? gBrandBundle.getString("brandShortName");
|
||||
|
||||
/*** optional options, there are checked for existance and a fallback provided ***/
|
||||
/*** optional options, there are checked for existence and a fallback provided ***/
|
||||
features: ["hints", "mail", "marks", "addressbook", "tabs"],
|
||||
defaults: { guioptions: "frb" },
|
||||
|
||||
|
||||
@@ -588,14 +588,14 @@ function Mail() //{{{
|
||||
if (mail.currentFolder.isServer)
|
||||
return liberator.beep();
|
||||
|
||||
mail.currentFolder.markAllMessagesRead();
|
||||
mail.currentFolder.markAllMessagesRead(msgWindow);
|
||||
});
|
||||
|
||||
mappings.add(myModes, ["<C-t>"],
|
||||
"Mark all messages as read",
|
||||
function ()
|
||||
{
|
||||
mail.getFolders("", false).forEach(function (folder) { folder.markAllMessagesRead(); });
|
||||
mail.getFolders("", false).forEach(function (folder) { folder.markAllMessagesRead(msgWindow); });
|
||||
});
|
||||
|
||||
// DISPLAY OPTIONS
|
||||
@@ -890,12 +890,13 @@ function Mail() //{{{
|
||||
return false;
|
||||
},
|
||||
|
||||
/*
|
||||
* general-purpose method to find messages
|
||||
* @param validatorFunc(msg): return true/false whether msg should be selected or not
|
||||
* @param canWrap: when true, wraps around folders
|
||||
* @param openThreads: should we open closed threads?
|
||||
* @param reverse: change direction of searching
|
||||
/**
|
||||
* General-purpose method to find messages
|
||||
*
|
||||
* @param {function} validatorFunc(msg): return true/false whether msg should be selected or not
|
||||
* @param {boolean} canWrap: when true, wraps around folders
|
||||
* @param {boolean} openThreads: should we open closed threads?
|
||||
* @param {boolean} reverse: change direction of searching
|
||||
*/
|
||||
selectMessage: function (validatorFunc, canWrap, openThreads, reverse, count)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
2009:
|
||||
* Jonathan Austin
|
||||
* Steven Romanow
|
||||
|
||||
2008:
|
||||
* John Baber
|
||||
* Mark Orr
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
* IMPORTANT: Due to much improved autocompletion, changed default 'complete' option
|
||||
value to 'sfl', listing intelligent Firefox location bar results. Removed possibility
|
||||
to use 'h' in 'complete'.
|
||||
* IMPORTANT: AlwaysHint modes were removed as they didn't make too
|
||||
much sense with the new hint system
|
||||
* IMPORTANT: AlwaysHint mode with ;F mode changed the semantics slightly
|
||||
* IMPORTANT: command actions now take an args object, returned from
|
||||
commands.parseArgs, as their first argument. This will break any commands
|
||||
not using the args parser explicitly. The old string value is now
|
||||
|
||||
@@ -3,7 +3,6 @@ Priority list:
|
||||
|
||||
BUGS:
|
||||
- add window resize support to hints
|
||||
- can't reverse tab through the vimperator toolbar
|
||||
- searching backwards incrementally does not work i.e. with 'incsearch' set
|
||||
- http://msdn2.microsoft.com/en-us/library/ms535258.aspx does not scroll with j/k/etc.
|
||||
same for http://forum.mootools.net/topic.php?id=3458 and
|
||||
@@ -22,7 +21,19 @@ BUGS:
|
||||
|
||||
(recent CVS regressions):
|
||||
- visual caret mode is broken
|
||||
- BookmarkAdd is fired once for each bookmark periodically i.e. not in response to adding a bookmark
|
||||
- the message system is a bit of a debacle at the moment but I'm not sure how
|
||||
it's supposed to work. MST, can you spec it when you have some time?
|
||||
E.g. :ls | :echomsg "Foobar" doesn't add "Foobar" to the already open MOW.
|
||||
Obviously I think it should but I'm not sure if it's a bug or not in your
|
||||
view, thanks. --djk
|
||||
The spec is easy: echomsg() is used for informational purposes, and should therefore
|
||||
never need user interaction. Therefore: If the MOW is open, print the message there,
|
||||
but never open the MOW for an echomsg(). --mst
|
||||
- While the old :open foo<tab> was broken/annoying, so is the one after 02-01-2008, as
|
||||
I am often waiting ~20sec or more after doing :open not-cached-things<tab>.
|
||||
We should probably just abort searching after 5 secs if we already have found some entries.
|
||||
- :set noflashblock seems broken (= :set fb? afterwards says "fb"), let's see if that's a
|
||||
plugin or a vimp issue.
|
||||
|
||||
FEATURES:
|
||||
9 finish :help TODOs
|
||||
@@ -30,6 +41,15 @@ FEATURES:
|
||||
9 adaptive timeout for auto-completions, :set completions can be updated more often than
|
||||
:open foo
|
||||
9 use the storage module for autocommands
|
||||
8 support 'activate' in buffer.followLink?
|
||||
Leave this to the bookmarks.tabs.loadInBackground. Hint activation
|
||||
should be nearly equivalent to the corresponding mouse motion, and that
|
||||
mouse movement would be governed by the FF pref. However, :tabopen is
|
||||
something Vimp specific, and so it needs a specific setting (i.e.,
|
||||
activate). OTOH, I think it would be better if ";t" *always* opens a
|
||||
new foreground tab and ";b" *always* opensa new background tab. So "F"
|
||||
should be the only hint mode that changes based on loadInBackground.
|
||||
--Ted
|
||||
8 add support for filename special characters such as %
|
||||
8 :redir and 'verbosefile'
|
||||
8 middleclick in content == p, and if command line is open, paste there the clipboard buffer
|
||||
@@ -37,8 +57,10 @@ FEATURES:
|
||||
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
|
||||
7 adaptive learning for tab-completions
|
||||
(https://bugzilla.mozilla.org/show_bug.cgi?id=395739 could help)
|
||||
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
|
||||
8 allow for multiple ex commands separated with |
|
||||
7 use ctrl-n/p in insert mode for word completion
|
||||
7 implement QuickFix window based on ItemList
|
||||
7 [ctrl-o/i] to Go back to a Previous Position (done partly, however currently does not use a per tab jumplist)
|
||||
@@ -53,9 +75,10 @@ FEATURES:
|
||||
6 support private mode (and :set [no]private): http://ehsanakhgari.org/blog/2008-11-08/prepare-your-add-private-browsing
|
||||
6 add [count] support to :b* and :tab* commands where missing
|
||||
6 registers
|
||||
6 allow for multiple ex commands separated with |
|
||||
Here, unlike Vim, y and "*y would be equivalent. That is, the pasteboard would
|
||||
always be the default register. --Ted
|
||||
6 check/correct spellings in insert mode with some mappings
|
||||
6 add more autocommands (TabClose, TabOpen, TabChanged, DownloadPre/Post any more?)
|
||||
6 add more autocommands (TabClose, TabOpen, TabChanged any more?)
|
||||
6 jump to the next heading with ]h, next image ]i, previous textbox [t and so on
|
||||
6 :grep support (needs location list)
|
||||
6 use '' to jump between marks like vim
|
||||
@@ -68,12 +91,13 @@ FEATURES:
|
||||
5 make a command to search within google search results
|
||||
(http://gadelkareem.com/2007/01/28/using-google-ajax-api-as-an-array/)
|
||||
maybe impossible, needs a per-site key from google
|
||||
4 y and Y could maybe changed to, but probably not: Y, yy and yl=yank location, ys=yank selection,
|
||||
yd=yank domain name, yt=yank title, yw=yank current word, yf=yank filename, (other things to yank?)
|
||||
4 } { should jump to the next paragraph of the page (maybe impossible)
|
||||
3 A format for 'guitablabel' and 'statusline'
|
||||
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
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
const DEFAULT_FAVICON = "chrome://mozapps/skin/places/defaultFavicon.png";
|
||||
|
||||
// Try to import older command line history, quick marks, etc.
|
||||
liberator.registerObserver("load_options", function () {
|
||||
liberator.registerObserver("load", function () {
|
||||
if (!options.getPref("extensions.vimperator.commandline_cmd_history"))
|
||||
return;
|
||||
|
||||
@@ -61,12 +61,20 @@ function Bookmarks() //{{{
|
||||
const taggingService = PlacesUtils.tagging;
|
||||
const faviconService = Cc["@mozilla.org/browser/favicon-service;1"].getService(Ci.nsIFaviconService);
|
||||
|
||||
// XXX for strange Firefox bug :(
|
||||
// Error: [Exception... "Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [nsIObserverService.addObserver]"
|
||||
// nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)"
|
||||
// location: "JS frame :: file://~firefox/components/nsTaggingService.js :: anonymous :: line 89"
|
||||
// data: no]
|
||||
// Source file: file://~firefox/components/nsTaggingService.js
|
||||
taggingService.getTagsForURI(window.makeURI("http://mysterious.bug"), {});
|
||||
|
||||
const Bookmark = new Struct("url", "title", "icon", "keyword", "tags", "id");
|
||||
const Keyword = new Struct("keyword", "title", "icon", "url");
|
||||
Bookmark.defaultValue("icon", function () getFavicon(this.url));
|
||||
Bookmark.prototype.__defineGetter__("extra", function () [
|
||||
['keyword', this.keyword, "Keyword"],
|
||||
['tags', this.tags.join(', '), "Tag"]
|
||||
["keyword", this.keyword, "Keyword"],
|
||||
["tags", this.tags.join(", "), "Tag"]
|
||||
].filter(function (item) item[1]));
|
||||
|
||||
const storage = modules.storage;
|
||||
@@ -411,7 +419,7 @@ function Bookmarks() //{{{
|
||||
get format() ({
|
||||
anchored: false,
|
||||
title: ["URL", "Info"],
|
||||
keys: { text: "url", description: "title", icon: "icon", extra: "extra" },
|
||||
keys: { text: "url", description: "title", icon: "icon", extra: "extra", tags: "tags" },
|
||||
process: [template.icon, template.bookmarkDescription]
|
||||
}),
|
||||
|
||||
@@ -692,7 +700,7 @@ function History() //{{{
|
||||
"Go back in the browser history",
|
||||
function (args)
|
||||
{
|
||||
args = args.string;
|
||||
let url = args.literalArg;
|
||||
|
||||
if (args.bang)
|
||||
{
|
||||
@@ -700,12 +708,12 @@ function History() //{{{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (args)
|
||||
if (url)
|
||||
{
|
||||
let sh = window.getWebNavigation().sessionHistory;
|
||||
for (let i = sh.index - 1; i >= 0; i--)
|
||||
for (let i in util.range(sh.index, 0, true))
|
||||
{
|
||||
if (sh.getEntryAtIndex(i, false).URI.spec == args)
|
||||
if (sh.getEntryAtIndex(i, false).URI.spec == url)
|
||||
{
|
||||
window.getWebNavigation().gotoIndex(i);
|
||||
return;
|
||||
@@ -715,7 +723,7 @@ function History() //{{{
|
||||
}
|
||||
else
|
||||
{
|
||||
history.stepTo(args.count > 0 ? -1 * args.count : -1);
|
||||
history.stepTo(-Math.max(args.count, 1));
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -738,7 +746,7 @@ function History() //{{{
|
||||
"Go forward in the browser history",
|
||||
function (args)
|
||||
{
|
||||
args = args.string;
|
||||
let url = args.literalArg;
|
||||
|
||||
if (args.bang)
|
||||
{
|
||||
@@ -746,12 +754,12 @@ function History() //{{{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (args)
|
||||
if (url)
|
||||
{
|
||||
let sh = window.getWebNavigation().sessionHistory;
|
||||
for (let i in util.range(sh.index + 1, sh.count))
|
||||
{
|
||||
if (sh.getEntryAtIndex(i, false).URI.spec == args)
|
||||
if (sh.getEntryAtIndex(i, false).URI.spec == url)
|
||||
{
|
||||
window.getWebNavigation().gotoIndex(i);
|
||||
return;
|
||||
@@ -761,7 +769,7 @@ function History() //{{{
|
||||
}
|
||||
else
|
||||
{
|
||||
history.stepTo(args.count > 0 ? args.count : 1);
|
||||
history.stepTo(Math.max(args.count, 1));
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -837,31 +845,30 @@ function History() //{{{
|
||||
if (index >= 0 && index < window.getWebNavigation().sessionHistory.count)
|
||||
window.getWebNavigation().gotoIndex(index);
|
||||
else
|
||||
liberator.beep();
|
||||
liberator.beep(); // XXX: really wanted?
|
||||
},
|
||||
|
||||
goToStart: function goToStart()
|
||||
{
|
||||
let index = window.getWebNavigation().sessionHistory.index;
|
||||
if (index == 0)
|
||||
{
|
||||
liberator.beep(); // XXX: really wanted?
|
||||
return;
|
||||
}
|
||||
|
||||
if (index > 0)
|
||||
window.getWebNavigation().gotoIndex(0);
|
||||
else
|
||||
liberator.beep(); // XXX: really wanted?
|
||||
|
||||
},
|
||||
|
||||
goToEnd: function goToEnd()
|
||||
{
|
||||
let index = window.getWebNavigation().sessionHistory.index;
|
||||
if (index == window.getWebNavigation().sessionHistory.count - 1)
|
||||
{
|
||||
liberator.beep();
|
||||
return;
|
||||
}
|
||||
let sh = window.getWebNavigation().sessionHistory;
|
||||
let max = sh.count - 1;
|
||||
|
||||
if (sh.index < max)
|
||||
window.getWebNavigation().gotoIndex(max);
|
||||
else
|
||||
liberator.beep(); // XXX: really wanted?
|
||||
|
||||
},
|
||||
|
||||
// if openItems is true, open the matching history items in tabs rather than display
|
||||
|
||||
@@ -31,7 +31,7 @@ const config = { //{{{
|
||||
name: "Vimperator",
|
||||
hostApplication: "Firefox",
|
||||
|
||||
/*** optional options, there are checked for existance and a fallback provided ***/
|
||||
/*** optional options, there are checked for existence and a fallback provided ***/
|
||||
features: ["bookmarks", "hints", "history", "marks", "quickmarks", "session", "tabs", "windows"],
|
||||
defaults: { guioptions: "rb" },
|
||||
|
||||
@@ -430,16 +430,12 @@ const config = { //{{{
|
||||
{
|
||||
setter: function (value)
|
||||
{
|
||||
const ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService2);
|
||||
const ioService = services.get("io");
|
||||
ioService.offline = !value;
|
||||
gPrefService.setBoolPref("browser.offline", ioService.offline);
|
||||
return value;
|
||||
},
|
||||
getter: function ()
|
||||
{
|
||||
const ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService2);
|
||||
return ioService.offline;
|
||||
}
|
||||
getter: function () !services.get("io").offline
|
||||
});
|
||||
|
||||
options.add(["titlestring"],
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -57,18 +57,18 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|:doautoa| |:doautoall|
|
||||
||:doautoa[ll] {event} [url]|| +
|
||||
||:doautoa[ll] {event} [a][url][a]|| +
|
||||
________________________________________________________________________________
|
||||
Apply the autocommands matching the specified URL to all buffers. If no [url]
|
||||
is specified use the current URL.
|
||||
Apply the autocommands matching the specified URL to all buffers. If no
|
||||
[a][url][a] is specified use the current URL.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|:do| |:doautocmd|
|
||||
||:do[autocmd] {event} [url]|| +
|
||||
||:do[autocmd] {event} [a][url][a]|| +
|
||||
________________________________________________________________________________
|
||||
Apply the autocommands matching the specified URL to the current buffer. If no
|
||||
[url] is specified use the current URL.
|
||||
[a][url][a] is specified use the current URL.
|
||||
________________________________________________________________________________
|
||||
|
||||
section:Examples[autocmd-examples]
|
||||
|
||||
@@ -30,27 +30,29 @@ ________________________________________________________________________________
|
||||
section:Opening{nbsp}web{nbsp}pages[opening]
|
||||
|
||||
|o| |:o| |:open|
|
||||
||:o[pen][!] [arg1], [arg2], ...|| +
|
||||
||:o[pen][!] [a][arg1][a], [a][arg2][a], ...|| +
|
||||
||o||
|
||||
________________________________________________________________________________
|
||||
Open one or more URLs in the current tab.
|
||||
Multiple URLs can be separated with 'urlseparator' (default: ", " Note that the
|
||||
space after the comma is required.")
|
||||
The first URL is opened in the current tab, and all other URLs are
|
||||
opened in new tabs.
|
||||
Each token is analyzed and in this order:
|
||||
|
||||
1. Opened as a local file if it is an existing relative or absolute filename.
|
||||
- [c]:open /etc/fstab[c] shows the file system table.
|
||||
- [c]:open ../other/foo.html[c] in your home directory opens
|
||||
. Opened as a local file if it is an existing relative or absolute filename.
|
||||
* [c]:open /etc/fstab[c] shows the file system table.
|
||||
* [c]:open ../other/foo.html[c] in your home directory opens
|
||||
[a]/home/other/foo.html[a]
|
||||
2. Opened with the specified search engine if the token looks like a search
|
||||
. Opened with the specified search engine if the token looks like a search
|
||||
string and the first word is the name of a search engine ([c]:open wikipedia
|
||||
linus torvalds[c] opens the Wikipedia entry for linus torvalds). The short
|
||||
name of a search engine is automatically guessed from its name. If you want
|
||||
to set a custom name, you can change it with [c]:dialog searchengines[c].
|
||||
3. Opened with the default search engine or keyword (specified with the
|
||||
. Opened with the default search engine or keyword (specified with the
|
||||
'defsearch' option) if the first word is no search engine ([c]:open linus
|
||||
torvalds[c] opens a Google search for linux torvalds).
|
||||
4. Passed directly to Firefox in all other cases ([c]:open www.osnews.com,
|
||||
. Passed directly to Firefox in all other cases ([c]:open www.osnews.com,
|
||||
www.slashdot.org[c] opens OSNews in the current, and Slashdot in a new
|
||||
background tab).
|
||||
|
||||
@@ -65,19 +67,18 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|t| |:t| |:tabopen| |:tabnew| |:tabe| |:tabedit|
|
||||
||:tabopen[!] [arg1], [arg2], ...|| +
|
||||
||:tabopen[!] [a][arg1][a], [a][arg2][a], ...|| +
|
||||
||t||
|
||||
________________________________________________________________________________
|
||||
Just like [c]:open[c], but opens the resulting web page(s)
|
||||
in a new tab. When used with [!], the 'tabopen' value of the 'activate' option
|
||||
is negated.
|
||||
Just like [c]:open[c], but also uses a new tab for the first URL. When
|
||||
used with [!], the 'tabopen' value of the 'activate' option is negated.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|T| +
|
||||
||T||
|
||||
________________________________________________________________________________
|
||||
Open one or more URLs in a new tab, based on current location. Works like
|
||||
Open one or more URLs in a new tab based on current location. Works like
|
||||
[m]t[m], but preselects current URL in the [c]:tabopen[c] query.
|
||||
________________________________________________________________________________
|
||||
|
||||
@@ -94,16 +95,15 @@ ________________________________________________________________________________
|
||||
|O| +
|
||||
||O||
|
||||
________________________________________________________________________________
|
||||
Open one or more URLs in the current tab, based on current location. Works
|
||||
Open one or more URLs in the current tab based on current location. Works
|
||||
like [m]o[m], but preselects current URL in the [c]:open[c] query.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|:winopen| |:wopen| |:winedit|
|
||||
||:wino[pen][!] [arg1], [arg2], ...|| +
|
||||
||:wino[pen][!] [a][arg1][a], [a][arg2][a], ...|| +
|
||||
________________________________________________________________________________
|
||||
Just like help::open[browsing.html#opening], but opens the resulting web page(s)
|
||||
in a new window.
|
||||
Just like [c]:tabopen[c], but opens the resulting web page(s) in a new window.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
@@ -274,11 +274,10 @@ ________________________________________________________________________________
|
||||
section:Writing[writing,save-file]
|
||||
|
||||
|:w| |:write| |:sav| |:saveas| +
|
||||
||:sav[eas][!] [file]||
|
||||
||:sav[eas][!] [a][file][a]||
|
||||
________________________________________________________________________________
|
||||
Save current web page to disk. If [file] is omitted, save to the page's
|
||||
default filename. Existing documents will only be overwritten if [!] is
|
||||
given.
|
||||
Save current web page to disk. If [a][file][a] is omitted, save to the page's
|
||||
default filename. Existing documents will only be overwritten if [!] is given.
|
||||
________________________________________________________________________________
|
||||
|
||||
section:Quitting[quitting,save-session]
|
||||
|
||||
@@ -47,9 +47,9 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|:vie| |:viewsource|
|
||||
||:vie[wsource][!] [url]|| +
|
||||
||:vie[wsource][!] [a][url][a]|| +
|
||||
________________________________________________________________________________
|
||||
View source code of current document. If [url] is specified then view the
|
||||
View source code of current document. If [a][url][a] is specified then view the
|
||||
source of that document. When [!] is given, it is opened with the external
|
||||
editor.
|
||||
________________________________________________________________________________
|
||||
@@ -97,24 +97,29 @@ ________________________________________________________________________________
|
||||
|<Left>| |h| +
|
||||
||[count]h||
|
||||
________________________________________________________________________________
|
||||
Scroll document to the left. Count is supported: [m]10h[m] will move 10 times as much to the left. +
|
||||
If the document cannot scroll more, a beep is emitted (unless 'visualbell' is set).
|
||||
Scroll document to the left. If [count] is specified then move [count] times as
|
||||
much to the left. +
|
||||
If the document cannot scroll more, a beep is emitted (unless 'visualbell' is
|
||||
set).
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|<C-e>| |<Down>| |j| +
|
||||
||[count]j||
|
||||
________________________________________________________________________________
|
||||
Scroll document down. Count is supported: [m]10j[m] will move 10 times as much down. +
|
||||
If the document cannot scroll more, a beep is emitted (unless 'visualbell' is set).
|
||||
Scroll document down. If [count] is specified then move [count] times as much
|
||||
down. +
|
||||
If the document cannot scroll more, a beep is emitted (unless 'visualbell' is
|
||||
set).
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|<C-y>| |<Up>| |k| +
|
||||
||[count]k||
|
||||
________________________________________________________________________________
|
||||
Scroll document up. Count is supported: [m]10k[m] will move 10 times as much up. +
|
||||
If the document cannot scroll more, a beep is emitted (unless 'visualbell' is set).
|
||||
Scroll document up. If [count] is specified then move [count] times as much up. +
|
||||
If the document cannot scroll more, a beep is emitted (unless 'visualbell' is
|
||||
set).
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
@@ -139,8 +144,10 @@ ________________________________________________________________________________
|
||||
|<Right>| |l| +
|
||||
||[count]l||
|
||||
________________________________________________________________________________
|
||||
Scroll document to the right. Count is supported: [m]10l[m] will move 10 times as much to the right. +
|
||||
If the document cannot scroll more, a beep is emitted (unless 'visualbell' is set).
|
||||
Scroll document to the right. If [count] is specified then move [count] times
|
||||
as much to the right. +
|
||||
If the document cannot scroll more, a beep is emitted (unless 'visualbell' is
|
||||
set).
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
@@ -217,11 +224,11 @@ ________________________________________________________________________________
|
||||
|
||||
section:Zooming[zooming,zoom]
|
||||
|
||||
The zooming commands are dependent on two properties - a zoom range and a
|
||||
The zooming commands are dependent on two properties -- a zoom range and a
|
||||
series of levels within that range.
|
||||
|
||||
The absolute value of the page zoom is limited to a value within the configured
|
||||
zoom range (default: 30% - 300%). The zoom levels are used by
|
||||
zoom range (default: 30%--300%). The zoom levels are used by
|
||||
[m]zi[m]/[m]zo[m], and similar commands, to change the zoom value in steps. The
|
||||
default zoom levels are 30%, 50%, 67%, 80%, 90%, 100%, 110%, 120%, 133%, 150%,
|
||||
170%, 200%, 240%, 300%.
|
||||
@@ -306,12 +313,12 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|:zo| |:zoom|
|
||||
||:zo[om][!] [value]|| +
|
||||
||:zo[om][!] [a][value][a]|| +
|
||||
||:zo[om][!] +{value} | -{value}|| +
|
||||
________________________________________________________________________________
|
||||
Set zoom value of current web page. [value] can be an absolute value between 30
|
||||
and 300% or a relative value if prefixed with "-" or "+". If [value] is
|
||||
omitted, zoom is reset to 100%.
|
||||
Set zoom value of current web page. [a][value][a] can be an absolute value
|
||||
between 30 and 300% or a relative value if prefixed with "-" or "+". If
|
||||
[a][value][a] is omitted, zoom is reset to 100%.
|
||||
|
||||
Normally this command operates on the text zoom, if used with [!] it operates
|
||||
on full zoom.
|
||||
@@ -339,14 +346,14 @@ ________________________________________________________________________________
|
||||
|
||||
section:Alternate{nbsp}style{nbsp}sheets[alternate-stylesheet]
|
||||
|
||||
Page authors may specify alternate style sheets for an HTML document. Users
|
||||
can then switch between these various style sheets, selecting their favorite.
|
||||
Page authors may specify alternate style sheets for an HTML document. Users can
|
||||
then switch between these various style sheets, selecting their favorite.
|
||||
|
||||
|:pagest| |:pagestyle|
|
||||
||:pagest[yle] [stylesheet]|| +
|
||||
||:pagest[yle] [a][stylesheet][a]|| +
|
||||
________________________________________________________________________________
|
||||
Select the author style sheet to apply. If [stylesheet] is not specified the
|
||||
page's default style sheet is used.
|
||||
Select the author style sheet to apply. If [a][stylesheet][a] is not specified
|
||||
the page's default style sheet is used.
|
||||
|
||||
All author styling can be removed by setting the 'usermode' option.
|
||||
________________________________________________________________________________
|
||||
|
||||
@@ -53,10 +53,11 @@ Some notes about the code above:
|
||||
- The actual help code for this command is embedded in at least 4 underscores
|
||||
(_). This generates a quoteblock and indents the text so it is more clear
|
||||
that it belongs to the command.
|
||||
- Wrap things in *$$[c]$$* and they are drawn like a :command. Also *$$[o]$$*
|
||||
and *$$[m]$$* are available to show options and mappings.
|
||||
- Any string within \{...\} and $$[arg]$$, $$[url]$$, $$[count]$$ and $$[!]$$ are
|
||||
automatically drawn in a blue color.
|
||||
- Wrap things in *$$[c]$$* and they are drawn like a :command. Also *$$[o]$$*,
|
||||
*$$[m]$$* and *$$[a]$$* are available to markup options, mappings, and
|
||||
arguments.
|
||||
- As a convenience, any string within \{...\} and $$[count]$$ and $$[!]$$ are
|
||||
automatically marked up as an argument.
|
||||
|
||||
There are also some additional asciidoc commands specifically for writing
|
||||
Vimperator documentation:
|
||||
|
||||
@@ -8,10 +8,9 @@ INTRO TO BE WRITTEN...
|
||||
||:ec[ho] {expr}||
|
||||
________________________________________________________________________________
|
||||
Echo the expression. Useful for showing informational messages. Multiple lines
|
||||
can be separated by \n. {expr} can either be a quoted string, or any
|
||||
expression which can be fed to eval() like 4+5. You can also view the source
|
||||
code of objects and functions if the return value of {expr} is an object or
|
||||
function.
|
||||
can be separated by \n. {expr} can either be a quoted string, or any expression
|
||||
which can be fed to eval() like 4+5. You can also view the source code of
|
||||
objects and functions if the return value of {expr} is an object or function.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
@@ -43,8 +42,8 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|:js| |:javas| |:javascript|
|
||||
||:javas[cript] \\{cmd\\}|| +
|
||||
||:javascript <<\\{endpattern\\}\n\\{script\\}\n\\{endpattern\\}|| +
|
||||
||:javas[cript] {cmd}|| +
|
||||
||:javascript <<{endpattern}\n{empty}{script}\n{empty}{endpattern} || +
|
||||
||:javascript[!]||
|
||||
________________________________________________________________________________
|
||||
Run any JavaScript command through eval(). Acts as a JavaScript interpreter by
|
||||
|
||||
@@ -16,12 +16,9 @@ window.addEventListener("message", function (event) {
|
||||
}, true);
|
||||
|
||||
document.addEventListener("click", function (event) {
|
||||
let elem = event.target;
|
||||
if (/^(option|mapping|command)$/.test(elem.className))
|
||||
var tag = elem.textContent.replace(/\s.*/, "");
|
||||
if (elem.className == "command")
|
||||
tag = tag.replace(/\[.*?\]/g, "");
|
||||
if (tag)
|
||||
elem.href = "chrome://liberator/content/help.xul?" + encodeURIComponent(tag);
|
||||
let evt = document.createEvent("UIEvents");
|
||||
evt.initEvent("liberatorHelpLink", true, true);
|
||||
event.target.dispatchEvent(evt);
|
||||
}, true);
|
||||
|
||||
// vim: set fdm=marker sw=4 ts=4 et:
|
||||
|
||||
@@ -5,7 +5,7 @@ HEADER
|
||||
INTRO TO BE WRITTEN...
|
||||
|
||||
|f| +
|
||||
||f\\{hint\\}||
|
||||
||#f#{hint}||
|
||||
________________________________________________________________________________
|
||||
Start QuickHint mode. In QuickHint mode, every hintable item (according to the
|
||||
'hinttags' XPath query) is assigned a unique number. You can now either type
|
||||
@@ -20,7 +20,7 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|F| +
|
||||
||F\\{hint\\}||
|
||||
||#F#{hint}||
|
||||
________________________________________________________________________________
|
||||
Start QuickHint mode, but open link in a new tab. Like normal QuickHint mode
|
||||
(activated with [m]f[m]) but opens the link in a new tab.
|
||||
@@ -30,33 +30,38 @@ ________________________________________________________________________________
|
||||
|extended-hints| +
|
||||
|
||||
|;| +
|
||||
||;\\{mode\\}\\{hint\\}||
|
||||
||#;#{mode}{empty}{hint}||
|
||||
________________________________________________________________________________
|
||||
Start an extended hint mode. ExtendedHint mode is useful, since in this mode
|
||||
you can yank link locations, open them in a new window or save images. If
|
||||
you want to yank the location of hint [a]24[a], press [m];y[m] to start
|
||||
this hint mode. Then press [a]24[a] to copy the hint location.
|
||||
|
||||
{mode} can be either one of: +
|
||||
{mode} can be one of: +
|
||||
|
||||
* [m];[m] to focus a link and hover it with the mouse
|
||||
* [m]?[m] to show information about the element (incomplete)
|
||||
* [m]a[m] to save its destination (prompting for save location)
|
||||
* [m]f[m] to focus a frame
|
||||
* [m]s[m] to save its destination
|
||||
* [m]o[m] to open its location in the current tab
|
||||
* [m]t[m] to open its location in a new tab
|
||||
* [m]b[m] like [m]t[m] but inverts the option whether the tab is activated
|
||||
* [m]O[m] to open its location in an [c]:open[c] query
|
||||
* [m]T[m] to open its location in a [c]:tabopen[c] query
|
||||
* [m]v[m] to view its destination source
|
||||
* [m]w[m] to open its destination in a new window
|
||||
* [m]W[m] to open its location in a [c]:winopen[c] query
|
||||
* [m]y[m] to yank its destination location
|
||||
* [m]Y[m] to yank its text description
|
||||
* |;;| [m];[m] to focus a link and hover it with the mouse
|
||||
* |;?| [m]?[m] to show information about the element (incomplete)
|
||||
* |;s| [m]s[m] to save its destination
|
||||
* |;a| [m]a[m] to save its destination (prompting for save location)
|
||||
* |;f| [m]f[m] to focus a frame
|
||||
* |;o| [m]o[m] to open its location in the current tab
|
||||
* |;t| [m]t[m] to open its location in a new tab
|
||||
* |;b| [m]b[m] to open its location in a new background tab
|
||||
* |;w| [m]w[m] to open its destination in a new window
|
||||
* |;F| [m]F[m] to follow a sequence of [m]<CR>[m]-delimited hints in background tabs
|
||||
* |;O| [m]O[m] to preselect its location in an [c]:open[c] query
|
||||
* |;T| [m]T[m] to preselect its location in a [c]:tabopen[c] query
|
||||
* |;W| [m]W[m] to preselect its location in a [c]:winopen[c] query
|
||||
* |;v| [m]v[m] to view its destination source
|
||||
* |;V| [m]V[m] to view its destination source in the external editor
|
||||
* |;y| [m]y[m] to yank its destination location
|
||||
* |;Y| [m]Y[m] to yank its text description
|
||||
|
||||
Hintable elements for all extended hint modes can be set in the
|
||||
'extendedhinttags' XPath string.
|
||||
|
||||
Note: The behavior of [m];t[m] and [m];b[m] is inverted if the
|
||||
\'browser.tabs.loadInBackground' Firefox preference is set to false.
|
||||
________________________________________________________________________________
|
||||
|
||||
// vim: set syntax=asciidoc:
|
||||
|
||||
@@ -38,7 +38,7 @@ more, you can either send me greetings, patches or make a donation:
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Of course as a believer in free open source software, only make a donation
|
||||
if you really like Vimperator and the money doesn't hurt - otherwise just use
|
||||
if you really like Vimperator and the money doesn't hurt -- otherwise just use
|
||||
it, recommend it and like it :)
|
||||
|
||||
section:Help{nbsp}topics[overview]
|
||||
|
||||
@@ -15,7 +15,7 @@ Vimperator supports a number of different marks:
|
||||
section:Bookmarks[bookmarks]
|
||||
|
||||
|a| |:bma| |:bmark|
|
||||
||:bma[rk][!] [-title=title] [-keyword=kw] [-tags=tag1,tag2] [url]|| +
|
||||
||:bma[rk][!] [a][-title=title][a] [a][-keyword=kw][a] [a][-tags=tag1,tag2][a] [a][url][a]|| +
|
||||
||a||
|
||||
____________________________________________________________________________
|
||||
Add a bookmark. +
|
||||
@@ -27,12 +27,12 @@ The following options are interpreted:
|
||||
- -keyword=keyword (short option: -k)
|
||||
|
||||
If [!] is present, a new bookmark is always added. Otherwise, the first
|
||||
bookmark matching [url] is updated.
|
||||
bookmark matching [a][url][a] is updated.
|
||||
|
||||
When creating a new bookmark, if [a][-title][a] isn't given, either the web
|
||||
page's title or URL is used. You can omit the optional [url] argument, so just
|
||||
do [c]:bmark[c] to bookmark the currently loaded web page with a default title
|
||||
and without any tags.
|
||||
page's title or URL is used. You can omit the optional [a][url][a] argument, so
|
||||
just do [c]:bmark[c] to bookmark the currently loaded web page with a default
|
||||
title and without any tags.
|
||||
____________________________________________________________________________
|
||||
|
||||
|
||||
@@ -47,10 +47,11 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|:bmarks|
|
||||
||:bmarks[!] [filter]|| +
|
||||
||:bmarks[!] [a][filter][a]|| +
|
||||
________________________________________________________________________________
|
||||
List or open multiple bookmarks. Open the message window at the bottom of the
|
||||
screen with all bookmarks which match [filter] either in the title or URL.
|
||||
screen with all bookmarks which match [a][filter][a] either in the title or
|
||||
URL.
|
||||
|
||||
The special version [c]:bmarks![c] works the same as [c]:bmarks[c] except it
|
||||
opens all the found bookmarks in new tabs.
|
||||
@@ -62,10 +63,10 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|:delbm| |:delbmarks|
|
||||
||:delbm[arks] [url]|| +
|
||||
||:delbm[arks] [a][url][a]|| +
|
||||
________________________________________________________________________________
|
||||
Delete a bookmark. Deletes *all* bookmarks which match the [url].
|
||||
If omitted, [url] defaults to the URL of the current buffer. Use [m]<Tab>[m]
|
||||
Delete a bookmark. Deletes *all* bookmarks which match the [a][url][a]. If
|
||||
omitted, [a][url][a] defaults to the URL of the current buffer. Use [m]<Tab>[m]
|
||||
key on a string to complete the URL which you want to delete.
|
||||
|
||||
The following options WILL be interpreted in the future:
|
||||
@@ -94,40 +95,40 @@ ________________________________________________________________________________
|
||||
|<M-Left>| |<A-Left>| |H| +
|
||||
||[count]H||
|
||||
________________________________________________________________________________
|
||||
Go back in the browser history. Count is supported: [m]3H[m] goes back 3 steps.
|
||||
Go back in the browser history. If [count] is specified go back [count] pages.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|<M-Right>| |<A-Right>| |L| +
|
||||
||[count]L||
|
||||
________________________________________________________________________________
|
||||
Go forward in the browser history. Count is supported: [m]3L[m] goes forward 3 steps.
|
||||
Go forward in the browser history. If [count] is specified go forward [count]
|
||||
pages.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|:ba| |:back|
|
||||
||:[count]ba[ck][!] [url]|| +
|
||||
||:[count]ba[ck][!] [a][url][a]|| +
|
||||
________________________________________________________________________________
|
||||
Go back in the browser history. Count is supported, [c]:3back[c] goes back 3
|
||||
pages in the browser history. +
|
||||
Go back in the browser history. If [count] is specified go back [count] pages. +
|
||||
The special version [c]:back![c] goes to the beginning of the browser history.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|:fw| |:fo| |:forward|
|
||||
||:[count]fo[rward][!] [url]|| +
|
||||
||:[count]fo[rward][!] [a][url][a]|| +
|
||||
________________________________________________________________________________
|
||||
Go forward in the browser history. Count is supported, [c]:3forward[c] goes
|
||||
forward 3 pages in the browser history. The special version [c]:forward![c]
|
||||
goes to the end of the browser history.
|
||||
Go forward in the browser history. If [count] is specified go forward [count]
|
||||
pages. +
|
||||
The special version [c]:forward![c] goes to the end of the browser history.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|:hs| |:hist| |:history|
|
||||
||:hist[ory][!] [filter]|| +
|
||||
||:hist[ory][!] [a][filter][a]|| +
|
||||
________________________________________________________________________________
|
||||
Show recently visited URLs. Open the message window at the bottom of the
|
||||
screen with all history items which match [filter] either in the title or URL.
|
||||
Show recently visited URLs. Open the message window at the bottom of the screen
|
||||
with all history items which match [a][filter][a] either in the title or URL.
|
||||
|
||||
The special version [c]:history![c] works the same as [c]:history[c] except
|
||||
it opens all the found items in new tabs.
|
||||
@@ -183,7 +184,7 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|:qma| |:qmark|
|
||||
||:qma[rk] {a-zA-Z0-9} [url]|| +
|
||||
||:qma[rk] {a-zA-Z0-9} [a][url][a]|| +
|
||||
________________________________________________________________________________
|
||||
Mark a URL with a letter for quick access. You can also mark whole groups like this: +
|
||||
[c]:qmark f \http://forum1.com, \http://forum2.com, imdb some artist[c]
|
||||
@@ -191,9 +192,10 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|:qmarks|
|
||||
||:qmarks [arg]||
|
||||
||:qmarks [a][arg][a]||
|
||||
________________________________________________________________________________
|
||||
Show all QuickMarks. If [arg] is specified then limit the list to those QuickMarks mentioned.
|
||||
Show all QuickMarks. If [a][arg][a] is specified then limit the list to those
|
||||
QuickMarks mentioned.
|
||||
________________________________________________________________________________
|
||||
|
||||
section:Local{nbsp}marks[localmarks]
|
||||
@@ -237,9 +239,10 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|:marks| +
|
||||
||:marks [arg]||
|
||||
||:marks [a][arg][a]||
|
||||
________________________________________________________________________________
|
||||
Show all location marks of current web page. If [arg] is specified then limit the list to those marks mentioned.
|
||||
Show all location marks of current web page. If [a][arg][a] is specified then
|
||||
limit the list to those marks mentioned.
|
||||
________________________________________________________________________________
|
||||
|
||||
// vim: set syntax=asciidoc:
|
||||
|
||||
@@ -26,7 +26,7 @@ Show all options. Show all options.
|
||||
____
|
||||
|
||||
|E518| |E519|
|
||||
||:se[t] {option}*||
|
||||
||:se[t] {option}?||
|
||||
____
|
||||
Show value of {option}.
|
||||
____
|
||||
@@ -185,7 +185,7 @@ preferences.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|:set-!|
|
||||
|:set!| |:set-!|
|
||||
||:se[t]! {preference}={value}|| +
|
||||
________________________________________________________________________________
|
||||
Change any Firefox {preference} (those in the about:config window). You can also
|
||||
@@ -209,8 +209,9 @@ Define when tabs are automatically activated. Available items:
|
||||
____
|
||||
|
||||
|
||||
|$CDPATH|
|
||||
|\'cd'| |\'cdpath'|
|
||||
||'cdpath' 'cd'|| string (default: black)
|
||||
||'cdpath' 'cd'|| string (default: equivalent to _$CDPATH_ or ",,")
|
||||
____
|
||||
List of directories searched when executing the :cd command. This is only used
|
||||
for relative paths, if an absolute path is specified then the option is
|
||||
@@ -239,9 +240,9 @@ ____
|
||||
|\'ds'| |\'defsearch'|
|
||||
||'defsearch' 'ds'|| string (default: "google")
|
||||
____
|
||||
Sets the default search engine.
|
||||
The default search engine name is used in the [c]:[tab]open [arg][c] command if
|
||||
[[arg]] neither looks like a URL or like a specified search engine/keyword.
|
||||
Sets the default search engine. The default search engine name is used in the
|
||||
[c]:[tab]open [arg][c] command if [a][arg][a] neither looks like a URL or like
|
||||
a specified search engine/keyword.
|
||||
|
||||
This means, it you set 'defsearch' to "youtube", then [c]:open arnold
|
||||
schwarzenegger[c] will be exactly the same as [c]:open youtube arnold
|
||||
@@ -249,11 +250,11 @@ schwarzenegger[c]. Therefore, you need to add a keyword or search engine
|
||||
"youtube" first.
|
||||
|
||||
If 'defsearch' is empty, then Firefox will always attempt to open the
|
||||
raw [[arg]].
|
||||
raw [a][arg][a].
|
||||
____
|
||||
|
||||
|
||||
|\'editor'| |i_<Ctrl-i>|
|
||||
|\'editor'| |i_<C-i>|
|
||||
||'editor'|| string (default: "gvim -f")
|
||||
____
|
||||
Set the external text editor.
|
||||
@@ -469,7 +470,10 @@ ____
|
||||
|\'nolpl'| |\'lpl'| |\'noloadplugins'| |\'loadplugins'|
|
||||
||'loadplugins' 'lpl'|| boolean (default on)
|
||||
____
|
||||
Load plugin scripts when starting up.
|
||||
Load plugin scripts when starting up. When on, yet unloaded plugins are
|
||||
automatically loaded after the vimperatorrc file has been sourced. To
|
||||
load plugins earlier, use the [c]:loadplugins[c] command within the
|
||||
vimperatorrc.
|
||||
____
|
||||
|
||||
|
||||
@@ -594,7 +598,7 @@ ____
|
||||
|\'rtp'| |\'runtimepath'|
|
||||
||'runtimepath' 'rtp'|| stringlist
|
||||
____
|
||||
(default: \'$VIMPERATOR_RUNTIME' or Unix, Mac: "\~/.vimperator", Windows: "\~/vimperator")
|
||||
(default: _$VIMPERATOR_RUNTIME_ or Unix, Mac: "\~/.vimperator", Windows: "\~/vimperator")
|
||||
|
||||
List of directories searched for runtime files: +
|
||||
macros/ +
|
||||
@@ -603,6 +607,9 @@ plugin/ +
|
||||
Example: [c]:set runtimepath=\~/myvimperator,\~/.vimperator[c] +
|
||||
This will search for plugins in both "\~/myvimperator/plugin" and
|
||||
"\~/.vimperator/plugin"
|
||||
|
||||
On startup, if the environment variable _$VIMPERATOR_RUNTIME_ does not
|
||||
exist, Vimperator will set it to match this value.
|
||||
____
|
||||
|
||||
|
||||
@@ -618,18 +625,18 @@ ____
|
||||
|
||||
|
||||
|\'shell'| |\'sh'|
|
||||
||'shell' 'sh'|| string (default: "-c", Win32: "/c")
|
||||
||'shell' 'sh'|| string (default: _$SHELL_ or "sh", Win32: "cmd.exe")
|
||||
____
|
||||
Shell to use for executing :! and :run commands.
|
||||
____
|
||||
|
||||
|
||||
|\'shellcmdflag'| |\'shcf'|
|
||||
||'shellcmdflag' 'shcf'|| string (default: $SHELL or "sh", Win32: "cmd.exe")
|
||||
||'shellcmdflag' 'shcf'|| string (default: "-c", Win32: "/c")
|
||||
____
|
||||
Flag passed to shell when executing :! and :run commands.
|
||||
|
||||
E.g. bash -c gvim
|
||||
E.g. "bash -c gvim"
|
||||
____
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ HEADER
|
||||
|
||||
Vimperator provides a Vim-like interface to Firefox's standard text search
|
||||
functionality. There is no support for using regular expressions in search
|
||||
commands as Firefox does not provide native regexp support. It is unlikely
|
||||
that this will ever be available.
|
||||
commands as Firefox does not provide native regexp support. It is unlikely that
|
||||
this will ever be available.
|
||||
|
||||
|/| +
|
||||
||/\\{pattern\\}[/]<CR>|| +
|
||||
|
||||
@@ -16,10 +16,10 @@ ____________________________________________________________________________
|
||||
|
||||
|
||||
|:macros|
|
||||
||:mac[ros] [args]|| +
|
||||
||:mac[ros] [a][pat][a]|| +
|
||||
________________________________________________________________________________
|
||||
List recorded macros matching the optional regular expression [args]. If no
|
||||
regexp is given, list all macros.
|
||||
List recorded macros matching the optional regular expression [a][pat][a]. If
|
||||
no regexp is given, list all macros.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
@@ -95,9 +95,11 @@ ________________________________________________________________________________
|
||||
|:lpl| |:loadplugins|
|
||||
||:loadplugins|| +
|
||||
________________________________________________________________________________
|
||||
Load all unloaded plugins immediately. This is useful both for sourcing new
|
||||
plugins without restarting vimperator, and making sure that a plugin is loaded
|
||||
so that you can use its commands from your vimperatorrc.
|
||||
Load all unloaded plugins immediately. Because plugins are automatically
|
||||
loaded after vimperatorrc is sourced, this command must be placed early
|
||||
in the vimperatorrc file if vimperatorrc also includes commands that are
|
||||
implemented by plugins. Additionally, this command allows for sourcing
|
||||
new plugins without restarting vimperator.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|
||||
@@ -5,40 +5,46 @@ be documented here.
|
||||
|
||||
section:Initialization[initialization,startup]
|
||||
|
||||
At startup Vimperator can perform user initialization commands. When one of
|
||||
the following is successfully located, it is executed, and no further
|
||||
locations are tried.
|
||||
At startup, Vimperator completes the following tasks in order.
|
||||
|
||||
|$VIMPERATOR_INIT|
|
||||
1. _$VIMPERATOR_INIT_ - May contain a single ex command, usually
|
||||
[c]:source {file}[c].
|
||||
2. [a]\~/_vimperatorrc[a] - Windows only. If this file exists, its contents
|
||||
are executed.
|
||||
3. [a]\~/.vimperatorrc[a] - If this file exists, its contents are executed.
|
||||
. Vimperator can perform user initialization commands. When
|
||||
one of the following is successfully located, it is executed, and no
|
||||
further locations are tried.
|
||||
|
||||
If 'exrc' is set then any RC file in the current directory is also sourced.
|
||||
.. |$VIMPERATOR_INIT| _$VIMPERATOR_INIT_ -- May contain a single ex
|
||||
command (e.g.,
|
||||
"[c]:source {file}[c]").
|
||||
.. [a]\~/_vimperatorrc[a] -- Windows only. If this file exists, its
|
||||
contents are executed.
|
||||
.. [a]\~/.vimperatorrc[a] -- If this file exists, its contents are
|
||||
executed.
|
||||
|
||||
The plugin directory can be in any of the directories in 'runtimepath'.
|
||||
. If 'exrc' is set, then any RC file in the current directory is also sourced.
|
||||
|
||||
All directories in 'runtimepath' are searched for plugins and they are are all
|
||||
loaded.
|
||||
. All directories in 'runtimepath' are searched for a "plugin"
|
||||
subdirectory and all yet unloaded plugins are loaded. For each
|
||||
plugin directory, all *.\{js,vimp} files (including those in further
|
||||
subdirectories) are sourced alphabetically. No plugins will be sourced
|
||||
if 'noloadplugins' is set. Any particular plugin will not be loaded
|
||||
if it has already been loaded (e.g., by an earlier [c]:loadplugins[c]
|
||||
command).
|
||||
|
||||
Plugins will not be sourced if 'noloadplugins' is set.
|
||||
The user's ~ (i.e., "home") directory is determined as follows:
|
||||
|
||||
The user's \'$HOME'(~) directory is determined as follows:
|
||||
|
||||
* Unix and Mac - _$HOME_ is used.
|
||||
* Windows - if _%HOME%_ is set then this is used, otherwise _%USERPROFILE%_ or finally
|
||||
_%HOMEDRIVE%%HOMEPATH%_.
|
||||
* On Unix and Mac, the environment variable _$HOME_ is used.
|
||||
* On Windows, Vimperator checks for the existence of _%HOME%_, then
|
||||
_%USERPROFILE%_, and then _%HOMEDRIVE%%HOMEPATH%_. It uses the first one
|
||||
it finds.
|
||||
|
||||
section:Saving{nbsp}settings[save-settings]
|
||||
|
||||
|:mkv| |:mkvimperatorrc|
|
||||
||:mkv[imperatorrc][!] [file]|| +
|
||||
||:mkv[imperatorrc][!] [a][file][a]|| +
|
||||
________________________________________________________________________________
|
||||
Write current key mappings and changed options to [file]. If no [file] is
|
||||
specified then _~/.vimperatorrc_ is written unless this file already exists. The
|
||||
special version [c]:mkvimperatorrc![c] will overwrite [file] if it exists.
|
||||
Write current key mappings and changed options to [a][file][a]. If no
|
||||
[a][file][a] is specified then _~/.vimperatorrc_ is written unless this file
|
||||
already exists. The special version [c]:mkvimperatorrc![c] will overwrite
|
||||
[a][file][a] if it exists.
|
||||
|
||||
Warning: this differs from Vim's behavior which defaults to writing the file
|
||||
in the current directory.
|
||||
|
||||
@@ -92,14 +92,14 @@ ________________________________________________________________________________
|
||||
|:sty| |:style| +
|
||||
||:sty[le][!] [-name={name}] [-append] {filter} [{css}]|| +
|
||||
________________________________________________________________________________
|
||||
Add CSS styles to the browser or to web pages. {filter} is a
|
||||
comma separated list of URLs to match. URLs ending with [c]*[c]
|
||||
are matched as prefixes, URLs not containing any [c]:[c] or
|
||||
[c]/[c] characters are matched as domains. If {name} (short
|
||||
option: [c]-n[c]) is provided, any existing style with the same
|
||||
name is overridden, and the style may later be deleted using
|
||||
{name}. If -append (short option: -a) is provided along with -name,
|
||||
{css} and {filter} are appended to its current value.
|
||||
Add CSS styles to the browser or to web pages. {filter} is a comma
|
||||
separated list of URLs to match. URLs ending with [c]*[c] are matched as
|
||||
prefixes, URLs not containing any [c]:[c] or [c]/[c] characters are
|
||||
matched as domains. If {name} (short option: [c]-n[c]) is provided, any
|
||||
existing style with the same name is overridden, and the style may later
|
||||
be deleted using {name}. If -append (short option: [c]-a[c]) is provided
|
||||
along with [c]-name[c], {css} and {filter} are appended to its current
|
||||
value.
|
||||
|
||||
If {css} isn't provided, matching styles are listed.
|
||||
________________________________________________________________________________
|
||||
@@ -112,8 +112,10 @@ the filter are disabled. For instance, a filter [c]mozilla.org[c], given a
|
||||
style for [c]www.google.com,mozilla.org[c], will result in a style for
|
||||
[c]www.google.com[c]. The available options are:
|
||||
|
||||
- -name: The name provided to [c]:style[c] (short option: -n)
|
||||
- -index: For unnamed styles, the index listed by [c]:style[c] (short option: -i)
|
||||
* [c]-name[c]: The name provided to [c]:style[c] (short option:
|
||||
[c]-n[c])
|
||||
* [c]-index[c]: For unnamed styles, the index listed by [c]:style[c]
|
||||
(short option: [c]-i[c])
|
||||
________________________________________________________________________________
|
||||
|
||||
// vim: set syntax=asciidoc:
|
||||
|
||||
@@ -3,17 +3,17 @@ HEADER
|
||||
|tabs| +
|
||||
|
||||
Tabs are used to be able to view many web pages at the same time. Each tab
|
||||
contains exactly one buffer - multiple buffers per tab are not supported. As a
|
||||
contains exactly one buffer -- multiple buffers per tab are not supported. As a
|
||||
result many buffer and tab commands are interchangeable.
|
||||
|
||||
section:Listing{nbsp}tabs[listing-tabs]
|
||||
|
||||
|B| |:tabs| |:ls| |:files| |:buffers|
|
||||
||:buffers [filter]|| +
|
||||
||:buffers [a][filter][a]|| +
|
||||
||B||
|
||||
________________________________________________________________________________
|
||||
Show a list of buffers (=tabs) matching [filter]. Without [filter] list all
|
||||
tabs.
|
||||
Show a list of buffers (=tabs) matching [a][filter][a]. Without [a][filter][a]
|
||||
list all tabs.
|
||||
________________________________________________________________________________
|
||||
|
||||
section:Opening{nbsp}tabs[opening-tabs]
|
||||
@@ -63,7 +63,7 @@ ________________________________________________________________________________
|
||||
||[count]gt||
|
||||
________________________________________________________________________________
|
||||
Go to the next tab. Cycles to the first tab, when the last is selected. +
|
||||
Count is supported: [m]3gt[m] goes to the third tab.
|
||||
If [count] is specified go to the [count]th tab.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ ________________________________________________________________________________
|
||||
||[count]gT||
|
||||
________________________________________________________________________________
|
||||
Go {count} pages back. Wraps around from the first tab to the last tab. +
|
||||
Count is supported: [m]3gT[m] goes three tabs back.
|
||||
If [count] is specified go back [count] tabs.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
@@ -174,16 +174,15 @@ ________________________________________________________________________________
|
||||
section:Closing{nbsp}tabs[closing-tabs]
|
||||
|
||||
|d| |:tabc| |:tabclose| |:bun| |:bunload| |:bw| |:bwipeout| |:bd| |:bdelete|
|
||||
||:[count]bd[elete][!] [arg]|| +
|
||||
||:[count]bd[elete][!] [a][arg][a]|| +
|
||||
||[count]d||
|
||||
________________________________________________________________________________
|
||||
Delete current buffer (=tab). Count is supported, [c]:2bd[c] removes two tabs
|
||||
and the one to the right is selected. Afterwards, the tab to the right of the
|
||||
deleted one is selected.
|
||||
Delete current buffer (=tab). If [count] is specified then [count] tabs are
|
||||
removed. Afterwards, the tab to the right of the deleted tab(s) is selected.
|
||||
|
||||
When used with [arg], remove all tabs which contain [arg] in the hostname.
|
||||
[!] forces this command to also search for [arg] in the full URL and also
|
||||
the title of the tab. Use with care.
|
||||
When used with [a][arg][a], remove all tabs which contain [a][arg][a] in the
|
||||
hostname. [!] forces this command to also search for [a][arg][a] in the full
|
||||
URL and also the title of the tab. Use with care.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
@@ -195,11 +194,11 @@ ________________________________________________________________________________
|
||||
|
||||
|
||||
|u| |:u| |:undo|
|
||||
||:[count]u[ndo] [url]|| +
|
||||
||:[count]u[ndo] [a][url][a]|| +
|
||||
||[count]u||
|
||||
________________________________________________________________________________
|
||||
Undo closing of a tab. If a count is given, don't close the last but the
|
||||
[count]th last tab. With [url] restores the tab matching the URL.
|
||||
[count]th last tab. With [a][url][a] restores the tab matching the URL.
|
||||
________________________________________________________________________________
|
||||
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@ section:Quick-start{nbsp}tutorial[tutorial]
|
||||
|
||||
If you've started using Vimperator from scratch (i.e., without any
|
||||
customization), you should be looking at this help page in a relatively
|
||||
bare-looking window. The menubar, navigation bar, and bookmark bars are
|
||||
hidden. In case you missed the notice in the help:Introduction[intro.html],
|
||||
you can regain these by issuing the command
|
||||
bare-looking window. The menubar, navigation bar, and bookmark bars are hidden.
|
||||
In case you missed the notice in the help:Introduction[intro.html], you can
|
||||
regain these by issuing the command
|
||||
|
||||
:set go+=mTb<CR>
|
||||
|
||||
@@ -32,8 +32,8 @@ different meanings depending on which mode the browser is in. Vimperator has
|
||||
several modes, but the 2 most important are ``normal'' mode and
|
||||
``command-line'' mode.
|
||||
|
||||
When Vimperator starts, it is in normal mode by default. This is probably
|
||||
where you will spend the majority of your time.
|
||||
When Vimperator starts, it is in normal mode by default. This is probably where
|
||||
you will spend the majority of your time.
|
||||
|
||||
The other core mode of Vimperator, command-line mode, can be entered from
|
||||
normal mode by typing a \':' (colon). You will frequently see Vimperator
|
||||
@@ -45,11 +45,11 @@ Vimperator.
|
||||
|
||||
section:Getting{nbsp}help[getting-help]
|
||||
|
||||
Vim is a great editor but it's not much of a web browser. So even seasoned
|
||||
Vim users will probably have to look at Vimperator documentation sooner or
|
||||
later. Most of the documentation for Vimperator's features are easily found
|
||||
using the [c]:help[c] command. For example, you can find help on the
|
||||
[c]:help[c] command by typing
|
||||
Vim is a great editor but it's not much of a web browser. So even seasoned Vim
|
||||
users will probably have to look at Vimperator documentation sooner or later.
|
||||
Most of the documentation for Vimperator's features are easily found using the
|
||||
[c]:help[c] command. For example, you can find help on the [c]:help[c] command
|
||||
by typing
|
||||
|
||||
:help :help<CR>
|
||||
|
||||
@@ -114,10 +114,10 @@ Vimmers.
|
||||
* [m]d[m] --
|
||||
close the active tab (delete the buffer)
|
||||
|
||||
To open a web page in a new tab, use the [c]:tabopen {url}[c]. To open a URL
|
||||
in the current tab, use [c]:open[c]. The normal mode
|
||||
mappings [m]t[m] and [m]o[m], respectively, map to these commands, so the
|
||||
following pairs sequences are equivalent:
|
||||
To open a web page in a new tab, use the [c]:tabopen {url}[c]. To open a URL in
|
||||
the current tab, use [c]:open[c]. The normal mode mappings [m]t[m] and [m]o[m],
|
||||
respectively, map to these commands, so the following pairs sequences are
|
||||
equivalent:
|
||||
|
||||
:open my.webmail.com<CR>
|
||||
omy.webmail.com<CR>
|
||||
@@ -131,14 +131,14 @@ So now you can navigate around in Vimperator. But wait... how do you *open* a
|
||||
page or tab linked in a web page? How do you ``click'' on all those links
|
||||
without your tailed friend?
|
||||
|
||||
The answer is ``hints''. Activating hints displays a number next to every
|
||||
link Vimperator can find. To follow the link, simply type the number
|
||||
corresponding to the hint, a white number inside a red square by default.
|
||||
The answer is ``hints''. Activating hints displays a number next to every link
|
||||
Vimperator can find. To follow the link, simply type the number corresponding
|
||||
to the hint, a white number inside a red square by default.
|
||||
|
||||
For text links, there's an additional shortcut; you can type some text
|
||||
contained in the link and Vimperator will search all the links it can find and
|
||||
only hint the matching links, further narrowing down the list. If the text
|
||||
you type uniquely identifies any given link, Vimperator will follow that link
|
||||
only hint the matching links, further narrowing down the list. If the text you
|
||||
type uniquely identifies any given link, Vimperator will follow that link
|
||||
immediately without any further user input.
|
||||
|
||||
Whichever way you choose to indicate your target link, once Vimperator has
|
||||
@@ -171,15 +171,14 @@ following:
|
||||
|
||||
section:Saving{nbsp}for{nbsp}posterity{nbsp}-{nbsp}vimperatorrc[vimperatorrc]
|
||||
|
||||
Once you get Vimperator set up with your desired options, maps, and
|
||||
commands, you'll probably want them to be available the next time you
|
||||
open Vimperator. Continuing the Vim theme, this is done with a
|
||||
vimperatorrc file.
|
||||
Once you get Vimperator set up with your desired options, maps, and commands,
|
||||
you'll probably want them to be available the next time you open Vimperator.
|
||||
Continuing the Vim theme, this is done with a vimperatorrc file.
|
||||
|
||||
To save your current settings and allow them to be loaded automatically
|
||||
next time you start Vimperator, issue the [c]:mkv[c] command.
|
||||
|
||||
This will create the file *$HOME/.vimperatorrc* containing your settings.
|
||||
This will create the file *_$HOME_/.vimperatorrc* containing your settings.
|
||||
It is a simple text file, just like a vimrc file and can be easily
|
||||
edited to suit your preferences.
|
||||
|
||||
@@ -196,9 +195,9 @@ Vimperator supports all of Vim's classic methods of exiting.
|
||||
section:Where{nbsp}did{nbsp}Firefox{nbsp}go?[whither-firefox]
|
||||
|
||||
You might feel pretty disoriented now. Don't worry. This is still Firefox
|
||||
underneath. Here are some ways Vimperator allows Firefox to shine through.
|
||||
See the [c]:help[c] for these commands and mappings for more information on
|
||||
how to make the best use of them.
|
||||
underneath. Here are some ways Vimperator allows Firefox to shine through. See
|
||||
the [c]:help[c] for these commands and mappings for more information on how to
|
||||
make the best use of them.
|
||||
|
||||
* [c]:dialog[c] --
|
||||
To access some of Firefox's many dialog windows, you can use the
|
||||
@@ -239,16 +238,16 @@ as above, with [c]:set go+=m[c], and select *Add-ons* from the *Tools* menu.
|
||||
|
||||
section:I'm{nbsp}interested...but{nbsp}lost![support]
|
||||
|
||||
Vimperator has an energetic and growing user base. If you've run into a
|
||||
problem that you can't seem to solve with Vimperator, or if you think you might
|
||||
have found a bug, please let us know! There is support available on the
|
||||
Vimperator has an energetic and growing user base. If you've run into a problem
|
||||
that you can't seem to solve with Vimperator, or if you think you might have
|
||||
found a bug, please let us know! There is support available on the
|
||||
http://vimperator.cutup.org/index.php?title=Main_Page[wiki], or in the
|
||||
#vimperator IRC channel on http://freenode.net/[freenode].
|
||||
|
||||
If you have any feature requests or (even better) offers to help, we'd love to
|
||||
hear from you as well. Developers work on Vimperator whenever possible, but
|
||||
we are neither infinite nor omnipotent; please bear with us. If you can't
|
||||
wait for us to get around to it, rest assured patches are welcome! See
|
||||
the help:Developer[developer.html] page for more information.
|
||||
hear from you as well. Developers work on Vimperator whenever possible, but we
|
||||
are neither infinite nor omnipotent; please bear with us. If you can't wait for
|
||||
us to get around to it, rest assured patches are welcome! See the
|
||||
help:Developer[developer.html] page for more information.
|
||||
|
||||
// vim: set syntax=asciidoc:
|
||||
|
||||
@@ -18,6 +18,7 @@ var skipTests = [":bmarks", "gg"];
|
||||
// Put definitions here which might change due to internal liberator refactoring
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var doc; // document where we output status messages
|
||||
var multilineOutput = document.getElementById("liberator-multiline-output")
|
||||
var singlelineOutput = document.getElementById("liberator-commandline-command")
|
||||
|
||||
@@ -28,10 +29,10 @@ var singlelineOutput = document.getElementById("liberator-commandline-command")
|
||||
// previous command
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// A series of ex commands or mappings, each with a
|
||||
// A series of Ex commands or mappings, each with a
|
||||
// function checking whether the command succeeded
|
||||
// If the string starts with a ":" it is executed as an ex command, otherwise as a mapping
|
||||
// You can also mix commands mappings
|
||||
// If the string starts with a ":" it is executed as an Ex command, otherwise as a mapping
|
||||
// You can also mix commands and mappings
|
||||
let tests = [
|
||||
{ cmds: [":!dir"],
|
||||
verify: function () getMultilineOutput().length > 10 },
|
||||
@@ -45,6 +46,8 @@ let tests = [
|
||||
verify: function () getSinglelineOutput() == "test" },
|
||||
{ cmds: [":qmark V http://test.vimperator.org", ":qmarks"],
|
||||
verify: function () getMultilineOutput().indexOf("test.vimperator.org") >= 0 },
|
||||
{ cmds: [":javascript liberator.echo('test', commandline.FORCE_MULTILINE)"],
|
||||
verify: function () getMultilineOutput() == "test" },
|
||||
// { cmds: [":echomsg \"testmsg\""],
|
||||
// verify: function () getOutput() == "testmsg" },
|
||||
// { cmds: [":echoerr \"testerr\""],
|
||||
@@ -56,7 +59,7 @@ let tests = [
|
||||
// testing tab behavior
|
||||
];
|
||||
|
||||
// these functions highly depend on the liberator API, so use ex command tests whenever possible
|
||||
// these functions highly depend on the liberator API, so use Ex command tests whenever possible
|
||||
let functions = [
|
||||
function () { return bookmarks.get("").length > 0 }, // will fail for people without bookmarks :( Might want to add one before
|
||||
function () { return history.get("").length > 0 }
|
||||
@@ -64,7 +67,7 @@ let functions = [
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// functions below should be as generic as possible, and not require being rewritten
|
||||
// even after doing major vimperator refactoring
|
||||
// even after doing major Vimperator refactoring
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function resetEnvironment()
|
||||
@@ -89,15 +92,14 @@ function getBufferPosition()
|
||||
y: win.scrollMaxY ? win.pageYOffset / win.scrollMaxY : 0 }
|
||||
};
|
||||
|
||||
// TODO: need to find a way to wait for page load
|
||||
function getLocation() window.content.document.location.href;
|
||||
|
||||
var doc;
|
||||
|
||||
function echoLine(str, group)
|
||||
{
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
doc.body.appendChild(util.xmlToDom(
|
||||
<div highlight={group} style="border: 1px solid gray; white-space: pre; height: 1.5em; line-height: 1.5em;">{str}</div>,
|
||||
doc));
|
||||
@@ -106,6 +108,7 @@ function echoMulti(str, group)
|
||||
{
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
doc.body.appendChild(util.xmlToDom(<div class="ex-command-output"
|
||||
style="white-space: nowrap; border: 1px solid black; min-height: 1.5em;"
|
||||
highlight={group}>{template.maybeXML(str)}</div>,
|
||||
@@ -120,13 +123,13 @@ commands.addUserCommand(["regr[essions]"],
|
||||
// TODO: count (better even range) support to just run test 34 of 102
|
||||
// TODO: bang support to either: a) run commands like deleting bookmarks which
|
||||
// should only be done in a clean profile or b) run functions and not
|
||||
// just ex command tests; Yet to be decided
|
||||
// just Ex command tests; Yet to be decided
|
||||
|
||||
let updateOutputHeight = null;
|
||||
function init()
|
||||
{
|
||||
liberator.registerObserver("echoLine", echoLine);
|
||||
liberator.registerObserver("echoMulti", echoMulti);
|
||||
liberator.registerObserver("echoMultiline", echoMulti);
|
||||
liberator.open("chrome://liberator/content/buffer.xhtml", liberator.NEW_TAB);
|
||||
events.waitForPageLoad();
|
||||
doc = content.document;
|
||||
@@ -144,7 +147,7 @@ commands.addUserCommand(["regr[essions]"],
|
||||
function cleanup()
|
||||
{
|
||||
liberator.unregisterObserver("echoLine", echoLine);
|
||||
liberator.unregisterObserver("echoMulti", echoMulti);
|
||||
liberator.unregisterObserver("echoMultiline", echoMulti);
|
||||
commandline.updateOutputHeight = updateOutputHeight;
|
||||
}
|
||||
|
||||
@@ -178,7 +181,7 @@ commands.addUserCommand(["regr[essions]"],
|
||||
}
|
||||
};
|
||||
|
||||
liberator.echomsg("Running test " + currentTest + " of " + totalTests + ": " + testDescription, 0);
|
||||
commandline.echo("Running test " + currentTest + " of " + totalTests + ": " + testDescription, "Filter", commandline.APPEND_TO_MESSAGES);
|
||||
resetEnvironment();
|
||||
if ("init" in test)
|
||||
test.init();
|
||||
@@ -203,7 +206,7 @@ commands.addUserCommand(["regr[essions]"],
|
||||
if (args.count >= 1 && currentTest != args.count)
|
||||
continue;
|
||||
|
||||
liberator.echomsg("Running test " + currentTest + " of " + totalTests + ": " + util.clip(func.toString().replace(/[\s\n]+/gm, " "), 80));
|
||||
commandline.echo("Running test " + currentTest + " of " + totalTests + ": " + util.clip(func.toString().replace(/[\s\n]+/gm, " "), 80), "Filter", commandline.APPEND_TO_MESSAGES);
|
||||
resetEnvironment();
|
||||
|
||||
if (!func())
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
" Vim syntax file
|
||||
" Language: VIMperator configuration file
|
||||
" Maintainer: Doug Kearns <dougkearns@gmail.com>
|
||||
" Last Change: 2008 Dec 07
|
||||
" Last Change: 2008 Dec 31
|
||||
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
@@ -23,13 +23,13 @@ syn keyword vimperatorCommand ab[breviate] ab[clear] addo[ns] b[uffer] ba[ck] bd
|
||||
\ cm[ap] cmapc[lear] cno[remap] comc[lear] com[mand] cu[nmap] do[autocmd] doautoa[ll] delbm[arks] delc[ommand] delmac[ros]
|
||||
\ delm[arks] delqm[arks] dels[tyle] dia[log] dl downl[oads] e[dit] ec[ho] echoe[rr] echom[sg] em[enu] exe[cute] exu[sage]
|
||||
\ fini[sh] files fo[rward] fw h[elp] ha[rdcopy] hi[ghlight] hist[ory] hs ia[bbrev] iabc[lear] im[ap] imapc[lear] ino[remap]
|
||||
\ iuna[bbrev] iu[nmap] javas[cript] ju[mps] js let ls macros ma[rk] map mapc[lear] marks mes[sages] mkv[imperatorrc] no[remap]
|
||||
\ noh[lsearch] norm[al] o[pen] optionu[sage] pa[geinfo] pagest[yle] pc[lose] pl[ay] pref[erences] prefs pw[d] q[uit] qa[ll]
|
||||
\ qma[rk] qmarks quita[ll] re[draw] re[load] reloada[ll] res[tart] run runt[ime] sty[le] sav[eas] sb[ar] sb[open] sbcl[ose]
|
||||
\ scrip[tnames] se[t] setg[lobal] setl[ocal] sideb[ar] so[urce] st[op] tN[ext] t[open] tab tabde[tach] tabd[uplicate]
|
||||
\ tabN[ext] tabc[lose] tabe[dit] tabfir[st] tabl[ast] tabm[ove] tabn[ext] tabnew tabo[nly] tabopen tabp[revious] tabr[ewind]
|
||||
\ tabs time tn[ext] tp[revious] u[ndo] una[bbreviate] undoa[ll] unl[et] unm[ap] ve[rsion] vie[wsource] viu[sage] w[rite]
|
||||
\ wc[lose] win[open] winc[lose] wine[dit] wo[pen] wqa[ll] wq xa[ll] zo[om]
|
||||
\ iuna[bbrev] iu[nmap] javas[cript] ju[mps] js let loadplugins lpl ls macros ma[rk] map mapc[lear] marks mes[sages]
|
||||
\ mkv[imperatorrc] no[remap] noh[lsearch] norm[al] o[pen] optionu[sage] pa[geinfo] pagest[yle] pc[lose] pl[ay] pref[erences]
|
||||
\ prefs pw[d] q[uit] qa[ll] qma[rk] qmarks quita[ll] re[draw] re[load] reloada[ll] res[tart] run runt[ime] sty[le] sav[eas]
|
||||
\ sb[ar] sb[open] sbcl[ose] scrip[tnames] se[t] setg[lobal] setl[ocal] sideb[ar] so[urce] st[op] tN[ext] t[open] tab
|
||||
\ tabde[tach] tabd[uplicate] tabN[ext] tabc[lose] tabe[dit] tabfir[st] tabl[ast] tabm[ove] tabn[ext] tabnew tabo[nly] tabopen
|
||||
\ tabp[revious] tabr[ewind] tabs time tn[ext] tp[revious] u[ndo] una[bbreviate] undoa[ll] unl[et] unm[ap] ve[rsion]
|
||||
\ vie[wsource] viu[sage] w[rite] wc[lose] win[open] winc[lose] wine[dit] wo[pen] wqa[ll] wq xa[ll] zo[om]
|
||||
\ contained
|
||||
|
||||
syn match vimperatorCommand "!" contained
|
||||
@@ -43,7 +43,7 @@ syn keyword vimperatorAutoEvent BookmarkAdd DOMLoad LocationChange PageLoadPre P
|
||||
syn match vimperatorAutoEventList "\(\a\+,\)*\a\+" contained contains=vimperatorAutoEvent
|
||||
|
||||
syn region vimperatorSet matchgroup=vimperatorCommand start="\%(^\s*:\=\)\@<=\<\%(setl\%[ocal]\|setg\%[lobal]\|set\=\)\=\>"
|
||||
\ end="$" keepend oneline contains=vimperatorOption,vimperatorComment,vimperatorString
|
||||
\ end="$" keepend oneline contains=vimperatorOption,vimperatorString
|
||||
|
||||
syn keyword vimperatorOption activate act alfc albc cdpath cd complete cpt defsearch ds editor extendedhinttags eht eventignore ei
|
||||
\ followhints fh guioptions go helpfile hf hintmatching hm hs hinttags ht hinttimeout hto history hi laststatus ls lbc lfc
|
||||
|
||||
Reference in New Issue
Block a user