From d43ef37bda874406162cb563bdcb0f1bd6f89904 Mon Sep 17 00:00:00 2001 From: Mark Finkle Date: Tue, 9 Mar 2010 22:42:04 -0500 Subject: [PATCH] Bug 466770 - fix content autocomplete [r=vingtetun] --- mobile/chrome/content/browser-ui.js | 136 ++++++++++++++----- mobile/chrome/content/browser.xul | 2 + mobile/themes/hildon/browser.css | 38 ++++++ mobile/themes/hildon/images/arrowleft-16.png | Bin 0 -> 280 bytes mobile/themes/hildon/jar.mn | 1 + mobile/themes/wince/browser.css | 38 ++++++ mobile/themes/wince/images/arrowleft-16.png | Bin 0 -> 280 bytes mobile/themes/wince/jar.mn | 1 + 8 files changed, 180 insertions(+), 36 deletions(-) create mode 100644 mobile/themes/hildon/images/arrowleft-16.png create mode 100644 mobile/themes/wince/images/arrowleft-16.png diff --git a/mobile/chrome/content/browser-ui.js b/mobile/chrome/content/browser-ui.js index 805cfb31631b..3d91e5bbe7f5 100644 --- a/mobile/chrome/content/browser-ui.js +++ b/mobile/chrome/content/browser-ui.js @@ -1086,6 +1086,11 @@ var FormHelper = { return this._selectContainer = document.getElementById("select-container"); }, + get _autofillContainer() { + delete this._autofillContainer; + return this._autofillContainer = document.getElementById("form-helper-autofill"); + }, + _getRectForElement: function formHelper_getRectForElement(aElement) { const kDistanceMax = 100; let elRect = Browser.getBoundingContentRect(aElement); @@ -1109,6 +1114,14 @@ var FormHelper = { _update: function(aPreviousElement, aNewElement) { this._updateSelect(aPreviousElement, aNewElement); + // Setup autofill UI + if (aNewElement instanceof HTMLInputElement && aNewElement.type == "text") { + let suggestions = this._getSuggestions(); + this._setSuggestions(suggestions); + } else { + this._autofillContainer.hidden = true; + } + let height = Math.floor(this._container.getBoundingClientRect().height); this._container.top = window.innerHeight - height; @@ -1216,6 +1229,44 @@ var FormHelper = { return (index != -1 ? this._nodes[++index] : null); }, + _fac: Cc["@mozilla.org/satchel/form-autocomplete;1"].getService(Ci.nsIFormAutoComplete), + _getSuggestions: function() { + let suggestions = []; + let currentValue = this._currentElement.value; + let results = this._fac.autoCompleteSearch(this._currentElement.name, currentValue, this._currentElement, null); + if (results.matchCount > 0) { + for (let i = 0; i < results.matchCount; i++) { + let value = results.getValueAt(i); + suggestions.push(value); + } + } + + return suggestions; + }, + + _setSuggestions: function(aSuggestions) { + let autofill = this._autofillContainer; + while (autofill.hasChildNodes()) + autofill.removeChild(autofill.lastChild); + + let fragment = document.createDocumentFragment(); + for (let i = 0; i < aSuggestions.length; i++) { + let value = aSuggestions[i]; + let button = document.createElement("label"); + button.setAttribute("value", value); + fragment.appendChild(button); + } + autofill.appendChild(fragment); + autofill.hidden = !aSuggestions.length; + }, + + doAutoFill: function formHelperDoAutoFill(aElement) { + if (!this._currentElement) + return; + + this._currentElement.value = aElement.value; + }, + getLabelsFor: function(aElement) { let associatedLabels = []; if (this._isValidElement(aElement)) { @@ -1268,7 +1319,6 @@ var FormHelper = { return false; this._open = true; - window.addEventListener("keypress", this, true); window.addEventListener("keyup", this, false); let bv = Browser._browserView; bv.ignorePageScroll(true); @@ -1288,6 +1338,7 @@ var FormHelper = { this._updateSelect(this._currentElement, null); this._helperSpacer.hidden = true; + // give the form spacer area back to the content let bv = Browser._browserView; Browser.forceChromeReflow(); @@ -1296,7 +1347,6 @@ var FormHelper = { bv.ignorePageScroll(false); - window.removeEventListener("keypress", this, true); window.removeEventListener("keyup", this, false); this._container.hidden = true; this._currentElement = null; @@ -1309,41 +1359,55 @@ var FormHelper = { return; let currentElement = this.getCurrentElement(); - if (aEvent.type == "keypress") { - switch (aEvent.keyCode) { - case aEvent.DOM_VK_DOWN: - if (currentElement instanceof HTMLTextAreaElement) { - let existSelection = currentElement.selectionEnd - currentElement.selectionStart; - let isEnd = (currentElement.textLength == currentElement.selectionEnd); - if (!isEnd || existSelection) - return; + switch (aEvent.keyCode) { + case aEvent.DOM_VK_DOWN: + if (currentElement instanceof HTMLTextAreaElement) { + let existSelection = currentElement.selectionEnd - currentElement.selectionStart; + let isEnd = (currentElement.textLength == currentElement.selectionEnd); + if (!isEnd || existSelection) + return; + } + + this.goToNext(); + break; + + case aEvent.DOM_VK_UP: + if (currentElement instanceof HTMLTextAreaElement) { + let existSelection = currentElement.selectionEnd - currentElement.selectionStart; + let isStart = (currentElement.selectionEnd == 0); + if (!isStart || existSelection) + return; + } + + this.goToPrevious(); + break; + + case aEvent.DOM_VK_RETURN: + break; + + default: + let target = aEvent.target; + if (currentElement instanceof HTMLInputElement && currentElement.type == "text") { + let suggestions = this._getSuggestions(); + this._setSuggestions(suggestions); + + let height = Math.floor(this._container.getBoundingClientRect().height); + this._container.top = window.innerHeight - height; + this._helperSpacer.setAttribute("height", height); + + // XXX if we are at the bottom of the page we need to give back the content + // area by refreshing it + if (suggestions.length == 0) { + let bv = Browser._browserView; + Browser.forceChromeReflow(); + Browser.contentScrollboxScroller.scrollBy(0, 0); + bv.onAfterVisibleMove(); } - - this.goToNext(); - aEvent.preventDefault(); - aEvent.stopPropagation(); - break; - - case aEvent.DOM_VK_UP: - if (currentElement instanceof HTMLTextAreaElement) { - let existSelection = currentElement.selectionEnd - currentElement.selectionStart; - let isStart = (currentElement.selectionEnd == 0); - if (!isStart || existSelection) - return; - } - - this.goToPrevious(); - aEvent.preventDefault(); - aEvent.stopPropagation(); - break; - } - } - else if (aEvent.type == "keyup") { - let target = aEvent.target; - if (currentElement == target && this._isValidSelectElement(target)) { - SelectHelper.unselectAll(); - SelectHelper.selectByIndex(target.selectedIndex); - } + } else if (currentElement == target && this._isValidSelectElement(target)) { + SelectHelper.unselectAll(); + SelectHelper.selectByIndex(target.selectedIndex); + } + break; } }, diff --git a/mobile/chrome/content/browser.xul b/mobile/chrome/content/browser.xul index a78aa7119ee5..f593f5f5162b 100644 --- a/mobile/chrome/content/browser.xul +++ b/mobile/chrome/content/browser.xul @@ -274,6 +274,8 @@