Bug 1465875 part 2. Eliminate use of "instanceof nsIDOMNSEditablElement". r=qdot
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 01 Jun 2018 22:35:22 -0400
changeset 475179 7c9969cf727a3885d25453de55101f56134a4a49
parent 475178 3ef0eb8cbf3bade62d66cc607bcc28c043188100
child 475180 51f14f44ca9cb1b51c8874d1a285e3e9de40661e
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersqdot
bugs1465875
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1465875 part 2. Eliminate use of "instanceof nsIDOMNSEditablElement". r=qdot
accessible/tests/browser/shared-head.js
accessible/tests/mochitest/editabletext/editabletext.js
accessible/tests/mochitest/events.js
editor/libeditor/tests/test_bug471722.html
editor/libeditor/tests/test_bug502673.html
mobile/android/chrome/geckoview/GeckoViewSelectionActionContent.js
toolkit/content/tests/chrome/bug451540_window.xul
toolkit/modules/BrowserUtils.jsm
toolkit/modules/Finder.jsm
toolkit/modules/FinderHighlighter.jsm
--- a/accessible/tests/browser/shared-head.js
+++ b/accessible/tests/browser/shared-head.js
@@ -142,18 +142,17 @@ function invokeSetStyle(browser, id, sty
  * @param  {Object}  browser  current "tabbrowser" element
  * @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.localName == "textbox") {
+    if (elm.editor || elm.localName == "textbox") {
       elm.selectionStart = elm.selectionEnd = elm.value.length;
     }
     elm.focus();
   });
 }
 
 /**
  * Load a list of scripts into the test
--- a/accessible/tests/mochitest/editabletext/editabletext.js
+++ b/accessible/tests/mochitest/editabletext/editabletext.js
@@ -195,20 +195,21 @@ function editableTextTest(aID) {
                       getValueChecker(aResStr), testID);
   };
 
   // ////////////////////////////////////////////////////////////////////////////
   // Implementation details.
 
   function getValue() {
     var elm = getNode(aID);
-    if (elm instanceof Ci.nsIDOMNSEditableElement)
+    var elmClass = ChromeUtils.getClassName(elm);
+    if (elmClass === "HTMLTextAreaElement" || elmClass === "HTMLInputElement")
       return elm.value;
 
-    if (ChromeUtils.getClassName(elm) == "HTMLDocument")
+    if (elmClass === "HTMLDocument")
       return elm.body.textContent;
 
     return elm.textContent;
   }
 
   /**
    * Common checkers.
    */
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -1259,18 +1259,17 @@ function synthOpenComboboxKey(aID, aChec
  * Focus invoker.
  */
 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 ||
+    if (this.DOMNode.editor ||
         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";
--- a/editor/libeditor/tests/test_bug471722.html
+++ b/editor/libeditor/tests/test_bug471722.html
@@ -24,20 +24,18 @@ https://bugzilla.mozilla.org/show_bug.cg
     <script type="application/javascript">
 
       /** Test for Bug 471722 **/
     
       SimpleTest.waitForExplicitFinish();
 
       function doTest() {
         var t1 = $("t1");
-        var editor = null;
+        var editor = SpecialPowers.wrap(t1).editor;
 
-        if (t1 instanceof SpecialPowers.Ci.nsIDOMNSEditableElement)
-          editor = SpecialPowers.wrap(t1).editor;
         ok(editor, "able to get editor for the element");
         t1.focus();
         t1.select();
 
         try {
 
           // Cut the initial text in the textbox
           ok(editor.canCut(), "can cut text");
--- a/editor/libeditor/tests/test_bug502673.html
+++ b/editor/libeditor/tests/test_bug502673.html
@@ -28,70 +28,64 @@ https://bugzilla.mozilla.org/show_bug.cg
       SimpleTest.waitForExplicitFinish();
 
       function listener() {
       }
 
       listener.prototype =
       {
         NotifyDocumentWillBeDestroyed: function () {
-          if (this.input instanceof SpecialPowers.Ci.nsIDOMNSEditableElement) {
-            var editor = SpecialPowers.wrap(this.input).editor;
-            editor.removeDocumentStateListener(this);
-          }
+          var editor = SpecialPowers.wrap(this.input).editor;
+          editor.removeDocumentStateListener(this);
         },
 
         NotifyDocumentCreated: function () {
         },
 
         NotifyDocumentStateChanged: function (aNowDirty) {
-          if (this.input instanceof SpecialPowers.Ci.nsIDOMNSEditableElement) {
-            var editor = SpecialPowers.wrap(this.input).editor;
-            editor.removeDocumentStateListener(this);
-          }
+          var editor = SpecialPowers.wrap(this.input).editor;
+          editor.removeDocumentStateListener(this);
         },
 
         QueryInterface: SpecialPowers.wrapCallback(function(iid) {
           if (iid.equals(SpecialPowers.Ci.nsIDocumentStateListener) ||
               iid.equals(SpecialPowers.Ci.nsISupports))
             return this;
           throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
         }),
       };
 
       function doTest() {
         var input = document.getElementById("ip");
-        if (input instanceof SpecialPowers.Ci.nsIDOMNSEditableElement) {
-          // Add multiple listeners to the same editor
-          var editor = SpecialPowers.wrap(input).editor;
-          var listener1 = new listener();
-          listener1.input = input;
-          var listener2 = new listener();
-          listener2.input = input;
-          var listener3 = new listener();
-          listener3.input = input;
-          editor.addDocumentStateListener(listener1);
-          editor.addDocumentStateListener(listener2);
-          editor.addDocumentStateListener(listener3);
+
+        // Add multiple listeners to the same editor
+        var editor = SpecialPowers.wrap(input).editor;
+        var listener1 = new listener();
+        listener1.input = input;
+        var listener2 = new listener();
+        listener2.input = input;
+        var listener3 = new listener();
+        listener3.input = input;
+        editor.addDocumentStateListener(listener1);
+        editor.addDocumentStateListener(listener2);
+        editor.addDocumentStateListener(listener3);
 
-          // Test 1. Fire NotifyDocumentStateChanged notifications where the
-          // listeners remove themselves
-          input.value = "mozilla";
-          editor.undo(1);
+        // Test 1. Fire NotifyDocumentStateChanged notifications where the
+        // listeners remove themselves
+        input.value = "mozilla";
+        editor.undo(1);
 
-          // Report success if we get here - clearly we didn't crash
-          ok(true, "Multiple listeners removed themselves after " +
-                   "NotifyDocumentStateChanged notifications - didn't crash");
+        // Report success if we get here - clearly we didn't crash
+        ok(true, "Multiple listeners removed themselves after " +
+                 "NotifyDocumentStateChanged notifications - didn't crash");
 
-         // Add the listeners again for the next test
-         editor.addDocumentStateListener(listener1);
-         editor.addDocumentStateListener(listener2);
-         editor.addDocumentStateListener(listener3);
-
-        }
+        // Add the listeners again for the next test
+        editor.addDocumentStateListener(listener1);
+        editor.addDocumentStateListener(listener2);
+        editor.addDocumentStateListener(listener3);
         
         // Test 2. Fire NotifyDocumentWillBeDestroyed notifications where the
         // listeners remove themselves (though in the real world, listeners
         // shouldn't do this as nsEditor::PreDestroy removes them as
         // listeners anyway)
         document.body.removeChild(input);
         ok(true, "Multiple listeners removed themselves after " +
                  "NotifyDocumentWillBeDestroyed notifications - didn't crash");
--- a/mobile/android/chrome/geckoview/GeckoViewSelectionActionContent.js
+++ b/mobile/android/chrome/geckoview/GeckoViewSelectionActionContent.js
@@ -72,17 +72,17 @@ class GeckoViewSelectionActionContent ex
     return win && win.HTMLInputElement &&
            focus instanceof win.HTMLInputElement &&
            !focus.mozIsTextField(/* excludePassword */ true);
   }
 
   _getSelectionController(aEvent) {
     if (aEvent.selectionEditable) {
       const focus = aEvent.target.activeElement;
-      if (focus instanceof Ci.nsIDOMNSEditableElement && focus.editor) {
+      if (focus.editor) {
         return focus.editor.selectionController;
       }
     }
 
     return aEvent.target.defaultView
                  .QueryInterface(Ci.nsIInterfaceRequestor)
                  .getInterface(Ci.nsIDocShell)
                  .QueryInterface(Ci.nsIInterfaceRequestor)
--- a/toolkit/content/tests/chrome/bug451540_window.xul
+++ b/toolkit/content/tests/chrome/bug451540_window.xul
@@ -110,17 +110,19 @@
         Assert.equal(selection.rangeCount, expectedRangeCount, message);
       });
     }
 
     async function testInput(elementId, testTypeText) {
       let isEditableElement = await ContentTask.spawn(gBrowser, elementId, async function(elementId) {
         let doc = content.document;
         let element = doc.getElementById(elementId);
-        return element instanceof Ci.nsIDOMNSEditableElement;
+        let elementClass = ChromeUtils.getClassName(element);
+        return elementClass === "HTMLInputElement" ||
+               elementClass === "HTMLTextAreaElement";
       });
       if (!isEditableElement) {
         return;
       }
 
       // Initialize the findbar
       let matchCase = gFindBar.getElement("find-case-sensitive");
       if (matchCase.checked) {
--- a/toolkit/modules/BrowserUtils.jsm
+++ b/toolkit/modules/BrowserUtils.jsm
@@ -480,17 +480,17 @@ var BrowserUtils = {
     let selection = focusedWindow.getSelection();
     let selectionStr = selection.toString();
     let fullText;
 
     let url;
     let linkText;
 
     // try getting a selected text in text input.
-    if (!selectionStr && focusedElement instanceof Ci.nsIDOMNSEditableElement) {
+    if (!selectionStr && focusedElement) {
       // Don't get the selection for password fields. See bug 565717.
       if (ChromeUtils.getClassName(focusedElement) === "HTMLTextAreaElement" ||
           (ChromeUtils.getClassName(focusedElement) === "HTMLInputElement" &&
            focusedElement.mozIsTextField(true))) {
         selection = focusedElement.editor.selection;
         selectionStr = selection.toString();
       }
     }
--- a/toolkit/modules/Finder.jsm
+++ b/toolkit/modules/Finder.jsm
@@ -251,18 +251,17 @@ Finder.prototype = {
     let focusedWindow = {};
     let focusedElement =
       Services.focus.getFocusedElementForWindow(this._getWindow(), true,
                                                 focusedWindow);
     focusedWindow = focusedWindow.value;
 
     let selText;
 
-    if (focusedElement instanceof Ci.nsIDOMNSEditableElement &&
-        focusedElement.editor) {
+    if (focusedElement && focusedElement.editor) {
       // The user may have a selection in an input or textarea.
       selText = focusedElement.editor.selectionController
         .getSelection(Ci.nsISelectionController.SELECTION_NORMAL)
         .toString();
     } else {
       // Look for any selected text on the actual page.
       selText = focusedWindow.getSelection().toString();
     }
@@ -484,17 +483,17 @@ Finder.prototype = {
     if (!win)
       return null;
 
     let selection = win.getSelection();
     if (!selection.rangeCount || selection.isCollapsed) {
       // The selection can be into an input or a textarea element.
       let nodes = win.document.querySelectorAll("input, textarea");
       for (let node of nodes) {
-        if (node instanceof Ci.nsIDOMNSEditableElement && node.editor) {
+        if (node.editor) {
           try {
             let sc = node.editor.selectionController;
             selection = sc.getSelection(Ci.nsISelectionController.SELECTION_NORMAL);
             if (selection.rangeCount && !selection.isCollapsed) {
               break;
             }
           } catch (e) {
             // If this textarea is hidden, then its selection controller might
--- a/toolkit/modules/FinderHighlighter.jsm
+++ b/toolkit/modules/FinderHighlighter.jsm
@@ -1392,25 +1392,26 @@ FinderHighlighter.prototype = {
     window.document.removeEventListener("visibilitychange", dict.highlightListeners[5]);
 
     dict.highlightListeners = null;
   },
 
   /**
    * For a given node returns its editable parent or null if there is none.
    * It's enough to check if node is a text node and its parent's parent is
-   * instance of nsIDOMNSEditableElement.
+   * an input or textarea.
    *
    * @param node the node we want to check
    * @returns the first node in the parent chain that is editable,
    *          null if there is no such node
    */
   _getEditableNode(node) {
     if (node.nodeType === node.TEXT_NODE && node.parentNode && node.parentNode.parentNode &&
-        node.parentNode.parentNode instanceof Ci.nsIDOMNSEditableElement) {
+        (ChromeUtils.getClassName(node.parentNode.parentNode) === "HTMLInputElement" ||
+         ChromeUtils.getClassName(node.parentNode.parentNode) === "HTMLTextAreaElement")) {
       return node.parentNode.parentNode;
     }
     return null;
   },
 
   /**
    * Add ourselves as an nsIEditActionListener and nsIDocumentStateListener for
    * a given editor