Bug 1423122 - Use the correct selection object in the getSelectionInfo when an input element is selected r=Felipe a=gchang
authorThom Chiovoloni <tchiovoloni@mozilla.com>
Wed, 06 Dec 2017 15:27:46 -0500
changeset 445316 23dd8e97b482d748b5c5ebea0a1d9d679bd66866
parent 445315 df953324066b58824a34bcdedf7704674452b60d
child 445317 f8ae2687ccc18da13270339d5a0c19fb41c72cb0
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersFelipe, gchang
bugs1423122
milestone58.0
Bug 1423122 - Use the correct selection object in the getSelectionInfo when an input element is selected r=Felipe a=gchang MozReview-Commit-ID: L8nANaiYfyc
toolkit/modules/BrowserUtils.jsm
toolkit/modules/tests/browser/browser.ini
toolkit/modules/tests/browser/browser_BrowserUtils.js
toolkit/modules/tests/browser/file_getSelectionDetails_inputs.html
--- a/toolkit/modules/BrowserUtils.jsm
+++ b/toolkit/modules/BrowserUtils.jsm
@@ -487,31 +487,32 @@ this.BrowserUtils = {
     let focusedWindow = {};
     let focusedElement = Services.focus.getFocusedElementForWindow(topWindow, true, focusedWindow);
     focusedWindow = focusedWindow.value;
 
     let selection = focusedWindow.getSelection();
     let selectionStr = selection.toString();
     let fullText;
 
-    let collapsed = selection.isCollapsed;
-
     let url;
     let linkText;
 
     // try getting a selected text in text input.
     if (!selectionStr && focusedElement instanceof Ci.nsIDOMNSEditableElement) {
       // Don't get the selection for password fields. See bug 565717.
       if (ChromeUtils.getClassName(focusedElement) === "HTMLTextAreaElement" ||
           (focusedElement instanceof Ci.nsIDOMHTMLInputElement &&
            focusedElement.mozIsTextField(true))) {
-        selectionStr = focusedElement.editor.selection.toString();
+        selection = focusedElement.editor.selection;
+        selectionStr = selection.toString();
       }
     }
 
+    let collapsed = selection.isCollapsed;
+
     if (selectionStr) {
       // Have some text, let's figure out if it looks like a URL that isn't
       // actually a link.
       linkText = selectionStr.trim();
       if (/^(?:https?|ftp):/i.test(linkText)) {
         try {
           url = this.makeURI(linkText);
         } catch (ex) {}
--- a/toolkit/modules/tests/browser/browser.ini
+++ b/toolkit/modules/tests/browser/browser.ini
@@ -6,32 +6,34 @@ support-files =
   testremotepagemanager2.html
   file_FinderIframeTest.html
   file_FinderSample.html
   file_WebNavigation_page1.html
   file_WebNavigation_page2.html
   file_WebNavigation_page3.html
   file_WebRequest_page1.html
   file_WebRequest_page2.html
+  file_getSelectionDetails_inputs.html
   file_image_good.png
   file_image_bad.png
   file_image_redirect.png
   file_style_good.css
   file_style_bad.css
   file_style_redirect.css
   file_script_good.js
   file_script_bad.js
   file_script_redirect.js
   file_script_xhr.js
   head.js
   WebRequest_dynamic.sjs
   WebRequest_redirection.sjs
 
 [browser_AsyncPrefs.js]
 [browser_Battery.js]
+[browser_BrowserUtils.js]
 [browser_Deprecated.js]
 [browser_Finder.js]
 [browser_Finder_hidden_textarea.js]
 [browser_Finder_offscreen_text.js]
 [browser_Finder_pointer_events_none.js]
 [browser_FinderHighlighter.js]
 skip-if = debug || os = "linux"
 [browser_FinderHighlighter2.js]
new file mode 100644
--- /dev/null
+++ b/toolkit/modules/tests/browser/browser_BrowserUtils.js
@@ -0,0 +1,49 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+Cu.import("resource://gre/modules/BrowserUtils.jsm");
+
+add_task(async function test_getSelectionDetails_input() {
+  // Mostly a regression test for bug 1420560
+  const url = kFixtureBaseURL + "file_getSelectionDetails_inputs.html";
+  await BrowserTestUtils.withNewTab({ gBrowser, url }, async browser => {
+    await ContentTask.spawn(browser, null, () => {
+      function checkSelection({ id, text, linkURL }) {
+        content.document.getElementById(id).select();
+        // It seems that when running as a test, the previous line will set
+        // the both the window's selection and the input's selection to contain
+        // the input's text. Outside of tests, only the input's selection seems
+        // to be updated, so we explicitly clear the window's selection to
+        // ensure we're doing the right thing in the case that only the input's
+        // selection is present.
+        content.getSelection().removeAllRanges();
+        let info = BrowserUtils.getSelectionDetails(content);
+        Assert.equal(text, info.text);
+        Assert.ok(!info.collapsed);
+        Assert.equal(linkURL, info.linkURL);
+      }
+
+      checkSelection({
+        id: "url-no-scheme",
+        text: "test.example.com",
+        linkURL: "http://test.example.com/"
+      });
+      checkSelection({
+        id: "url-with-scheme",
+        text: "https://test.example.com",
+        linkURL: "https://test.example.com/"
+      });
+      checkSelection({
+        id: "not-url",
+        text: "foo. bar",
+        linkURL: null
+      });
+      checkSelection({
+        id: "not-url-number",
+        text: "3.5",
+        linkURL: null
+      });
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/modules/tests/browser/file_getSelectionDetails_inputs.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <input id="url-no-scheme" value="test.example.com" >
+    <input id="url-with-scheme" value="https://test.example.com">
+    <input id="not-url" value="foo. bar">
+    <input id="not-url-number" value="3.5">
+  </body>
+</html>
\ No newline at end of file