minibuffer-annotation-mode: new mode
commit550d8213f6ed1b8c3df6754dba31ca7edc63161a
authorDavid Kettler <kettler@internode.on.net>
Sat, 10 Mar 2012 00:28:36 +0000 (10 10:58 +1030)
committerJohn Foerch <jjfoerch@earthlink.net>
Sat, 10 Mar 2012 19:27:57 +0000 (10 14:27 -0500)
treead401859b230de4a763f5d1d9a681fe563242049
parent072870fd8a6e5ba6053f3a3593bc6bcfa83ef916
minibuffer-annotation-mode: new mode

minibuffer-annotation-mode provides an inline annotation to the right of
the minibuffer input.  This will be used to replace hints_url_panel with
an improved UI in a subsequent patch, and other possible uses in the
future.

The annotation is implemented via 'annotated-textbox', a new XBL binding
that extends a textbox with an integrated label that appears to the right
of the input, and it is pushed further to the right as the input grows.

When a textbox is bound to annotated-textbox it gains two properties.  The
'annotate' property is a boolean that determines whether the annotation is
shown.  When false (the default) the annotated-textbox behaves just like a
regular textbox.  The 'annotation' property is a string that gives the
text to display.

The annotated-textbox is styled by CSS, and can be themed with Conkeror's
theme system.  The bound textbox's width becomes the minimum width of the
input area.  The annotation's position is not adjusted until the input
text overflows this width.  Right-padding on the strut (explained below)
gives a minimum amount of space to be preserved between the end of the
input text and the beginning of the annotation text.  This padding also
ensures enough visual space for the insertion point.

* Implementation Notes

Implementing the annotated-textbox binding to extend the textbox
binding is simpler than encapsulating it; all the properties from the
textbox apply to the new binding with no effort.  Many more 'inherits'
properties would otherwise need to be set and maintained as the
xulrunner platform evolves.

However there is the disadvantage that the content element needs to be
copied from the textbox binding; there is no way in XBL to include the
content when extending a binding.  The textbox content (an hbox and an
input element) has changed only slightly between xulrunner 1.9.1 and
11.0.  There are new properties to be inherited and the setting of
flex on the input element has gone.  The content in annotated-textbox
specifies all the properties to inherit from 11.0 and includes the
flex on the input element; the latter does no harm in recent xulrunner
and is required to handle growing correctly in 1.9.1.

Internally, the annotated-textbox makes a deck of the input textbox
with a "strut" label, then continually updates the strut with the
input text, so that the strut width controls the input width.  The
strut is placed in a box with hidden overflow; this prevents wide text
from expanding the textbox.  The annotation is given a much larger
flex value than the input, so that as the textbox fills, the
annotation will be truncated before the input.  The strut has right
padding which acts as a spacer between the input and annotation and
also allows room for the cursor.

It is assumed that the annotation will only be enabled with an initial
blank input value.  This is true of the minibuffer-input use case.
However, in the more general case where it is enabled later during an
input, the strut will be wrong until the next keystroke.  It does not
work to set the strut to the input value when enabled, because in the
usual case the input field may not yet have had a prior value cleared.

Development note: To check that the strut label matches the input,
change the deck to a stack and use the following css:

textbox [anonid="strut"] {
  color: red;
  font-style: oblique;
}

Thanks to John Foerch for many suggestions.  The idea for using a deck
and strut is from http://www.blackfishsoftware.com/node/47.
content/annotated-textbox.xml [new file with mode: 0644]
content/minibuffer-annotation.css [new file with mode: 0644]
modules/minibuffer.js
style/default/minibuffer.css