[FIX] assertion errors in search view when selecting all of a search input's content
authorXavier Morel <xmo@openerp.com>
Tue, 4 Jun 2013 15:05:51 +0000 (17:05 +0200)
committerXavier Morel <xmo@openerp.com>
Tue, 4 Jun 2013 15:05:51 +0000 (17:05 +0200)
Force normalization of the input's root node, Firefox tends to spawn
multiple text node children then create selection ranges over all of
them and worse.

lp bug: https://launchpad.net/bugs/1169945 fixed

bzr revid: xmo@openerp.com-20130604150551-0m0b48aifg9favz8

addons/web/static/src/js/search.js

index e84a947..f0d211f 100644 (file)
@@ -131,6 +131,7 @@ my.InputView = instance.web.Widget.extend({
         paste: 'onPaste',
     },
     getSelection: function () {
+        this.el.normalize();
         // get Text node
         var root = this.el.childNodes[0];
         if (!root || !root.textContent) {
@@ -139,6 +140,16 @@ my.InputView = instance.web.Widget.extend({
             return {start: 0, end: 0};
         }
         var range = window.getSelection().getRangeAt(0);
+        // In Firefox, depending on the way text is selected (drag, double- or
+        // triple-click) the range may start or end on the parent of the
+        // selected text nodeā€½ Check for this condition and fixup the range
+        // note: apparently with C-a this can go even higher?
+        if (range.startContainer === this.el && range.startOffset === 0) {
+            range.setStart(root, 0);
+        }
+        if (range.endContainer === this.el && range.endOffset === 1) {
+            range.setEnd(root, root.length)
+        }
         assert(range.startContainer === root,
                "selection should be in the input view");
         assert(range.endContainer === root,
@@ -149,6 +160,7 @@ my.InputView = instance.web.Widget.extend({
         }
     },
     onKeydown: function (e) {
+        this.el.normalize();
         var sel;
         switch (e.which) {
         // Do not insert newline, but let it bubble so searchview can use it
@@ -186,6 +198,7 @@ my.InputView = instance.web.Widget.extend({
         }
     },
     setCursorAtEnd: function () {
+        this.el.normalize();
         var sel = window.getSelection();
         sel.removeAllRanges();
         var range = document.createRange();
@@ -196,13 +209,14 @@ my.InputView = instance.web.Widget.extend({
         // from about half the link to half the text, paste in search box then
         // hit the left arrow key, getSelection would blow up).
         //
-        // Explicitly selecting only the inner text node (only child node at
-        // this point, though maybe we should assert that) avoiids the issue
+        // Explicitly selecting only the inner text node (only child node
+        // since we've normalized the parent) avoids the issue
         range.selectNode(this.el.childNodes[0]);
         range.collapse(false);
         sel.addRange(range);
     },
     onPaste: function () {
+        this.el.normalize();
         // In MSIE and Webkit, it is possible to get various representations of
         // the clipboard data at this point e.g.
         // window.clipboardData.getData('Text') and
@@ -224,6 +238,7 @@ my.InputView = instance.web.Widget.extend({
             var data = this.$el.text();
             // paste raw text back in
             this.$el.empty().text(data);
+            this.el.normalize();
             // Set the cursor at the end of the text, so the cursor is not lost
             // in some kind of error-spawning limbo.
             this.setCursorAtEnd();