forked from mirrors/gecko-dev
Bug 1887954 - Make nsIFrame::GetLastLeaf() never returns a frame in native anonymous subtrees under the given frame r=emilio
It does not check whether the child frame is in a native anonymous subtree only when every first child at digging the frame tree. This patch rewrites the complicated loop with 2 for-loops and make it always check whether the frame is for a native anonymous subtree root or not before updating the result. Differential Revision: https://phabricator.services.mozilla.com/D206283
This commit is contained in:
parent
4818daad52
commit
9bfe998503
3 changed files with 47 additions and 15 deletions
|
|
@ -10716,21 +10716,27 @@ ComputedStyle* nsIFrame::DoGetParentComputedStyle(
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsIFrame::GetLastLeaf(nsIFrame** aFrame) {
|
void nsIFrame::GetLastLeaf(nsIFrame** aFrame) {
|
||||||
if (!aFrame || !*aFrame) return;
|
if (!aFrame || !*aFrame) {
|
||||||
nsIFrame* child = *aFrame;
|
return;
|
||||||
// if we are a block frame then go for the last line of 'this'
|
}
|
||||||
while (1) {
|
for (nsIFrame* maybeLastLeaf = (*aFrame)->PrincipalChildList().LastChild();
|
||||||
child = child->PrincipalChildList().FirstChild();
|
maybeLastLeaf;) {
|
||||||
if (!child) return; // nothing to do
|
nsIFrame* lastChildNotInSubTree = nullptr;
|
||||||
nsIFrame* siblingFrame;
|
for (nsIFrame* child = maybeLastLeaf; child;
|
||||||
nsIContent* content;
|
child = child->GetPrevSibling()) {
|
||||||
// ignore anonymous elements, e.g. mozTableAdd* mozTableRemove*
|
nsIContent* content = child->GetContent();
|
||||||
// see bug 278197 comment #12 #13 for details
|
// ignore anonymous elements, e.g. mozTableAdd* mozTableRemove*
|
||||||
while ((siblingFrame = child->GetNextSibling()) &&
|
// see bug 278197 comment #12 #13 for details
|
||||||
(content = siblingFrame->GetContent()) &&
|
if (content && !content->IsRootOfNativeAnonymousSubtree()) {
|
||||||
!content->IsRootOfNativeAnonymousSubtree())
|
lastChildNotInSubTree = child;
|
||||||
child = siblingFrame;
|
break;
|
||||||
*aFrame = child;
|
}
|
||||||
|
}
|
||||||
|
if (!lastChildNotInSubTree) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*aFrame = lastChildNotInSubTree;
|
||||||
|
maybeLastLeaf = lastChildNotInSubTree->PrincipalChildList().LastChild();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3939,6 +3939,9 @@ class nsIFrame : public nsQueryFrame {
|
||||||
public:
|
public:
|
||||||
// given a frame five me the first/last leaf available
|
// given a frame five me the first/last leaf available
|
||||||
// XXX Robert O'Callahan wants to move these elsewhere
|
// XXX Robert O'Callahan wants to move these elsewhere
|
||||||
|
// FIXME: Only GetLastLeaf() never returns a leaf frame in native anonymous
|
||||||
|
// subtrees under aFrame. However, GetFirstLeaf() may return a leaf frame
|
||||||
|
// in a native anonymous subtree.
|
||||||
static void GetLastLeaf(nsIFrame** aFrame);
|
static void GetLastLeaf(nsIFrame** aFrame);
|
||||||
static void GetFirstLeaf(nsIFrame** aFrame);
|
static void GetFirstLeaf(nsIFrame** aFrame);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
getSelection().addRange(document.createRange());
|
||||||
|
const range = document.createRange();
|
||||||
|
range.selectNode(document.querySelector("meter"));
|
||||||
|
getSelection().addRange(range);
|
||||||
|
getSelection().modify('move', 'left', 'line');
|
||||||
|
document.querySelector("input").style.display = "none";
|
||||||
|
getSelection().modify('move', 'left', 'lineboundary');
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<input>
|
||||||
|
<div contenteditable>
|
||||||
|
<meter>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in a new issue