From 52d7e4f3dbfe27952b1727fdc908a5134ea90004 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 9 May 2024 15:44:02 -0700 Subject: [PATCH 1/2] PR #2514 - Don't split up happy emoji sequences Loosely based on https://phabricator.services.mozilla.com/D25101 Includes changes to `GetEmojiPresentation`, added in e38b57ca. The `EmojiComponent` response includes hair color, skin tone, ZWJ, VS16, Combining Enclosing Keycap, and the Tag unicode characters used for subdivision flag emojis. This means that `IsClusterExtender` should support all these characters, and be forward compatible with any future Unicode changes. This also lets us restructure `ClusterIterator::Next` to check for EmojiComponents after a TextDefault character, without any stupid constants. --- intl/unicharutil/util/nsUnicodeProperties.cpp | 44 ++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/intl/unicharutil/util/nsUnicodeProperties.cpp b/intl/unicharutil/util/nsUnicodeProperties.cpp index 8a2b04a8b0..b9c8b83fb2 100644 --- a/intl/unicharutil/util/nsUnicodeProperties.cpp +++ b/intl/unicharutil/util/nsUnicodeProperties.cpp @@ -152,7 +152,8 @@ IsClusterExtender(uint32_t aCh, uint8_t aCategory) { return ((aCategory >= HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK && aCategory <= HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) || - (aCh >= 0x200c && aCh <= 0x200d) || // ZWJ, ZWNJ + (GetEmojiPresentation(aCh) == EmojiComponent) || + (aCh == 0x200c) || // ZWNJ (aCh >= 0xff9e && aCh <= 0xff9f)); // katakana sound marks } @@ -224,8 +225,25 @@ ClusterIterator::Next() } } + const uint32_t kZWJ = 0x200d; + uint32_t aNextCh = 0; + if (mPos + 1 < mLimit) { + aNextCh = *mPos; + uint32_t aLowCh = *(mPos + 1); + if (NS_IS_HIGH_SURROGATE(aNextCh) && NS_IS_LOW_SURROGATE(aLowCh)) { + aNextCh = SURROGATE_TO_UCS4(aNextCh, aLowCh); + } + } + + bool baseIsEmoji = (GetEmojiPresentation(ch) == EmojiDefault) || + (GetEmojiPresentation(ch) == EmojiComponent) || + (GetEmojiPresentation(ch) == TextDefault && + GetEmojiPresentation(aNextCh) == EmojiComponent); + bool prevWasZwj = false; + while (mPos < mLimit) { ch = *mPos; + size_t chLen = 1; // Check for surrogate pairs; note that isolated surrogates will just // be treated as generic (non-cluster-extending) characters here, @@ -233,16 +251,30 @@ ClusterIterator::Next() if (NS_IS_HIGH_SURROGATE(ch) && mPos < mLimit - 1 && NS_IS_LOW_SURROGATE(*(mPos + 1))) { ch = SURROGATE_TO_UCS4(ch, *(mPos + 1)); + chLen = 2; } - if (!IsClusterExtender(ch)) { + uint32_t aExtCh = 0; + if (mPos + chLen < mLimit) { + aExtCh = *(mPos + chLen); + uint32_t aLowCh = *(mPos + chLen + 1); + if (NS_IS_HIGH_SURROGATE(aExtCh) && NS_IS_LOW_SURROGATE(aLowCh)) { + aExtCh = SURROGATE_TO_UCS4(aExtCh, aLowCh); + } + } + bool extendCluster = + IsClusterExtender(ch) || + (baseIsEmoji && prevWasZwj && + ((GetEmojiPresentation(ch) == EmojiDefault) || + (GetEmojiPresentation(ch) == EmojiComponent) || + (GetEmojiPresentation(ch) == TextDefault && + GetEmojiPresentation(aExtCh) == EmojiComponent))); + if (!extendCluster) { break; } - mPos++; - if (!IS_IN_BMP(ch)) { - mPos++; - } + prevWasZwj = (ch == kZWJ); + mPos += chLen; } NS_ASSERTION(mText < mPos && mPos <= mLimit, From 4a95f9d4183668c072e371aa3990851dfa5d917e Mon Sep 17 00:00:00 2001 From: Basilisk-Dev Date: Fri, 10 May 2024 11:18:06 -0400 Subject: [PATCH 2/2] [Basilisk] fix bug with preferences not working --- .../components/preferences/in-content/applications.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/application/basilisk/components/preferences/in-content/applications.js b/application/basilisk/components/preferences/in-content/applications.js index 07072195ab..f32724d74d 100644 --- a/application/basilisk/components/preferences/in-content/applications.js +++ b/application/basilisk/components/preferences/in-content/applications.js @@ -1086,14 +1086,14 @@ var gApplicationsPane = { handlerInfoWrapper = new HandlerInfoWrapper(mimeType.type, wrappedHandlerInfo); handlerInfoWrapper.handledOnlyByPlugin = true; this._handledTypes[mimeType.type] = handlerInfoWrapper; - #ifdef DEBUG +#ifdef DEBUG console.log("Enumerate MIME type: " + mimeType.type); - #endif +#endif } catch(e) { - #ifdef DEBUG +#ifdef DEBUG console.log("Error fetching MIME type info for " + mimeType.type); console.log(e); - #endif +#endif continue; } }