Bug 991427 - Check if the last character of the string is part of a surrogate pair when truncating text for display in the context menu, to avoid splitting surrogate pairs, r=gavin
authorAndrea <andreaio.it@hotmail.it>
Sat, 16 Aug 2014 17:06:10 -0700
changeset 200014 82722ad59732fd355f6bd77d5194ceaa1dab23c3
parent 200007 94ba78a423050deda23c6382fc3aa004d5e89913
child 200015 05f052f7c8946bcd7be6bb4fbf07d953637dffb1
push idunknown
push userunknown
push dateunknown
reviewersgavin
bugs991427
milestone34.0a1
Bug 991427 - Check if the last character of the string is part of a surrogate pair when truncating text for display in the context menu, to avoid splitting surrogate pairs, r=gavin
browser/base/content/nsContextMenu.js
browser/base/content/test/general/browser_bug970746.js
browser/base/content/test/general/browser_bug970746.xhtml
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -1672,18 +1672,25 @@ nsContextMenu.prototype = {
   // Formats the 'Search <engine> for "<selection or link text>"' context menu.
   formatSearchContextItem: function() {
     var menuItem = document.getElementById("context-searchselect");
     var selectedText = this.isTextSelected ? this.textSelected : this.linkText();
 
     // Store searchTerms in context menu item so we know what to search onclick
     menuItem.searchTerms = selectedText;
 
-    if (selectedText.length > 15)
-      selectedText = selectedText.substr(0,15) + this.ellipsis;
+    // If the JS character after our truncation point is a trail surrogate,
+    // include it in the truncated string to avoid splitting a surrogate pair.
+    if (selectedText.length > 15) {
+      let truncLength = 15;
+      let truncChar = selectedText[15].charCodeAt(0);
+      if (truncChar >= 0xDC00 && truncChar <= 0xDFFF)
+        truncLength++;
+      selectedText = selectedText.substr(0,truncLength) + this.ellipsis;
+    }
 
     // Use the current engine if the search bar is visible, the default
     // engine otherwise.
     var engineName = "";
     var ss = Cc["@mozilla.org/browser/search-service;1"].
              getService(Ci.nsIBrowserSearchService);
     if (isElementVisible(BrowserSearch.searchBar))
       engineName = ss.currentEngine.name;
--- a/browser/base/content/test/general/browser_bug970746.js
+++ b/browser/base/content/test/general/browser_bug970746.js
@@ -103,16 +103,23 @@ function test() {
 
     testElement({
       id: "partialLink",
       isSelected: false,
       shouldBeShown: true,
       expectedLabelContents: "A partial link " + ellipsis,
     });
 
+    testElement({
+      id: "surrogatePair",
+      isSelected: true,
+      shouldBeShown: true,
+      expectedLabelContents: "This character\uD83D\uDD25" + ellipsis,
+    });
+
     // cleanup
     document.popupNode = null;
     gBrowser.removeCurrentTab();
     finish();
   }, true);
 
   content.location = "http://mochi.test:8888/browser/browser/base/content/test/general/browser_bug970746.xhtml";
 }
--- a/browser/base/content/test/general/browser_bug970746.xhtml
+++ b/browser/base/content/test/general/browser_bug970746.xhtml
@@ -1,16 +1,20 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <html xmlns="http://www.w3.org/1999/xhtml">
-	<body>
-		<a href="http://mozilla.org" id="link">I'm a link!</a>
-		<a href="http://mozilla.org" id="longLink">I'm a really long link and I should be truncated.</a>
+  <body>
+    <a href="http://mozilla.org" id="link">I'm a link!</a>
+    <a href="http://mozilla.org" id="longLink">I'm a really long link and I should be truncated.</a>
 
-		<span id="plainText">
-			Right clicking me when I'm selected should show the menu item.
-		</span>
-		<span id="mixedContent">
-			I'm some text, and <a href="http://mozilla.org">I'm a link!</a>
-		</span>
+    <span id="plainText">
+      Right clicking me when I'm selected should show the menu item.
+    </span>
+    <span id="mixedContent">
+      I'm some text, and <a href="http://mozilla.org">I'm a link!</a>
+    </span>
 
-		<a href="http://mozilla.org">A partial <span id="partialLink">link selection</span></a>
-	</body>
+    <a href="http://mozilla.org">A partial <span id="partialLink">link selection</span></a>
+
+    <span id="surrogatePair">
+      This characteršŸ”„  shouldn't be truncated. 
+    </span>
+  </body>
 </html>