This commit is contained in:
Cameron Kaiser 2017-10-14 19:03:40 -07:00
parent f37f7669db
commit b8ebae8398
4 changed files with 46 additions and 13 deletions

View File

@ -47,10 +47,18 @@ enum {
// bit is set, and if so it indicates whether we're only whitespace or // bit is set, and if so it indicates whether we're only whitespace or
// not. // not.
NS_TEXT_IS_ONLY_WHITESPACE = DATA_NODE_FLAG_BIT(3), NS_TEXT_IS_ONLY_WHITESPACE = DATA_NODE_FLAG_BIT(3),
// This bit is set if there is a NewlineProperty attached to the node
// (used by nsTextFrame).
NS_HAS_NEWLINE_PROPERTY = DATA_NODE_FLAG_BIT(4),
// This bit is set if there is a FlowLengthProperty attached to the node
// (used by nsTextFrame).
NS_HAS_FLOWLENGTH_PROPERTY = DATA_NODE_FLAG_BIT(5),
}; };
// Make sure we have enough space for those bits // Make sure we have enough space for those bits
ASSERT_NODE_FLAGS_SPACE(NODE_TYPE_SPECIFIC_BITS_OFFSET + 4); ASSERT_NODE_FLAGS_SPACE(NODE_TYPE_SPECIFIC_BITS_OFFSET + 6);
#undef DATA_NODE_FLAG_BIT #undef DATA_NODE_FLAG_BIT

View File

@ -398,6 +398,7 @@ include('/ipc/chromium/chromium-config.mozbuild')
LOCAL_INCLUDES += [ LOCAL_INCLUDES += [
'/docshell/base', # for nsDocShell.h '/docshell/base', # for nsDocShell.h
'/dom/base', # for nsDocument.h
'/layout/base', # for TouchManager.h '/layout/base', # for TouchManager.h
'/layout/generic', # for nsTextFrame.h '/layout/generic', # for nsTextFrame.h
] ]

View File

@ -62,7 +62,6 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsLineBreaker.h" #include "nsLineBreaker.h"
#include "nsIWordBreaker.h" #include "nsIWordBreaker.h"
#include "nsGenericDOMDataNode.h"
#include "nsIFrameInlines.h" #include "nsIFrameInlines.h"
#include <algorithm> #include <algorithm>
@ -637,7 +636,9 @@ int32_t nsTextFrame::GetInFlowContentLength() {
} }
FlowLengthProperty* flowLength = FlowLengthProperty* flowLength =
static_cast<FlowLengthProperty*>(mContent->GetProperty(nsGkAtoms::flowlength)); mContent->HasFlag(NS_HAS_FLOWLENGTH_PROPERTY)
? static_cast<FlowLengthProperty*>(mContent->GetProperty(nsGkAtoms::flowlength))
: nullptr;
/** /**
* This frame must start inside the cached flow. If the flow starts at * This frame must start inside the cached flow. If the flow starts at
@ -665,6 +666,7 @@ int32_t nsTextFrame::GetInFlowContentLength() {
delete flowLength; delete flowLength;
flowLength = nullptr; flowLength = nullptr;
} }
mContent->SetFlags(NS_HAS_FLOWLENGTH_PROPERTY);
} }
if (flowLength) { if (flowLength) {
flowLength->mStartOffset = mContentOffset; flowLength->mStartOffset = mContentOffset;
@ -4073,9 +4075,13 @@ nsTextFrame::Init(nsIContent* aContent,
// Remove any NewlineOffsetProperty or InFlowContentLengthProperty since they // Remove any NewlineOffsetProperty or InFlowContentLengthProperty since they
// might be invalid if the content was modified while there was no frame // might be invalid if the content was modified while there was no frame
aContent->DeleteProperty(nsGkAtoms::newline); if (aContent->HasFlag(NS_HAS_NEWLINE_PROPERTY)) {
if (PresContext()->BidiEnabled()) { aContent->DeleteProperty(nsGkAtoms::newline);
aContent->UnsetFlags(NS_HAS_NEWLINE_PROPERTY);
}
if (aContent->HasFlag(NS_HAS_FLOWLENGTH_PROPERTY)) {
aContent->DeleteProperty(nsGkAtoms::flowlength); aContent->DeleteProperty(nsGkAtoms::flowlength);
aContent->UnsetFlags(NS_HAS_FLOWLENGTH_PROPERTY);
} }
// Since our content has a frame now, this flag is no longer needed. // Since our content has a frame now, this flag is no longer needed.
@ -4572,11 +4578,15 @@ nsTextFrame::DisconnectTextRuns()
nsresult nsresult
nsTextFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo) nsTextFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
{ {
mContent->DeleteProperty(nsGkAtoms::newline); if (mContent->HasFlag(NS_HAS_NEWLINE_PROPERTY)) {
if (PresContext()->BidiEnabled()) { mContent->DeleteProperty(nsGkAtoms::newline);
mContent->DeleteProperty(nsGkAtoms::flowlength); mContent->UnsetFlags(NS_HAS_NEWLINE_PROPERTY);
} }
if (mContent->HasFlag(NS_HAS_FLOWLENGTH_PROPERTY)) {
mContent->DeleteProperty(nsGkAtoms::flowlength);
mContent->UnsetFlags(NS_HAS_FLOWLENGTH_PROPERTY);
}
// Find the first frame whose text has changed. Frames that are entirely // Find the first frame whose text has changed. Frames that are entirely
// before the text change are completely unaffected. // before the text change are completely unaffected.
nsTextFrame* next; nsTextFrame* next;
@ -8588,7 +8598,9 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
NewlineProperty* cachedNewlineOffset = nullptr; NewlineProperty* cachedNewlineOffset = nullptr;
if (textStyle->NewlineIsSignificant(this)) { if (textStyle->NewlineIsSignificant(this)) {
cachedNewlineOffset = cachedNewlineOffset =
static_cast<NewlineProperty*>(mContent->GetProperty(nsGkAtoms::newline)); mContent->HasFlag(NS_HAS_NEWLINE_PROPERTY)
? static_cast<NewlineProperty*>(mContent->GetProperty(nsGkAtoms::newline))
: nullptr;
if (cachedNewlineOffset && cachedNewlineOffset->mStartOffset <= offset && if (cachedNewlineOffset && cachedNewlineOffset->mStartOffset <= offset &&
(cachedNewlineOffset->mNewlineOffset == -1 || (cachedNewlineOffset->mNewlineOffset == -1 ||
cachedNewlineOffset->mNewlineOffset >= offset)) { cachedNewlineOffset->mNewlineOffset >= offset)) {
@ -9039,6 +9051,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
delete cachedNewlineOffset; delete cachedNewlineOffset;
cachedNewlineOffset = nullptr; cachedNewlineOffset = nullptr;
} }
mContent->SetFlags(NS_HAS_NEWLINE_PROPERTY);
} }
if (cachedNewlineOffset) { if (cachedNewlineOffset) {
cachedNewlineOffset->mStartOffset = offset; cachedNewlineOffset->mStartOffset = offset;
@ -9046,6 +9059,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
} }
} else if (cachedNewlineOffset) { } else if (cachedNewlineOffset) {
mContent->DeleteProperty(nsGkAtoms::newline); mContent->DeleteProperty(nsGkAtoms::newline);
mContent->UnsetFlags(NS_HAS_NEWLINE_PROPERTY);
} }
// Compute space and letter counts for justification, if required // Compute space and letter counts for justification, if required
@ -9496,7 +9510,10 @@ void
nsTextFrame::AdjustOffsetsForBidi(int32_t aStart, int32_t aEnd) nsTextFrame::AdjustOffsetsForBidi(int32_t aStart, int32_t aEnd)
{ {
AddStateBits(NS_FRAME_IS_BIDI); AddStateBits(NS_FRAME_IS_BIDI);
mContent->DeleteProperty(nsGkAtoms::flowlength); if (mContent->HasFlag(NS_HAS_FLOWLENGTH_PROPERTY)) {
mContent->DeleteProperty(nsGkAtoms::flowlength);
mContent->UnsetFlags(NS_HAS_FLOWLENGTH_PROPERTY);
}
/* /*
* After Bidi resolution we may need to reassign text runs. * After Bidi resolution we may need to reassign text runs.

View File

@ -10,6 +10,7 @@
#include "mozilla/EventForwards.h" #include "mozilla/EventForwards.h"
#include "mozilla/gfx/2D.h" #include "mozilla/gfx/2D.h"
#include "nsFrame.h" #include "nsFrame.h"
#include "nsGenericDOMDataNode.h"
#include "nsSplittableFrame.h" #include "nsSplittableFrame.h"
#include "nsLineBox.h" #include "nsLineBox.h"
#include "gfxSkipChars.h" #include "gfxSkipChars.h"
@ -92,7 +93,10 @@ public:
aNextContinuation->RemoveStateBits(NS_FRAME_IS_FLUID_CONTINUATION); aNextContinuation->RemoveStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
// Setting a non-fluid continuation might affect our flow length (they're // Setting a non-fluid continuation might affect our flow length (they're
// quite rare so we assume it always does) so we delete our cached value: // quite rare so we assume it always does) so we delete our cached value:
GetContent()->DeleteProperty(nsGkAtoms::flowlength); if (GetContent()->HasFlag(NS_HAS_FLOWLENGTH_PROPERTY)) {
GetContent()->DeleteProperty(nsGkAtoms::flowlength);
GetContent()->UnsetFlags(NS_HAS_FLOWLENGTH_PROPERTY);
}
} }
virtual nsIFrame* GetNextInFlowVirtual() const override { return GetNextInFlow(); } virtual nsIFrame* GetNextInFlowVirtual() const override { return GetNextInFlow(); }
nsIFrame* GetNextInFlow() const { nsIFrame* GetNextInFlow() const {
@ -109,7 +113,10 @@ public:
!mNextContinuation->HasAnyStateBits(NS_FRAME_IS_FLUID_CONTINUATION)) { !mNextContinuation->HasAnyStateBits(NS_FRAME_IS_FLUID_CONTINUATION)) {
// Changing from non-fluid to fluid continuation might affect our flow // Changing from non-fluid to fluid continuation might affect our flow
// length, so we delete our cached value: // length, so we delete our cached value:
GetContent()->DeleteProperty(nsGkAtoms::flowlength); if (GetContent()->HasFlag(NS_HAS_FLOWLENGTH_PROPERTY)) {
GetContent()->DeleteProperty(nsGkAtoms::flowlength);
GetContent()->UnsetFlags(NS_HAS_FLOWLENGTH_PROPERTY);
}
} }
if (aNextInFlow) { if (aNextInFlow) {
aNextInFlow->AddStateBits(NS_FRAME_IS_FLUID_CONTINUATION); aNextInFlow->AddStateBits(NS_FRAME_IS_FLUID_CONTINUATION);