From 5bed2b0138029aa61b43d17cd5cc80b76ebd2a6a Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Fri, 24 May 2019 08:10:55 +0000 Subject: [PATCH] Bug 1553378 - Devirtualize calls to GetText() / TextLength() when we know we have a Text node. r=smaug,jfkthame Differential Revision: https://phabricator.services.mozilla.com/D32100 --HG-- extra : moz-landing-system : lando --- dom/base/CharacterData.cpp | 3 +- dom/base/CharacterData.h | 6 +-- dom/base/DirectionalityUtils.cpp | 31 +++++------ dom/base/DirectionalityUtils.h | 2 +- dom/base/Selection.cpp | 4 +- dom/base/nsContentUtils.cpp | 3 +- dom/base/nsRange.cpp | 4 +- dom/events/ContentEventHandler.cpp | 74 ++++++++++---------------- dom/svg/SVGTextContentElement.cpp | 2 +- editor/libeditor/HTMLEditRules.cpp | 2 +- editor/libeditor/TextEditor.cpp | 2 +- editor/libeditor/WSRunObject.cpp | 18 +++---- layout/base/RestyleManager.cpp | 2 +- layout/base/nsBidiPresUtils.cpp | 4 +- layout/base/nsCSSFrameConstructor.cpp | 37 +++++-------- layout/base/nsCSSFrameConstructor.h | 4 +- layout/base/nsLayoutUtils.cpp | 2 +- layout/forms/nsTextControlFrame.cpp | 3 +- layout/generic/nsFontInflationData.cpp | 7 +-- layout/generic/nsTextFrame.cpp | 59 ++++++++++---------- layout/generic/nsTextFrame.h | 9 +++- layout/generic/nsTextFrameUtils.cpp | 4 +- layout/generic/nsTextFrameUtils.h | 8 ++- layout/svg/SVGTextFrame.cpp | 14 +++-- 24 files changed, 141 insertions(+), 163 deletions(-) diff --git a/dom/base/CharacterData.cpp b/dom/base/CharacterData.cpp index 8cb03bd21de0..bcfb50a80723 100644 --- a/dom/base/CharacterData.cpp +++ b/dom/base/CharacterData.cpp @@ -251,7 +251,8 @@ nsresult CharacterData::SetTextInternal( Directionality oldDir = eDir_NotSet; bool dirAffectsAncestor = (NodeType() == TEXT_NODE && - TextNodeWillChangeDirection(this, &oldDir, aOffset)); + TextNodeWillChangeDirection(static_cast(this), &oldDir, + aOffset)); if (aOffset == 0 && endOffset == textLength) { // Replacing whole text or old text was empty. Don't bother to check for diff --git a/dom/base/CharacterData.h b/dom/base/CharacterData.h index 98e6d4e80e32..78be2096f8da 100644 --- a/dom/base/CharacterData.h +++ b/dom/base/CharacterData.h @@ -117,10 +117,10 @@ class CharacterData : public nsIContent { } const nsTextFragment* GetText() override { return &mText; } + uint32_t TextLength() const final { return TextDataLength(); } const nsTextFragment& TextFragment() const { return mText; } - - uint32_t TextLength() const final { return TextDataLength(); } + uint32_t TextDataLength() const { return mText.GetLength(); } /** * Set the text to the given value. If aNotify is true then @@ -197,8 +197,6 @@ class CharacterData : public nsIContent { void ReplaceData(uint32_t aOffset, uint32_t aCount, const nsAString& aData, ErrorResult& rv); - uint32_t TextDataLength() const { return mText.GetLength(); } - //---------------------------------------- #ifdef DEBUG diff --git a/dom/base/DirectionalityUtils.cpp b/dom/base/DirectionalityUtils.cpp index 62827a174082..2989f9b896af 100644 --- a/dom/base/DirectionalityUtils.cpp +++ b/dom/base/DirectionalityUtils.cpp @@ -378,14 +378,14 @@ static Directionality GetDirectionFromText(const char* aText, return eDir_NotSet; } -static Directionality GetDirectionFromText(const nsTextFragment* aFrag, +static Directionality GetDirectionFromText(const Text* aTextNode, uint32_t* aFirstStrong = nullptr) { - if (aFrag->Is2b()) { - return GetDirectionFromText(aFrag->Get2b(), aFrag->GetLength(), - aFirstStrong); + const nsTextFragment* frag = &aTextNode->TextFragment(); + if (frag->Is2b()) { + return GetDirectionFromText(frag->Get2b(), frag->GetLength(), aFirstStrong); } - return GetDirectionFromText(aFrag->Get1b(), aFrag->GetLength(), aFirstStrong); + return GetDirectionFromText(frag->Get1b(), frag->GetLength(), aFirstStrong); } static nsTextNode* WalkDescendantsAndGetDirectionFromText( @@ -405,12 +405,12 @@ static nsTextNode* WalkDescendantsAndGetDirectionFromText( for (uint32_t i = 0; i < assignedNodes.Length(); ++i) { nsIContent* assignedNode = assignedNodes[i]->AsContent(); if (assignedNode->NodeType() == nsINode::TEXT_NODE) { + auto text = static_cast(assignedNode); if (assignedNode != aSkip) { - Directionality textNodeDir = - GetDirectionFromText(assignedNode->GetText()); + Directionality textNodeDir = GetDirectionFromText(text); if (textNodeDir != eDir_NotSet) { *aDirectionality = textNodeDir; - return static_cast(assignedNode); + return text; } } } else if (assignedNode->IsElement() && @@ -426,10 +426,11 @@ static nsTextNode* WalkDescendantsAndGetDirectionFromText( } if (child->NodeType() == nsINode::TEXT_NODE && child != aSkip) { - Directionality textNodeDir = GetDirectionFromText(child->GetText()); + auto text = static_cast(child); + Directionality textNodeDir = GetDirectionFromText(text); if (textNodeDir != eDir_NotSet) { *aDirectionality = textNodeDir; - return static_cast(child); + return text; } } child = child->GetNextNode(aRoot); @@ -1052,7 +1053,7 @@ void SetAncestorDirectionIfAuto(nsTextNode* aTextNode, Directionality aDir, } } -bool TextNodeWillChangeDirection(nsIContent* aTextNode, Directionality* aOldDir, +bool TextNodeWillChangeDirection(nsTextNode* aTextNode, Directionality* aOldDir, uint32_t aOffset) { if (!NodeAffectsDirAutoAncestor(aTextNode)) { nsTextNodeDirectionalityMap::EnsureMapIsClearFor(aTextNode); @@ -1060,13 +1061,13 @@ bool TextNodeWillChangeDirection(nsIContent* aTextNode, Directionality* aOldDir, } uint32_t firstStrong; - *aOldDir = GetDirectionFromText(aTextNode->GetText(), &firstStrong); + *aOldDir = GetDirectionFromText(aTextNode, &firstStrong); return (aOffset <= firstStrong); } void TextNodeChangedDirection(nsTextNode* aTextNode, Directionality aOldDir, bool aNotify) { - Directionality newDir = GetDirectionFromText(aTextNode->GetText()); + Directionality newDir = GetDirectionFromText(aTextNode); if (newDir == eDir_NotSet) { if (aOldDir != eDir_NotSet && aTextNode->HasTextNodeDirectionalityMap()) { // This node used to have a strong directional character but no @@ -1102,7 +1103,7 @@ void SetDirectionFromNewTextNode(nsTextNode* aTextNode) { aTextNode->SetAncestorHasDirAuto(); } - Directionality dir = GetDirectionFromText(aTextNode->GetText()); + Directionality dir = GetDirectionFromText(aTextNode); if (dir != eDir_NotSet) { SetAncestorDirectionIfAuto(aTextNode, dir); } @@ -1114,7 +1115,7 @@ void ResetDirectionSetByTextNode(nsTextNode* aTextNode) { return; } - Directionality dir = GetDirectionFromText(aTextNode->GetText()); + Directionality dir = GetDirectionFromText(aTextNode); if (dir != eDir_NotSet && aTextNode->HasTextNodeDirectionalityMap()) { nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode, aTextNode); } diff --git a/dom/base/DirectionalityUtils.h b/dom/base/DirectionalityUtils.h index 411a5d11e467..5ebac948960c 100644 --- a/dom/base/DirectionalityUtils.h +++ b/dom/base/DirectionalityUtils.h @@ -96,7 +96,7 @@ void WalkDescendantsClearAncestorDirAuto(nsIContent* aContent); * * @return whether the text node affects the directionality of any element */ -bool TextNodeWillChangeDirection(nsIContent* aTextNode, Directionality* aOldDir, +bool TextNodeWillChangeDirection(nsTextNode* aTextNode, Directionality* aOldDir, uint32_t aOffset); /** diff --git a/dom/base/Selection.cpp b/dom/base/Selection.cpp index e99bb99eb0a8..f3075cb39e77 100644 --- a/dom/base/Selection.cpp +++ b/dom/base/Selection.cpp @@ -1474,8 +1474,8 @@ void Selection::SelectFramesForContent(nsIContent* aContent, bool aSelected) { // as a text frame. if (frame->IsTextFrame()) { nsTextFrame* textFrame = static_cast(frame); - textFrame->SetSelectedRange(0, aContent->GetText()->GetLength(), aSelected, - mSelectionType); + textFrame->SetSelectedRange(0, textFrame->TextFragment()->GetLength(), + aSelected, mSelectionType); } else { frame->InvalidateFrameSubtree(); // frame continuations? } diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 8623f415caa0..b9090e579f41 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -9056,8 +9056,7 @@ bool nsContentUtils::SerializeNodeToMarkup(nsINode* aRoot, case nsINode::TEXT_NODE: case nsINode::CDATA_SECTION_NODE: { - const nsTextFragment* text = - static_cast(current)->GetText(); + const nsTextFragment* text = ¤t->AsText()->TextFragment(); nsIContent* parent = current->GetParent(); if (ShouldEscape(parent)) { AppendEncodedCharacters(text, builder); diff --git a/dom/base/nsRange.cpp b/dom/base/nsRange.cpp index 7c07b937f7a2..81f1f969ab4a 100644 --- a/dom/base/nsRange.cpp +++ b/dom/base/nsRange.cpp @@ -2875,7 +2875,7 @@ void nsRange::CollectClientRectsAndText( if (node == startContainer) { int32_t offset = startContainer == endContainer ? static_cast(aEndOffset) - : content->GetText()->GetLength(); + : content->AsText()->TextDataLength(); GetPartialTextRect(aCollector, aTextList, content, static_cast(aStartOffset), offset, aClampToEdge, aFlushLayout); @@ -2989,7 +2989,7 @@ nsresult nsRange::GetUsedFontFaces(nsLayoutUtils::UsedFontFaceList& aResult, if (node == startContainer) { int32_t offset = startContainer == endContainer ? mEnd.Offset() - : content->GetText()->GetLength(); + : content->AsText()->TextDataLength(); nsLayoutUtils::GetFontFacesForText(frame, mStart.Offset(), offset, true, aResult, fontFaces, aMaxRanges, aSkipCollapsedWhitespace); diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp index 5132659025a5..cca1affa5589 100644 --- a/dom/events/ContentEventHandler.cpp +++ b/dom/events/ContentEventHandler.cpp @@ -506,33 +506,19 @@ static void ConvertToNativeNewlines(nsString& aString) { #endif } -static void AppendString(nsAString& aString, nsIContent* aContent) { - NS_ASSERTION(aContent->IsText(), "aContent is not a text node!"); - const nsTextFragment* text = aContent->GetText(); - if (!text) { - return; - } - text->AppendTo(aString); +static void AppendString(nsAString& aString, Text* aText) { + aText->TextFragment().AppendTo(aString); } -static void AppendSubString(nsAString& aString, nsIContent* aContent, - uint32_t aXPOffset, uint32_t aXPLength) { - NS_ASSERTION(aContent->IsText(), "aContent is not a text node!"); - const nsTextFragment* text = aContent->GetText(); - if (!text) { - return; - } - text->AppendTo(aString, int32_t(aXPOffset), int32_t(aXPLength)); +static void AppendSubString(nsAString& aString, Text* aText, uint32_t aXPOffset, + uint32_t aXPLength) { + aText->TextFragment().AppendTo(aString, int32_t(aXPOffset), + int32_t(aXPLength)); } #if defined(XP_WIN) -static uint32_t CountNewlinesInXPLength(nsIContent* aContent, - uint32_t aXPLength) { - NS_ASSERTION(aContent->IsText(), "aContent is not a text node!"); - const nsTextFragment* text = aContent->GetText(); - if (!text) { - return 0; - } +static uint32_t CountNewlinesInXPLength(Text* aText, uint32_t aXPLength) { + const nsTextFragment* text = aText->TextFragment(); // For automated tests, we should abort on debug build. MOZ_ASSERT(aXPLength == UINT32_MAX || aXPLength <= text->GetLength(), "aXPLength is out-of-bounds"); @@ -546,13 +532,9 @@ static uint32_t CountNewlinesInXPLength(nsIContent* aContent, return newlines; } -static uint32_t CountNewlinesInNativeLength(nsIContent* aContent, +static uint32_t CountNewlinesInNativeLength(Text* aText, uint32_t aNativeLength) { - NS_ASSERTION(aContent->IsText(), "aContent is not a text node!"); - const nsTextFragment* text = aContent->GetText(); - if (!text) { - return 0; - } + const nsTextFragment* text = &aText->TextFragment(); // For automated tests, we should abort on debug build. MOZ_ASSERT( (aNativeLength == UINT32_MAX || aNativeLength <= text->GetLength() * 2), @@ -584,8 +566,9 @@ uint32_t ContentEventHandler::GetNativeTextLength(nsIContent* aContent, if (aStartOffset == aEndOffset) { return 0; } - return GetTextLength(aContent, LINE_BREAK_TYPE_NATIVE, aEndOffset) - - GetTextLength(aContent, LINE_BREAK_TYPE_NATIVE, aStartOffset); + return GetTextLength(aContent->AsText(), LINE_BREAK_TYPE_NATIVE, aEndOffset) - + GetTextLength(aContent->AsText(), LINE_BREAK_TYPE_NATIVE, + aStartOffset); } /* static */ @@ -594,7 +577,7 @@ uint32_t ContentEventHandler::GetNativeTextLength(nsIContent* aContent, if (NS_WARN_IF(!aContent->IsText())) { return 0; } - return GetTextLength(aContent, LINE_BREAK_TYPE_NATIVE, aMaxLength); + return GetTextLength(aContent->AsText(), LINE_BREAK_TYPE_NATIVE, aMaxLength); } /* static */ @@ -630,7 +613,7 @@ uint32_t ContentEventHandler::GetTextLength(nsIContent* aContent, // of the XP newline ("\n"), so XP length is equal to the length of the // native offset plus the number of newlines encountered in the string. (aLineBreakType == LINE_BREAK_TYPE_NATIVE) - ? CountNewlinesInXPLength(aContent, aMaxLength) + ? CountNewlinesInXPLength(aContent->AsText(), aMaxLength) : 0; #else // On other platforms, the native and XP newlines are the same. @@ -651,7 +634,8 @@ static uint32_t ConvertToXPOffset(nsIContent* aContent, // On Windows, the length of a native newline ("\r\n") is twice the length of // the XP newline ("\n"), so XP offset is equal to the length of the native // offset minus the number of newlines encountered in the string. - return aNativeOffset - CountNewlinesInNativeLength(aContent, aNativeOffset); + return aNativeOffset - CountNewlinesInNativeLength(aContent->AsText(), + aNativeOffset); #else // On other platforms, the native and XP newlines are the same. return aNativeOffset; @@ -731,8 +715,7 @@ nsresult ContentEventHandler::GenerateFlatTextContent( } if (startNode == endNode && startNode->IsText()) { - nsIContent* content = startNode->AsContent(); - AppendSubString(aString, content, aRawRange.StartOffset(), + AppendSubString(aString, startNode->AsText(), aRawRange.StartOffset(), aRawRange.EndOffset() - aRawRange.StartOffset()); ConvertToNativeNewlines(aString); return NS_OK; @@ -752,18 +735,17 @@ nsresult ContentEventHandler::GenerateFlatTextContent( if (!node->IsContent()) { continue; } - nsIContent* content = node->AsContent(); - if (content->IsText()) { - if (content == startNode) { - AppendSubString(aString, content, aRawRange.StartOffset(), - content->TextLength() - aRawRange.StartOffset()); - } else if (content == endNode) { - AppendSubString(aString, content, 0, aRawRange.EndOffset()); + if (node->IsText()) { + if (node == startNode) { + AppendSubString(aString, node->AsText(), aRawRange.StartOffset(), + node->AsText()->TextLength() - aRawRange.StartOffset()); + } else if (node == endNode) { + AppendSubString(aString, node->AsText(), 0, aRawRange.EndOffset()); } else { - AppendString(aString, content); + AppendString(aString, node->AsText()); } - } else if (ShouldBreakLineBefore(content, mRootContent)) { + } else if (ShouldBreakLineBefore(node->AsContent(), mRootContent)) { aString.Append(char16_t('\n')); } } @@ -1001,7 +983,7 @@ nsresult ContentEventHandler::ExpandToClusterBoundary(nsIContent* aContent, } // If the frame isn't available, we only can check surrogate pair... - const nsTextFragment* text = aContent->GetText(); + const nsTextFragment* text = &aContent->AsText()->TextFragment(); NS_ENSURE_TRUE(text, NS_ERROR_FAILURE); if (NS_IS_LOW_SURROGATE(text->CharAt(*aXPOffset)) && NS_IS_HIGH_SURROGATE(text->CharAt(*aXPOffset - 1))) { @@ -1864,7 +1846,7 @@ nsresult ContentEventHandler::OnQueryTextRectArray( } // Assign the characters whose rects are computed by the call of // nsTextFrame::GetCharacterRectsInRange(). - AppendSubString(chars, firstContent, firstFrame.mOffsetInNode, + AppendSubString(chars, firstContent->AsText(), firstFrame.mOffsetInNode, charRects.Length()); if (NS_WARN_IF(chars.Length() != charRects.Length())) { return NS_ERROR_UNEXPECTED; diff --git a/dom/svg/SVGTextContentElement.cpp b/dom/svg/SVGTextContentElement.cpp index 6884a8cc9876..b41d691bb0ce 100644 --- a/dom/svg/SVGTextContentElement.cpp +++ b/dom/svg/SVGTextContentElement.cpp @@ -83,7 +83,7 @@ Maybe SVGTextContentElement::GetNonLayoutDependentNumberOfChars() { return Nothing(); } - const nsTextFragment* text = static_cast(n)->GetText(); + const nsTextFragment* text = &n->AsText()->TextFragment(); uint32_t length = text->GetLength(); if (text->Is2b()) { diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index 0fef9d42574a..e087001b98f0 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -2429,7 +2429,7 @@ nsresult HTMLEditRules::WillDeleteSelection( eo--; // Bug 1068979: delete both codepoints if surrogate pair if (so > 0) { - const nsTextFragment* text = nodeAsText->GetText(); + const nsTextFragment* text = &nodeAsText->TextFragment(); if (NS_IS_LOW_SURROGATE(text->CharAt(so)) && NS_IS_HIGH_SURROGATE(text->CharAt(so - 1))) { so--; diff --git a/editor/libeditor/TextEditor.cpp b/editor/libeditor/TextEditor.cpp index 3458dbd5b6ff..10e4da6ede2d 100644 --- a/editor/libeditor/TextEditor.cpp +++ b/editor/libeditor/TextEditor.cpp @@ -587,7 +587,7 @@ nsresult TextEditor::ExtendSelectionForDelete(nsIEditor::EDirection* aAction) { if (insertionPoint.IsInTextNode()) { const nsTextFragment* data = - insertionPoint.GetContainerAsText()->GetText(); + &insertionPoint.GetContainerAsText()->TextFragment(); uint32_t offset = insertionPoint.Offset(); if ((offset > 1 && NS_IS_LOW_SURROGATE(data->CharAt(offset - 1)) && NS_IS_HIGH_SURROGATE(data->CharAt(offset - 2))) || diff --git a/editor/libeditor/WSRunObject.cpp b/editor/libeditor/WSRunObject.cpp index 741facb51765..11e78ef78495 100644 --- a/editor/libeditor/WSRunObject.cpp +++ b/editor/libeditor/WSRunObject.cpp @@ -657,7 +657,7 @@ nsresult WSRunObject::GetWSNodes() { // first look backwards to find preceding ws nodes if (Text* textNode = mScanStartPoint.GetContainerAsText()) { - const nsTextFragment* textFrag = textNode->GetText(); + const nsTextFragment* textFrag = &textNode->TextFragment(); mNodeArray.InsertElementAt(0, textNode); if (!mScanStartPoint.IsStartOfContainer()) { for (uint32_t i = mScanStartPoint.Offset(); i; i--) { @@ -701,10 +701,10 @@ nsresult WSRunObject::GetWSNodes() { } else if (priorNode->IsText() && priorNode->IsEditable()) { RefPtr textNode = priorNode->GetAsText(); mNodeArray.InsertElementAt(0, textNode); - const nsTextFragment* textFrag; - if (!textNode || !(textFrag = textNode->GetText())) { + if (!textNode) { return NS_ERROR_NULL_POINTER; } + const nsTextFragment* textFrag = &textNode->TextFragment(); uint32_t len = textNode->TextLength(); if (len < 1) { @@ -763,7 +763,7 @@ nsresult WSRunObject::GetWSNodes() { // then look ahead to find following ws nodes if (Text* textNode = mScanEndPoint.GetContainerAsText()) { // don't need to put it on list. it already is from code above - const nsTextFragment* textFrag = textNode->GetText(); + const nsTextFragment* textFrag = &textNode->TextFragment(); if (!mScanEndPoint.IsEndOfContainer()) { for (uint32_t i = mScanEndPoint.Offset(); i < textNode->TextLength(); i++) { @@ -808,10 +808,10 @@ nsresult WSRunObject::GetWSNodes() { } else if (nextNode->IsText() && nextNode->IsEditable()) { RefPtr textNode = nextNode->GetAsText(); mNodeArray.AppendElement(textNode); - const nsTextFragment* textFrag; - if (!textNode || !(textFrag = textNode->GetText())) { + if (!textNode) { return NS_ERROR_NULL_POINTER; } + const nsTextFragment* textFrag = &textNode->TextFragment(); uint32_t len = textNode->TextLength(); if (len < 1) { @@ -1510,7 +1510,7 @@ nsresult WSRunObject::InsertNBSPAndRemoveFollowingASCIIWhitespaces( // Now, the text node may have been modified by mutation observer. // So, the NBSP may have gone. if (aPoint.mTextNode->TextDataLength() <= aPoint.mOffset || - aPoint.mTextNode->GetText()->CharAt(aPoint.mOffset) != kNBSP) { + aPoint.mTextNode->TextFragment().CharAt(aPoint.mOffset) != kNBSP) { // This is just preparation of an edit action. Let's return NS_OK. // XXX Perhaps, we should return another success code which indicates // mutation observer touched the DOM tree. However, that should @@ -1640,11 +1640,11 @@ char16_t WSRunObject::GetCharAt(Text* aTextNode, int32_t aOffset) const { // return 0 if we can't get a char, for whatever reason NS_ENSURE_TRUE(aTextNode, 0); - int32_t len = int32_t(aTextNode->TextLength()); + int32_t len = int32_t(aTextNode->TextDataLength()); if (aOffset < 0 || aOffset >= len) { return 0; } - return aTextNode->GetText()->CharAt(aOffset); + return aTextNode->TextFragment().CharAt(aOffset); } template diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index 28258dc1b4d6..fc872e107e42 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -286,7 +286,7 @@ void RestyleManager::CharacterDataChanged( return; } - const nsTextFragment* text = aContent->GetText(); + const nsTextFragment* text = &aContent->AsText()->TextFragment(); const size_t oldLength = aInfo.mChangeStart; const size_t newLength = text->GetLength(); diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index 42a9cda6e94c..880331e21305 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -1277,10 +1277,10 @@ bool nsBidiPresUtils::ChildListMayRequireBidi(nsIFrame* aFirstChild, // Check whether the text frame has any RTL characters; if so, bidi // resolution will be needed. - nsIContent* content = frame->GetContent(); + dom::Text* content = frame->GetContent()->AsText(); if (content != *aCurrContent) { *aCurrContent = content; - const nsTextFragment* txt = content->GetText(); + const nsTextFragment* txt = &content->TextFragment(); if (txt->Is2b() && HasRTLChars(MakeSpan(txt->Get2b(), txt->GetLength()))) { return true; diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index df979a881a30..3bfe23120c66 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -9989,35 +9989,24 @@ static int32_t FirstLetterCount(const nsTextFragment* aFragment) { return count; } -static bool NeedFirstLetterContinuation(nsIContent* aContent) { - MOZ_ASSERT(aContent, "null ptr"); - - bool result = false; - if (aContent) { - const nsTextFragment* frag = aContent->GetText(); - if (frag) { - int32_t flc = FirstLetterCount(frag); - int32_t tl = frag->GetLength(); - if (flc < tl) { - result = true; - } - } - } - return result; +static bool NeedFirstLetterContinuation(Text* aText) { + MOZ_ASSERT(aText, "null ptr"); + int32_t flc = FirstLetterCount(&aText->TextFragment()); + int32_t tl = aText->TextDataLength(); + return flc < tl; } -static bool IsFirstLetterContent(nsIContent* aContent) { - return aContent->TextLength() && !aContent->TextIsOnlyWhitespace(); +static bool IsFirstLetterContent(Text* aText) { + return aText->TextDataLength() && !aText->TextIsOnlyWhitespace(); } /** * Create a letter frame, only make it a floating frame. */ nsFirstLetterFrame* nsCSSFrameConstructor::CreateFloatingLetterFrame( - nsFrameConstructorState& aState, nsIContent* aTextContent, - nsIFrame* aTextFrame, nsContainerFrame* aParentFrame, - ComputedStyle* aParentComputedStyle, ComputedStyle* aComputedStyle, - nsFrameList& aResult) { + nsFrameConstructorState& aState, Text* aTextContent, nsIFrame* aTextFrame, + nsContainerFrame* aParentFrame, ComputedStyle* aParentComputedStyle, + ComputedStyle* aComputedStyle, nsFrameList& aResult) { MOZ_ASSERT(aParentComputedStyle); nsFirstLetterFrame* letterFrame = @@ -10081,9 +10070,7 @@ nsFirstLetterFrame* nsCSSFrameConstructor::CreateFloatingLetterFrame( */ void nsCSSFrameConstructor::CreateLetterFrame( nsContainerFrame* aBlockFrame, nsContainerFrame* aBlockContinuation, - nsIContent* aTextContent, nsContainerFrame* aParentFrame, - nsFrameList& aResult) { - MOZ_ASSERT(aTextContent->IsText(), "aTextContent isn't text"); + Text* aTextContent, nsContainerFrame* aParentFrame, nsFrameList& aResult) { NS_ASSERTION(aBlockFrame->IsBlockFrameOrSubclass(), "Not a block frame?"); // Get a ComputedStyle for the first-letter-frame. @@ -10217,7 +10204,7 @@ void nsCSSFrameConstructor::WrapFramesInFirstLetterFrame( LayoutFrameType frameType = frame->Type(); if (LayoutFrameType::Text == frameType) { // Wrap up first-letter content in a letter frame - nsIContent* textContent = frame->GetContent(); + Text* textContent = frame->GetContent()->AsText(); if (IsFirstLetterContent(textContent)) { // Create letter frame to wrap up the text CreateLetterFrame(aBlockFrame, aBlockContinuation, textContent, diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 85c3b80b3bcc..6f44f8a5382d 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -1920,14 +1920,14 @@ class nsCSSFrameConstructor final : public nsFrameManager { // Methods support :first-letter style nsFirstLetterFrame* CreateFloatingLetterFrame( - nsFrameConstructorState& aState, nsIContent* aTextContent, + nsFrameConstructorState& aState, mozilla::dom::Text* aTextContent, nsIFrame* aTextFrame, nsContainerFrame* aParentFrame, ComputedStyle* aParentComputedStyle, ComputedStyle* aComputedStyle, nsFrameList& aResult); void CreateLetterFrame(nsContainerFrame* aBlockFrame, nsContainerFrame* aBlockContinuation, - nsIContent* aTextContent, + mozilla::dom::Text* aTextContent, nsContainerFrame* aParentFrame, nsFrameList& aResult); void WrapFramesInFirstLetterFrame(nsContainerFrame* aBlockFrame, diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index c217ddfb6c96..396450f5bbe1 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -9363,7 +9363,7 @@ void nsLayoutUtils::AppendFrameTextContent(nsIFrame* aFrame, auto textFrame = static_cast(aFrame); auto offset = textFrame->GetContentOffset(); auto length = textFrame->GetContentLength(); - textFrame->GetContent()->GetText()->AppendTo(aResult, offset, length); + textFrame->TextFragment()->AppendTo(aResult, offset, length); } else { for (nsIFrame* child : aFrame->PrincipalChildList()) { AppendFrameTextContent(child, aResult); diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index bbb1e5dc2009..18f0f1843f15 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -890,8 +890,7 @@ nsresult nsTextControlFrame::SelectAllOrCollapseToEndOfText(bool aSelect) { child = child->GetPreviousSibling(); if (child && child->IsText()) { rootNode = child; - const nsTextFragment* fragment = child->GetText(); - numChildren = fragment ? fragment->GetLength() : 0; + numChildren = child->AsText()->TextDataLength(); } } } diff --git a/layout/generic/nsFontInflationData.cpp b/layout/generic/nsFontInflationData.cpp index 195970948ed2..4f9f8fb77bd0 100644 --- a/layout/generic/nsFontInflationData.cpp +++ b/layout/generic/nsFontInflationData.cpp @@ -258,7 +258,7 @@ void nsFontInflationData::UpdateISize(const ReflowInput& aReflowInput) { if (content && kid == content->GetPrimaryFrame()) { uint32_t len = nsTextFrameUtils:: ComputeApproximateLengthWithWhitespaceCompression( - content, kid->StyleText()); + content->AsText(), kid->StyleText()); if (len != 0) { return kid; } @@ -295,7 +295,8 @@ static uint32_t DoCharCountOfLargestOption(nsIFrame* aContainer) { if (optionChild->IsTextFrame()) { optionResult += nsTextFrameUtils:: ComputeApproximateLengthWithWhitespaceCompression( - optionChild->GetContent(), optionChild->StyleText()); + optionChild->GetContent()->AsText(), + optionChild->StyleText()); } } } @@ -334,7 +335,7 @@ void nsFontInflationData::ScanTextIn(nsIFrame* aFrame) { if (content && kid == content->GetPrimaryFrame()) { uint32_t len = nsTextFrameUtils:: ComputeApproximateLengthWithWhitespaceCompression( - content, kid->StyleText()); + content->AsText(), kid->StyleText()); if (len != 0) { nscoord fontSize = kid->StyleFont()->mFont.size; if (fontSize > 0) { diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 8233a217b8b8..948f027a6fe8 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -676,7 +676,7 @@ void GlyphObserver::NotifyGlyphsChanged() { int32_t nsTextFrame::GetContentEnd() const { nsTextFrame* next = GetNextContinuation(); - return next ? next->GetContentOffset() : mContent->GetText()->GetLength(); + return next ? next->GetContentOffset() : TextFragment()->GetLength(); } struct FlowLengthProperty { @@ -716,7 +716,7 @@ int32_t nsTextFrame::GetInFlowContentLength() { nsTextFrame* nextBidi = LastInFlow()->GetNextContinuation(); int32_t endFlow = - nextBidi ? nextBidi->GetContentOffset() : mContent->TextLength(); + nextBidi ? nextBidi->GetContentOffset() : GetContent()->TextLength(); if (!flowLength) { flowLength = new FlowLengthProperty; @@ -1047,7 +1047,7 @@ class BuildTextRunsScanner { int32_t GetContentEnd() { return mEndFrame ? mEndFrame->GetContentOffset() - : mStartFrame->GetContent()->GetText()->GetLength(); + : mStartFrame->TextFragment()->GetLength(); } }; @@ -1306,7 +1306,7 @@ BuildTextRunsScanner::FindBoundaryResult BuildTextRunsScanner::FindBoundaries( if (aState->mSeenSpaceForLineBreakingOnThisLine) { return FB_CONTINUE; } - const nsTextFragment* frag = textFrame->GetContent()->GetText(); + const nsTextFragment* frag = textFrame->TextFragment(); uint32_t start = textFrame->GetContentOffset(); uint32_t length = textFrame->GetContentLength(); const void* text; @@ -1684,7 +1684,7 @@ void BuildTextRunsScanner::AccumulateRunInfo(nsTextFrame* aFrame) { mMaxTextLength += aFrame->GetContentLength(); } } - mDoubleByteText |= aFrame->GetContent()->GetText()->Is2b(); + mDoubleByteText |= aFrame->TextFragment()->Is2b(); mLastFrame = aFrame; mCommonAncestorWithLastFrame = aFrame->GetParent(); @@ -1705,7 +1705,7 @@ void BuildTextRunsScanner::AccumulateRunInfo(nsTextFrame* aFrame) { static bool HasTerminalNewline(const nsTextFrame* aFrame) { if (aFrame->GetContentLength() == 0) return false; - const nsTextFragment* frag = aFrame->GetContent()->GetText(); + const nsTextFragment* frag = aFrame->TextFragment(); return frag->CharAt(aFrame->GetContentEnd() - 1) == '\n'; } @@ -2244,7 +2244,7 @@ already_AddRefed BuildTextRunsScanner::BuildTextRunForFrames( // Figure out what content is included in this flow. nsIContent* content = f->GetContent(); - const nsTextFragment* frag = content->GetText(); + const nsTextFragment* frag = f->TextFragment(); int32_t contentStart = mappedFlow->mStartFrame->GetContentOffset(); int32_t contentEnd = mappedFlow->GetContentEnd(); int32_t contentLength = contentEnd - contentStart; @@ -2523,8 +2523,7 @@ bool BuildTextRunsScanner::SetupLineBreakerContext(gfxTextRun* aTextRun) { GetCSSWhitespaceToCompressionMode(f, textStyle); // Figure out what content is included in this flow. - nsIContent* content = f->GetContent(); - const nsTextFragment* frag = content->GetText(); + const nsTextFragment* frag = f->TextFragment(); int32_t contentStart = mappedFlow->mStartFrame->GetContentOffset(); int32_t contentEnd = mappedFlow->GetContentEnd(); int32_t contentLength = contentEnd - contentStart; @@ -2579,7 +2578,7 @@ static bool HasCompressedLeadingWhitespace( gfxSkipCharsIterator iter = aIterator; int32_t frameContentOffset = aFrame->GetContentOffset(); - const nsTextFragment* frag = aFrame->GetContent()->GetText(); + const nsTextFragment* frag = aFrame->TextFragment(); while (frameContentOffset < aContentEndOffset && iter.IsOriginalCharSkipped()) { if (IsTrimmableSpace(frag, frameContentOffset, aStyleText)) return true; @@ -3188,7 +3187,7 @@ class MOZ_STACK_CLASS PropertyProvider final mFontGroup(nullptr), mFontMetrics(aFontMetrics), mTextStyle(aFrame->StyleText()), - mFrag(aFrame->GetContent()->GetText()), + mFrag(aFrame->TextFragment()), mLineContainer(nullptr), mFrame(aFrame), mStart(aStart), @@ -4768,7 +4767,7 @@ void nsTextFrame::NotifyNativeAnonymousTextnodeChange(uint32_t aOldLength) { info.mAppend = false; info.mChangeStart = 0; info.mChangeEnd = aOldLength; - info.mReplaceLength = mContent->TextLength(); + info.mReplaceLength = GetContent()->TextLength(); CharacterDataChanged(info); } @@ -7066,7 +7065,7 @@ nsIFrame::ContentOffsets nsTextFrame::GetCharacterOffsetAtFramePointInternal( // ...but don't let selection/insertion-point split two Regional Indicator // chars that are ligated in the textrun to form a single flag symbol. uint32_t offs = extraCluster.GetOriginalOffset(); - const nsTextFragment* frag = GetContent()->GetText(); + const nsTextFragment* frag = TextFragment(); if (offs + 1 < frag->GetLength() && NS_IS_HIGH_SURROGATE(frag->CharAt(offs)) && NS_IS_LOW_SURROGATE(frag->CharAt(offs + 1)) && @@ -7483,7 +7482,7 @@ nsIFrame::FrameSearchResult nsTextFrame::PeekOffsetNoAmount(bool aForward, gfxSkipCharsIterator iter = EnsureTextRun(nsTextFrame::eInflated); if (!mTextRun) return CONTINUE_EMPTY; - TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText()); + TrimmedOffsets trimmed = GetTrimmedOffsets(TextFragment()); // Check whether there are nonskipped characters in the trimmmed range return (iter.ConvertOriginalToSkipped(trimmed.GetEnd()) > iter.ConvertOriginalToSkipped(trimmed.mStart)) @@ -7544,7 +7543,7 @@ class MOZ_STACK_CLASS ClusterIterator { static bool IsAcceptableCaretPosition(const gfxSkipCharsIterator& aIter, bool aRespectClusters, const gfxTextRun* aTextRun, - nsIFrame* aFrame) { + nsTextFrame* aFrame) { if (aIter.IsOriginalCharSkipped()) return false; uint32_t index = aIter.GetSkippedOffset(); if (aRespectClusters && !aTextRun->IsClusterStart(index)) return false; @@ -7556,7 +7555,7 @@ static bool IsAcceptableCaretPosition(const gfxSkipCharsIterator& aIter, // this far because the low surrogate is also marked as non-clusterStart // so we'll return FALSE above.) uint32_t offs = aIter.GetOriginalOffset(); - const nsTextFragment* frag = aFrame->GetContent()->GetText(); + const nsTextFragment* frag = aFrame->TextFragment(); uint32_t ch = frag->CharAt(offs); if (gfxFontUtils::IsVarSelector(ch) || @@ -7608,7 +7607,7 @@ nsIFrame::FrameSearchResult nsTextFrame::PeekOffsetCharacter( if (!mTextRun) return CONTINUE_EMPTY; TrimmedOffsets trimmed = - GetTrimmedOffsets(mContent->GetText(), TrimmedOffsetFlags::NoTrimAfter); + GetTrimmedOffsets(TextFragment(), TrimmedOffsetFlags::NoTrimAfter); // A negative offset means "end of frame". int32_t startOffset = @@ -7741,7 +7740,7 @@ ClusterIterator::ClusterIterator(nsTextFrame* aTextFrame, int32_t aPosition, } mIterator.SetOriginalOffset(aPosition); - mFrag = aTextFrame->GetContent()->GetText(); + mFrag = aTextFrame->TextFragment(); mTrimmed = aTextFrame->GetTrimmedOffsets( mFrag, aTrimSpaces ? nsTextFrame::TrimmedOffsetFlags::Default : nsTextFrame::TrimmedOffsetFlags::NoTrimAfter | @@ -8049,7 +8048,7 @@ void nsTextFrame::AddInlineMinISizeForFlow(gfxContext* aRenderingContext, // Pass null for the line container. This will disable tab spacing, but that's // OK since we can't really handle tabs for intrinsic sizing anyway. const nsStyleText* textStyle = StyleText(); - const nsTextFragment* frag = mContent->GetText(); + const nsTextFragment* frag = TextFragment(); // If we're hyphenating, the PropertyProvider needs the actual length; // otherwise we can just pass INT32_MAX to mean "all the text" @@ -8246,7 +8245,7 @@ void nsTextFrame::AddInlinePrefISizeForFlow( // OK since we can't really handle tabs for intrinsic sizing anyway. const nsStyleText* textStyle = StyleText(); - const nsTextFragment* frag = mContent->GetText(); + const nsTextFragment* frag = TextFragment(); PropertyProvider provider(textRun, textStyle, frag, this, iter, INT32_MAX, nullptr, 0, aTextRunType); @@ -8775,7 +8774,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, uint32_t flowEndInTextRun; nsIFrame* lineContainer = aLineLayout.LineContainerFrame(); - const nsTextFragment* frag = mContent->GetText(); + const nsTextFragment* frag = TextFragment(); // DOM offsets of the text range we need to measure, after trimming // whitespace, restricting to first-letter, and restricting preformatted text @@ -8799,7 +8798,7 @@ void nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, contentNewLineOffset = cachedNewlineOffset->mNewlineOffset; } else { contentNewLineOffset = - FindChar(frag, offset, mContent->TextLength() - offset, '\n'); + FindChar(frag, offset, GetContent()->TextLength() - offset, '\n'); } if (contentNewLineOffset < offset + length) { /* @@ -9349,7 +9348,7 @@ nsTextFrame::TrimOutput nsTextFrame::TrimTrailingWhiteSpace( uint32_t trimmedStart = start.GetSkippedOffset(); - const nsTextFragment* frag = mContent->GetText(); + const nsTextFragment* frag = TextFragment(); TrimmedOffsets trimmed = GetTrimmedOffsets(frag); gfxSkipCharsIterator trimmedEndIter = start; const nsStyleText* textStyle = StyleText(); @@ -9517,7 +9516,7 @@ nsIFrame::RenderedText nsTextFrame::GetRenderedText( RenderedText result; nsBlockFrame* lineContainer = nullptr; nsTextFrame* textFrame; - const nsTextFragment* textFrag = mContent->GetText(); + const nsTextFragment* textFrag = TextFragment(); uint32_t offsetInRenderedString = 0; bool haveOffsets = false; @@ -9693,9 +9692,9 @@ bool nsTextFrame::IsEmpty() { return true; } - bool isEmpty = IsAllWhitespace( - mContent->GetText(), - textStyle->mWhiteSpace != mozilla::StyleWhiteSpace::PreLine); + bool isEmpty = + IsAllWhitespace(TextFragment(), textStyle->mWhiteSpace != + mozilla::StyleWhiteSpace::PreLine); AddStateBits(isEmpty ? TEXT_IS_ONLY_WHITESPACE : TEXT_ISNOT_ONLY_WHITESPACE); return isEmpty; } @@ -9705,7 +9704,7 @@ bool nsTextFrame::IsEmpty() { void nsTextFrame::ToCString(nsCString& aBuf, int32_t* aTotalContentLength) const { // Get the frames text content - const nsTextFragment* frag = mContent->GetText(); + const nsTextFragment* frag = TextFragment(); if (!frag) { return; } @@ -9886,7 +9885,7 @@ mozilla::JustificationAssignment nsTextFrame::GetJustificationAssignment() } uint32_t nsTextFrame::CountGraphemeClusters() const { - const nsTextFragment* frag = GetContent()->GetText(); + const nsTextFragment* frag = TextFragment(); MOZ_ASSERT(frag, "Text frame must have text fragment"); nsAutoString content; frag->AppendTo(content, GetContentOffset(), GetContentLength()); @@ -9906,6 +9905,6 @@ bool nsTextFrame::HasNonSuppressedText() { } TrimmedOffsets offsets = - GetTrimmedOffsets(mContent->GetText(), TrimmedOffsetFlags::NoTrimAfter); + GetTrimmedOffsets(TextFragment(), TrimmedOffsetFlags::NoTrimAfter); return offsets.mLength != 0; } diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index 769743576320..7ec6329a7153 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -11,7 +11,7 @@ #include "mozilla/EventForwards.h" #include "mozilla/gfx/2D.h" #include "mozilla/UniquePtr.h" -#include "mozilla/dom/CharacterData.h" +#include "mozilla/dom/Text.h" #include "nsFrame.h" #include "nsFrameSelection.h" #include "nsSplittableFrame.h" @@ -157,6 +157,13 @@ class nsTextFrame : public nsFrame { void ToCString(nsCString& aBuf, int32_t* aTotalContentLength) const; #endif + // Returns this text frame's content's text fragment. + // + // Assertions in Init() ensure we only ever get a Text node as content. + const nsTextFragment* TextFragment() const { + return &mContent->AsText()->TextFragment(); + } + ContentOffsets CalcContentOffsetsFromFramePoint(const nsPoint& aPoint) final; ContentOffsets GetCharacterOffsetAtFramePoint(const nsPoint& aPoint); diff --git a/layout/generic/nsTextFrameUtils.cpp b/layout/generic/nsTextFrameUtils.cpp index a187efa9c4f7..bd75e00596ab 100644 --- a/layout/generic/nsTextFrameUtils.cpp +++ b/layout/generic/nsTextFrameUtils.cpp @@ -340,8 +340,8 @@ template bool nsTextFrameUtils::IsSkippableCharacterForTransformText( char16_t aChar); uint32_t nsTextFrameUtils::ComputeApproximateLengthWithWhitespaceCompression( - nsIContent* aContent, const nsStyleText* aStyleText) { - const nsTextFragment* frag = aContent->GetText(); + Text* aText, const nsStyleText* aStyleText) { + const nsTextFragment* frag = &aText->TextFragment(); // This is an approximation so we don't really need anything // too fancy here. uint32_t len; diff --git a/layout/generic/nsTextFrameUtils.h b/layout/generic/nsTextFrameUtils.h index 508dd72dac50..2fc91ed6ea68 100644 --- a/layout/generic/nsTextFrameUtils.h +++ b/layout/generic/nsTextFrameUtils.h @@ -13,6 +13,12 @@ class nsIContent; struct nsStyleText; +namespace mozilla { +namespace dom { +class Text; +} +} // namespace mozilla + #define BIG_TEXT_NODE_SIZE 4096 #define CH_NBSP 160 @@ -133,7 +139,7 @@ class nsTextFrameUtils { } static uint32_t ComputeApproximateLengthWithWhitespaceCompression( - nsIContent* aContent, const nsStyleText* aStyleText); + mozilla::dom::Text* aText, const nsStyleText* aStyleText); }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsTextFrameUtils::Flags) diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index 0da136dd6b82..575c747f6bcf 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -980,7 +980,7 @@ void TextRenderedRun::GetClipEdges(nscoord& aVisIStartEdge, // white space, as the nsTextFrame when painting does not include them when // interpreting clip edges. nsTextFrame::TrimmedOffsets trimmedOffsets = - mFrame->GetTrimmedOffsets(mFrame->GetContent()->GetText()); + mFrame->GetTrimmedOffsets(mFrame->TextFragment()); TrimOffsets(frameOffset, frameLength, trimmedOffsets); // Convert the trimmed whole-nsTextFrame offset/length into skipped @@ -1885,7 +1885,7 @@ TextRenderedRun TextRenderedRunIterator::Next() { uint32_t untrimmedOffset = offset; uint32_t untrimmedLength = length; nsTextFrame::TrimmedOffsets trimmedOffsets = - frame->GetTrimmedOffsets(frame->GetContent()->GetText()); + frame->GetTrimmedOffsets(frame->TextFragment()); TrimOffsets(offset, length, trimmedOffsets); charIndex += offset - untrimmedOffset; @@ -2364,9 +2364,8 @@ bool CharIterator::IsOriginalCharTrimmed() const { mFrameForTrimCheck = TextFrame(); uint32_t offset = mFrameForTrimCheck->GetContentOffset(); uint32_t length = mFrameForTrimCheck->GetContentLength(); - nsIContent* content = mFrameForTrimCheck->GetContent(); nsTextFrame::TrimmedOffsets trim = mFrameForTrimCheck->GetTrimmedOffsets( - content->GetText(), + mFrameForTrimCheck->TextFragment(), (mPostReflow ? nsTextFrame::TrimmedOffsetFlags::Default : nsTextFrame::TrimmedOffsetFlags::NotPostReflow)); TrimOffsets(offset, length, trim); @@ -2382,7 +2381,7 @@ bool CharIterator::IsOriginalCharTrimmed() const { (index >= mTrimmedOffset + mTrimmedLength && mFrameForTrimCheck->StyleText()->NewlineIsSignificant( mFrameForTrimCheck) && - mFrameForTrimCheck->GetContent()->GetText()->CharAt(index) == '\n')); + mFrameForTrimCheck->TextFragment()->CharAt(index) == '\n')); } void CharIterator::GetOriginalGlyphOffsets(uint32_t& aOriginalOffset, @@ -3804,8 +3803,7 @@ nsresult SVGTextFrame::GetSubStringLength(nsIContent* aContent, uint32_t trimmedOffset = untrimmedOffset; uint32_t trimmedLength = untrimmedLength; nsTextFrame::TrimmedOffsets trimmedOffsets = frame->GetTrimmedOffsets( - frame->GetContent()->GetText(), - nsTextFrame::TrimmedOffsetFlags::NotPostReflow); + frame->TextFragment(), nsTextFrame::TrimmedOffsetFlags::NotPostReflow); TrimOffsets(trimmedOffset, trimmedLength, trimmedOffsets); textElementCharIndex += trimmedOffset - untrimmedOffset; @@ -4414,7 +4412,7 @@ void SVGTextFrame::DetermineCharPositions(nsTArray& aPositions) { // Any white space characters trimmed at the start of the line of text. nsTextFrame::TrimmedOffsets trimmedOffsets = - frame->GetTrimmedOffsets(frame->GetContent()->GetText()); + frame->GetTrimmedOffsets(frame->TextFragment()); while (it.GetOriginalOffset() < trimmedOffsets.mStart) { aPositions.AppendElement(position); it.AdvanceOriginal(1);