mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1927111 - Add support for ChromeOnly flush: false for GeometryUtils. r=layout-reviewers,webidl,saschanaz,dshin
This will be useful for the front-end to replace nsIDOMWindowUtils.getBoundsWithoutFlushing(), since I need content box bounds. Differential Revision: https://phabricator.services.mozilla.com/D226931
This commit is contained in:
parent
9fbce11ad8
commit
94a6ec677c
@ -11,14 +11,20 @@
|
||||
*/
|
||||
|
||||
enum CSSBoxType { "margin", "border", "padding", "content" };
|
||||
dictionary BoxQuadOptions {
|
||||
CSSBoxType box = "border";
|
||||
GeometryNode relativeTo;
|
||||
|
||||
dictionary GeometryUtilsOptions {
|
||||
[ChromeOnly]
|
||||
boolean createFramesForSuppressedWhitespace = true;
|
||||
[ChromeOnly]
|
||||
boolean flush = true;
|
||||
};
|
||||
|
||||
dictionary ConvertCoordinateOptions {
|
||||
dictionary BoxQuadOptions : GeometryUtilsOptions {
|
||||
CSSBoxType box = "border";
|
||||
GeometryNode relativeTo;
|
||||
};
|
||||
|
||||
dictionary ConvertCoordinateOptions : GeometryUtilsOptions {
|
||||
CSSBoxType fromBox = "border";
|
||||
CSSBoxType toBox = "border";
|
||||
};
|
||||
|
@ -36,15 +36,23 @@ enum GeometryNodeType {
|
||||
};
|
||||
|
||||
static nsIFrame* GetFrameForNode(nsINode* aNode, GeometryNodeType aType,
|
||||
bool aCreateFramesForSuppressedWhitespace) {
|
||||
Document* doc = aNode->OwnerDoc();
|
||||
if (aType == GEOMETRY_NODE_TEXT && aCreateFramesForSuppressedWhitespace) {
|
||||
if (PresShell* presShell = doc->GetPresShell()) {
|
||||
presShell->FrameConstructor()->EnsureFrameForTextNodeIsCreatedAfterFlush(
|
||||
static_cast<CharacterData*>(aNode));
|
||||
}
|
||||
const GeometryUtilsOptions& aOptions) {
|
||||
RefPtr<Document> doc = aNode->GetComposedDoc();
|
||||
if (!doc) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aOptions.mFlush) {
|
||||
if (aType == GEOMETRY_NODE_TEXT &&
|
||||
aOptions.mCreateFramesForSuppressedWhitespace) {
|
||||
if (PresShell* presShell = doc->GetPresShell()) {
|
||||
presShell->FrameConstructor()
|
||||
->EnsureFrameForTextNodeIsCreatedAfterFlush(
|
||||
static_cast<CharacterData*>(aNode));
|
||||
}
|
||||
}
|
||||
doc->FlushPendingNotifications(FlushType::Layout);
|
||||
}
|
||||
doc->FlushPendingNotifications(FlushType::Layout);
|
||||
|
||||
switch (aType) {
|
||||
case GEOMETRY_NODE_TEXT:
|
||||
@ -62,81 +70,73 @@ static nsIFrame* GetFrameForNode(nsINode* aNode, GeometryNodeType aType,
|
||||
|
||||
static nsIFrame* GetFrameForGeometryNode(
|
||||
const Optional<OwningGeometryNode>& aGeometryNode, nsINode* aDefaultNode,
|
||||
bool aCreateFramesForSuppressedWhitespace) {
|
||||
const GeometryUtilsOptions& aOptions) {
|
||||
if (!aGeometryNode.WasPassed()) {
|
||||
return GetFrameForNode(aDefaultNode->OwnerDoc(), GEOMETRY_NODE_DOCUMENT,
|
||||
aCreateFramesForSuppressedWhitespace);
|
||||
aOptions);
|
||||
}
|
||||
|
||||
const OwningGeometryNode& value = aGeometryNode.Value();
|
||||
if (value.IsElement()) {
|
||||
return GetFrameForNode(value.GetAsElement(), GEOMETRY_NODE_ELEMENT,
|
||||
aCreateFramesForSuppressedWhitespace);
|
||||
aOptions);
|
||||
}
|
||||
if (value.IsDocument()) {
|
||||
return GetFrameForNode(value.GetAsDocument(), GEOMETRY_NODE_DOCUMENT,
|
||||
aCreateFramesForSuppressedWhitespace);
|
||||
aOptions);
|
||||
}
|
||||
return GetFrameForNode(value.GetAsText(), GEOMETRY_NODE_TEXT,
|
||||
aCreateFramesForSuppressedWhitespace);
|
||||
return GetFrameForNode(value.GetAsText(), GEOMETRY_NODE_TEXT, aOptions);
|
||||
}
|
||||
|
||||
static nsIFrame* GetFrameForGeometryNode(const GeometryNode& aGeometryNode) {
|
||||
// This will create frames for suppressed whitespace nodes.
|
||||
static nsIFrame* GetFrameForGeometryNode(const GeometryNode& aGeometryNode,
|
||||
const GeometryUtilsOptions& aOptions) {
|
||||
if (aGeometryNode.IsElement()) {
|
||||
return GetFrameForNode(&aGeometryNode.GetAsElement(), GEOMETRY_NODE_ELEMENT,
|
||||
true);
|
||||
aOptions);
|
||||
}
|
||||
if (aGeometryNode.IsDocument()) {
|
||||
return GetFrameForNode(&aGeometryNode.GetAsDocument(),
|
||||
GEOMETRY_NODE_DOCUMENT, true);
|
||||
GEOMETRY_NODE_DOCUMENT, aOptions);
|
||||
}
|
||||
return GetFrameForNode(&aGeometryNode.GetAsText(), GEOMETRY_NODE_TEXT, true);
|
||||
return GetFrameForNode(&aGeometryNode.GetAsText(), GEOMETRY_NODE_TEXT,
|
||||
aOptions);
|
||||
}
|
||||
|
||||
static nsIFrame* GetFrameForNode(nsINode* aNode,
|
||||
bool aCreateFramesForSuppressedWhitespace) {
|
||||
const GeometryUtilsOptions& aOptions) {
|
||||
if (aNode->IsElement()) {
|
||||
return GetFrameForNode(aNode, GEOMETRY_NODE_ELEMENT,
|
||||
aCreateFramesForSuppressedWhitespace);
|
||||
return GetFrameForNode(aNode, GEOMETRY_NODE_ELEMENT, aOptions);
|
||||
}
|
||||
if (aNode == aNode->OwnerDoc()) {
|
||||
return GetFrameForNode(aNode, GEOMETRY_NODE_DOCUMENT,
|
||||
aCreateFramesForSuppressedWhitespace);
|
||||
return GetFrameForNode(aNode, GEOMETRY_NODE_DOCUMENT, aOptions);
|
||||
}
|
||||
NS_ASSERTION(aNode->IsText(), "Unknown node type");
|
||||
return GetFrameForNode(aNode, GEOMETRY_NODE_TEXT,
|
||||
aCreateFramesForSuppressedWhitespace);
|
||||
return GetFrameForNode(aNode, GEOMETRY_NODE_TEXT, aOptions);
|
||||
}
|
||||
|
||||
static nsIFrame* GetFirstNonAnonymousFrameForGeometryNode(
|
||||
const Optional<OwningGeometryNode>& aNode, nsINode* aDefaultNode,
|
||||
bool aCreateFramesForSuppressedWhitespace) {
|
||||
nsIFrame* f = GetFrameForGeometryNode(aNode, aDefaultNode,
|
||||
aCreateFramesForSuppressedWhitespace);
|
||||
if (f) {
|
||||
f = nsLayoutUtils::GetFirstNonAnonymousFrame(f);
|
||||
const GeometryUtilsOptions& aOptions) {
|
||||
if (nsIFrame* f = GetFrameForGeometryNode(aNode, aDefaultNode, aOptions)) {
|
||||
return nsLayoutUtils::GetFirstNonAnonymousFrame(f);
|
||||
}
|
||||
return f;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static nsIFrame* GetFirstNonAnonymousFrameForGeometryNode(
|
||||
const GeometryNode& aNode) {
|
||||
// This will create frames for suppressed whitespace nodes.
|
||||
nsIFrame* f = GetFrameForGeometryNode(aNode);
|
||||
if (f) {
|
||||
f = nsLayoutUtils::GetFirstNonAnonymousFrame(f);
|
||||
const GeometryNode& aNode, const GeometryUtilsOptions& aOptions) {
|
||||
if (nsIFrame* f = GetFrameForGeometryNode(aNode, aOptions)) {
|
||||
return nsLayoutUtils::GetFirstNonAnonymousFrame(f);
|
||||
}
|
||||
return f;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static nsIFrame* GetFirstNonAnonymousFrameForNode(nsINode* aNode) {
|
||||
// This will create frames for suppressed whitespace nodes.
|
||||
nsIFrame* f = GetFrameForNode(aNode, true);
|
||||
if (f) {
|
||||
f = nsLayoutUtils::GetFirstNonAnonymousFrame(f);
|
||||
static nsIFrame* GetFirstNonAnonymousFrameForNode(
|
||||
nsINode* aNode, const GeometryUtilsOptions& aOptions) {
|
||||
if (nsIFrame* f = GetFrameForNode(aNode, aOptions)) {
|
||||
return nsLayoutUtils::GetFirstNonAnonymousFrame(f);
|
||||
}
|
||||
return f;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,7 +178,7 @@ static nsRect GetBoxRectForFrame(nsIFrame** aFrame, CSSBoxType aType) {
|
||||
class AccumulateQuadCallback : public nsLayoutUtils::BoxCallback {
|
||||
public:
|
||||
AccumulateQuadCallback(Document* aParentObject,
|
||||
nsTArray<RefPtr<DOMQuad> >& aResult,
|
||||
nsTArray<RefPtr<DOMQuad>>& aResult,
|
||||
nsIFrame* aRelativeToFrame,
|
||||
const nsPoint& aRelativeToBoxTopLeft,
|
||||
CSSBoxType aBoxType)
|
||||
@ -226,7 +226,7 @@ class AccumulateQuadCallback : public nsLayoutUtils::BoxCallback {
|
||||
}
|
||||
|
||||
nsISupports* mParentObject;
|
||||
nsTArray<RefPtr<DOMQuad> >& mResult;
|
||||
nsTArray<RefPtr<DOMQuad>>& mResult;
|
||||
nsIFrame* mRelativeToFrame;
|
||||
nsPoint mRelativeToBoxTopLeft;
|
||||
CSSBoxType mBoxType;
|
||||
@ -262,10 +262,9 @@ static bool CheckFramesInSameTopLevelBrowsingContext(nsIFrame* aFrame1,
|
||||
}
|
||||
|
||||
void GetBoxQuads(nsINode* aNode, const dom::BoxQuadOptions& aOptions,
|
||||
nsTArray<RefPtr<DOMQuad> >& aResult, CallerType aCallerType,
|
||||
nsTArray<RefPtr<DOMQuad>>& aResult, CallerType aCallerType,
|
||||
ErrorResult& aRv) {
|
||||
nsIFrame* frame =
|
||||
GetFrameForNode(aNode, aOptions.mCreateFramesForSuppressedWhitespace);
|
||||
nsIFrame* frame = GetFrameForNode(aNode, aOptions);
|
||||
if (!frame) {
|
||||
// No boxes to return
|
||||
return;
|
||||
@ -273,14 +272,12 @@ void GetBoxQuads(nsINode* aNode, const dom::BoxQuadOptions& aOptions,
|
||||
AutoWeakFrame weakFrame(frame);
|
||||
Document* ownerDoc = aNode->OwnerDoc();
|
||||
nsIFrame* relativeToFrame = GetFirstNonAnonymousFrameForGeometryNode(
|
||||
aOptions.mRelativeTo, ownerDoc,
|
||||
aOptions.mCreateFramesForSuppressedWhitespace);
|
||||
aOptions.mRelativeTo, ownerDoc, aOptions);
|
||||
// The first frame might be destroyed now if the above call lead to an
|
||||
// EnsureFrameForTextNode call. We need to get the first frame again
|
||||
// when that happens and re-check it.
|
||||
if (!weakFrame.IsAlive()) {
|
||||
frame =
|
||||
GetFrameForNode(aNode, aOptions.mCreateFramesForSuppressedWhitespace);
|
||||
frame = GetFrameForNode(aNode, aOptions);
|
||||
if (!frame) {
|
||||
// No boxes to return
|
||||
return;
|
||||
@ -310,7 +307,7 @@ void GetBoxQuads(nsINode* aNode, const dom::BoxQuadOptions& aOptions,
|
||||
|
||||
void GetBoxQuadsFromWindowOrigin(nsINode* aNode,
|
||||
const dom::BoxQuadOptions& aOptions,
|
||||
nsTArray<RefPtr<DOMQuad> >& aResult,
|
||||
nsTArray<RefPtr<DOMQuad>>& aResult,
|
||||
ErrorResult& aRv) {
|
||||
// We want the quads relative to the window. To do this, we ignore the
|
||||
// provided aOptions.mRelativeTo and instead use the document node of
|
||||
@ -395,14 +392,15 @@ static void TransformPoints(nsINode* aTo, const GeometryNode& aFrom,
|
||||
uint32_t aPointCount, CSSPoint* aPoints,
|
||||
const ConvertCoordinateOptions& aOptions,
|
||||
CallerType aCallerType, ErrorResult& aRv) {
|
||||
nsIFrame* fromFrame = GetFirstNonAnonymousFrameForGeometryNode(aFrom);
|
||||
nsIFrame* fromFrame =
|
||||
GetFirstNonAnonymousFrameForGeometryNode(aFrom, aOptions);
|
||||
AutoWeakFrame weakFrame(fromFrame);
|
||||
nsIFrame* toFrame = GetFirstNonAnonymousFrameForNode(aTo);
|
||||
nsIFrame* toFrame = GetFirstNonAnonymousFrameForNode(aTo, aOptions);
|
||||
// The first frame might be destroyed now if the above call lead to an
|
||||
// EnsureFrameForTextNode call. We need to get the first frame again
|
||||
// when that happens.
|
||||
if (fromFrame && !weakFrame.IsAlive()) {
|
||||
fromFrame = GetFirstNonAnonymousFrameForGeometryNode(aFrom);
|
||||
fromFrame = GetFirstNonAnonymousFrameForGeometryNode(aFrom, aOptions);
|
||||
}
|
||||
if (!fromFrame || !toFrame) {
|
||||
aRv.ThrowNotFoundError(
|
||||
|
@ -40,12 +40,12 @@ typedef dom::OwningTextOrElementOrDocument OwningGeometryNode;
|
||||
* GeometryUtils.getBoxQuads. May set an error in aRv.
|
||||
*/
|
||||
void GetBoxQuads(nsINode* aNode, const dom::BoxQuadOptions& aOptions,
|
||||
nsTArray<RefPtr<dom::DOMQuad> >& aResult,
|
||||
nsTArray<RefPtr<dom::DOMQuad>>& aResult,
|
||||
dom::CallerType aCallerType, ErrorResult& aRv);
|
||||
|
||||
void GetBoxQuadsFromWindowOrigin(nsINode* aNode,
|
||||
const dom::BoxQuadOptions& aOptions,
|
||||
nsTArray<RefPtr<dom::DOMQuad> >& aResult,
|
||||
nsTArray<RefPtr<dom::DOMQuad>>& aResult,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<dom::DOMQuad> ConvertQuadFromNode(
|
||||
|
Loading…
Reference in New Issue
Block a user