mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1143570 - Part 1: Use an nsBlockInFlowLineIterator to determine whether a BR frame is visible or not; r=roc
This commit is contained in:
parent
29d8e53169
commit
1b9af9fc20
@ -49,7 +49,8 @@
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ShadowRoot.h"
|
||||
#include "mozilla/dom/EncodingUtils.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsBlockFrame.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -324,7 +325,45 @@ nsDocumentEncoder::IncludeInContext(nsINode *aNode)
|
||||
|
||||
static
|
||||
bool
|
||||
IsInvisibleBreak(nsINode *aNode) {
|
||||
LineHasNonEmptyContentWorker(nsIFrame* aFrame)
|
||||
{
|
||||
// Look for non-empty frames, but ignore inline and br frames.
|
||||
// For inline frames, descend into the children, if any.
|
||||
if (aFrame->GetType() == nsGkAtoms::inlineFrame) {
|
||||
nsIFrame* child = aFrame->GetFirstPrincipalChild();
|
||||
while (child) {
|
||||
if (LineHasNonEmptyContentWorker(child)) {
|
||||
return true;
|
||||
}
|
||||
child = child->GetNextSibling();
|
||||
}
|
||||
} else {
|
||||
if (aFrame->GetType() != nsGkAtoms::brFrame &&
|
||||
!aFrame->IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
LineHasNonEmptyContent(nsLineBox* aLine)
|
||||
{
|
||||
int32_t count = aLine->GetChildCount();
|
||||
for (nsIFrame* frame = aLine->mFirstChild; count > 0;
|
||||
--count, frame = frame->GetNextSibling()) {
|
||||
if (LineHasNonEmptyContentWorker(frame)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
IsInvisibleBreak(nsINode *aNode)
|
||||
{
|
||||
if (!aNode->IsElement() || !aNode->IsEditable()) {
|
||||
return false;
|
||||
}
|
||||
@ -333,14 +372,36 @@ IsInvisibleBreak(nsINode *aNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the BRFrame has caused a visible line break, it should have a next
|
||||
// sibling, or otherwise no siblings (or immediately after a br) and a
|
||||
// non-zero height.
|
||||
bool visible = frame->GetNextSibling() ||
|
||||
((!frame->GetPrevSibling() ||
|
||||
frame->GetPrevSibling()->GetType() == nsGkAtoms::brFrame) &&
|
||||
frame->GetRect().Height() != 0);
|
||||
return !visible;
|
||||
nsContainerFrame* f = frame->GetParent();
|
||||
while (f && f->IsFrameOfType(nsBox::eLineParticipant)) {
|
||||
f = f->GetParent();
|
||||
}
|
||||
nsBlockFrame* blockAncestor = do_QueryFrame(f);
|
||||
if (!blockAncestor) {
|
||||
// The container frame doesn't support line breaking.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool valid = false;
|
||||
nsBlockInFlowLineIterator iter(blockAncestor, frame, &valid);
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool lineNonEmpty = LineHasNonEmptyContent(iter.GetLine());
|
||||
|
||||
while (iter.Next()) {
|
||||
auto currentLine = iter.GetLine();
|
||||
// Completely skip empty lines.
|
||||
if (!currentLine->IsEmpty()) {
|
||||
// If we come across an inline line, the BR has caused a visible line break.
|
||||
if (currentLine->IsInline()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lineNonEmpty;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -28,6 +28,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=116083
|
||||
<div data-result="foo bar ! baz" style="white-space: pre-line" contenteditable><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div>
|
||||
<div data-result="foo bar ! baz" style="white-space: -moz-pre-space"><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div>
|
||||
<div data-result="foo bar ! baz" style="white-space: -moz-pre-space" contenteditable><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div>
|
||||
<div data-result="foo bar baz qux"><div>foo<br></div><span>bar<br>baz<br>qux</span></div>
|
||||
<div data-result="foo bar baz qux" contenteditable><div>foo<br></div><span>bar<br>baz<br>qux</span></div>
|
||||
<div data-result="foo "><div>foo</div><span><br></span></div>
|
||||
<div data-result="foo " contenteditable><div>foo</div><span><br></span></div>
|
||||
<div data-result="foo bar"><div>foo</div><span><br></span><div>bar</div></div>
|
||||
<div data-result="foo bar" contenteditable><div>foo</div><span><br></span><div>bar</div></div>
|
||||
<div data-result="foo bar "><div>foo</div><span>bar<br></span></div>
|
||||
<div data-result="foo bar" contenteditable><div>foo</div><span>bar<br></span></div>
|
||||
<div data-result="foo bar baz"><div>foo</div><span>bar<br></span><div>baz</div></div>
|
||||
<div data-result="foo bar baz" contenteditable><div>foo</div><span>bar<br></span><div>baz</div></div>
|
||||
<div data-result=" foo"><div><br><br><div>foo</div></div></div>
|
||||
<div data-result=" foo" contenteditable><div><br><br><div>foo</div></div></div>
|
||||
<div data-result="foo bar"><div>foo<br>bar</div></div>
|
||||
<div data-result="foo bar" contenteditable><div>foo<br>bar</div></div>
|
||||
<div data-result="foo bar "><div>foo<br>bar<br></div></div>
|
||||
<div data-result="foo bar" contenteditable><div>foo<br>bar<br></div></div>
|
||||
<div data-result=" foo bar ">foo bar</div>
|
||||
</div>
|
||||
<script type="application/javascript">
|
||||
|
Loading…
Reference in New Issue
Block a user