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) {
|
||||
if (!aFrame || !*aFrame) return;
|
||||
nsIFrame* child = *aFrame;
|
||||
// if we are a block frame then go for the last line of 'this'
|
||||
while (1) {
|
||||
child = child->PrincipalChildList().FirstChild();
|
||||
if (!child) return; // nothing to do
|
||||
nsIFrame* siblingFrame;
|
||||
nsIContent* content;
|
||||
if (!aFrame || !*aFrame) {
|
||||
return;
|
||||
}
|
||||
for (nsIFrame* maybeLastLeaf = (*aFrame)->PrincipalChildList().LastChild();
|
||||
maybeLastLeaf;) {
|
||||
nsIFrame* lastChildNotInSubTree = nullptr;
|
||||
for (nsIFrame* child = maybeLastLeaf; child;
|
||||
child = child->GetPrevSibling()) {
|
||||
nsIContent* content = child->GetContent();
|
||||
// ignore anonymous elements, e.g. mozTableAdd* mozTableRemove*
|
||||
// see bug 278197 comment #12 #13 for details
|
||||
while ((siblingFrame = child->GetNextSibling()) &&
|
||||
(content = siblingFrame->GetContent()) &&
|
||||
!content->IsRootOfNativeAnonymousSubtree())
|
||||
child = siblingFrame;
|
||||
*aFrame = child;
|
||||
if (content && !content->IsRootOfNativeAnonymousSubtree()) {
|
||||
lastChildNotInSubTree = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!lastChildNotInSubTree) {
|
||||
return;
|
||||
}
|
||||
*aFrame = lastChildNotInSubTree;
|
||||
maybeLastLeaf = lastChildNotInSubTree->PrincipalChildList().LastChild();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3939,6 +3939,9 @@ class nsIFrame : public nsQueryFrame {
|
|||
public:
|
||||
// given a frame five me the first/last leaf available
|
||||
// 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 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