mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-23 18:42:27 +01:00
InformationList -> gone, long live ItemList. Initial commit of new HTML based completion framework. Simple 1:1 port for now, advanced features will come later. :set wildoptions=auto broken for now, needs a more substantial rewrite anyway.
This commit is contained in:
3
Donators
3
Donators
@@ -3,6 +3,9 @@
|
||||
Also drop me a note, if you want the donated amount to be displayed.
|
||||
|
||||
2008:
|
||||
* Robert Meerman
|
||||
* Silvio Di Stefano
|
||||
* Lance Feagan
|
||||
* Alexander Klink
|
||||
* Chaz McGarvey
|
||||
* Jesse Hathaway
|
||||
|
||||
3
TODO
3
TODO
@@ -20,7 +20,6 @@ BUGS:
|
||||
|
||||
FEATURES:
|
||||
8 middleclick in content == p, and if command line is open, paste there the clipboard buffer
|
||||
8 ;?<hint> should show more information
|
||||
8 all search commands should start searching from the top of the visible viewport
|
||||
7 adaptive learning for tab-completions
|
||||
(https://bugzilla.mozilla.org/show_bug.cgi?id=395739 could help)
|
||||
@@ -34,6 +33,7 @@ FEATURES:
|
||||
google to another page and click 10 links there, [d would take me back to the google page
|
||||
opera's fast forward does something like this
|
||||
7 make an option to disable session saving by default when you close Firefox
|
||||
6 :tabdetach
|
||||
6 add [count] support to :b* and :tab* commands where missing
|
||||
6 registers
|
||||
6 allow for multiple ex commands separated with |
|
||||
@@ -45,6 +45,7 @@ FEATURES:
|
||||
6 pipe selected text/link/website to an external command
|
||||
6 :set wildoptions=auto mode, which would list completions on each keystroke (maybe performance problems)
|
||||
6 Use ctrl-w+j/k/w to switch between sidebar, content, preview window
|
||||
6 ;?<hint> should show more information
|
||||
5 Favicons in completion windows and some other places?
|
||||
5 make a command to search within google search results
|
||||
(http://gadelkareem.com/2007/01/28/using-google-ajax-api-as-an-array/)
|
||||
|
||||
@@ -60,6 +60,14 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
<window id="messengerWindow">
|
||||
|
||||
<keyset id="mainKeyset">
|
||||
<key id="key_open_vimbar" key=":" oncommand="liberator.commandline.open(':', '', liberator.modes.EX);" modifiers=""/>
|
||||
<key id="key_stop" keycode="VK_ESCAPE" oncommand="liberator.events.onEscape();"/>
|
||||
<!-- other keys are handled inside the event loop in events.js -->
|
||||
</keyset>
|
||||
|
||||
<panel id="liberator-visualbell"/>
|
||||
|
||||
<!--this notifies us also of focus events in the XUL
|
||||
from: http://developer.mozilla.org/en/docs/XUL_Tutorial:Updating_Commands !-->
|
||||
<commandset id="onVimperatorFocus"
|
||||
@@ -71,13 +79,32 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
events="select"
|
||||
oncommandupdate="if (typeof liberator.events != 'undefined') liberator.events.onSelectionChange(event);"/>
|
||||
|
||||
<keyset id="mainKeyset">
|
||||
<key id="key_open_vimbar" key=":" oncommand="liberator.commandline.open(':', '', liberator.modes.EX);" modifiers=""/>
|
||||
<key id="key_stop" keycode="VK_ESCAPE" oncommand="liberator.events.onEscape();"/>
|
||||
<!-- other keys are handled inside the event loop in events.js -->
|
||||
</keyset>
|
||||
<vbox class="liberator-container" hidden="false" collapsed="true">
|
||||
<iframe id="liberator-multiline-output" src="about:blank" flex="1" height="10px" hidden="false" collapsed="false"
|
||||
onclick="liberator.commandline.onMultilineOutputEvent(event)"/>
|
||||
</vbox>
|
||||
|
||||
<panel id="liberator-visualbell"/>
|
||||
<vbox class="liberator-container" hidden="false" collapsed="true">
|
||||
<iframe id="liberator-completions" src="about:blank" flex="1" height="250px" hidden="false" collapsed="false"
|
||||
onclick="liberator.commandline.onMultilineOutputEvent(event)"/>
|
||||
</vbox>
|
||||
|
||||
<hbox id="liberator-commandline" hidden="false" class="hl-Normal">
|
||||
<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.commandline.onEvent(event);"
|
||||
onfocus="liberator.commandline.onEvent(event);"
|
||||
onblur="liberator.commandline.onEvent(event);"/>
|
||||
</hbox>
|
||||
|
||||
<vbox class="liberator-container" hidden="false" collapsed="false">
|
||||
<textbox id="liberator-multiline-input" class="plain" flex="1" rows="1" hidden="false" collapsed="true" multiline="true"
|
||||
onkeypress="liberator.commandline.onMultilineInputEvent(event);"
|
||||
oninput="liberator.commandline.onMultilineInputEvent(event);"
|
||||
onblur="liberator.commandline.onMultilineInputEvent(event);"/>
|
||||
</vbox>
|
||||
|
||||
</window>
|
||||
|
||||
<statusbar id="status-bar" class="hl-StatusLine">
|
||||
<hbox insertafter="statusTextBox" id="liberator-statusline" flex="1" height="10" hidden="false" align="center">
|
||||
@@ -92,42 +119,6 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
<statusbarpanel id="statusbarpanel-progress" hidden="true"/>
|
||||
</statusbar>
|
||||
|
||||
<vbox id="liberator-container" hidden="false">
|
||||
<!--listbox id="liberator-previewwindow" class="plain" rows="10" flex="1" hidden="true"
|
||||
onclick= "liberator.previewwindow.onEvent(event);"
|
||||
ondblclick="liberator.previewwindow.onEvent(event);"
|
||||
onkeydown= "liberator.previewwindow.onEvent(event);">
|
||||
<listcols>
|
||||
<listcol flex="1" width="50%"/>
|
||||
<listcol flex="1" width="50%"/>
|
||||
</listcols>
|
||||
</listbox-->
|
||||
|
||||
<iframe id="liberator-multiline-output" src="about:blank" flex="1" height="10px" hidden="false" collapsed="true"
|
||||
onclick="liberator.commandline.onMultilineOutputEvent(event)"/>
|
||||
|
||||
<listbox id="liberator-completion" class="plain" rows="1" flex="1" hidden="true">
|
||||
<listcols>
|
||||
<listcol flex="1" width="50%"/>
|
||||
<listcol flex="1" width="50%"/>
|
||||
</listcols>
|
||||
</listbox>
|
||||
|
||||
<hbox insertafter="status-bar" id="liberator-commandline" hidden="false" class="hl-Normal">
|
||||
<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.commandline.onEvent(event);"
|
||||
onfocus="liberator.commandline.onEvent(event);"
|
||||
onblur="liberator.commandline.onEvent(event);"/>
|
||||
</hbox>
|
||||
|
||||
<textbox id="liberator-multiline-input" class="plain" flex="1" rows="1" hidden="false" collapsed="true" multiline="true"
|
||||
onkeypress="liberator.commandline.onMultilineInputEvent(event);"
|
||||
oninput="liberator.commandline.onMultilineInputEvent(event);"
|
||||
onblur="liberator.commandline.onMultilineInputEvent(event);"/>
|
||||
</vbox>
|
||||
</window>
|
||||
|
||||
</overlay>
|
||||
|
||||
<!-- vim: set fdm=marker sw=4 ts=4 et: -->
|
||||
|
||||
@@ -89,28 +89,17 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
<statusbarpanel id="statusbarpanel-progress" hidden="true"/-->
|
||||
</statusbar>
|
||||
|
||||
<vbox id="liberator-container" hidden="false">
|
||||
<!--listbox id="liberator-previewwindow" class="plain" rows="10" flex="1" hidden="true"
|
||||
onclick= "liberator.previewwindow.onEvent(event);"
|
||||
ondblclick="liberator.previewwindow.onEvent(event);"
|
||||
onkeydown= "liberator.previewwindow.onEvent(event);">
|
||||
<listcols>
|
||||
<listcol flex="1" width="50%"/>
|
||||
<listcol flex="1" width="50%"/>
|
||||
</listcols>
|
||||
</listbox-->
|
||||
|
||||
<iframe id="liberator-multiline-output" src="about:blank" flex="1" height="10px" hidden="false" collapsed="true"
|
||||
<vbox class="liberator-container" hidden="false" collapsed="true">
|
||||
<iframe id="liberator-multiline-output" src="about:blank" flex="1" height="10px" hidden="false" collapsed="false"
|
||||
onclick="liberator.commandline.onMultilineOutputEvent(event)"/>
|
||||
</vbox>
|
||||
|
||||
<listbox id="liberator-completion" class="plain" rows="1" flex="1" hidden="true">
|
||||
<listcols>
|
||||
<listcol flex="1" width="50%"/>
|
||||
<listcol flex="1" width="50%"/>
|
||||
</listcols>
|
||||
</listbox>
|
||||
<vbox class="liberator-container" hidden="false" collapsed="true">
|
||||
<iframe id="liberator-completions" src="about:blank" flex="1" height="250px" hidden="false" collapsed="false"
|
||||
onclick="liberator.commandline.onMultilineOutputEvent(event)"/>
|
||||
</vbox>
|
||||
|
||||
<hbox insertafter="status-bar" id="liberator-commandline" hidden="false" class="hl-Normal">
|
||||
<hbox id="liberator-commandline" hidden="false" class="hl-Normal">
|
||||
<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.commandline.onEvent(event);"
|
||||
@@ -118,11 +107,13 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
onblur="liberator.commandline.onEvent(event);"/>
|
||||
</hbox>
|
||||
|
||||
<vbox class="liberator-container" hidden="false" collapsed="false">
|
||||
<textbox id="liberator-multiline-input" class="plain" flex="1" rows="1" hidden="false" collapsed="true" multiline="true"
|
||||
onkeypress="liberator.commandline.onMultilineInputEvent(event);"
|
||||
oninput="liberator.commandline.onMultilineInputEvent(event);"
|
||||
onblur="liberator.commandline.onMultilineInputEvent(event);"/>
|
||||
</vbox>
|
||||
|
||||
</window>
|
||||
|
||||
</overlay>
|
||||
|
||||
417
content/ui.js
417
content/ui.js
@@ -40,9 +40,6 @@ liberator.CommandLine = function () //{{{
|
||||
|
||||
const UNINITIALIZED = -2; // notifies us, if we need to start history/tab-completion from the beginning
|
||||
|
||||
var completionlist = new liberator.InformationList("liberator-completion", { minItems: 1, maxItems: 10 });
|
||||
var completions = [];
|
||||
|
||||
liberator.storage.newArray("history-search", true);
|
||||
liberator.storage.newArray("history-command", true);
|
||||
|
||||
@@ -70,13 +67,15 @@ liberator.CommandLine = function () //{{{
|
||||
var historyIndex = UNINITIALIZED;
|
||||
var historyStart = "";
|
||||
|
||||
var completionList = new liberator.ItemList("liberator-completions");
|
||||
var completions = [];
|
||||
// for the example command "open sometext| othertext" (| is the cursor pos):
|
||||
var completionStartIndex = 0; // will be 5 because we want to complete arguments for the :open command
|
||||
var completionPrefix = ""; // will be: "open sometext"
|
||||
var completionPostfix = ""; // will be: " othertext"
|
||||
var completionIndex = UNINITIALIZED;
|
||||
|
||||
var wildIndex = 0; // keep track how often we press <Tab> in a row
|
||||
var completionIndex = UNINITIALIZED;
|
||||
var startHints = false; // whether we're waiting to start hints mode
|
||||
|
||||
// the containing box for the promptWidget and commandWidget
|
||||
@@ -88,6 +87,7 @@ liberator.CommandLine = function () //{{{
|
||||
|
||||
// the widget used for multiline output
|
||||
var multilineOutputWidget = document.getElementById("liberator-multiline-output");
|
||||
var outputContainer = multilineOutputWidget.parentNode;
|
||||
multilineOutputWidget.contentDocument.body.setAttribute("style", "margin: 0px; font-family: -moz-fixed;"); // get rid of the default border
|
||||
multilineOutputWidget.contentDocument.body.innerHTML = "";
|
||||
var stylesheet = multilineOutputWidget.contentDocument.createElement("link");
|
||||
@@ -176,21 +176,20 @@ liberator.CommandLine = function () //{{{
|
||||
// : echoed lines longer than v-c-c.width should wrap and use MOW
|
||||
function setMultiline(str, highlightGroup)
|
||||
{
|
||||
multilineInputWidget.collapsed = true;
|
||||
//outputContainer.collapsed = true;
|
||||
|
||||
var output = "<div class=\"ex-command-output " + highlightGroup + "\">" + str + "</div>";
|
||||
if (!multilineOutputWidget.collapsed)
|
||||
if (!outputContainer.collapsed)
|
||||
{
|
||||
// FIXME: need to make sure an open MOW is closed when commands
|
||||
// that don't generate output are executed
|
||||
output = multilineOutputWidget.contentDocument.body.innerHTML + output;
|
||||
multilineOutputWidget.collapsed = true;
|
||||
//outputContainer.collapsed = true;
|
||||
}
|
||||
|
||||
var id = liberator.config.mainWindowID || "main-window";
|
||||
var fontSize = document.defaultView.getComputedStyle(document.getElementById(id), null).getPropertyValue("font-size");
|
||||
multilineOutputWidget.contentDocument.body.setAttribute("style", "font-size: " + fontSize);
|
||||
|
||||
multilineOutputWidget.contentDocument.body.id = "liberator-multiline-output-content";
|
||||
multilineOutputWidget.contentDocument.body.innerHTML = output;
|
||||
|
||||
@@ -204,8 +203,8 @@ liberator.CommandLine = function () //{{{
|
||||
var contentHeight = multilineOutputWidget.contentDocument.height;
|
||||
var height = contentHeight < availableHeight ? contentHeight : availableHeight;
|
||||
|
||||
multilineOutputWidget.height = height + "px";
|
||||
multilineOutputWidget.collapsed = false;
|
||||
outputContainer.height = height + "px";
|
||||
outputContainer.collapsed = false;
|
||||
|
||||
if (liberator.options["more"] && multilineOutputWidget.contentWindow.scrollMaxY > 0)
|
||||
{
|
||||
@@ -232,17 +231,15 @@ liberator.CommandLine = function () //{{{
|
||||
|
||||
function autosizeMultilineInputWidget()
|
||||
{
|
||||
// XXX: faster/better method?
|
||||
|
||||
var lines = 0;
|
||||
var str = multilineInputWidget.value;
|
||||
for (var i = 0; i < str.length; i++)
|
||||
{
|
||||
if (str[i] == "\n")
|
||||
lines++;
|
||||
}
|
||||
|
||||
if (lines == 0)
|
||||
lines = 1;
|
||||
|
||||
multilineInputWidget.setAttribute("rows", lines.toString());
|
||||
}
|
||||
|
||||
@@ -440,7 +437,7 @@ liberator.CommandLine = function () //{{{
|
||||
// not yet used
|
||||
FORCE_MULTILINE : 1 << 0,
|
||||
FORCE_SINGLELINE : 1 << 1,
|
||||
DISALLOW_MULTILINE : 1 << 2, // if an echo() should try to use the single line,
|
||||
DISALLOW_MULTILINE : 1 << 2, // if an echo() should try to use the single line
|
||||
// but output nothing when the MOW is open; when also
|
||||
// FORCE_MULTILINE is given, FORCE_MULTILINE takes precedence
|
||||
APPEND_TO_MESSAGES : 1 << 3, // will show the string in :messages
|
||||
@@ -492,8 +489,10 @@ liberator.CommandLine = function () //{{{
|
||||
clear: function ()
|
||||
{
|
||||
multilineInputWidget.collapsed = true;
|
||||
multilineOutputWidget.collapsed = true;
|
||||
completionlist.hide();
|
||||
outputContainer.collapsed = true;
|
||||
completionList.hide();
|
||||
//htmllist.hide();
|
||||
//htmllist.clear();
|
||||
completions = [];
|
||||
|
||||
setLine("", this.HL_NORMAL);
|
||||
@@ -521,7 +520,7 @@ liberator.CommandLine = function () //{{{
|
||||
where = setMultiline;
|
||||
else if (flags & this.FORCE_SINGLELINE)
|
||||
where = setLine;
|
||||
else if (!multilineOutputWidget.collapsed)
|
||||
else if (!outputContainer.collapsed)
|
||||
{
|
||||
if (flags & this.DISALLOW_MULTILINE)
|
||||
where = null;
|
||||
@@ -614,7 +613,7 @@ liberator.CommandLine = function () //{{{
|
||||
currentExtendedMode = null; /* Don't let modes.pop trigger "cancel" */
|
||||
history.add(command);
|
||||
liberator.modes.pop(true);
|
||||
completionlist.hide();
|
||||
completionList.hide();
|
||||
liberator.focusContent(false);
|
||||
liberator.statusline.updateProgress(""); // we may have a "match x of y" visible
|
||||
return liberator.triggerCallback("submit", mode, command);
|
||||
@@ -679,6 +678,19 @@ liberator.CommandLine = function () //{{{
|
||||
// always reset our completion history so up/down keys will start with new values
|
||||
historyIndex = UNINITIALIZED;
|
||||
|
||||
// TODO: call just once, and not on each <Tab>
|
||||
var wim = liberator.options["wildmode"].split(/,/);
|
||||
var hasList = false;
|
||||
var longest = false;
|
||||
var full = false;
|
||||
var wildType = wim[wildIndex++] || wim[wim.length - 1];
|
||||
if (wildType == "list" || wildType == "list:full" || wildType == "list:longest")
|
||||
hasList = true;
|
||||
if (wildType == "longest" || wildType == "list:longest")
|
||||
longest = true;
|
||||
else if (wildType == "full" || wildType == "list:full")
|
||||
full = true;
|
||||
|
||||
// we need to build our completion list first
|
||||
if (completionIndex == UNINITIALIZED)
|
||||
{
|
||||
@@ -704,6 +716,9 @@ liberator.CommandLine = function () //{{{
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
if (hasList)
|
||||
completionList.setItems(completions, -1);
|
||||
}
|
||||
|
||||
if (completions.length == 0)
|
||||
@@ -715,27 +730,8 @@ liberator.CommandLine = function () //{{{
|
||||
return false;
|
||||
}
|
||||
|
||||
var wim = liberator.options["wildmode"].split(/,/);
|
||||
var hasList = false;
|
||||
var longest = false;
|
||||
var full = false;
|
||||
var wildType = wim[wildIndex++] || wim[wim.length - 1];
|
||||
if (wildType == "list" || wildType == "list:full" || wildType == "list:longest")
|
||||
hasList = true;
|
||||
if (wildType == "longest" || wildType == "list:longest")
|
||||
longest = true;
|
||||
else if (wildType == "full" || wildType == "list:full")
|
||||
full = true;
|
||||
|
||||
// show the list
|
||||
if (hasList)
|
||||
{
|
||||
if (completionIndex < 0)
|
||||
completionlist.show(completions);
|
||||
else
|
||||
completionlist.show();
|
||||
}
|
||||
|
||||
completionList.show();
|
||||
|
||||
if (full)
|
||||
{
|
||||
@@ -748,16 +744,20 @@ liberator.CommandLine = function () //{{{
|
||||
else
|
||||
{
|
||||
completionIndex++;
|
||||
if (completionIndex >= completions.length)
|
||||
completionIndex = -1;
|
||||
if (completionIndex > completions.length)
|
||||
completionIndex = 0;
|
||||
}
|
||||
|
||||
liberator.statusline.updateProgress("match " + (completionIndex + 1) + " of " + completions.length);
|
||||
// FIXME: this innocent looking line is the source of a big performance
|
||||
// problem, when keeping <Tab> pressed down, so disable it for now
|
||||
// liberator.statusline.updateProgress("match " + (completionIndex + 1) + " of " + completions.length);
|
||||
|
||||
liberator.statusline.updateProgress(res);
|
||||
// if the list is hidden, this function does nothing
|
||||
completionlist.selectItem(completionIndex);
|
||||
completionList.selectItem(completionIndex);
|
||||
}
|
||||
|
||||
if (completionIndex == -1 && !longest) // wrapped around matches, reset command line
|
||||
if ((completionIndex == -1 || completionIndex >= completions.length) && !longest) // wrapped around matches, reset command line
|
||||
{
|
||||
if (full && completions.length > 1)
|
||||
setCommand(completionPrefix + completionPostfix);
|
||||
@@ -787,6 +787,7 @@ liberator.CommandLine = function () //{{{
|
||||
// prevent tab from moving to the next field
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
else if (key == "<BS>")
|
||||
{
|
||||
@@ -854,7 +855,6 @@ liberator.CommandLine = function () //{{{
|
||||
var passEvent = false;
|
||||
|
||||
function isScrollable() { return !win.scrollMaxY == 0; }
|
||||
|
||||
function atEnd() { return win.scrollY / win.scrollMaxY >= 1; }
|
||||
|
||||
var key = liberator.events.toString(event);
|
||||
@@ -1053,13 +1053,14 @@ liberator.CommandLine = function () //{{{
|
||||
}
|
||||
},
|
||||
|
||||
// to allow asynchronous adding of completions
|
||||
// to allow asynchronous adding of completions, broken
|
||||
// since the completion -> ItemList rewrite
|
||||
setCompletions: function (compl, start)
|
||||
{
|
||||
if (liberator.mode != liberator.modes.COMMAND_LINE)
|
||||
return;
|
||||
|
||||
// liberator.log(compl);
|
||||
completionList.setItems(compl, -1);
|
||||
|
||||
if (completionIndex >= 0 && completionIndex < compl.length && completionIndex < completions.length)
|
||||
{
|
||||
@@ -1070,8 +1071,8 @@ liberator.CommandLine = function () //{{{
|
||||
completionIndex = -1;
|
||||
|
||||
completions = compl;
|
||||
completionlist.show(compl);
|
||||
completionlist.selectItem(completionIndex);
|
||||
completionList.selectItem(completionIndex);
|
||||
completionList.show();
|
||||
|
||||
var command = this.getCommand();
|
||||
completionPrefix = command.substring(0, commandWidget.selectionStart);
|
||||
@@ -1084,104 +1085,207 @@ liberator.CommandLine = function () //{{{
|
||||
resetCompletions: function ()
|
||||
{
|
||||
completionIndex = historyIndex = UNINITIALIZED;
|
||||
wildIndex = 0;
|
||||
},
|
||||
};
|
||||
//}}}
|
||||
}; //}}}
|
||||
|
||||
/**
|
||||
* The list which is used for the completion box, the preview window and the buffer preview window
|
||||
* The list which is used for the completion box (and QuickFix window in future)
|
||||
*
|
||||
* @param id: the id of the the XUL widget which we want to fill
|
||||
* @param options: an optional hash which modifies the behavior of the list
|
||||
* @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
|
||||
*
|
||||
* TODO: get rid off "completion" variables, we are dealing with variables after all
|
||||
*/
|
||||
liberator.InformationList = function (id, options) //{{{
|
||||
liberator.ItemList = function (id) //{{{
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////// PRIVATE SECTION /////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////{{{
|
||||
|
||||
const CONTEXT_LINES = 3;
|
||||
var maxItems = 10;
|
||||
var minItems = 1;
|
||||
var maxItems = 20;
|
||||
var minItems = 2;
|
||||
var incrementalFill = true; // make display faster, but does not show scrollbar
|
||||
var completionElements = [];
|
||||
|
||||
if (options)
|
||||
var iframe = document.getElementById(id);
|
||||
if (!iframe)
|
||||
{
|
||||
if (options.maxItems) maxItems = options.maxItems;
|
||||
if (options.minItems) minItems = options.minItems;
|
||||
if (options.incrementalFill) incrementalFill = options.incrementalFill;
|
||||
liberator.log("No iframe with id: " + id + " found, strange things may happen!")
|
||||
return;
|
||||
}
|
||||
|
||||
var widget = document.getElementById(id);
|
||||
var completions = null; // a reference to the Array of completions
|
||||
var listOffset = 0; // how many items is the displayed list shifted from the internal tab index
|
||||
var listIndex = 0; // listOffset + listIndex = completions[item]
|
||||
var doc = iframe.contentDocument;
|
||||
var container = iframe.parentNode;
|
||||
|
||||
// add a single completion item to the list
|
||||
function addItem(completionItem, atBeginning)
|
||||
var stylesheet = doc.createElement("link");
|
||||
stylesheet.setAttribute("rel", "Stylesheet");
|
||||
stylesheet.setAttribute("href", "chrome://" + liberator.config.name.toLowerCase() + "/skin/vimperator.css");
|
||||
doc.body.id = id + "-content";
|
||||
doc.getElementsByTagName("head")[0].appendChild(stylesheet);
|
||||
|
||||
var completions = []; // a reference to the Array of completions
|
||||
var listOffset = -1; // how many items is the displayed list shifted from the internal tab index
|
||||
var listIndex = -1; // listOffset + listIndex = completions[item]
|
||||
var selectedElement = null;
|
||||
|
||||
// FIXME: ItemList shouldn't know of favicons of course, so also temporary
|
||||
try {
|
||||
var faviconService = Components.classes["@mozilla.org/browser/favicon-service;1"].getService(Components.interfaces.nsIFaviconService);
|
||||
const ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
} catch (e) { } // for muttator!
|
||||
|
||||
|
||||
// TODO: temporary, to be changed/removed
|
||||
function createRow(a, b, c)
|
||||
{
|
||||
var item = document.createElement("listitem");
|
||||
var cell1 = document.createElement("listcell");
|
||||
var cell2 = document.createElement("listcell");
|
||||
|
||||
cell1.setAttribute("label", completionItem[0]);
|
||||
cell2.setAttribute("label", completionItem[1]);
|
||||
cell2.setAttribute("style", "color:green; font-family: sans");
|
||||
|
||||
item.appendChild(cell1);
|
||||
item.appendChild(cell2);
|
||||
if (atBeginning == true)
|
||||
var row = doc.createElement("tr");
|
||||
row.setAttribute("class", "liberator-compitem");
|
||||
var icon = doc.createElement("td");
|
||||
icon.setAttribute("style", "width: 16px");
|
||||
if (a)
|
||||
{
|
||||
var items = widget.getElementsByTagName("listitem");
|
||||
if (items.length > 0)
|
||||
widget.insertBefore(item, items[0]);
|
||||
else
|
||||
widget.appendChild(item);
|
||||
var img = doc.createElement("img");
|
||||
img.setAttribute("width", "16px");
|
||||
img.setAttribute("height", "16px");
|
||||
img.setAttribute("src", a);
|
||||
icon.appendChild(img);
|
||||
}
|
||||
row.appendChild(icon);
|
||||
|
||||
var title = doc.createElement("td");
|
||||
title.appendChild(doc.createTextNode(b));
|
||||
title.setAttribute("style", "width: 45%; overflow:hidden");
|
||||
row.appendChild(title);
|
||||
|
||||
var url = doc.createElement("td");
|
||||
url.setAttribute("style", "color: gray");
|
||||
url.appendChild(doc.createTextNode(c));
|
||||
row.appendChild(url);
|
||||
|
||||
return row;
|
||||
|
||||
var row = doc.createElement("tr");
|
||||
row.setAttribute("class", "liberator-compitem");
|
||||
var icon = doc.createElement("td");
|
||||
icon.innerHTML = '<td style="vertical-align: middle"><img src="' + a + '" width="16px" height="16px"/></td><td style="vertical-align:middle">' + b + ' <br/><span style="color: green">' + c + '</span></td>';
|
||||
row.appendChild(icon);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
function autoSize()
|
||||
{
|
||||
function getHeight()
|
||||
{
|
||||
if (completionElements.length == 0)
|
||||
return doc.height;
|
||||
|
||||
var wanted = maxItems + listOffset;
|
||||
if (wanted > completionElements.length)
|
||||
wanted = completionElements.length;
|
||||
return completionElements[wanted - 1].getBoundingClientRect().bottom;
|
||||
}
|
||||
|
||||
var height = getHeight();
|
||||
if (height == 0) // sometimes we don't have the correct size at this point
|
||||
setTimeout(function() { container.height = getHeight(); }, 10);
|
||||
else
|
||||
widget.appendChild(item);
|
||||
container.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* uses the entries in completions to fill the listbox
|
||||
* does incremental filling to speed up things
|
||||
*
|
||||
* @param startindex: start at this index and show maxItems
|
||||
* @returns the number of items
|
||||
* @param offset: start at this index and show maxItems
|
||||
*/
|
||||
function fill(startindex)
|
||||
function fill(offset)
|
||||
{
|
||||
var complength = completions.length;
|
||||
if (listOffset == offset || offset < 0 || offset >= completions.length)
|
||||
return;
|
||||
|
||||
// remove all old items first
|
||||
var items = widget.getElementsByTagName("listitem");
|
||||
while (items.length > 0)
|
||||
if (listIndex > -1 && offset == listOffset + 1)
|
||||
{
|
||||
widget.removeChild(items[0]);
|
||||
listOffset = offset;
|
||||
var icon = "";
|
||||
try {
|
||||
var uri = ioService.newURI(completions[offset][0], null, null);
|
||||
icon = faviconService.getFaviconImageForPage(uri).spec;
|
||||
} catch (e) { }
|
||||
|
||||
var row = createRow(icon, completions[offset + maxItems - 1][0], completions[offset + maxItems - 1][1]);
|
||||
var e = doc.getElementsByTagName("tbody");
|
||||
e[e.length - 1].removeChild(e[e.length - 1].firstElementChild);
|
||||
e[e.length - 1].appendChild(row);
|
||||
completionElements = doc.getElementsByClassName("liberator-compitem"); // TODO: make faster
|
||||
return;
|
||||
}
|
||||
|
||||
if (!incrementalFill)
|
||||
else if (listIndex > -1 && offset == listOffset - 1)
|
||||
{
|
||||
for (let i = 0; i < completions.length; i++)
|
||||
addItem(completions[i], false);
|
||||
return complength;
|
||||
listOffset = offset;
|
||||
var icon = "";
|
||||
try {
|
||||
var uri = ioService.newURI(completions[offset][0], null, null);
|
||||
icon = faviconService.getFaviconImageForPage(uri).spec;
|
||||
} catch (e) { }
|
||||
var row = createRow(icon, completions[offset][0], completions[offset][1]);
|
||||
var e = doc.getElementsByTagName("tbody");
|
||||
e[e.length - 1].removeChild(e[e.length - 1].lastElementChild);
|
||||
e[e.length - 1].insertBefore(row, e[e.length - 1].firstElementChild);
|
||||
completionElements = doc.getElementsByClassName("liberator-compitem"); // TODO: make faster
|
||||
return;
|
||||
}
|
||||
listOffset = offset;
|
||||
|
||||
// find start index
|
||||
if (startindex + maxItems > complength)
|
||||
startindex = complength - maxItems;
|
||||
if (startindex < 0)
|
||||
startindex = 0;
|
||||
// do a full refill of the list:
|
||||
doc.body.innerHTML = "";
|
||||
|
||||
listOffset = startindex;
|
||||
listIndex = -1;
|
||||
var div = doc.createElement("div");
|
||||
div.setAttribute("class", "ex-command-output hl-Normal");
|
||||
div.innerHTML = "<span style=\"color: magenta; font-weight: bold\">Completions:</span>";
|
||||
var table = doc.createElement("table");
|
||||
table.setAttribute("width", "100%");
|
||||
table.setAttribute("style", "table-layout: fixed; width: 100%");
|
||||
//div.appendChild(table);
|
||||
var tbody = doc.createElement("tbody");
|
||||
table.appendChild(tbody);
|
||||
|
||||
for (var i = startindex; i < complength && i < startindex + maxItems; i++)
|
||||
for (var i = 0; i < completions.length; i++)
|
||||
{
|
||||
addItem(completions[i], false);
|
||||
}
|
||||
var elem = completions[i];
|
||||
if (i >= listOffset && i - listOffset < maxItems)
|
||||
{
|
||||
var icon = "";
|
||||
try {
|
||||
var uri = ioService.newURI(elem[0], null, null);
|
||||
icon = faviconService.getFaviconImageForPage(uri).spec;
|
||||
//dump(icon + "\n");
|
||||
} catch (e) { }
|
||||
|
||||
return (i - startindex);
|
||||
if (i == -132434)
|
||||
{
|
||||
var row = doc.createElement("tr");
|
||||
row.setAttribute("align", "center");
|
||||
row.innerHTML = '<th width="16px"></th><th style="background-color: gray !important;"><span style="font-weight: bold;">Bookmarks</span></th>';
|
||||
tbody.appendChild(row);
|
||||
}
|
||||
else
|
||||
{
|
||||
tbody.appendChild(createRow(icon, elem[0], elem[1]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
doc.body.appendChild(div);
|
||||
doc.body.appendChild(table);
|
||||
|
||||
completionElements = doc.getElementsByClassName("liberator-compitem");
|
||||
autoSize();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////}}}
|
||||
@@ -1190,60 +1294,33 @@ liberator.InformationList = function (id, options) //{{{
|
||||
|
||||
return {
|
||||
|
||||
/**
|
||||
* Show the completion list window
|
||||
*
|
||||
* @param compl: if null, only show the list with current entries, otherwise
|
||||
* use entries of 'compl' to fill the list.
|
||||
* Required format: [["left", "right"], ["another"], ["completion"]]
|
||||
*/
|
||||
show: function (compl, rows)
|
||||
{
|
||||
//maxItems = liberator.options["previewheight"];
|
||||
clear: function () { this.setItems([]); doc.body.innerHTML = ""; },
|
||||
hide: function () { container.collapsed = true; },
|
||||
show: function () { container.collapsed = false; },
|
||||
visible: function () { return !container.collapsed; },
|
||||
|
||||
if (compl)
|
||||
setItems: function (items, selectedItem)
|
||||
{
|
||||
completions = compl;
|
||||
fill(0);
|
||||
}
|
||||
listOffset = listIndex = -1;
|
||||
completions = items || [];
|
||||
if (typeof(selectedItem) != "number")
|
||||
selectedItem = -1;
|
||||
|
||||
var length = completions.length;
|
||||
if (length > maxItems)
|
||||
length = maxItems;
|
||||
if (length >= minItems)
|
||||
{
|
||||
widget.setAttribute("rows", rows ? rows : length.toString());
|
||||
widget.hidden = false;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
widget.hidden = true;
|
||||
return false;
|
||||
}
|
||||
this.selectItem(selectedItem);
|
||||
},
|
||||
|
||||
hide: function ()
|
||||
{
|
||||
widget.hidden = true;
|
||||
},
|
||||
|
||||
visible: function ()
|
||||
{
|
||||
return !widget.hidden;
|
||||
},
|
||||
|
||||
/**
|
||||
* select index, refill list if necessary
|
||||
*/
|
||||
// select index, refill list if necessary
|
||||
selectItem: function (index)
|
||||
{
|
||||
if (widget.hidden)
|
||||
if (container.collapsed) // fixme
|
||||
return;
|
||||
|
||||
if (!incrementalFill)
|
||||
if (index == -1 || index == completions.length) // wrapped around
|
||||
{
|
||||
widget.selectedIndex = index;
|
||||
if (listIndex >= 0)
|
||||
completionElements[listIndex - listOffset].style.backgroundColor = "";
|
||||
|
||||
listIndex = index;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1261,40 +1338,19 @@ liberator.InformationList = function (id, options) //{{{
|
||||
if (newOffset < 0)
|
||||
newOffset = 0;
|
||||
|
||||
// for speed reason: just remove old item, and add the new one at the end of the list
|
||||
var items = widget.getElementsByTagName("listitem");
|
||||
if (newOffset == listOffset + 1)
|
||||
{
|
||||
widget.removeChild(items[0]);
|
||||
addItem(completions[index + CONTEXT_LINES], false);
|
||||
}
|
||||
else if (newOffset == listOffset - 1)
|
||||
{
|
||||
widget.removeChild(items[items.length-1]);
|
||||
addItem(completions[index - CONTEXT_LINES], true);
|
||||
}
|
||||
else if (newOffset == listOffset)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
fill(newOffset);
|
||||
|
||||
listOffset = newOffset;
|
||||
widget.selectedIndex = index - listOffset;
|
||||
if (selectedElement)
|
||||
selectedElement.style.backgroundColor = "";
|
||||
selectedElement = completionElements[index - newOffset];
|
||||
selectedElement.style.backgroundColor = "yellow";
|
||||
|
||||
listIndex = index;
|
||||
return;
|
||||
},
|
||||
|
||||
onEvent: function (event)
|
||||
{
|
||||
var listcells = document.getElementsByTagName("listcell");
|
||||
// 2 columns for now, use the first column
|
||||
var index = (widget.selectedIndex * 2) + 0;
|
||||
var val = listcells[index].getAttribute("label");
|
||||
if (val && event.button == 0 && event.type == "dblclick") // left double click
|
||||
liberator.open(val);
|
||||
else if (val && event.button == 1) // middle click
|
||||
liberator.open(val, liberator.NEW_TAB);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1302,6 +1358,7 @@ liberator.InformationList = function (id, options) //{{{
|
||||
//}}}
|
||||
}; //}}}
|
||||
|
||||
|
||||
liberator.StatusLine = function () //{{{
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1444,7 +1501,9 @@ liberator.StatusLine = function () //{{{
|
||||
progress = "";
|
||||
|
||||
if (typeof progress == "string")
|
||||
{
|
||||
progressWidget.value = progress;
|
||||
}
|
||||
else if (typeof progress == "number")
|
||||
{
|
||||
var progressStr = "";
|
||||
|
||||
@@ -289,7 +289,6 @@ liberator.util = { //{{{
|
||||
|
||||
begin: for (var url = 0; url < urls.length; url++)
|
||||
{
|
||||
|
||||
var file = liberator.io.getFile(urls[url]);
|
||||
if (file.exists() && file.isReadable())
|
||||
{
|
||||
|
||||
@@ -78,26 +78,17 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
events="select"
|
||||
oncommandupdate="if (typeof liberator.events != 'undefined') liberator.events.onSelectionChange(event);"/>
|
||||
|
||||
<vbox id="liberator-container" hidden="false">
|
||||
<!--listbox id="liberator-previewwindow" class="plain" rows="10" flex="1" hidden="true"
|
||||
onclick= "liberator.previewwindow.onEvent(event);"
|
||||
ondblclick="liberator.previewwindow.onEvent(event);"
|
||||
onkeydown= "liberator.previewwindow.onEvent(event);">
|
||||
<listcols>
|
||||
<listcol flex="1" width="50%"/>
|
||||
<listcol flex="1" width="50%"/>
|
||||
</listcols>
|
||||
</listbox-->
|
||||
|
||||
<iframe id="liberator-multiline-output" src="about:blank" flex="1" height="10px" hidden="false" collapsed="true"
|
||||
<!-- As of Firefox 3.1pre, <iframe>.height changes do not seem to have immediate effect,
|
||||
therefore we need to put them into a <vbox> for which that works just fine -->
|
||||
<vbox class="liberator-container" hidden="false" collapsed="true">
|
||||
<iframe id="liberator-multiline-output" src="about:blank" flex="1" height="10px" hidden="false" collapsed="false"
|
||||
onclick="liberator.commandline.onMultilineOutputEvent(event)"/>
|
||||
</vbox>
|
||||
|
||||
<listbox id="liberator-completion" class="plain" rows="1" flex="1" hidden="true">
|
||||
<listcols>
|
||||
<listcol flex="1" width="50%"/>
|
||||
<listcol flex="1" width="50%"/>
|
||||
</listcols>
|
||||
</listbox>
|
||||
<vbox class="liberator-container" hidden="false" collapsed="true">
|
||||
<iframe id="liberator-completions" src="about:blank" flex="1" height="250px" hidden="false" collapsed="false"
|
||||
onclick="liberator.commandline.onMultilineOutputEvent(event)"/>
|
||||
</vbox>
|
||||
|
||||
<hbox id="liberator-commandline" hidden="false" class="hl-Normal">
|
||||
<label class="plain" id="liberator-commandline-prompt" flex="0" crop="end" value="" collapsed="true"/>
|
||||
@@ -107,6 +98,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
onblur="liberator.commandline.onEvent(event);"/>
|
||||
</hbox>
|
||||
|
||||
<vbox class="liberator-container" hidden="false" collapsed="false">
|
||||
<textbox id="liberator-multiline-input" class="plain" flex="1" rows="1" hidden="false" collapsed="true" multiline="true"
|
||||
onkeypress="liberator.commandline.onMultilineInputEvent(event);"
|
||||
oninput="liberator.commandline.onMultilineInputEvent(event);"
|
||||
@@ -119,7 +111,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
<hbox insertbefore="statusbar-display" id="liberator-statusline" flex="1" height="10" hidden="false" align="center">
|
||||
<textbox class="plain" id="liberator-statusline-field-url" readonly="false" flex="1" crop="end"/>
|
||||
<label class="plain" id="liberator-statusline-field-inputbuffer" flex="0"/>
|
||||
<label class="plain" id="liberator-statusline-field-progress" flex="0"/>
|
||||
<label class="plain" id="liberator-statusline-field-progress" flex="0" width="200px"/>
|
||||
<label class="plain" id="liberator-statusline-field-tabcount" flex="0"/>
|
||||
<label class="plain" id="liberator-statusline-field-bufferposition" flex="0"/>
|
||||
</hbox>
|
||||
|
||||
@@ -30,11 +30,11 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
#liberator-bufferwindow, #liberator-completion, #liberator-previewwindow {
|
||||
#liberator-completions {
|
||||
-moz-user-focus: ignore;
|
||||
overflow: -moz-scrollbars-none !important; /* does not seem to work fully */
|
||||
border-width: 0px !important;
|
||||
-moz-appearance: none !important; /* prevent an ugly 3D border */
|
||||
/*-moz-appearance: none !important; /* prevent an ugly 3D border */
|
||||
}
|
||||
|
||||
/* the selected item in listboxes is hardly readable without this */
|
||||
@@ -45,6 +45,10 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
color: HighlightText !important;
|
||||
}
|
||||
|
||||
/*.liberator-compitem {
|
||||
min-height: 16px;
|
||||
}*/
|
||||
|
||||
/* fixes the min-height: 22px from firefox */
|
||||
#status-bar, statusbarpanel {
|
||||
-moz-appearance: none !important;
|
||||
@@ -78,6 +82,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
#liberator-commandline {
|
||||
padding: 1px;
|
||||
font-family: monospace;
|
||||
/*
|
||||
background-color: white;
|
||||
color: black;
|
||||
@@ -155,7 +160,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
|
||||
color: black !important;
|
||||
}
|
||||
.hl-URL {
|
||||
background-color: white;
|
||||
background-color: inherit;
|
||||
color: green;
|
||||
text-decoration: none;
|
||||
}
|
||||
@@ -167,30 +172,36 @@ a.hl-URL:hover {
|
||||
|
||||
/* MOW */
|
||||
|
||||
#liberator-multiline-output {
|
||||
#liberator-completions, #liberator-multiline-output {
|
||||
overflow: hidden;
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
#liberator-multiline-output-content {
|
||||
white-space: pre; /* -moz-pre-wrap FIXME: Should lines wrap like Vim? */
|
||||
#liberator-completions-content, #liberator-multiline-output-content {
|
||||
white-space: pre;
|
||||
font-family: -moz-fixed;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
#liberator-multiline-output-content * {
|
||||
#liberator-completions-content *, #liberator-multiline-output-content * {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
#liberator-multiline-output-content table {
|
||||
#liberator-completions-content table, #liberator-multiline-output-content table {
|
||||
white-space: inherit;
|
||||
border-spacing: 0px;
|
||||
}
|
||||
|
||||
#liberator-multiline-output-content td,
|
||||
#liberator-multiline-output-content th {
|
||||
#liberator-completions-content td, #liberator-multiline-output-content td,
|
||||
#liberator-completions-content th, #liberator-multiline-output-content th {
|
||||
padding: 0px 2px;
|
||||
}
|
||||
|
||||
/* for muttator's composer */
|
||||
#content-frame, #appcontent {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
|
||||
/* vim: set fdm=marker sw=4 ts=4 et: */
|
||||
|
||||
Reference in New Issue
Block a user