Bug 560426 - Form fill interferes with custom input autocomplete arrow keys [r=mfinkle]
authorVivien Nicolas <21@vingtetun.org>
Thu, 01 Jul 2010 22:21:21 +0200
changeset 66350 753b296b41019557b8dfdf3e66f31ec08ee80a7a
parent 66349 8a06ecf16a5544d91057ec277184815e7fb0d7d7
child 66351 e2dc78500ba68e2d336a3df61faeec6e3a6a7913
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle
bugs560426
Bug 560426 - Form fill interferes with custom input autocomplete arrow keys [r=mfinkle]
mobile/chrome/content/browser-ui.js
mobile/chrome/content/forms.js
--- a/mobile/chrome/content/browser-ui.js
+++ b/mobile/chrome/content/browser-ui.js
@@ -1472,16 +1472,19 @@ var FormHelper = {
       let height = Math.floor(this._container.getBoundingClientRect().height);
       this._container.top = window.innerHeight - height;
       let containerHeight = this._container.getBoundingClientRect().height;
       this._helperSpacer.setAttribute("height", containerHeight);
     }
   },
 
   getAutocompleteSuggestions: function(aElement) {
+    if (!aElement.canAutocomplete)
+      return [];
+
     let suggestions = [];
     let autocompleteService = Cc["@mozilla.org/satchel/form-autocomplete;1"].getService(Ci.nsIFormAutoComplete);
     let results = autocompleteService.autoCompleteSearch(aElement.name, aElement.value, aElement, null);
     if (results.matchCount > 0) {
       for (let i = 0; i < results.matchCount; i++) {
         let value = results.getValueAt(i);
         suggestions.push(value);
       }
--- a/mobile/chrome/content/forms.js
+++ b/mobile/chrome/content/forms.js
@@ -143,35 +143,57 @@ FormAssistant.prototype = {
         if (!current)
           return;
 
         current.autocomplete(json.value);
         break;
     }
   },
 
+  _els: Cc["@mozilla.org/eventlistenerservice;1"].getService(Ci.nsIEventListenerService),
+  _hasKeyListener: function _hasKeyListener(aElement) {
+    let els = this._els;
+    let listeners = els.getListenerInfoFor(aElement, {});
+    for (let i = 0; i < listeners.length; i++) {
+      let listener = listeners[i];
+      if (["keyup", "keydown", "keypress"].indexOf(listener.type) != -1
+          && !listener.inSystemEventGroup) {
+        return true;
+      }
+    }
+    return false;
+  },
+
   handleEvent: function formHelperHandleEvent(aEvent) {
     let currentWrapper = this.getCurrent();
     let currentElement = currentWrapper.element;
 
     switch (aEvent.keyCode) {
       case aEvent.DOM_VK_DOWN:
-        if (currentElement instanceof HTMLTextAreaElement) {
+        if (currentElement instanceof HTMLInputElement && !currentWrapper.canAutocomplete()) {
+          if (this._hasKeyListener(currentElement))
+            return;
+        }
+        else if (currentElement instanceof HTMLTextAreaElement) {
           let existSelection = currentElement.selectionEnd - currentElement.selectionStart;
           let isEnd = (currentElement.textLength == currentElement.selectionEnd);
           if (!isEnd || existSelection)
             return;
         }
 
         this.goToNext();
         sendAsyncMessage("FormAssist:Show", this.getJSON());
         break;
 
       case aEvent.DOM_VK_UP:
-        if (currentElement instanceof HTMLTextAreaElement) {
+        if (currentElement instanceof HTMLInputElement && !currentWrapper.canAutocomplete()) {
+          if (this._hasKeyListener(currentElement))
+            return;
+        }
+        else if (currentElement instanceof HTMLTextAreaElement) {
           let existSelection = currentElement.selectionEnd - currentElement.selectionStart;
           let isStart = (currentElement.selectionEnd == 0);
           if (!isStart || existSelection)
             return;
         }
 
         this.goToPrevious();
         sendAsyncMessage("FormAssist:Show", this.getJSON());
@@ -371,17 +393,23 @@ BasicWrapper.prototype = {
         }
       }
     }
     return elRect;
   },
 
   /** Element is capable of having autocomplete suggestions. */
   canAutocomplete: function() {
-    return this.element instanceof HTMLInputElement;
+    if (this.element instanceof HTMLInputElement) {
+      let autocomplete = this.element.getAttribute("autocomplete");
+      let allowedValues = ["off", "false", "disabled"];
+      if (allowedValues.indexOf(autocomplete) == -1)
+        return true;
+    }
+    return false;
   },
 
   autocomplete: function(aValue) {
     this.element.value = aValue;
 
     let event = this.element.ownerDocument.createEvent("Events");
     event.initEvent("DOMAutoComplete", true, true);
     this.element.dispatchEvent(event);