From 061cbb0141df513113563c86e5df7c17cd46700f Mon Sep 17 00:00:00 2001
From: Alex Yatskov <alex@foosoft.net>
Date: Sun, 12 Jun 2016 14:32:23 -0700
Subject: Better selection handling, fixing scan length being treated as a
 string.

---
 ext/fg/js/range.js | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

(limited to 'ext/fg/js')

diff --git a/ext/fg/js/range.js b/ext/fg/js/range.js
index 0cf79ddf..f6af7122 100644
--- a/ext/fg/js/range.js
+++ b/ext/fg/js/range.js
@@ -27,16 +27,29 @@ class Range {
     }
 
     setLength(length) {
-        const node   = this.rng.startContainer;
-        const offset = this.rng.startOffset;
+        const end = this.findEnd(this.rng.startContainer, this.rng.startOffset, length);
+        this.rng.setEnd(end.node, end.offset);
+    }
+
+    findEnd(node, offset, length) {
+        if (node.nodeType === 3) {
+            const remainder = node.data.length - offset;
+            if (remainder >= length) {
+                return {node, offset: offset + length};
+            }
+
+            length -= remainder;
+        }
+
+        if (node.childNodes.length > 0) {
+            return this.findEnd(node.childNodes[0], 0, length);
+        }
 
-        length = Math.min(node.length - offset, length);
-        if (length === 0) {
-            return null;
+        if (node.nextSibling !== null) {
+            return this.findEnd(node.nextSibling, 0, length);
         }
 
-        this.rng.setEnd(node, offset + length);
-        return length;
+        return {node, offset: node.data.length};
     }
 
     containsPoint(point) {
-- 
cgit v1.2.3