diff --git a/lib/codemirror.js b/lib/codemirror.js
index 7f9a529977ada3e54f30f90e5d22a133f2a3a1ed..c02a32f2ba31ecd327d36c4075ebc4d889be13db 100644
--- a/lib/codemirror.js
+++ b/lib/codemirror.js
@@ -1646,18 +1646,24 @@
 
     var rect;
     if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
-      while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start;
-      while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end;
-      if (ie && ie_version < 9 && start == 0 && end == mEnd - mStart) {
-        rect = node.parentNode.getBoundingClientRect();
-      } else if (ie && cm.options.lineWrapping) {
-        var rects = range(node, start, end).getClientRects();
-        if (rects.length)
-          rect = rects[bias == "right" ? rects.length - 1 : 0];
-        else
-          rect = nullRect;
-      } else {
-        rect = range(node, start, end).getBoundingClientRect() || nullRect;
+      for (;;) {
+        while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start;
+        while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end;
+        if (ie && ie_version < 9 && start == 0 && end == mEnd - mStart) {
+          rect = node.parentNode.getBoundingClientRect();
+        } else if (ie && cm.options.lineWrapping) {
+          var rects = range(node, start, end).getClientRects();
+          if (rects.length)
+            rect = rects[bias == "right" ? rects.length - 1 : 0];
+          else
+            rect = nullRect;
+        } else {
+          rect = range(node, start, end).getBoundingClientRect() || nullRect;
+        }
+        if (rect.left || rect.right || start == 0) break;
+        end = start;
+        start = start - 1;
+        collapse = "right";
       }
     } else { // If it is a widget, simply get the box for the whole widget.
       if (start > 0) collapse = bias = "right";