From 550d8213f6ed1b8c3df6754dba31ca7edc63161a Mon Sep 17 00:00:00 2001 From: David Kettler Date: Sat, 10 Mar 2012 10:58:36 +1030 Subject: [PATCH] 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 | 71 +++++++++++++++++++++++++++++++++++++++ content/minibuffer-annotation.css | 3 ++ modules/minibuffer.js | 34 +++++++++++++++++++ style/default/minibuffer.css | 11 ++++++ 4 files changed, 119 insertions(+) create mode 100644 content/annotated-textbox.xml create mode 100644 content/minibuffer-annotation.css diff --git a/content/annotated-textbox.xml b/content/annotated-textbox.xml new file mode 100644 index 0000000..e579865 --- /dev/null +++ b/content/annotated-textbox.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + false + + document.getAnonymousElementByAttribute(this, "anonid", "annotation"); + + + document.getAnonymousElementByAttribute(this, "anonid", "strut"); + + + + + return this._annotate; + + + + + + + + + + + if (this._annotate) + this._strut.setAttribute("value", this.value); + + + + + diff --git a/content/minibuffer-annotation.css b/content/minibuffer-annotation.css new file mode 100644 index 0000000..4c5b5e8 --- /dev/null +++ b/content/minibuffer-annotation.css @@ -0,0 +1,3 @@ +#minibuffer-input { + -moz-binding: url("chrome://conkeror-gui/content/annotated-textbox.xml#annotated-textbox"); +} diff --git a/modules/minibuffer.js b/modules/minibuffer.js index 6b19305..0f3946d 100644 --- a/modules/minibuffer.js +++ b/modules/minibuffer.js @@ -447,4 +447,38 @@ function minibuffer_abort (window) { interactive("minibuffer-abort", null, function (I) { minibuffer_abort(I.window); }); +/* + * Minibuffer-annotation-mode + */ + +var minibuffer_annotation_mode = { + stylesheet: "chrome://conkeror-gui/content/minibuffer-annotation.css", + users: [], + enabled: false, + register: function (user) { + this.users.push(user); + this._switch_if_needed(); + }, + unregister: function (user) { + var i = this.users.indexOf(user); + if (i > -1) + this.users.splice(i, 1); + this._switch_if_needed(); + }, + _switch_if_needed: function (user) { + if (this.enabled && this.users.length == 0) + this._disable(); + if (!this.enabled && this.users.length != 0) + this._enable(); + }, + _enable: function () { + register_agent_stylesheet(this.stylesheet); + this.enabled = true; + }, + _disable: function () { + unregister_agent_stylesheet(this.stylesheet); + this.enabled = false; + } +}; + provide("minibuffer"); diff --git a/style/default/minibuffer.css b/style/default/minibuffer.css index 253559e..1c476ba 100644 --- a/style/default/minibuffer.css +++ b/style/default/minibuffer.css @@ -10,6 +10,17 @@ background-color: -moz-field !important; } +#minibuffer-input .textbox-input-box { + width: 5em; +} + +#minibuffer-input [anonid="annotation"] { + font-style: oblique; +} + +#minibuffer-input [anonid="strut"] { + padding-right: 1em !important; +} /* mode text widgets */ -- 2.11.4.GIT