Bug 1286464 part.4 ContentEventHandler::SetRangeFromFlatTextOffset() should set end of the range to after a line break when the range is end between a set of native line breakers r=smaug draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 28 Jul 2016 17:23:47 +0900
changeset 400160 b7933554c2a5bf51b8faabe3a96d006971510e0a
parent 400159 635cec95ee9f3d73f619186925464ae17010e929
child 400161 98021e68cd0150149e6417c5a8f91979f5baad76
push id26081
push usermasayuki@d-toybox.com
push dateFri, 12 Aug 2016 17:11:29 +0000
reviewerssmaug
bugs1286464
milestone51.0a1
Bug 1286464 part.4 ContentEventHandler::SetRangeFromFlatTextOffset() should set end of the range to after a line break when the range is end between a set of native line breakers r=smaug Currently, ContentEventHandler::SetRangeFromFlatTextOffset() sets end point to before a line breaker when the end of queried range is between a set of native line breakers (i.e., "\r]\n" on Windows). This causes unexpected empty range (e.g., "[]\n") when it queries a text rect at [\r]\n. Therefore, it should select an XP line breaker in such case (i.e., the range should be "[\n]" when it queries "[\r]\n" or "\r[\n]"). Note that we don't need to do anything at setting selection start because it's always aligned to before the line breaker. MozReview-Commit-ID: 6ht8QNAhibY
dom/events/ContentEventHandler.cpp
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -1066,17 +1066,29 @@ ContentEventHandler::SetRangeFromFlatTex
     // range.
     if (endOffset <= offset + textLength) {
       MOZ_ASSERT(startSet,
         "The start of the range should've been set already");
       if (content->IsNodeOfType(nsINode::eTEXT)) {
         // Rule #2.1: ]textNode or text]Node or textNode]
         uint32_t xpOffset = endOffset - offset;
         if (aLineBreakType == LINE_BREAK_TYPE_NATIVE) {
-          xpOffset = ConvertToXPOffset(content, xpOffset);
+          uint32_t xpOffsetCurrent = ConvertToXPOffset(content, xpOffset);
+          if (xpOffset && GetBRLength(aLineBreakType) > 1) {
+            MOZ_ASSERT(GetBRLength(aLineBreakType) == 2);
+            uint32_t xpOffsetPre = ConvertToXPOffset(content, xpOffset - 1);
+            // If previous character's XP offset is same as current character's,
+            // it means that the end offset is between \r and \n.  So, the
+            // range end should be after the \n.
+            if (xpOffsetPre == xpOffsetCurrent) {
+              xpOffset = xpOffsetCurrent + 1;
+            } else {
+              xpOffset = xpOffsetCurrent;
+            }
+          }
         }
         if (aExpandToClusterBoundaries) {
           rv = ExpandToClusterBoundary(content, true, &xpOffset);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
         }
         NS_ASSERTION(xpOffset <= INT32_MAX,