Bug 1456703 - Stop using nsIDOMXULTextBoxElement to detect XUL textboxes draft
authorBrian Grinstead <bgrinstead@mozilla.com>
Thu, 26 Apr 2018 15:15:10 -0700
changeset 788736 41fa16051b094d2edb9c675352193cee4ba8f8b4
parent 788735 63a0e2f626febb98d87d2543955ab99a653654ff
child 788737 64837aff12d1632b7ec8601ae95c335bf68fac35
push id108076
push userbgrinstead@mozilla.com
push dateThu, 26 Apr 2018 22:17:10 +0000
bugs1456703
milestone61.0a1
Bug 1456703 - Stop using nsIDOMXULTextBoxElement to detect XUL textboxes This is used in JS via instanceof checks, and in C++ only to get the `inputField` attribute (the actual HTML input or textarea). We can swap out instanceof by checking the tag name, and we can directly query for the input field from C++. MozReview-Commit-ID: 7xpHQMYzYhD
accessible/tests/browser/shared-head.js
accessible/tests/mochitest/events.js
dom/base/nsFocusManager.cpp
toolkit/content/tests/widgets/tree_shared.js
toolkit/content/widgets/textbox.xml
toolkit/modules/sessionstore/FormData.jsm
--- a/accessible/tests/browser/shared-head.js
+++ b/accessible/tests/browser/shared-head.js
@@ -143,17 +143,17 @@ function invokeSetStyle(browser, id, sty
  * @param  {String}  id       content element id
  * @return {Promise} promise  indicating that focus is set
  */
 function invokeFocus(browser, id) {
   Logger.log(`Setting focus on a node with id: ${id}`);
   return ContentTask.spawn(browser, id, contentId => {
     let elm = content.document.getElementById(contentId);
     if (elm instanceof Ci.nsIDOMNSEditableElement && elm.editor ||
-        elm instanceof Ci.nsIDOMXULTextBoxElement) {
+        elm.localName == "textbox") {
       elm.selectionStart = elm.selectionEnd = elm.value.length;
     }
     elm.focus();
   });
 }
 
 /**
  * Load a list of scripts into the test
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -1261,17 +1261,17 @@ function synthOpenComboboxKey(aID, aChec
 function synthFocus(aNodeOrID, aCheckerOrEventSeq) {
   var checkerOfEventSeq =
     aCheckerOrEventSeq ? aCheckerOrEventSeq : new focusChecker(aNodeOrID);
   this.__proto__ = new synthAction(aNodeOrID, checkerOfEventSeq);
 
   this.invoke = function synthFocus_invoke() {
     if (this.DOMNode instanceof Ci.nsIDOMNSEditableElement &&
         this.DOMNode.editor ||
-        this.DOMNode instanceof Ci.nsIDOMXULTextBoxElement) {
+        this.DOMNode.localName == "textbox") {
       this.DOMNode.selectionStart = this.DOMNode.selectionEnd = this.DOMNode.value.length;
     }
     this.DOMNode.focus();
   };
 
   this.getID = function synthFocus_getID() {
     return prettyName(aNodeOrID) + " focus";
   };
@@ -1418,17 +1418,17 @@ function closeCombobox(aComboboxID) {
 /**
  * Select all invoker.
  */
 function synthSelectAll(aNodeOrID, aCheckerOrEventSeq) {
   this.__proto__ = new synthAction(aNodeOrID, aCheckerOrEventSeq);
 
   this.invoke = function synthSelectAll_invoke() {
     if (this.DOMNode instanceof Ci.nsIDOMHTMLInputElement ||
-        this.DOMNode instanceof Ci.nsIDOMXULTextBoxElement) {
+        this.DOMNode.localName == "textbox") {
       this.DOMNode.select();
 
     } else {
       window.getSelection().selectAllChildren(this.DOMNode);
     }
   };
 
   this.getID = function synthSelectAll_getID() {
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -369,19 +369,19 @@ nsFocusManager::GetRedirectedFocus(nsICo
       }
     }
   }
 
 #ifdef MOZ_XUL
   if (aContent->IsXULElement()) {
     nsCOMPtr<nsIDOMNode> inputField;
 
-    nsCOMPtr<nsIDOMXULTextBoxElement> textbox = do_QueryInterface(aContent);
-    if (textbox) {
-      textbox->GetInputField(getter_AddRefs(inputField));
+    if (aContent->IsXULElement(nsGkAtoms::textbox)) {
+      return aContent->OwnerDoc()->
+        GetAnonymousElementByAttribute(aContent, nsGkAtoms::anonid, NS_LITERAL_STRING("input"));
     }
     else {
       nsCOMPtr<nsIDOMXULMenuListElement> menulist = do_QueryInterface(aContent);
       if (menulist) {
         menulist->GetInputField(getter_AddRefs(inputField));
       }
       else if (aContent->IsXULElement(nsGkAtoms::scale)) {
         nsCOMPtr<nsIDocument> doc = aContent->GetComposedDoc();
--- a/toolkit/content/tests/widgets/tree_shared.js
+++ b/toolkit/content/tests/widgets/tree_shared.js
@@ -99,17 +99,17 @@ function testtag_tree(treeid, treerowinf
   is(tree.editingRow == -1 && tree.editingColumn == null, true, testid + " startEditing 15 editingRow");
   tree.startEditing(1, null);
   is(tree.editingRow == -1 && tree.editingColumn == null, true, testid + " startEditing null column editingRow");
   tree.startEditing(2, tree.columns[1]);
   is(tree.editingRow == -1 && tree.editingColumn == null, true, testid + " startEditing non editable cell editingRow");
 
   tree.startEditing(1, ecolumn);
   var inputField = tree.inputField;
-  is(inputField instanceof Ci.nsIDOMXULTextBoxElement, true, testid + "inputField");
+  is(inputField.localName, "textbox", testid + "inputField");
   inputField.value = "Changed Value";
   tree.stopEditing(true);
   is(tree.view.getCellText(1, ecolumn), "Changed Value", testid + "edit cell accept");
 
   // this cell can be edited, but stopEditing(false) means don't accept the change.
   tree.startEditing(1, ecolumn);
   inputField.value = "Second Value";
   tree.stopEditing(false);
--- a/toolkit/content/widgets/textbox.xml
+++ b/toolkit/content/widgets/textbox.xml
@@ -525,17 +525,17 @@
         <getter><![CDATA[
           if (!this._spellCheckInitialized) {
             this._spellCheckInitialized = true;
 
             if (ChromeUtils.getClassName(document) != "XULDocument")
               return null;
 
             var textbox = document.getBindingParent(this);
-            if (!textbox || !(textbox instanceof Ci.nsIDOMXULTextBoxElement))
+            if (!textbox || textbox.localName != "textbox")
               return null;
 
             try {
               ChromeUtils.import("resource://gre/modules/InlineSpellChecker.jsm", this);
               this.InlineSpellCheckerUI = new this.InlineSpellChecker(textbox.editor);
             } catch (ex) { }
           }
 
--- a/toolkit/modules/sessionstore/FormData.jsm
+++ b/toolkit/modules/sessionstore/FormData.jsm
@@ -200,17 +200,17 @@ var FormDataInternal = {
       // We do not want to collect credit card numbers.
       if (node instanceof Ci.nsIDOMHTMLInputElement &&
           isValidCCNumber(node.value)) {
         continue;
       }
 
       if (node instanceof Ci.nsIDOMHTMLInputElement ||
           ChromeUtils.getClassName(node) === "HTMLTextAreaElement" ||
-          node instanceof Ci.nsIDOMXULTextBoxElement) {
+          (node.namespaceURI == this.namespaceURIs.xul && node.localName == "textbox")) {
         switch (node.type) {
           case "checkbox":
           case "radio":
             value = node.checked;
             hasDefaultValue = value == node.defaultChecked;
             break;
           case "file":
             value = { type: "file", fileList: node.mozGetFileNameArray() };