import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1217373 - [Presentation WebAPI] Avoid B2G crash due to potential excessive releases in PresentationSessionTransport. r=jdm (58598d7b43)
- Bug 1200969 - Fix timing issue in PresentationRequestUIGlue. r=fabrice (a9d4efcfb0)
- Bug 1217712 - Part 1 - reject session request to packaged app with no "presentation" permission. r=seanlin. (300835465b)
- Bug 1217712 - Part 2 - handle abnormal control channel close with no reason. r=seanlin. (deca080f98)
- Bug 1196947 - Performance tools should display a message in private browsing, r=jsantell (c184a61fa1)
- Bug 1103094 - Add accessor for nsIProfilerStartParams to nsIProfiler. r=BenWa (694cffcb92)
- Bug 366324 - Make SVG favicons work reliably. r=mak (7ba59f3165)
- Bug 1190364 - "With electrolysis (e10s) enabled and lots of tabs open, plugincheck often fails to find any plugins". r=billm (9eb8843429)
- Bug 1103094 - Start profiling subprocesses if the parent process is already profiling. r=BenWa (a53480a19e)
- Bug 1228489 - ifdef out ContentParent::StartProfiler for builds without profiler support. r=BenWa (2ef1eabf21)
- Bug 1211266 - Remote blobs coming from a different thread and a different manager must be kept alive until the creation of depending RemoteBlobs is not completed, r=bent, f=gerard-majax (bb0e2c4731)
- Bug 1098131 - Don't invalidate layers when simply changing SizeMode r=smaug,jimm (d6febd1e61)
- Bug 1187784 (part 5) - Replace nsBaseHashtable::EnumerateRead() calls in layout/ with iterators. r=heycam. (4f63429fb9)
- Bug 1187784 (part 6) - Replace nsBaseHashtable::EnumerateRead() calls in layout/ with iterators. r=heycam. (e6ee55faac)
- Bug 1187784 (part 7) - Replace nsBaseHashtable::EnumerateRead() calls in layout/ with iterators. r=heycam. (562892894a)
- Bug 1187784 (part 8) - Replace nsBaseHashtable::EnumerateRead() calls in layout/ with iterators. r=heycam. (3171c52a3a)
- Bug 1187784 (part 9) - Replace nsBaseHashtable::EnumerateRead() calls in layout/ with iterators. r=heycam. (7e5cb8f45b)
- Bug 1163907 - Remove #ifdef PR_LOGGING in AccessibleCaretLogger (0fcee5100f)
- Bug 1219470 - Replace PRLogModuleInfo with LazyLogModule. r=roc (0385266aac)
- bit of  Bug 1165518 - Part 2 (9b2aa1607f)
- Bug 1221902 part 1 - NS_RELEASE SheetLoadData::mNext iteratively instead of recursively to avoid blowing up the stack. r=bz (6598fea496)
- Bug 1187144 (part 5) - Replace nsBaseHashtable::Enumerate() calls in layout/ with iterators. r=dholbert. (4c87a8f678)
- Bug 1187144 (part 6) - Replace nsBaseHashtable::Enumerate() calls in layout/ with iterators. r=dholbert. (d3155de1bb)
- Bug 1187144 (part 7) - Replace nsBaseHashtable::Enumerate() calls in layout/ with iterators. r=dholbert. (a0c1f927c9)
- Bug 1187144 (part 2) - Replace nsBaseHashtable::Enumerate() calls in layout/ with iterators. r=dholbert. (0bcf383a4f)
- Bug 1219898 - Remove unneccessary gPreventMouseEvents flag. r=smaug (4e0dcf7e15)
- Bug 1187144 (part 1) - Replace nsBaseHashtable::Enumerate() calls in layout/ with iterators. r=heycam. (7b6a125dcd)
- Bug 1187144 (part 3) - Replace nsBaseHashtable::Enumerate() calls in layout/ with iterators. r=dholbert. (64f8a5288e)
- Bug 1158540 - Don't repeat the mRefCnt member of URLValue in ImageValue; r=dbaron (4ac4602546)
- Bug 1187144 (part 4) - Replace nsBaseHashtable::Enumerate() calls in layout/ with iterators. r=dholbert. (d781f47d77)
- Bug 1187144 (part 8) - Replace nsBaseHashtable::Enumerate() calls in layout/ with iterators. r=heycam. (e5d8deeb33)
- Bug 1219898 - Remove legacy handling of touch events for non-APZ e10s platforms. r=smaug (f928694ff8)
- Bug 1187144 (part 9) - Replace nsBaseHashtable::Enumerate() calls in layout/ with iterators. r=heycam. (0464196554)
- Bug 1172012 - Fixes a copy & paste error in nsCSSValue.cpp. r=heycam (fe61a7740b)
- Bug 1176782 part 3 - [css-align] Implement additional syntax and values for the 'justify-content' property in the style system. r=cam (95eb9717b1)
- Bug 1215702 patch 1 - Remove the CSS properties that use CSS_PROP_BACKENDONLY (marks, orphans, page, size, widows), i.e., properties that were added in early Gecko days but never actually implemented. r=heycam (4344349699)
- Bug 1215702 patch 2 - Remove the mechanism of backend-only CSS properties. r=heycam (3ae81722c2)
- Bug 1176782 part 4 - [css-align] Implement additional syntax and values for the 'align-items' property in the style system. r=cam (8048af001a)
- Bug 1176782 part 5 - [css-align] Implement additional syntax and values for the 'align-self' property in the style system. r=cam (b0505102c0)
- Bug 1176782 part 6 - [css-align] Implement additional syntax and values for the 'align-content' property in the style system. r=cam (7b40da66ce)
- Bug 1176782 part 7 - [css-align] Update the flexbox layout code to use the new align/justify style constants and remove the old in the style system. r=cam (67ee4f892a)
- Bug 1176782 part 8 - [css-align] Update three tests that assumed that the computed value of 'align-items' is 'stretch' on all types of boxes which is no longer true. (72a358dce2)
- Bug 1223568: Don't let fallback alignment values break flexbox special-case for "justify-content: stretch". r=mats (329012fbb2)
- Bug 1224804 - [css-align] Make ::-moz-table-outer inherit 'justify-self'. r=dholbert (4e0c2b4d9b)
- Bug 1158540 follow-up: Improve the comment (8a7b4a962f)
- Bug 1227377: Change ImageRequest::mRequests hashtable to use more specific type in its key (s/nsISupports/nsIDocument/). r=khuey (eea7692f2c)
- Bug 1168154 - Mark refcounted members of nsCSSValue::mValue as MOZ_OWNING_REF. r=heycam (2f9db113f1)
- Bug 1228188 - ifdef around Skia GetMaxSurfaceSize usage. r=eihrul (ea0eaa0ea4)
- Bug 1040668 part 1 - Avoid queuing transition event for disabled properties. r=dbaron (07fbda65d4)
- Bug 1139640 test: Add mochitest for DOM properties for CSS properties. r=heycam (f995e71ce7)
- Bug 1180083 - Avoid shadowing info() in test_property_database.html. r=dbaron (266f90254b)
- Bug 1208136: Give property_database.js a helper-function for pref lookups, to catch exceptions thrown for missing about:config prefs. r=dbaron (4ecd90f34e)
- Bug 1176792 part 1 - [css-grid] Implement the 'grid-column-gap', 'grid-row-gap', and 'grid-gap' properties in the style system. r=dholbert,dbaron (83d78611c5)
- Bug 1151213 part 2 - [css-grid][css-align] Reftests for the 'align-self' and 'justify-self' properties on grid items. (7c38f737f4)
- Bug 1151213 part 1 - [css-grid][css-align] Implement layout for the 'align-self' and 'justify-self' properties on grid items. r=dholbert (4e08c284e6)
- Bug 1151214 part 3 - [css-grid][css-align] Implement layout for the 'justify-content' and 'align-content' CSS properties on grid containers. r=dholbert (8a90fa412c)
- Bug 1222880 - Build a tree of AnimatedGeometryRoots to speed up traversal of ancestors. r=roc,tn (f9843046ae)
- Bug 1226875 - Remove nsIFrame::GetFirstChild(). r=mats (a21a74365a)
- Bug 1165667: Use reflow state's reference rendering context during flex layout, instead of creating a temporary one. r=mats (e8afd8bdb6)
- Bug 1151214 part 2 - [css-flexbox][css-align] Shim implemention for the new align/justify property values in flexbox layout (just to avoid fatal assertions). r=dholbert (1350c46c90)
- Bug 1155312: Convert flex container nsHTMLReflowMetrics/aDesiredSize-populating code to use logical coords. r=mats (54a61f1910)
- Bug 1223653 patch 1 - Fix incorrect function being called, caught by enum class type checking in next patch. r=jfkthame (91b2eb348f)
- Bug 1224464 patch 1 - Make nsCSSKeyword explicitly int16_t. r=heycam (7d6f615af5)
- Bug 1224464 patch 2 - Make nsCSSProps keyword tables be arrays of structs, to represent what they logically are. r=heycam (d21a2de083)
- Bug 1215424 - Convert ParseBoxProperty to CSSParseResult and remove ParseBoxPropertyVariant. r=heycam (4aff994d0d)
- Bug 837211 - Add -webkit prefixed aliases for various CSS properties, behind an off-by-default preference. r=bzbarsky (35889a3a30)
- Bug 1211101 part 1: Fix existing style system mochitests to accomodate webkit-prefixed property aliases. r=heycam (237efadebb)
- Bug 1210905 part 2: Remove now-unneeded *_values & prerequisites fields from aliases in property_database.js. r=heycam (ed311c73c5)
- Bug 1211101 part 2: Add supported (preffed off) webkit-prefixed CSS property aliases to property_database.js, for use in mochitests. r=heycam (5c3b7305f0)
- Bug 1179444: Add support for CSS properties -webkit-backface-visibility, -webkit-perspective, and -webkit-perspective-origin, as aliases (behind a pref). r=heycam (73b2c60d52)
- Bug 1208635 part 1: Add support for several prefixed CSS properties associated with -webkit-box, as aliases for modern flexbox properties (and behind a pref). r=heycam (9baa2ba20a)
- Bug 1208635 part 2: Extend existing parser code for CSSUnprefixingService "-webkit-box" handling to also activate if native unprefixing is enabled. r=heycam (89cc559272)
- Bug 1208635 part 3: Treat "-webkit-box" as a known CSS keyword, for better parsing performance. r=heycam (26a452e2cd)
- Bug 1210905 part 1: Make property_database.js automatically populate aliasing properties' *_values & prerequisites fields based on their alias target. r=heycam (a33d38d153)
- Bug 1210905 followup: Restore accidentally-removed 'subproperties' list on -moz-transform-style in style-system mochitest file property_database.js. (no review) (870de9afcb)
- Bug 1212607 - Re-expose -moz-window-dragging property to the content. r=dbaron (073f318ab0)
- Bug 1169837 - Remove box-sizing: padding-box in FF UI & Gecko Tests. r=dholbert (5581f54d75)
- Bug 1212191: In CSS mochitest helper-file "property_database.js", add subproperties array for aliases that are missing it, and make it mandatory for CSS_TYPE_SHORTHAND_AND_LONGHAND. r=heycam (0edd14cb7f)
- Bug 1176968 part 1: Refactor media-query parsing logic to use nsDependentString, to better allow for multiple consecutive prefixes. r=heycam (f3412f99e4)
- some XP theme stuff (245f69a17e)
- Bug 1179393: Add support for -webkit-border-image longhand CSS properties, as aliases (behind a pref). r=heycam (c95d45f6eb)
- Bug 1195884 - Reject CSS 'will-change: will-change' for spec compliance. r=dholbert (8e9c2cefa9)
- Bug 1176792 part 2 - [css-grid] Implement layout for the 'grid-column-gap' and 'grid-row-gap' properties. r=dholbert (c12fd29616)
- Bug 1151214 part 4 - [css-grid][css-align] Add reftests for the 'justify-content' and 'align-content' CSS properties on grid containers. (4924ad5e98)
- Bug 1176792 part 3 - [css-grid] Reftests for the 'grid-column-gap' and 'grid-row-gap' properties. (1bc2319d82)
- Bug 1224464 patch 3 - Rename KTableValue to KTableEntry now that it is a struct. r=heycam (4ebf24dcab)
- Bug 1224464 followup - Fix bustage on opt builds on CLOSED TREE (b23cee92e9)
This commit is contained in:
2023-02-09 12:45:41 +08:00
parent 664ef9175d
commit 1c5d25a761
214 changed files with 8201 additions and 4541 deletions
+39 -16
View File
@@ -4,6 +4,10 @@
"use strict"
function debug(aMsg) {
//dump("-*- PresentationRequestUIGlue: " + aMsg + "\n");
}
const { interfaces: Ci, utils: Cu, classes: Cc } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@@ -26,31 +30,50 @@ function PresentationRequestUIGlue() {
SystemAppProxy.addEventListener("mozPresentationContentEvent", aEvent => {
let detail = aEvent.detail;
if (detail.type != "presentation-receiver-launched") {
return;
}
switch (detail.type) {
case "presentation-receiver-launched": {
let sessionId = detail.id;
let resolver = this._resolvers[sessionId];
if (!resolver) {
debug("No correspondent resolver for session ID: " + sessionId);
return;
}
let sessionId = detail.sessionId;
let resolver = this._resolvers[sessionId];
if (!resolver) {
return;
}
delete this._resolvers[sessionId];
resolver.resolve(detail.frame);
break;
}
case "presentation-receiver-permission-denied": {
let sessionId = detail.id;
let resolver = this._resolvers[sessionId];
if (!resolver) {
debug("No correspondent resolver for session ID: " + sessionId);
return;
}
delete this._resolvers[sessionId];
resolver(detail.frame);
delete this._resolvers[sessionId];
resolver.reject();
break;
}
default:
return;
}
});
}
PresentationRequestUIGlue.prototype = {
sendRequest: function(aUrl, aSessionId) {
SystemAppProxy._sendCustomEvent("mozPresentationChromeEvent",
{ type: "presentation-launch-receiver",
url: aUrl,
id: aSessionId });
return new Promise(function(aResolve, aReject) {
this._resolvers[aSessionId] = aResolve;
this._resolvers[aSessionId] = {
resolve: aResolve,
reject: aReject,
};
SystemAppProxy._sendCustomEvent("mozPresentationChromeEvent",
{ type: "presentation-launch-receiver",
url: aUrl,
id: aSessionId });
}.bind(this));
},
@@ -20,16 +20,13 @@ SystemAppProxy.addEventListener('mozPresentationChromeEvent', function(aEvent) {
addMessageListener('trigger-ui-glue', function(aData) {
var promise = glue.sendRequest(aData.url, aData.sessionId);
promise.then(function(aFrame){
promise.then(function(aFrame) {
sendAsyncMessage('iframe-resolved', aFrame);
}).catch(function() {
sendAsyncMessage('iframe-rejected');
});
});
addMessageListener('trigger-presentation-content-event', function(aData) {
var detail = {
type: 'presentation-receiver-launched',
sessionId: aData.sessionId,
frame: aData.frame
};
SystemAppProxy._sendCustomEvent('mozPresentationContentEvent', detail);
addMessageListener('trigger-presentation-content-event', function(aDetail) {
SystemAppProxy._sendCustomEvent('mozPresentationContentEvent', aDetail);
});
@@ -4,7 +4,7 @@
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<head>
<meta charset="utf-8">
<title>Test for Presentation Device Selection</title>
<title>Test for Presentation UI Glue</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
</head>
@@ -57,14 +57,41 @@ function testReceiverLaunched() {
document.body.appendChild(iframe);
gScript.sendAsyncMessage('trigger-presentation-content-event',
{ sessionId : sessionId,
{ type: 'presentation-receiver-launched',
id: sessionId,
frame: iframe });
});
}
function testLaunchError() {
return new Promise(function(aResolve, aReject) {
gScript.addMessageListener('presentation-launch-receiver', function launchReceiverHandler(aDetail) {
gScript.removeMessageListener('presentation-launch-receiver', launchReceiverHandler);
ok(true, "A presentation-launch-receiver mozPresentationChromeEvent should be received.");
is(aDetail.url, url, "Url should be the same.");
is(aDetail.id, sessionId, "Session ID should be the same.");
gScript.addMessageListener('iframe-rejected', function iframeRejectedHandler() {
gScript.removeMessageListener('iframe-rejected', iframeRejectedHandler);
ok(true, "The promise should be rejected.");
aResolve();
});
gScript.sendAsyncMessage('trigger-presentation-content-event',
{ type: 'presentation-receiver-permission-denied',
id: sessionId });
});
gScript.sendAsyncMessage('trigger-ui-glue',
{ url: url,
sessionId : sessionId });
});
}
function runTests() {
testLaunchReceiver()
.then(testReceiverLaunched)
.then(testLaunchError)
.then(function() {
info('test finished, teardown');
gScript.destroy();
+1 -1
View File
@@ -6,7 +6,7 @@
body {
display: flex;
box-sizing: padding-box;
box-sizing: border-box;
min-height: 100vh;
padding: 0 48px;
align-items: center;
+18 -2
View File
@@ -5959,8 +5959,20 @@ nsDocShell::GetIsOffScreenBrowser(bool* aIsOffScreen)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetIsActiveAndForeground(bool aIsActive)
{
return SetIsActiveInternal(aIsActive, false);
}
NS_IMETHODIMP
nsDocShell::SetIsActive(bool aIsActive)
{
return SetIsActiveInternal(aIsActive, true);
}
nsresult
nsDocShell::SetIsActiveInternal(bool aIsActive, bool aIsHidden)
{
// We disallow setting active on chrome docshells.
if (mItemType == nsIDocShellTreeItem::typeChrome) {
@@ -5973,7 +5985,7 @@ nsDocShell::SetIsActive(bool aIsActive)
// Tell the PresShell about it.
nsCOMPtr<nsIPresShell> pshell = GetPresShell();
if (pshell) {
pshell->SetIsActive(aIsActive);
pshell->SetIsActive(aIsActive, aIsHidden);
}
// Tell the window about it
@@ -6007,7 +6019,11 @@ nsDocShell::SetIsActive(bool aIsActive)
}
if (!docshell->GetIsBrowserOrApp()) {
docshell->SetIsActive(aIsActive);
if (aIsHidden) {
docshell->SetIsActive(aIsActive);
} else {
docshell->SetIsActiveAndForeground(aIsActive);
}
}
}
+2
View File
@@ -490,6 +490,8 @@ protected:
uint32_t aRedirectFlags,
uint32_t aStateFlags) override;
nsresult SetIsActiveInternal(bool aIsActive, bool aIsHidden);
/**
* Helper function that determines if channel is an HTTP POST.
*
+7 -1
View File
@@ -46,7 +46,7 @@ interface nsITabParent;
typedef unsigned long nsLoadFlags;
[scriptable, builtinclass, uuid(b1df6e41-c8dd-45c2-bc18-dd330d986214)]
[scriptable, builtinclass, uuid(41b1cf17-b37b-4a62-9df8-5f67cfecab3f)]
interface nsIDocShell : nsIDocShellTreeItem
{
/**
@@ -617,6 +617,12 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
attribute boolean isActive;
/**
* Sets whether a docshell is active, as above, but ensuring it does
* not discard its layers
*/
void setIsActiveAndForeground(in boolean aIsActive);
/**
* Puts the docshell in prerendering mode. noscript because we want only
* native code to be able to put a docshell in prerendering.
+6 -3
View File
@@ -559,14 +559,15 @@ EnsureBlobForBackgroundManager(BlobImpl* aBlobImpl,
PBackgroundChild* aManager = nullptr)
{
MOZ_ASSERT(aBlobImpl);
RefPtr<BlobImpl> blobImpl = aBlobImpl;
if (!aManager) {
aManager = BackgroundChild::GetForCurrentThread();
MOZ_ASSERT(aManager);
if (!aManager) {
return blobImpl.forget();
}
}
RefPtr<BlobImpl> blobImpl = aBlobImpl;
const nsTArray<RefPtr<BlobImpl>>* subBlobImpls =
aBlobImpl->GetSubBlobImpls();
@@ -671,6 +672,8 @@ WriteBlob(JSStructuredCloneWriter* aWriter,
RefPtr<BlobImpl> blobImpl = EnsureBlobForBackgroundManager(aBlob->Impl());
MOZ_ASSERT(blobImpl);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blobImpl->SetMutable(false)));
// We store the position of the blobImpl in the array as index.
if (JS_WriteUint32Pair(aWriter, SCTAG_DOM_BLOB,
aHolder->BlobImpls().Length())) {
+1 -1
View File
@@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=320799
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=320799">Mozilla Bug 320799</a>
<p id="display">
<select id="s" style="width: 100px; box-sizing: padding-box">
<select id="s" style="width: 100px; box-sizing: border-box; border: 0">
<option>This is a test, it really is a test I tell you</option>
</select>
<select id="s2">
+5 -5
View File
@@ -413,13 +413,13 @@ function testPreventDefault() {
{ name: "touchmove", prevent: false },
{ name: "touchend", prevent: false }],
[{ name: "touchstart", prevent: true, doPrevent: true },
{ name: "touchmove", prevent: true },
{ name: "touchmove", prevent: true },
{ name: "touchend", prevent: true }],
{ name: "touchmove", prevent: false },
{ name: "touchmove", prevent: false },
{ name: "touchend", prevent: false }],
[{ name: "touchstart", prevent: false },
{ name: "touchmove", prevent: true, doPrevent: true },
{ name: "touchmove", prevent: true },
{ name: "touchend", prevent: true }],
{ name: "touchmove", prevent: false },
{ name: "touchend", prevent: false }],
[{ name: "touchstart", prevent: false },
{ name: "touchmove", prevent: false },
{ name: "touchmove", prevent: false, doPrevent: true },
+12 -1
View File
@@ -5,7 +5,7 @@
#include "domstubs.idl"
[scriptable, uuid(3dd203e4-66ec-40fd-acde-43f0b35c98e9)]
[scriptable, uuid(7615408c-1fb3-4128-8dd5-a3e2f3fa8842)]
interface nsITabParent : nsISupports
{
void injectTouchEvent(in AString aType,
@@ -28,6 +28,17 @@ interface nsITabParent : nsISupports
*/
attribute boolean docShellIsActive;
/**
* As an optimisation, setting the docshell's active state to
* inactive also triggers a layer invalidation to free up some
* potentially unhelpful memory usage. This attribute should be
* used where callers would like to set the docshell's state
* without losing any layer data.
*
* Otherwise, this does the same as setting the attribute above.
*/
void setDocShellIsActiveAndForeground(in boolean aIsActive);
readonly attribute uint64_t tabId;
/**
+73 -57
View File
@@ -1753,6 +1753,12 @@ protected:
BlobChild* mActor;
nsCOMPtr<nsIEventTarget> mActorTarget;
// We use this pointer to keep a live a blobImpl coming from a different
// process until this one is fully created. We set it to null when
// SendCreatedFromKnownBlob() is received. This is used only with KnownBlob
// params in the CTOR of a IPC BlobImpl.
RefPtr<BlobImpl> mDifferentProcessBlobImpl;
RefPtr<BlobImpl> mSameProcessBlobImpl;
const bool mIsSlice;
@@ -1760,31 +1766,20 @@ protected:
public:
// For File.
RemoteBlobImpl(BlobChild* aActor,
BlobImpl* aRemoteBlobImpl,
const nsAString& aName,
const nsAString& aContentType,
uint64_t aLength,
int64_t aModDate,
BlobDirState aDirState);
BlobDirState aDirState,
bool aIsSameProcessBlob);
// For Blob.
RemoteBlobImpl(BlobChild* aActor,
const nsAString& aContentType,
uint64_t aLength);
// For same-process blobs.
RemoteBlobImpl(BlobChild* aActor,
BlobImpl* aSameProcessBlobImpl,
const nsAString& aName,
BlobImpl* aRemoteBlobImpl,
const nsAString& aContentType,
uint64_t aLength,
int64_t aModDate,
BlobDirState aDirState);
// For same-process blobs.
RemoteBlobImpl(BlobChild* aActor,
BlobImpl* aSameProcessBlobImpl,
const nsAString& aContentType,
uint64_t aLength);
bool aIsSameProcessBlob);
// For mystery blobs.
explicit
@@ -1857,6 +1852,13 @@ public:
virtual BlobParent*
GetBlobParent() override;
void
NullifyDifferentProcessBlobImpl()
{
MOZ_ASSERT(mDifferentProcessBlobImpl);
mDifferentProcessBlobImpl = nullptr;
}
protected:
// For SliceImpl.
RemoteBlobImpl(const nsAString& aContentType, uint64_t aLength);
@@ -2086,56 +2088,43 @@ private:
BlobChild::
RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor,
BlobImpl* aRemoteBlobImpl,
const nsAString& aName,
const nsAString& aContentType,
uint64_t aLength,
int64_t aModDate,
BlobDirState aDirState)
BlobDirState aDirState,
bool aIsSameProcessBlob)
: BlobImplBase(aName, aContentType, aLength, aModDate, aDirState)
, mIsSlice(false)
{
if (aIsSameProcessBlob) {
MOZ_ASSERT(aRemoteBlobImpl);
mSameProcessBlobImpl = aRemoteBlobImpl;
MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
} else {
mDifferentProcessBlobImpl = aRemoteBlobImpl;
}
CommonInit(aActor);
}
BlobChild::
RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor,
const nsAString& aContentType,
uint64_t aLength)
: BlobImplBase(aContentType, aLength)
, mIsSlice(false)
{
CommonInit(aActor);
}
BlobChild::
RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor,
BlobImpl* aSameProcessBlobImpl,
const nsAString& aName,
BlobImpl* aRemoteBlobImpl,
const nsAString& aContentType,
uint64_t aLength,
int64_t aModDate,
BlobDirState aDirState)
: BlobImplBase(aName, aContentType, aLength, aModDate, aDirState)
, mSameProcessBlobImpl(aSameProcessBlobImpl)
, mIsSlice(false)
{
MOZ_ASSERT(aSameProcessBlobImpl);
MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
CommonInit(aActor);
}
BlobChild::
RemoteBlobImpl::RemoteBlobImpl(BlobChild* aActor,
BlobImpl* aSameProcessBlobImpl,
const nsAString& aContentType,
uint64_t aLength)
bool aIsSameProcessBlob)
: BlobImplBase(aContentType, aLength)
, mSameProcessBlobImpl(aSameProcessBlobImpl)
, mIsSlice(false)
{
MOZ_ASSERT(aSameProcessBlobImpl);
MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
if (aIsSameProcessBlob) {
MOZ_ASSERT(aRemoteBlobImpl);
mSameProcessBlobImpl = aRemoteBlobImpl;
MOZ_ASSERT(gProcessType == GeckoProcessType_Default);
} else {
mDifferentProcessBlobImpl = aRemoteBlobImpl;
}
CommonInit(aActor);
}
@@ -3033,7 +3022,7 @@ BlobChild::CommonInit(BlobChild* aOther, BlobImpl* aBlobImpl)
uint64_t length = otherImpl->GetSize(rv);
MOZ_ASSERT(!rv.Failed());
RefPtr<RemoteBlobImpl> remoteBlob;
RemoteBlobImpl* remoteBlob = nullptr;
if (otherImpl->IsFile()) {
nsString name;
otherImpl->GetName(name);
@@ -3041,12 +3030,20 @@ BlobChild::CommonInit(BlobChild* aOther, BlobImpl* aBlobImpl)
int64_t modDate = otherImpl->GetLastModified(rv);
MOZ_ASSERT(!rv.Failed());
remoteBlob = new RemoteBlobImpl(this, name, contentType, length, modDate,
otherImpl->GetDirState());
remoteBlob = new RemoteBlobImpl(this, otherImpl, name, contentType, length,
modDate, otherImpl->GetDirState(),
false /* SameProcessBlobImpl */);
} else {
remoteBlob = new RemoteBlobImpl(this, contentType, length);
remoteBlob = new RemoteBlobImpl(this, otherImpl, contentType, length,
false /* SameProcessBlobImpl */);
}
// This RemoteBlob must be kept alive untill RecvCreatedFromKnownBlob is
// called because the parent will send this notification and we must be able
// to manage it.
MOZ_ASSERT(remoteBlob);
remoteBlob->AddRef();
CommonInit(aOther->ParentID(), remoteBlob);
}
@@ -3073,7 +3070,8 @@ BlobChild::CommonInit(const ChildBlobConstructorParams& aParams)
const NormalBlobConstructorParams& params =
blobParams.get_NormalBlobConstructorParams();
remoteBlob =
new RemoteBlobImpl(this, params.contentType(), params.length());
new RemoteBlobImpl(this, nullptr, params.contentType(), params.length(),
false /* SameProcessBlobImpl */);
break;
}
@@ -3081,11 +3079,13 @@ BlobChild::CommonInit(const ChildBlobConstructorParams& aParams)
const FileBlobConstructorParams& params =
blobParams.get_FileBlobConstructorParams();
remoteBlob = new RemoteBlobImpl(this,
nullptr,
params.name(),
params.contentType(),
params.length(),
params.modDate(),
BlobDirState(params.dirState()));
BlobDirState(params.dirState()),
false /* SameProcessBlobImpl */);
break;
}
@@ -3120,9 +3120,11 @@ BlobChild::CommonInit(const ChildBlobConstructorParams& aParams)
contentType,
size,
lastModifiedDate,
blobImpl->GetDirState());
blobImpl->GetDirState(),
true /* SameProcessBlobImpl */);
} else {
remoteBlob = new RemoteBlobImpl(this, blobImpl, contentType, size);
remoteBlob = new RemoteBlobImpl(this, blobImpl, contentType, size,
true /* SameProcessBlobImpl */);
}
break;
@@ -3592,6 +3594,20 @@ BlobChild::DeallocPBlobStreamChild(PBlobStreamChild* aActor)
return true;
}
bool
BlobChild::RecvCreatedFromKnownBlob()
{
MOZ_ASSERT(mRemoteBlobImpl);
// Releasing the other blob now that this blob is fully created.
mRemoteBlobImpl->NullifyDifferentProcessBlobImpl();
// Release the additional reference to ourself that was added in order to
// receive this RecvCreatedFromKnownBlob.
mRemoteBlobImpl->Release();
return true;
}
/*******************************************************************************
* BlobParent
******************************************************************************/
+3
View File
@@ -220,6 +220,9 @@ private:
virtual bool
DeallocPBlobStreamChild(PBlobStreamChild* aActor) override;
virtual bool
RecvCreatedFromKnownBlob() override;
};
// Only let ContentChild call BlobChild::Startup() and ensure that
+7 -9
View File
@@ -2806,22 +2806,20 @@ ContentChild::RecvOnAppThemeChanged()
}
bool
ContentChild::RecvStartProfiler(const uint32_t& aEntries,
const double& aInterval,
nsTArray<nsCString>&& aFeatures,
nsTArray<nsCString>&& aThreadNameFilters)
ContentChild::RecvStartProfiler(const ProfilerInitParams& params)
{
nsTArray<const char*> featureArray;
for (size_t i = 0; i < aFeatures.Length(); ++i) {
featureArray.AppendElement(aFeatures[i].get());
for (size_t i = 0; i < params.features().Length(); ++i) {
featureArray.AppendElement(params.features()[i].get());
}
nsTArray<const char*> threadNameFilterArray;
for (size_t i = 0; i < aThreadNameFilters.Length(); ++i) {
threadNameFilterArray.AppendElement(aThreadNameFilters[i].get());
for (size_t i = 0; i < params.threadFilters().Length(); ++i) {
threadNameFilterArray.AppendElement(params.threadFilters()[i].get());
}
profiler_start(aEntries, aInterval, featureArray.Elements(), featureArray.Length(),
profiler_start(params.entries(), params.interval(),
featureArray.Elements(), featureArray.Length(),
threadNameFilterArray.Elements(), threadNameFilterArray.Length());
return true;
+1 -4
View File
@@ -418,10 +418,7 @@ public:
const bool& aResult) override;
virtual bool RecvUpdateWindow(const uintptr_t& aChildId) override;
virtual bool RecvStartProfiler(const uint32_t& aEntries,
const double& aInterval,
nsTArray<nsCString>&& aFeatures,
nsTArray<nsCString>&& aThreadNameFilters) override;
virtual bool RecvStartProfiler(const ProfilerInitParams& params) override;
virtual bool RecvPauseProfiler(const bool& aPause) override;
virtual bool RecvStopProfiler() override;
virtual bool RecvGatherProfile() override;
+51 -8
View File
@@ -1220,10 +1220,12 @@ ContentParent::RecvGetBlocklistState(const uint32_t& aPluginId,
bool
ContentParent::RecvFindPlugins(const uint32_t& aPluginEpoch,
nsresult* aRv,
nsTArray<PluginTag>* aPlugins,
uint32_t* aNewPluginEpoch)
{
return mozilla::plugins::FindPluginsForContent(aPluginEpoch, aPlugins, aNewPluginEpoch);
*aRv = mozilla::plugins::FindPluginsForContent(aPluginEpoch, aPlugins, aNewPluginEpoch);
return true;
}
/*static*/ TabParent*
@@ -1551,6 +1553,21 @@ ContentParent::Init()
Unused << SendActivateA11y();
}
#endif
#ifdef MOZ_ENABLE_PROFILER_SPS
nsCOMPtr<nsIProfiler> profiler(do_GetService("@mozilla.org/tools/profiler;1"));
bool profilerActive = false;
DebugOnly<nsresult> rv = profiler->IsActive(&profilerActive);
MOZ_ASSERT(NS_SUCCEEDED(rv));
if (profilerActive) {
nsCOMPtr<nsIProfilerStartParams> currentProfilerParams;
rv = profiler->GetStartParams(getter_AddRefs(currentProfilerParams));
MOZ_ASSERT(NS_SUCCEEDED(rv));
StartProfiler(currentProfilerParams);
}
#endif
}
void
@@ -3276,13 +3293,7 @@ ContentParent::Observe(nsISupports* aSubject,
#ifdef MOZ_ENABLE_PROFILER_SPS
else if (!strcmp(aTopic, "profiler-started")) {
nsCOMPtr<nsIProfilerStartParams> params(do_QueryInterface(aSubject));
uint32_t entries;
double interval;
params->GetEntries(&entries);
params->GetInterval(&interval);
const nsTArray<nsCString>& features = params->GetFeatures();
const nsTArray<nsCString>& threadFilterNames = params->GetThreadFilterNames();
Unused << SendStartProfiler(entries, interval, features, threadFilterNames);
StartProfiler(params);
}
else if (!strcmp(aTopic, "profiler-stopped")) {
Unused << SendStopProfiler();
@@ -3516,6 +3527,18 @@ ContentParent::DeallocPBlobParent(PBlobParent* aActor)
return nsIContentParent::DeallocPBlobParent(aActor);
}
bool
ContentParent::RecvPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& aParams)
{
const ParentBlobConstructorParams& params = aParams.get_ParentBlobConstructorParams();
if (params.blobParams().type() == AnyBlobConstructorParams::TKnownBlobConstructorParams) {
return aActor->SendCreatedFromKnownBlob();
}
return true;
}
mozilla::PRemoteSpellcheckEngineParent *
ContentParent::AllocPRemoteSpellcheckEngineParent()
{
@@ -5762,6 +5785,26 @@ ContentParent::RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo)
#endif
}
void
ContentParent::StartProfiler(nsIProfilerStartParams* aParams)
{
#ifdef MOZ_ENABLE_PROFILER_SPS
if (NS_WARN_IF(!aParams)) {
return;
}
ProfilerInitParams ipcParams;
ipcParams.enabled() = true;
aParams->GetEntries(&ipcParams.entries());
aParams->GetInterval(&ipcParams.interval());
ipcParams.features() = aParams->GetFeatures();
ipcParams.threadFilters() = aParams->GetThreadFilterNames();
Unused << SendStartProfiler(ipcParams);
#endif
}
} // namespace dom
} // namespace mozilla
+5
View File
@@ -191,6 +191,7 @@ public:
virtual bool RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv) override;
virtual bool RecvGetBlocklistState(const uint32_t& aPluginId, uint32_t* aIsBlocklisted) override;
virtual bool RecvFindPlugins(const uint32_t& aPluginEpoch,
nsresult* aRv,
nsTArray<PluginTag>* aPlugins,
uint32_t* aNewPluginEpoch) override;
@@ -647,6 +648,9 @@ private:
override;
virtual bool DeallocPBlobParent(PBlobParent* aActor) override;
virtual bool RecvPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& params) override;
virtual bool DeallocPCrashReporterParent(PCrashReporterParent* crashreporter) override;
virtual bool RecvGetRandomValues(const uint32_t& length,
@@ -940,6 +944,7 @@ private:
virtual bool RecvGamepadListenerRemoved() override;
virtual bool RecvProfile(const nsCString& aProfile) override;
virtual bool RecvGetGraphicsDeviceInitData(DeviceInitData* aOut) override;
void StartProfiler(nsIProfilerStartParams* aParams);
virtual bool RecvGetDeviceStorageLocation(const nsString& aType,
nsString* aPath) override;
+5
View File
@@ -45,6 +45,11 @@ parent:
// Use only for testing!
sync GetFilePath()
returns (nsString filePath);
child:
// This method must be called by the parent when the PBlobParent is fully
// created in order to release the known blob.
CreatedFromKnownBlob();
};
} // namespace dom
+1 -1
View File
@@ -687,7 +687,7 @@ child:
/**
* Update the child side docShell active (resource use) state.
*/
SetDocShellIsActive(bool aIsActive);
SetDocShellIsActive(bool aIsActive, bool aIsHidden);
/**
* Navigate by key (Tab/Shift+Tab/F6/Shift+f6).
+3 -3
View File
@@ -64,6 +64,7 @@ include PBackgroundSharedTypes;
include PContentPermission;
include BrowserConfiguration;
include GraphicsMessages;
include ProfilerTypes;
// Workaround to prevent error if PContentChild.cpp & PContentBridgeParent.cpp
// are put into different UnifiedProtocolsXX.cpp files.
@@ -645,8 +646,7 @@ child:
/**
* Control the Gecko Profiler in the child process.
*/
async StartProfiler(uint32_t aEntries, double aInterval, nsCString[] aFeatures,
nsCString[] aThreadNameFilters);
async StartProfiler(ProfilerInitParams params);
async StopProfiler();
async PauseProfiler(bool aPause);
@@ -767,7 +767,7 @@ parent:
* process. |newPluginEpoch| is the current epoch in the chrome process. If
* |pluginEpoch == newPluginEpoch|, then |plugins| will be left empty.
*/
sync FindPlugins(uint32_t pluginEpoch) returns (PluginTag[] plugins, uint32_t newPluginEpoch);
sync FindPlugins(uint32_t pluginEpoch) returns (nsresult aResult, PluginTag[] plugins, uint32_t newPluginEpoch);
async PJavaScript();
+9 -180
View File
@@ -130,32 +130,6 @@ static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
static TabChildMap* sTabChildren;
class TabChild::DelayedFireContextMenuEvent final : public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
explicit DelayedFireContextMenuEvent(TabChild* tabChild)
: mTabChild(tabChild)
{
}
NS_IMETHODIMP Notify(nsITimer*) override
{
mTabChild->FireContextMenuEvent();
return NS_OK;
}
private:
~DelayedFireContextMenuEvent()
{
}
// Raw pointer is safe here because this object is held by a Timer, which is
// held by TabChild, we won't stay alive if TabChild dies.
TabChild *mTabChild;
};
static bool
UsingCompositorLRU()
{
@@ -169,9 +143,6 @@ UsingCompositorLRU()
return sCompositorLRUSize != 0;
}
NS_IMPL_ISUPPORTS(TabChild::DelayedFireContextMenuEvent,
nsITimerCallback)
TabChildBase::TabChildBase()
: mTabChildGlobal(nullptr)
{
@@ -601,7 +572,6 @@ TabChild::TabChild(nsIContentChild* aManager,
, mManager(aManager)
, mChromeFlags(aChromeFlags)
, mLayersId(0)
, mActivePointerId(-1)
, mAppPackageFileDescriptorRecved(false)
, mDidFakeShow(false)
, mNotified(false)
@@ -1834,153 +1804,6 @@ TabChild::RecvMouseScrollTestEvent(const FrameMetrics::ViewID& aScrollId, const
return true;
}
static Touch*
GetTouchForIdentifier(const WidgetTouchEvent& aEvent, int32_t aId)
{
for (uint32_t i = 0; i < aEvent.touches.Length(); ++i) {
Touch* touch = static_cast<Touch*>(aEvent.touches[i].get());
if (touch->mIdentifier == aId) {
return touch;
}
}
return nullptr;
}
void
TabChild::UpdateTapState(const WidgetTouchEvent& aEvent, nsEventStatus aStatus)
{
static bool sHavePrefs;
static bool sClickHoldContextMenusEnabled;
static nsIntSize sDragThreshold;
static int32_t sContextMenuDelayMs;
if (!sHavePrefs) {
sHavePrefs = true;
Preferences::AddBoolVarCache(&sClickHoldContextMenusEnabled,
"ui.click_hold_context_menus", true);
Preferences::AddIntVarCache(&sDragThreshold.width,
"ui.dragThresholdX", 25);
Preferences::AddIntVarCache(&sDragThreshold.height,
"ui.dragThresholdY", 25);
Preferences::AddIntVarCache(&sContextMenuDelayMs,
"ui.click_hold_context_menus.delay", 500);
}
if (aEvent.touches.Length() == 0) {
return;
}
bool currentlyTrackingTouch = (mActivePointerId >= 0);
if (aEvent.mMessage == eTouchStart) {
if (currentlyTrackingTouch || aEvent.touches.Length() > 1) {
// We're tracking a possible tap for another point, or we saw a
// touchstart for a later pointer after we canceled tracking of
// the first point. Ignore this one.
return;
}
if (aStatus == nsEventStatus_eConsumeNoDefault ||
TouchManager::gPreventMouseEvents ||
aEvent.mFlags.mMultipleActionsPrevented) {
return;
}
Touch* touch = aEvent.touches[0];
mGestureDownPoint = LayoutDevicePoint(touch->mRefPoint.x, touch->mRefPoint.y);
mActivePointerId = touch->mIdentifier;
if (sClickHoldContextMenusEnabled) {
MOZ_ASSERT(!mTapHoldTimer);
mTapHoldTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
RefPtr<DelayedFireContextMenuEvent> callback =
new DelayedFireContextMenuEvent(this);
mTapHoldTimer->InitWithCallback(callback,
sContextMenuDelayMs,
nsITimer::TYPE_ONE_SHOT);
}
return;
}
// If we're not tracking a touch or this event doesn't include the
// one we care about, bail.
if (!currentlyTrackingTouch) {
return;
}
Touch* trackedTouch = GetTouchForIdentifier(aEvent, mActivePointerId);
if (!trackedTouch) {
return;
}
LayoutDevicePoint currentPoint = LayoutDevicePoint(trackedTouch->mRefPoint.x, trackedTouch->mRefPoint.y);
int64_t time = aEvent.time;
switch (aEvent.mMessage) {
case eTouchMove:
if (std::abs(currentPoint.x - mGestureDownPoint.x) > sDragThreshold.width ||
std::abs(currentPoint.y - mGestureDownPoint.y) > sDragThreshold.height) {
CancelTapTracking();
}
return;
case eTouchEnd:
if (!TouchManager::gPreventMouseEvents) {
APZCCallbackHelper::DispatchSynthesizedMouseEvent(
eMouseMove, time, currentPoint, 0, mPuppetWidget);
APZCCallbackHelper::DispatchSynthesizedMouseEvent(
eMouseDown, time, currentPoint, 0, mPuppetWidget);
APZCCallbackHelper::DispatchSynthesizedMouseEvent(
eMouseUp, time, currentPoint, 0, mPuppetWidget);
}
// fall through
case eTouchCancel:
CancelTapTracking();
return;
default:
NS_WARNING("Unknown touch event type");
}
}
void
TabChild::FireContextMenuEvent()
{
if (mDestroyed) {
return;
}
double scale;
GetDefaultScale(&scale);
if (scale < 0) {
scale = 1;
}
MOZ_ASSERT(mTapHoldTimer && mActivePointerId >= 0);
bool defaultPrevented = APZCCallbackHelper::DispatchMouseEvent(
GetPresShell(),
NS_LITERAL_STRING("contextmenu"),
mGestureDownPoint / CSSToLayoutDeviceScale(scale),
2 /* Right button */,
1 /* Click count */,
0 /* Modifiers */,
true /* Ignore root scroll frame */,
nsIDOMMouseEvent::MOZ_SOURCE_TOUCH);
// Fire a click event if someone didn't call preventDefault() on the context
// menu event.
if (defaultPrevented) {
CancelTapTracking();
} else if (mTapHoldTimer) {
mTapHoldTimer->Cancel();
mTapHoldTimer = nullptr;
}
}
void
TabChild::CancelTapTracking()
{
mActivePointerId = -1;
if (mTapHoldTimer) {
mTapHoldTimer->Cancel();
}
mTapHoldTimer = nullptr;
}
bool
TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid,
@@ -2009,7 +1832,9 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
if (!AsyncPanZoomEnabled()) {
UpdateTapState(localEvent, status);
// We shouldn't have any e10s platforms that have touch events enabled
// without APZ.
MOZ_ASSERT(false);
return true;
}
@@ -2445,11 +2270,15 @@ TabChild::RecvSetUpdateHitRegion(const bool& aEnabled)
}
bool
TabChild::RecvSetDocShellIsActive(const bool& aIsActive)
TabChild::RecvSetDocShellIsActive(const bool& aIsActive, const bool& aIsHidden)
{
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
if (docShell) {
docShell->SetIsActive(aIsActive);
if (aIsHidden) {
docShell->SetIsActive(aIsActive);
} else {
docShell->SetIsActiveAndForeground(aIsActive);
}
}
return true;
}
+1 -22
View File
@@ -533,7 +533,7 @@ protected:
virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) override;
virtual bool RecvDestroy() override;
virtual bool RecvSetUpdateHitRegion(const bool& aEnabled) override;
virtual bool RecvSetDocShellIsActive(const bool& aIsActive) override;
virtual bool RecvSetDocShellIsActive(const bool& aIsActive, const bool& aIsHidden) override;
virtual bool RecvNavigateByKey(const bool& aForward, const bool& aForDocumentNavigation) override;
virtual bool RecvRequestNotifyAfterRemotePaint() override;
@@ -549,8 +549,6 @@ protected:
#endif
private:
class DelayedFireContextMenuEvent;
// Notify others that our TabContext has been updated. (At the moment, this
// sets the appropriate app-id and is-browser flags on our docshell.)
//
@@ -570,16 +568,6 @@ private:
void ApplyShowInfo(const ShowInfo& aInfo);
// These methods are used for tracking synthetic mouse events
// dispatched for compatibility. On each touch event, we
// UpdateTapState(). If we've detected that the current gesture
// isn't a tap, then we CancelTapTracking(). In the meantime, we
// may detect a context-menu event, and if so we
// FireContextMenuEvent().
void FireContextMenuEvent();
void CancelTapTracking();
void UpdateTapState(const WidgetTouchEvent& aEvent, nsEventStatus aStatus);
bool HasValidInnerSize();
void SetTabId(const TabId& aTabId);
@@ -603,15 +591,6 @@ private:
uint32_t mChromeFlags;
uint64_t mLayersId;
CSSRect mUnscaledOuterRect;
// When we're tracking a possible tap gesture, this is the "down"
// point of the touchstart.
LayoutDevicePoint mGestureDownPoint;
// The touch identifier of the active gesture.
int32_t mActivePointerId;
// A timer task that fires if the tap-hold timeout is exceeded by
// the touch we're tracking. That is, if touchend or a touchmove
// that exceeds the gesture threshold doesn't happen.
nsCOMPtr<nsITimer> mTapHoldTimer;
// Whether we have already received a FileDescriptor for the app package.
bool mAppPackageFileDescriptorRecved;
// At present only 1 of these is really expected.
+9 -1
View File
@@ -2910,7 +2910,7 @@ NS_IMETHODIMP
TabParent::SetDocShellIsActive(bool isActive)
{
mDocShellIsActive = isActive;
Unused << SendSetDocShellIsActive(isActive);
Unused << SendSetDocShellIsActive(isActive, true);
return NS_OK;
}
@@ -2921,6 +2921,14 @@ TabParent::GetDocShellIsActive(bool* aIsActive)
return NS_OK;
}
NS_IMETHODIMP
TabParent::SetDocShellIsActiveAndForeground(bool isActive)
{
mDocShellIsActive = isActive;
Unused << SendSetDocShellIsActive(isActive, false);
return NS_OK;
}
NS_IMETHODIMP
TabParent::GetTabId(uint64_t* aId)
{
+12 -7
View File
@@ -2349,9 +2349,11 @@ nsPluginHost::FindPluginsInContent(bool aCreatePluginList, bool* aPluginsChanged
MOZ_ASSERT(XRE_IsContentProcess());
dom::ContentChild* cp = dom::ContentChild::GetSingleton();
nsresult rv;
nsTArray<PluginTag> plugins;
uint32_t parentEpoch;
if (!cp->SendFindPlugins(ChromeEpochForContent(), &plugins, &parentEpoch)) {
if (!cp->SendFindPlugins(ChromeEpochForContent(), &rv, &plugins, &parentEpoch) ||
NS_FAILED(rv)) {
return NS_ERROR_NOT_AVAILABLE;
}
@@ -2564,7 +2566,7 @@ nsresult nsPluginHost::FindPlugins(bool aCreatePluginList, bool * aPluginsChange
return NS_OK;
}
bool
nsresult
mozilla::plugins::FindPluginsForContent(uint32_t aPluginEpoch,
nsTArray<PluginTag>* aPlugins,
uint32_t* aNewPluginEpoch)
@@ -2572,11 +2574,10 @@ mozilla::plugins::FindPluginsForContent(uint32_t aPluginEpoch,
MOZ_ASSERT(XRE_IsParentProcess());
RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
host->FindPluginsForContent(aPluginEpoch, aPlugins, aNewPluginEpoch);
return true;
return host->FindPluginsForContent(aPluginEpoch, aPlugins, aNewPluginEpoch);
}
void
nsresult
nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch,
nsTArray<PluginTag>* aPlugins,
uint32_t* aNewPluginEpoch)
@@ -2584,11 +2585,14 @@ nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch,
MOZ_ASSERT(XRE_IsParentProcess());
// Load plugins so that the epoch is correct.
LoadPlugins();
nsresult rv = LoadPlugins();
if (NS_FAILED(rv)) {
return rv;
}
*aNewPluginEpoch = ChromeEpoch();
if (aPluginEpoch == ChromeEpoch()) {
return;
return NS_OK;
}
nsTArray<nsCOMPtr<nsIInternalPluginTag>> plugins;
@@ -2628,6 +2632,7 @@ nsPluginHost::FindPluginsForContent(uint32_t aPluginEpoch,
tag->mLastModifiedTime,
tag->IsFromExtension()));
}
return NS_OK;
}
// This function is not relevant for fake plugins.
+3 -3
View File
@@ -119,9 +119,9 @@ public:
void GetPlugins(nsTArray<nsCOMPtr<nsIInternalPluginTag>>& aPluginArray,
bool aIncludeDisabled = false);
void FindPluginsForContent(uint32_t aPluginEpoch,
nsTArray<mozilla::plugins::PluginTag>* aPlugins,
uint32_t* aNewPluginEpoch);
nsresult FindPluginsForContent(uint32_t aPluginEpoch,
nsTArray<mozilla::plugins::PluginTag>* aPlugins,
uint32_t* aNewPluginEpoch);
nsresult GetURL(nsISupports* pluginInst,
const char* url,
+2 -2
View File
@@ -7,6 +7,7 @@ include protocol PPluginInstance;
include protocol PPluginScriptableObject;
include protocol PCrashReporter;
include protocol PContent;
include ProfilerTypes;
using NPError from "npapi.h";
using NPNVariable from "npapi.h";
@@ -95,8 +96,7 @@ child:
/**
* Control the Gecko Profiler in the plugin process.
*/
async StartProfiler(uint32_t aEntries, double aInterval, nsCString[] aFeatures,
nsCString[] aThreadNameFilters);
async StartProfiler(ProfilerInitParams params);
async StopProfiler();
async GatherProfile();
+1 -1
View File
@@ -19,7 +19,7 @@ bool
SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentParent,
bool aForceBridgeNow, nsresult* aResult, uint32_t* aRunID);
bool
nsresult
FindPluginsForContent(uint32_t aPluginEpoch,
nsTArray<PluginTag>* aPlugins,
uint32_t* aNewPluginEpoch);
+7 -9
View File
@@ -2495,22 +2495,20 @@ PluginModuleChild::ProcessNativeEvents() {
#endif
bool
PluginModuleChild::RecvStartProfiler(const uint32_t& aEntries,
const double& aInterval,
nsTArray<nsCString>&& aFeatures,
nsTArray<nsCString>&& aThreadNameFilters)
PluginModuleChild::RecvStartProfiler(const ProfilerInitParams& params)
{
nsTArray<const char*> featureArray;
for (size_t i = 0; i < aFeatures.Length(); ++i) {
featureArray.AppendElement(aFeatures[i].get());
for (size_t i = 0; i < params.features().Length(); ++i) {
featureArray.AppendElement(params.features()[i].get());
}
nsTArray<const char*> threadNameFilterArray;
for (size_t i = 0; i < aThreadNameFilters.Length(); ++i) {
threadNameFilterArray.AppendElement(aThreadNameFilters[i].get());
for (size_t i = 0; i < params.threadFilters().Length(); ++i) {
threadNameFilterArray.AppendElement(params.threadFilters()[i].get());
}
profiler_start(aEntries, aInterval, featureArray.Elements(), featureArray.Length(),
profiler_start(params.entries(), params.interval(),
featureArray.Elements(), featureArray.Length(),
threadNameFilterArray.Elements(), threadNameFilterArray.Length());
return true;
+1 -4
View File
@@ -147,10 +147,7 @@ protected:
virtual bool
RecvProcessNativeEventsInInterruptCall() override;
virtual bool RecvStartProfiler(const uint32_t& aEntries,
const double& aInterval,
nsTArray<nsCString>&& aFeatures,
nsTArray<nsCString>&& aThreadNameFilters) override;
virtual bool RecvStartProfiler(const ProfilerInitParams& params) override;
virtual bool RecvStopProfiler() override;
virtual bool RecvGatherProfile() override;
+9 -1
View File
@@ -3118,7 +3118,15 @@ PluginProfilerObserver::Observe(nsISupports *aSubject,
params->GetInterval(&interval);
const nsTArray<nsCString>& features = params->GetFeatures();
const nsTArray<nsCString>& threadFilterNames = params->GetThreadFilterNames();
Unused << mPmp->SendStartProfiler(entries, interval, features, threadFilterNames);
ProfilerInitParams ipcParams;
ipcParams.enabled() = true;
ipcParams.entries() = entries;
ipcParams.interval() = interval;
ipcParams.features() = features;
ipcParams.threadFilters() = threadFilterNames;
Unused << mPmp->SendStartProfiler(ipcParams);
} else if (!strcmp(aTopic, "profiler-stopped")) {
Unused << mPmp->SendStopProfiler();
} else if (!strcmp(aTopic, "profiler-subprocess-gather")) {
+1 -1
View File
@@ -614,7 +614,7 @@ PresentationControllingInfo::NotifyClosed(nsresult aReason)
// subsequent |Shutdown| calls.
SetControlChannel(nullptr);
if (NS_WARN_IF(NS_FAILED(aReason))) {
if (NS_WARN_IF(NS_FAILED(aReason) || !mIsResponderReady)) {
// The presentation session instance may already exist.
// Change the state to TERMINATED since it never succeeds.
SetState(nsIPresentationSessionListener::STATE_TERMINATED);
@@ -56,12 +56,22 @@ CopierCallbacks::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, nsre
return NS_OK;
}
NS_IMPL_ISUPPORTS(PresentationSessionTransport,
nsIPresentationSessionTransport,
nsITransportEventSink,
nsIInputStreamCallback,
nsIStreamListener,
nsIRequestObserver)
NS_IMPL_CYCLE_COLLECTION(PresentationSessionTransport, mTransport,
mSocketInputStream, mSocketOutputStream,
mInputStreamPump, mInputStreamScriptable,
mMultiplexStream, mMultiplexStreamCopier, mCallback)
NS_IMPL_CYCLE_COLLECTING_ADDREF(PresentationSessionTransport)
NS_IMPL_CYCLE_COLLECTING_RELEASE(PresentationSessionTransport)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PresentationSessionTransport)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPresentationSessionTransport)
NS_INTERFACE_MAP_ENTRY(nsIPresentationSessionTransport)
NS_INTERFACE_MAP_ENTRY(nsITransportEventSink)
NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_END
PresentationSessionTransport::PresentationSessionTransport()
: mReadyState(CLOSED)
@@ -44,7 +44,10 @@ class PresentationSessionTransport final : public nsIPresentationSessionTranspor
, public nsIStreamListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PresentationSessionTransport,
nsIPresentationSessionTransport)
NS_DECL_NSIPRESENTATIONSESSIONTRANSPORT
NS_DECL_NSITRANSPORTEVENTSINK
NS_DECL_NSIINPUTSTREAMCALLBACK
+1 -1
View File
@@ -519,7 +519,7 @@ Factory::GetMaxSurfaceSize(BackendType aType)
case BackendType::COREGRAPHICS_ACCELERATED:
return DrawTargetCG::GetMaxSurfaceSize();
#endif
#if defined(USE_SKIA)
#ifdef USE_SKIA
case BackendType::SKIA:
return DrawTargetSkia::GetMaxSurfaceSize();
#endif
+17
View File
@@ -11,6 +11,7 @@
#include "nsMathUtils.h"
#include <math.h>
#include <float.h>
#include <stdlib.h>
#include "nsDebug.h"
#include <algorithm>
@@ -57,6 +58,22 @@ inline void VERIFY_COORD(nscoord aCoord) {
#endif
}
/**
* Divide aSpace by aN. Assign the resulting quotient to aQuotient and
* return the remainder.
*/
inline nscoord NSCoordDivRem(nscoord aSpace, size_t aN, nscoord* aQuotient)
{
#ifdef NS_COORD_IS_FLOAT
*aQuotient = aSpace / aN;
return 0.0f;
#else
div_t result = div(aSpace, aN);
*aQuotient = nscoord(result.quot);
return nscoord(result.rem);
#endif
}
inline nscoord NSCoordMulDiv(nscoord aMult1, nscoord aMult2, nscoord aDiv) {
#ifdef NS_COORD_IS_FLOAT
return (aMult1 * aMult2 / aDiv);
+13
View File
@@ -13,6 +13,7 @@
#include "mozilla/AppProcessChecker.h"
#include "mozilla/Assertions.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/NuwaParent.h"
#include "mozilla/dom/PBlobParent.h"
#include "mozilla/dom/MessagePortParent.h"
@@ -220,6 +221,18 @@ BackgroundParentImpl::DeallocPBlobParent(PBlobParent* aActor)
return true;
}
bool
BackgroundParentImpl::RecvPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& aParams)
{
const ParentBlobConstructorParams& params = aParams;
if (params.blobParams().type() == AnyBlobConstructorParams::TKnownBlobConstructorParams) {
return aActor->SendCreatedFromKnownBlob();
}
return true;
}
PFileDescriptorSetParent*
BackgroundParentImpl::AllocPFileDescriptorSetParent(
const FileDescriptor& aFileDescriptor)
+4
View File
@@ -56,6 +56,10 @@ protected:
virtual bool
DeallocPBlobParent(PBlobParent* aActor) override;
virtual bool
RecvPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& params) override;
virtual PFileDescriptorSetParent*
AllocPFileDescriptorSetParent(const FileDescriptor& aFileDescriptor)
override;
-27
View File
@@ -1,27 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AccessibleCaretLogger.h"
namespace mozilla {
#ifdef PR_LOGGING
PRLogModuleInfo*
GetAccessibleCaretLog()
{
static PRLogModuleInfo* log = nullptr;
if (!log) {
log = PR_NewLogModule("AccessibleCaret");
}
return log;
}
#endif // PR_LOGGING
} // namespace mozilla
+4 -17
View File
@@ -7,34 +7,21 @@
#ifndef AccessibleCaretLog_h
#define AccessibleCaretLog_h
#include "prlog.h"
#include "mozilla/Logging.h"
namespace mozilla {
#ifdef PR_LOGGING
PRLogModuleInfo* GetAccessibleCaretLog();
static LazyLogModule sAccessibleCaretLog("AccessibleCaret");
#ifndef AC_LOG_BASE
#define AC_LOG_BASE(...) MOZ_LOG(GetAccessibleCaretLog(), mozilla::LogLevel::Debug, (__VA_ARGS__));
#define AC_LOG_BASE(...) MOZ_LOG(sAccessibleCaretLog, mozilla::LogLevel::Debug, (__VA_ARGS__));
#endif
#ifndef AC_LOGV_BASE
#define AC_LOGV_BASE(...) \
MOZ_LOG(GetAccessibleCaretLog(), LogLevel::Verbose, (__VA_ARGS__));
MOZ_LOG(sAccessibleCaretLog, LogLevel::Verbose, (__VA_ARGS__));
#endif
#else
#ifndef AC_LOGV_BASE
#define AC_LOGV_BASE(...)
#endif
#ifndef AC_LOGV_BASE
#define AC_LOGV_BASE(...)
#endif
#endif // PR_LOGGING
} // namespace mozilla
#endif // AccessibleCaretLog_h
+106 -143
View File
@@ -454,7 +454,7 @@ public:
const nsIntRect& aVisibleRect,
const DisplayItemClip& aClip,
LayerState aLayerState);
const nsIFrame* GetAnimatedGeometryRoot() { return mAnimatedGeometryRoot; }
AnimatedGeometryRoot* GetAnimatedGeometryRoot() { return mAnimatedGeometryRoot; }
/**
* Add the given hit regions to the hit regions to the hit retions for this
@@ -537,11 +537,11 @@ public:
* be non-null; all content in a PaintedLayer must have the same
* active scrolled root.
*/
const nsIFrame* mAnimatedGeometryRoot;
AnimatedGeometryRoot* mAnimatedGeometryRoot;
/**
* See NewLayerEntry::mAnimatedGeometryRootForScrollMetadata.
*/
const nsIFrame* mAnimatedGeometryRootForScrollMetadata;
AnimatedGeometryRoot* mAnimatedGeometryRootForScrollMetadata;
/**
* The offset between mAnimatedGeometryRoot and the reference frame.
*/
@@ -679,13 +679,13 @@ struct NewLayerEntry {
// mLayer is null if the previous entry is for a PaintedLayer that hasn't
// been optimized to some other form (yet).
RefPtr<Layer> mLayer;
const nsIFrame* mAnimatedGeometryRoot;
AnimatedGeometryRoot* mAnimatedGeometryRoot;
// For fixed background layers, mAnimatedGeometryRoot is the animated geometry
// root of the viewport frame it's fixed to, but we need to annotate it with
// scroll metadata starting from the animated geometry root of the element
// it's the background of, so that during async scrolling we can correctly
// transform the fixed layer's clip.
const nsIFrame* mAnimatedGeometryRootForScrollMetadata;
AnimatedGeometryRoot* mAnimatedGeometryRootForScrollMetadata;
const nsIFrame* mFixedPosFrameForLayerData;
// If non-null, this FrameMetrics is set to the be the first FrameMetrics
// on the layer.
@@ -745,10 +745,10 @@ class PaintedLayerDataNode {
public:
PaintedLayerDataNode(PaintedLayerDataTree& aTree,
PaintedLayerDataNode* aParent,
const nsIFrame* aAnimatedGeometryRoot);
AnimatedGeometryRoot* aAnimatedGeometryRoot);
~PaintedLayerDataNode();
const nsIFrame* AnimatedGeometryRoot() const { return mAnimatedGeometryRoot; }
AnimatedGeometryRoot* GetAnimatedGeometryRoot() const { return mAnimatedGeometryRoot; }
/**
* Whether this node's contents can potentially intersect aRect.
@@ -761,7 +761,7 @@ public:
* Create a PaintedLayerDataNode for aAnimatedGeometryRoot, add it to our
* children, and return it.
*/
PaintedLayerDataNode* AddChildNodeFor(const nsIFrame* aAnimatedGeometryRoot);
PaintedLayerDataNode* AddChildNodeFor(AnimatedGeometryRoot* aAnimatedGeometryRoot);
/**
* Find a PaintedLayerData in our mPaintedLayerDataStack that aItem can be
@@ -843,7 +843,7 @@ protected:
PaintedLayerDataTree& mTree;
PaintedLayerDataNode* mParent;
const nsIFrame* mAnimatedGeometryRoot;
AnimatedGeometryRoot* mAnimatedGeometryRoot;
/**
* Our contents: a PaintedLayerData stack and our child nodes.
@@ -933,7 +933,7 @@ public:
* color that can be pulled into the background of the added content, or
* transparent if that is not possible.
*/
void AddingOwnLayer(const nsIFrame* aAnimatedGeometryRoot,
void AddingOwnLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect* aRect,
nscolor* aOutUniformBackgroundColor);
@@ -943,7 +943,7 @@ public:
* created by a call out to aNewPaintedLayerCallback.
*/
template<typename NewPaintedLayerCallbackType>
PaintedLayerData* FindPaintedLayerFor(const nsIFrame* aAnimatedGeometryRoot,
PaintedLayerData* FindPaintedLayerFor(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect& aVisibleRect,
bool aForceOwnLayer,
bool aBackfaceidden,
@@ -960,7 +960,7 @@ public:
* that's aAnimatedGeometryRoot itself, then it's the animated geometry
* root for aAnimatedGeometryRoot's cross-doc parent frame.
*/
const nsIFrame* GetParentAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot);
AnimatedGeometryRoot* GetParentAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot);
/**
* Whether aAnimatedGeometryRoot has an intrinsic clip that doesn't move with
@@ -971,14 +971,14 @@ public:
* where we have easy access to a display list builder, which we use to get
* the clip rect result into the right coordinate space.
*/
bool IsClippedWithRespectToParentAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot,
bool IsClippedWithRespectToParentAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot,
nsIntRect* aOutClip);
/**
* Called by PaintedLayerDataNode when it is finished, so that we can drop
* our pointers to it.
*/
void NodeWasFinished(const nsIFrame* aAnimatedGeometryRoot);
void NodeWasFinished(AnimatedGeometryRoot* aAnimatedGeometryRoot);
nsDisplayListBuilder* Builder() const;
ContainerState& ContState() const { return mContainerState; }
@@ -990,14 +990,14 @@ protected:
* that doesn't move with respect to aAnimatedGeometryRoot.
* If aRect is null, *aRect will be considered infinite.
*/
void FinishPotentiallyIntersectingNodes(const nsIFrame* aAnimatedGeometryRoot,
void FinishPotentiallyIntersectingNodes(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect* aRect);
/**
* Make sure that there is a node for aAnimatedGeometryRoot and all of its
* ancestor geometry roots. Return the node for aAnimatedGeometryRoot.
*/
PaintedLayerDataNode* EnsureNodeFor(const nsIFrame* aAnimatedGeometryRoot);
PaintedLayerDataNode* EnsureNodeFor(AnimatedGeometryRoot* aAnimatedGeometryRoot);
/**
* Find an existing node in the tree for an ancestor of aAnimatedGeometryRoot.
@@ -1006,8 +1006,8 @@ protected:
* geometry root of the result, if neither are null.
*/
PaintedLayerDataNode*
FindNodeForAncestorAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame** aOutAncestorChild);
FindNodeForAncestorAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot,
AnimatedGeometryRoot** aOutAncestorChild);
ContainerState& mContainerState;
UniquePtr<PaintedLayerDataNode> mRoot;
@@ -1024,7 +1024,7 @@ protected:
* A hash map for quick access the node belonging to a particular animated
* geometry root.
*/
nsDataHashtable<nsPtrHashKey<const nsIFrame>, PaintedLayerDataNode*> mNodes;
nsDataHashtable<nsPtrHashKey<AnimatedGeometryRoot>, PaintedLayerDataNode*> mNodes;
};
/**
@@ -1060,11 +1060,11 @@ public:
bool isAtRoot = !aContainerItem || (aContainerItem->Frame() == mBuilder->RootReferenceFrame());
MOZ_ASSERT_IF(isAtRoot, mContainerReferenceFrame == mBuilder->RootReferenceFrame());
mContainerAnimatedGeometryRoot = isAtRoot
? mContainerReferenceFrame
: aContainerItem->AnimatedGeometryRoot();
? aBuilder->GetRootAnimatedGeometryRoot()
: aContainerItem->GetAnimatedGeometryRoot();
MOZ_ASSERT(!mBuilder->IsPaintingToWindow() ||
nsLayoutUtils::IsAncestorFrameCrossDoc(mBuilder->RootReferenceFrame(),
mContainerAnimatedGeometryRoot));
*mContainerAnimatedGeometryRoot));
NS_ASSERTION(!aContainerItem || !aContainerItem->ShouldFixToViewport(mBuilder),
"Container items never return true for ShouldFixToViewport");
mContainerFixedPosFrame =
@@ -1188,7 +1188,7 @@ protected:
friend class PaintedLayerData;
LayerManager::PaintedLayerCreationHint
GetLayerCreationHint(const nsIFrame* aAnimatedGeometryRoot);
GetLayerCreationHint(AnimatedGeometryRoot* aAnimatedGeometryRoot);
/**
* Creates a new PaintedLayer and sets up the transform on the PaintedLayer
@@ -1200,14 +1200,14 @@ protected:
* Find a PaintedLayer for recycling, recycle it and prepare it for use, or
* return null if no suitable layer was found.
*/
already_AddRefed<PaintedLayer> AttemptToRecyclePaintedLayer(const nsIFrame* aAnimatedGeometryRoot,
already_AddRefed<PaintedLayer> AttemptToRecyclePaintedLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot,
nsDisplayItem* aItem,
const nsPoint& aTopLeft);
/**
* Recycle aLayer and do any necessary invalidation.
*/
PaintedDisplayItemLayerUserData* RecyclePaintedLayer(PaintedLayer* aLayer,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
bool& didResetScrollPositionForLayerPixelAlignment);
/**
@@ -1217,7 +1217,7 @@ protected:
*/
void PreparePaintedLayerForUse(PaintedLayer* aLayer,
PaintedDisplayItemLayerUserData* aData,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIFrame* aReferenceFrame,
const nsPoint& aTopLeft,
bool aDidResetScrollPositionForLayerPixelAlignment);
@@ -1277,7 +1277,7 @@ protected:
* This can return the actual viewport frame for layers whose display items
* are directly on the viewport (e.g. background-attachment:fixed backgrounds).
*/
const nsIFrame* FindFixedPosFrameForLayerData(const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame* FindFixedPosFrameForLayerData(AnimatedGeometryRoot* aAnimatedGeometryRoot,
bool aDisplayItemFixedToViewport);
/**
* Set fixed-pos layer metadata on aLayer according to the data for aFixedPosFrame.
@@ -1317,7 +1317,7 @@ protected:
* permanently invisible.
*/
nsIntRegion ComputeOpaqueRect(nsDisplayItem* aItem,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIFrame* aFixedPosFrame,
const DisplayItemClip& aClip,
nsDisplayList* aList,
@@ -1343,8 +1343,8 @@ protected:
*/
PaintedLayerData NewPaintedLayerData(nsDisplayItem* aItem,
const nsIntRect& aVisibleRect,
const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame* aAnimatedGeometryRootForScrollMetadata,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRootForScrollMetadata,
const nsPoint& aTopLeft,
bool aShouldFixToViewport);
@@ -1370,14 +1370,14 @@ protected:
uint32_t aRoundedRectClipCount = UINT32_MAX);
bool ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
const nsIFrame **aAnimatedGeometryRoot);
AnimatedGeometryRoot **aAnimatedGeometryRoot);
nsDisplayListBuilder* mBuilder;
LayerManager* mManager;
FrameLayerBuilder* mLayerBuilder;
nsIFrame* mContainerFrame;
nsIFrame* mContainerReferenceFrame;
const nsIFrame* mContainerAnimatedGeometryRoot;
AnimatedGeometryRoot* mContainerAnimatedGeometryRoot;
const nsIFrame* mContainerFixedPosFrame;
ContainerLayer* mContainerLayer;
nsRect mContainerBounds;
@@ -2087,16 +2087,16 @@ RoundToMatchResidual(double aValue, double aOldResidual)
}
static void
ResetScrollPositionForLayerPixelAlignment(const nsIFrame* aAnimatedGeometryRoot)
ResetScrollPositionForLayerPixelAlignment(AnimatedGeometryRoot* aAnimatedGeometryRoot)
{
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(aAnimatedGeometryRoot);
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
if (sf) {
sf->ResetScrollPositionForLayerPixelAlignment();
}
}
static void
InvalidateEntirePaintedLayer(PaintedLayer* aLayer, const nsIFrame* aAnimatedGeometryRoot, const char *aReason)
InvalidateEntirePaintedLayer(PaintedLayer* aLayer, AnimatedGeometryRoot* aAnimatedGeometryRoot, const char *aReason)
{
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
@@ -2110,18 +2110,17 @@ InvalidateEntirePaintedLayer(PaintedLayer* aLayer, const nsIFrame* aAnimatedGeom
}
LayerManager::PaintedLayerCreationHint
ContainerState::GetLayerCreationHint(const nsIFrame* aAnimatedGeometryRoot)
ContainerState::GetLayerCreationHint(AnimatedGeometryRoot* aAnimatedGeometryRoot)
{
// Check whether the layer will be scrollable. This is used as a hint to
// influence whether tiled layers are used or not.
// Check whether there's any active scroll frame on the animated geometry
// root chain.
nsIFrame* fParent;
for (const nsIFrame* f = aAnimatedGeometryRoot;
f != mContainerAnimatedGeometryRoot;
f = nsLayoutUtils::GetAnimatedGeometryRootForFrame(mBuilder, fParent)) {
fParent = nsLayoutUtils::GetCrossDocParentFrame(f);
for (AnimatedGeometryRoot* agr = aAnimatedGeometryRoot;
agr != mContainerAnimatedGeometryRoot;
agr = agr->mParentAGR) {
nsIFrame* fParent = nsLayoutUtils::GetCrossDocParentFrame(*agr);
if (!fParent) {
break;
}
@@ -2142,7 +2141,7 @@ ContainerState::GetLayerCreationHint(const nsIFrame* aAnimatedGeometryRoot)
}
already_AddRefed<PaintedLayer>
ContainerState::AttemptToRecyclePaintedLayer(const nsIFrame* aAnimatedGeometryRoot,
ContainerState::AttemptToRecyclePaintedLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot,
nsDisplayItem* aItem,
const nsPoint& aTopLeft)
{
@@ -2199,7 +2198,7 @@ ContainerState::CreatePaintedLayer(PaintedLayerData* aData)
PaintedDisplayItemLayerUserData*
ContainerState::RecyclePaintedLayer(PaintedLayer* aLayer,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
bool& didResetScrollPositionForLayerPixelAlignment)
{
// Clear clip rect and mask layer so we don't accidentally stay clipped.
@@ -2253,7 +2252,7 @@ ContainerState::RecyclePaintedLayer(PaintedLayer* aLayer,
static void
ComputeAndSetIgnoreInvalidationRect(PaintedLayer* aLayer,
PaintedDisplayItemLayerUserData* aData,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
nsDisplayListBuilder* aBuilder,
const nsIntPoint& aLayerTranslation)
{
@@ -2262,7 +2261,7 @@ ComputeAndSetIgnoreInvalidationRect(PaintedLayer* aLayer,
return;
}
const nsIFrame* parentFrame = aAnimatedGeometryRoot->GetParent();
const nsIFrame* parentFrame = (*aAnimatedGeometryRoot)->GetParent();
// GetDirtyRectForScrolledContents will return an empty rect if parentFrame
// is not a scrollable frame.
@@ -2336,7 +2335,7 @@ ComputeAndSetIgnoreInvalidationRect(PaintedLayer* aLayer,
void
ContainerState::PreparePaintedLayerForUse(PaintedLayer* aLayer,
PaintedDisplayItemLayerUserData* aData,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIFrame* aReferenceFrame,
const nsPoint& aTopLeft,
bool didResetScrollPositionForLayerPixelAlignment)
@@ -2352,8 +2351,8 @@ ContainerState::PreparePaintedLayerForUse(PaintedLayer* aLayer,
// Set up transform so that 0,0 in the PaintedLayer corresponds to the
// (pixel-snapped) top-left of the aAnimatedGeometryRoot.
nsPoint offset = aAnimatedGeometryRoot->GetOffsetToCrossDoc(aReferenceFrame);
nscoord appUnitsPerDevPixel = aAnimatedGeometryRoot->PresContext()->AppUnitsPerDevPixel();
nsPoint offset = (*aAnimatedGeometryRoot)->GetOffsetToCrossDoc(aReferenceFrame);
nscoord appUnitsPerDevPixel = (*aAnimatedGeometryRoot)->PresContext()->AppUnitsPerDevPixel();
gfxPoint scaledOffset(
NSAppUnitsToDoublePixels(offset.x, appUnitsPerDevPixel)*mParameters.mXScale,
NSAppUnitsToDoublePixels(offset.y, appUnitsPerDevPixel)*mParameters.mYScale);
@@ -2638,13 +2637,13 @@ PaintedLayerData::GetContainerForImageLayer(nsDisplayListBuilder* aBuilder)
PaintedLayerDataNode::PaintedLayerDataNode(PaintedLayerDataTree& aTree,
PaintedLayerDataNode* aParent,
const nsIFrame* aAnimatedGeometryRoot)
AnimatedGeometryRoot* aAnimatedGeometryRoot)
: mTree(aTree)
, mParent(aParent)
, mAnimatedGeometryRoot(aAnimatedGeometryRoot)
, mAllDrawingAboveBackground(false)
{
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(mTree.Builder()->RootReferenceFrame(), mAnimatedGeometryRoot));
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(mTree.Builder()->RootReferenceFrame(), *mAnimatedGeometryRoot));
mHasClip = mTree.IsClippedWithRespectToParentAnimatedGeometryRoot(mAnimatedGeometryRoot, &mClipRect);
}
@@ -2655,9 +2654,9 @@ PaintedLayerDataNode::~PaintedLayerDataNode()
}
PaintedLayerDataNode*
PaintedLayerDataNode::AddChildNodeFor(const nsIFrame* aAnimatedGeometryRoot)
PaintedLayerDataNode::AddChildNodeFor(AnimatedGeometryRoot* aAnimatedGeometryRoot)
{
MOZ_ASSERT(mTree.GetParentAnimatedGeometryRoot(aAnimatedGeometryRoot) == mAnimatedGeometryRoot);
MOZ_ASSERT(aAnimatedGeometryRoot->mParentAGR == mAnimatedGeometryRoot);
UniquePtr<PaintedLayerDataNode> child =
MakeUnique<PaintedLayerDataNode>(mTree, this, aAnimatedGeometryRoot);
mChildren.AppendElement(Move(child));
@@ -2790,31 +2789,6 @@ PaintedLayerDataTree::Builder() const
return mContainerState.Builder();
}
const nsIFrame*
PaintedLayerDataTree::GetParentAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot)
{
MOZ_ASSERT(aAnimatedGeometryRoot);
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(Builder()->RootReferenceFrame(), aAnimatedGeometryRoot));
if (aAnimatedGeometryRoot == Builder()->RootReferenceFrame()) {
return nullptr;
}
nsIFrame* agr = Builder()->FindAnimatedGeometryRootFor(
const_cast<nsIFrame*>(aAnimatedGeometryRoot));
MOZ_ASSERT_IF(agr, nsLayoutUtils::IsAncestorFrameCrossDoc(Builder()->RootReferenceFrame(), agr));
if (agr != aAnimatedGeometryRoot) {
return agr;
}
// aAnimatedGeometryRoot is its own animated geometry root.
// Find the animated geometry root for its cross-doc parent frame.
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(aAnimatedGeometryRoot);
if (!parent) {
return nullptr;
}
return Builder()->FindAnimatedGeometryRootFor(parent);
}
void
PaintedLayerDataTree::Finish()
{
@@ -2826,13 +2800,13 @@ PaintedLayerDataTree::Finish()
}
void
PaintedLayerDataTree::NodeWasFinished(const nsIFrame* aAnimatedGeometryRoot)
PaintedLayerDataTree::NodeWasFinished(AnimatedGeometryRoot* aAnimatedGeometryRoot)
{
mNodes.Remove(aAnimatedGeometryRoot);
}
void
PaintedLayerDataTree::AddingOwnLayer(const nsIFrame* aAnimatedGeometryRoot,
PaintedLayerDataTree::AddingOwnLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect* aRect,
nscolor* aOutUniformBackgroundColor)
{
@@ -2853,7 +2827,7 @@ PaintedLayerDataTree::AddingOwnLayer(const nsIFrame* aAnimatedGeometryRoot,
template<typename NewPaintedLayerCallbackType>
PaintedLayerData*
PaintedLayerDataTree::FindPaintedLayerFor(const nsIFrame* aAnimatedGeometryRoot,
PaintedLayerDataTree::FindPaintedLayerFor(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect& aVisibleRect,
bool aForceOwnLayer,
bool aBackfaceHidden,
@@ -2873,10 +2847,10 @@ PaintedLayerDataTree::FindPaintedLayerFor(const nsIFrame* aAnimatedGeometryRoot,
}
void
PaintedLayerDataTree::FinishPotentiallyIntersectingNodes(const nsIFrame* aAnimatedGeometryRoot,
PaintedLayerDataTree::FinishPotentiallyIntersectingNodes(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect* aRect)
{
const nsIFrame* ancestorThatIsChildOfCommonAncestor = nullptr;
AnimatedGeometryRoot* ancestorThatIsChildOfCommonAncestor = nullptr;
PaintedLayerDataNode* ancestorNode =
FindNodeForAncestorAnimatedGeometryRoot(aAnimatedGeometryRoot,
&ancestorThatIsChildOfCommonAncestor);
@@ -2887,7 +2861,7 @@ PaintedLayerDataTree::FinishPotentiallyIntersectingNodes(const nsIFrame* aAnimat
return;
}
if (ancestorNode->AnimatedGeometryRoot() == aAnimatedGeometryRoot) {
if (ancestorNode->GetAnimatedGeometryRoot() == aAnimatedGeometryRoot) {
// aAnimatedGeometryRoot already has a node in the tree.
// This is the common case.
MOZ_ASSERT(!ancestorThatIsChildOfCommonAncestor);
@@ -2904,8 +2878,8 @@ PaintedLayerDataTree::FinishPotentiallyIntersectingNodes(const nsIFrame* aAnimat
// ancestorThatIsChildOfCommonAncestor is the last animated geometry root
// encountered on the way up from aAnimatedGeometryRoot to ancestorNode.
MOZ_ASSERT(ancestorThatIsChildOfCommonAncestor);
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(ancestorThatIsChildOfCommonAncestor, aAnimatedGeometryRoot));
MOZ_ASSERT(GetParentAnimatedGeometryRoot(ancestorThatIsChildOfCommonAncestor) == ancestorNode->AnimatedGeometryRoot());
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(*ancestorThatIsChildOfCommonAncestor, *aAnimatedGeometryRoot));
MOZ_ASSERT(ancestorThatIsChildOfCommonAncestor->mParentAGR == ancestorNode->GetAnimatedGeometryRoot());
// ancestorThatIsChildOfCommonAncestor is not in the tree yet!
MOZ_ASSERT(!mNodes.Get(ancestorThatIsChildOfCommonAncestor));
@@ -2921,7 +2895,7 @@ PaintedLayerDataTree::FinishPotentiallyIntersectingNodes(const nsIFrame* aAnimat
}
PaintedLayerDataNode*
PaintedLayerDataTree::EnsureNodeFor(const nsIFrame* aAnimatedGeometryRoot)
PaintedLayerDataTree::EnsureNodeFor(AnimatedGeometryRoot* aAnimatedGeometryRoot)
{
MOZ_ASSERT(aAnimatedGeometryRoot);
PaintedLayerDataNode* node = mNodes.Get(aAnimatedGeometryRoot);
@@ -2929,10 +2903,10 @@ PaintedLayerDataTree::EnsureNodeFor(const nsIFrame* aAnimatedGeometryRoot)
return node;
}
const nsIFrame* parentAnimatedGeometryRoot = GetParentAnimatedGeometryRoot(aAnimatedGeometryRoot);
AnimatedGeometryRoot* parentAnimatedGeometryRoot = aAnimatedGeometryRoot->mParentAGR;
if (!parentAnimatedGeometryRoot) {
MOZ_ASSERT(!mRoot);
MOZ_ASSERT(aAnimatedGeometryRoot == Builder()->RootReferenceFrame());
MOZ_ASSERT(*aAnimatedGeometryRoot == Builder()->RootReferenceFrame());
mRoot = MakeUnique<PaintedLayerDataNode>(*this, nullptr, aAnimatedGeometryRoot);
node = mRoot.get();
} else {
@@ -2946,10 +2920,10 @@ PaintedLayerDataTree::EnsureNodeFor(const nsIFrame* aAnimatedGeometryRoot)
}
bool
PaintedLayerDataTree::IsClippedWithRespectToParentAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot,
PaintedLayerDataTree::IsClippedWithRespectToParentAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot,
nsIntRect* aOutClip)
{
nsIScrollableFrame* scrollableFrame = nsLayoutUtils::GetScrollableFrameFor(aAnimatedGeometryRoot);
nsIScrollableFrame* scrollableFrame = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
if (!scrollableFrame) {
return false;
}
@@ -2960,8 +2934,8 @@ PaintedLayerDataTree::IsClippedWithRespectToParentAnimatedGeometryRoot(const nsI
}
PaintedLayerDataNode*
PaintedLayerDataTree::FindNodeForAncestorAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame** aOutAncestorChild)
PaintedLayerDataTree::FindNodeForAncestorAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot,
AnimatedGeometryRoot** aOutAncestorChild)
{
if (!aAnimatedGeometryRoot) {
return nullptr;
@@ -2971,12 +2945,11 @@ PaintedLayerDataTree::FindNodeForAncestorAnimatedGeometryRoot(const nsIFrame* aA
return node;
}
*aOutAncestorChild = aAnimatedGeometryRoot;
return FindNodeForAncestorAnimatedGeometryRoot(
GetParentAnimatedGeometryRoot(aAnimatedGeometryRoot), aOutAncestorChild);
return FindNodeForAncestorAnimatedGeometryRoot(aAnimatedGeometryRoot->mParentAGR, aOutAncestorChild);
}
const nsIFrame*
ContainerState::FindFixedPosFrameForLayerData(const nsIFrame* aAnimatedGeometryRoot,
ContainerState::FindFixedPosFrameForLayerData(AnimatedGeometryRoot* aAnimatedGeometryRoot,
bool aDisplayItemFixedToViewport)
{
if (!mManager->IsWidgetLayerManager()) {
@@ -2987,16 +2960,16 @@ ContainerState::FindFixedPosFrameForLayerData(const nsIFrame* aAnimatedGeometryR
nsPresContext* presContext = mContainerFrame->PresContext();
nsIFrame* viewport = presContext->PresShell()->GetRootFrame();
if (viewport == aAnimatedGeometryRoot && aDisplayItemFixedToViewport &&
if (viewport == *aAnimatedGeometryRoot && aDisplayItemFixedToViewport &&
nsLayoutUtils::ViewportHasDisplayPort(presContext)) {
// Probably a background-attachment:fixed item
return viewport;
}
// Viewports with no fixed-pos frames are not relevant.
if (!viewport->GetFirstChild(nsIFrame::kFixedList)) {
if (!viewport->GetChildList(nsIFrame::kFixedList).FirstChild()) {
return nullptr;
}
for (const nsIFrame* f = aAnimatedGeometryRoot; f; f = f->GetParent()) {
for (const nsIFrame* f = *aAnimatedGeometryRoot; f; f = f->GetParent()) {
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(f)) {
return f;
}
@@ -3593,8 +3566,8 @@ PaintedLayerData::AccumulateEventRegions(ContainerState* aState, nsDisplayLayerE
PaintedLayerData
ContainerState::NewPaintedLayerData(nsDisplayItem* aItem,
const nsIntRect& aVisibleRect,
const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame* aAnimatedGeometryRootForScrollMetadata,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRootForScrollMetadata,
const nsPoint& aTopLeft,
bool aShouldFixToViewport)
{
@@ -3704,7 +3677,7 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
*/
bool
ContainerState::ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
const nsIFrame **aAnimatedGeometryRoot)
AnimatedGeometryRoot **aAnimatedGeometryRoot)
{
for (nsDisplayItem* item = aList.GetBottom(); item; item = item->GetAbove()) {
LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
@@ -3716,7 +3689,7 @@ ContainerState::ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
// Try using the actual active scrolled root of the backmost item, as that
// should result in the least invalidation when scrolling.
*aAnimatedGeometryRoot = item->AnimatedGeometryRoot();
*aAnimatedGeometryRoot = item->GetAnimatedGeometryRoot();
return true;
}
return false;
@@ -3724,7 +3697,7 @@ ContainerState::ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
nsIntRegion
ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIFrame* aFixedPosFrame,
const DisplayItemClip& aClip,
nsDisplayList* aList,
@@ -3755,11 +3728,11 @@ ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
}
opaquePixels = ScaleRegionToInsidePixels(opaqueClipped, snapOpaque);
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(aAnimatedGeometryRoot);
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
if (sf) {
nsRect displayport;
bool usingDisplayport =
nsLayoutUtils::GetDisplayPort(aAnimatedGeometryRoot->GetContent(), &displayport);
nsLayoutUtils::GetDisplayPort((*aAnimatedGeometryRoot)->GetContent(), &displayport);
if (!usingDisplayport) {
// No async scrolling, so all that matters is that the layer contents
// cover the scrollport.
@@ -3783,15 +3756,15 @@ IsCaretWithCustomClip(nsDisplayItem* aItem, nsDisplayItem::Type aItemType)
}
static DisplayItemClip
GetScrollClipIntersection(nsDisplayListBuilder* aBuilder, const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame* aStopAtAnimatedGeometryRoot, bool aIsCaret)
GetScrollClipIntersection(nsDisplayListBuilder* aBuilder, AnimatedGeometryRoot* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aStopAtAnimatedGeometryRoot, bool aIsCaret)
{
DisplayItemClip resultClip;
nsIFrame* fParent;
for (const nsIFrame* f = aAnimatedGeometryRoot;
f != aStopAtAnimatedGeometryRoot;
f = nsLayoutUtils::GetAnimatedGeometryRootForFrame(aBuilder, fParent)) {
fParent = nsLayoutUtils::GetCrossDocParentFrame(f);
for (AnimatedGeometryRoot* agr = aAnimatedGeometryRoot;
agr != aStopAtAnimatedGeometryRoot;
agr = agr->mParentAGR) {
fParent = nsLayoutUtils::GetCrossDocParentFrame(*agr);
if (!fParent) {
// This means aStopAtAnimatedGeometryRoot was not an ancestor
// of aAnimatedGeometryRoot. This is a weird case but it
@@ -3801,7 +3774,7 @@ GetScrollClipIntersection(nsDisplayListBuilder* aBuilder, const nsIFrame* aAnima
return DisplayItemClip();
}
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(f);
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(*agr);
if (!scrollFrame) {
continue;
}
@@ -3834,7 +3807,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
PROFILER_LABEL("ContainerState", "ProcessDisplayItems",
js::ProfileEntry::Category::GRAPHICS);
const nsIFrame* lastAnimatedGeometryRoot = mContainerReferenceFrame;
AnimatedGeometryRoot* lastAnimatedGeometryRoot = mContainerAnimatedGeometryRoot;
nsPoint topLeft(0,0);
// When NO_COMPONENT_ALPHA is set, items will be flattened into a single
@@ -3842,7 +3815,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
// items.
if (mFlattenToSingleLayer) {
if (ChooseAnimatedGeometryRoot(*aList, &lastAnimatedGeometryRoot)) {
topLeft = lastAnimatedGeometryRoot->GetOffsetToCrossDoc(mContainerReferenceFrame);
topLeft = (*lastAnimatedGeometryRoot)->GetOffsetToCrossDoc(mContainerReferenceFrame);
}
}
@@ -3896,9 +3869,9 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
}
bool forceInactive;
const nsIFrame* animatedGeometryRoot;
const nsIFrame* animatedGeometryRootForScrollMetadata = nullptr;
const nsIFrame* realAnimatedGeometryRootOfItem = item->AnimatedGeometryRoot();
AnimatedGeometryRoot* animatedGeometryRoot;
AnimatedGeometryRoot* animatedGeometryRootForScrollMetadata = nullptr;
AnimatedGeometryRoot* realAnimatedGeometryRootOfItem = item->GetAnimatedGeometryRoot();
if (mFlattenToSingleLayer) {
forceInactive = true;
animatedGeometryRoot = lastAnimatedGeometryRoot;
@@ -3906,11 +3879,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
forceInactive = false;
if (mManager->IsWidgetLayerManager()) {
animatedGeometryRoot = realAnimatedGeometryRootOfItem;
// Unlike GetAnimatedGeometryRootFor(), GetAnimatedGeometryRootForFrame() does not
// take ShouldFixToViewport() into account, so it will return something different
// for fixed background items.
animatedGeometryRootForScrollMetadata = nsLayoutUtils::GetAnimatedGeometryRootFor(
item, mBuilder, nsLayoutUtils::AGR_IGNORE_BACKGROUND_ATTACHMENT_FIXED);
animatedGeometryRootForScrollMetadata = item->AnimatedGeometryRootForScrollMetadata();
} else {
// For inactive layer subtrees, splitting content into PaintedLayers
// based on animated geometry roots is pointless. It's more efficient
@@ -3918,10 +3887,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
animatedGeometryRoot = mContainerAnimatedGeometryRoot;
}
if (animatedGeometryRoot != lastAnimatedGeometryRoot) {
lastAnimatedGeometryRoot = animatedGeometryRoot;
topLeft = animatedGeometryRoot->GetOffsetToCrossDoc(mContainerReferenceFrame);
}
topLeft = (*animatedGeometryRoot)->GetOffsetToCrossDoc(mContainerReferenceFrame);
}
if (!animatedGeometryRootForScrollMetadata) {
animatedGeometryRootForScrollMetadata = animatedGeometryRoot;
@@ -3937,7 +3903,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
item->SetClip(mBuilder, clip);
}
bool shouldFixToViewport = !animatedGeometryRoot->GetParent() &&
bool shouldFixToViewport = !(*animatedGeometryRoot)->GetParent() &&
item->ShouldFixToViewport(mBuilder);
// For items that are fixed to the viewport, remove their clip at the
@@ -4056,13 +4022,11 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
clipRectUntyped = layerClipRect.ToUnknownRect();
clipPtr = &clipRectUntyped;
}
if (animatedGeometryRoot == item->Frame() &&
animatedGeometryRoot != mBuilder->RootReferenceFrame()) {
if (*animatedGeometryRoot == item->Frame() &&
*animatedGeometryRoot != mBuilder->RootReferenceFrame()) {
// This is the case for scrollbar thumbs, for example. In that case the
// clip we care about is the overflow:hidden clip on the scrollbar.
const nsIFrame* clipAnimatedGeometryRoot =
mPaintedLayerDataTree.GetParentAnimatedGeometryRoot(animatedGeometryRoot);
mPaintedLayerDataTree.AddingOwnLayer(clipAnimatedGeometryRoot,
mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRoot->mParentAGR,
clipPtr,
uniformColorPtr);
} else if (prerenderedTransform) {
@@ -4718,14 +4682,14 @@ ContainerState::CollectOldLayers()
}
struct OpaqueRegionEntry {
const nsIFrame* mAnimatedGeometryRoot;
AnimatedGeometryRoot* mAnimatedGeometryRoot;
const nsIFrame* mFixedPosFrameForLayerData;
nsIntRegion mOpaqueRegion;
};
static OpaqueRegionEntry*
FindOpaqueRegionEntry(nsTArray<OpaqueRegionEntry>& aEntries,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIFrame* aFixedPosFrameForLayerData)
{
for (uint32_t i = 0; i < aEntries.Length(); ++i) {
@@ -4767,10 +4731,10 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
nsTArray<RefPtr<Layer>> maskLayers;
nsIFrame* fParent;
for (const nsIFrame* f = aEntry->mAnimatedGeometryRootForScrollMetadata;
f != mContainerAnimatedGeometryRoot;
f = nsLayoutUtils::GetAnimatedGeometryRootForFrame(this->mBuilder, fParent)) {
fParent = nsLayoutUtils::GetCrossDocParentFrame(f);
for (AnimatedGeometryRoot* agr = aEntry->mAnimatedGeometryRootForScrollMetadata;
agr != mContainerAnimatedGeometryRoot;
agr = agr->mParentAGR) {
fParent = nsLayoutUtils::GetCrossDocParentFrame(*agr);
if (!fParent) {
// This means mContainerAnimatedGeometryRoot was not an ancestor
// of aEntry->mAnimatedGeometryRoot. This is a weird case but it
@@ -4784,7 +4748,7 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
return;
}
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(f);
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(*agr);
if (!scrollFrame) {
continue;
}
@@ -4881,7 +4845,7 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer
// If mFlattenToSingleLayer is true, there isn't going to be any
// async scrolling so we can apply all our opaqueness to the same
// entry, the entry for mContainerAnimatedGeometryRoot.
const nsIFrame* animatedGeometryRootForOpaqueness =
AnimatedGeometryRoot* animatedGeometryRootForOpaqueness =
mFlattenToSingleLayer ? mContainerAnimatedGeometryRoot : e->mAnimatedGeometryRoot;
OpaqueRegionEntry* data = FindOpaqueRegionEntry(opaqueRegions,
animatedGeometryRootForOpaqueness, e->mFixedPosFrameForLayerData);
@@ -4911,10 +4875,9 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer
}
if (!e->mOpaqueRegion.IsEmpty()) {
const nsIFrame* animatedGeometryRootToCover = animatedGeometryRootForOpaqueness;
AnimatedGeometryRoot* animatedGeometryRootToCover = animatedGeometryRootForOpaqueness;
if (e->mOpaqueForAnimatedGeometryRootParent &&
nsLayoutUtils::GetAnimatedGeometryRootForFrame(mBuilder, e->mAnimatedGeometryRoot->GetParent())
== mContainerAnimatedGeometryRoot) {
e->mAnimatedGeometryRoot->mParentAGR == mContainerAnimatedGeometryRoot) {
animatedGeometryRootToCover = mContainerAnimatedGeometryRoot;
data = FindOpaqueRegionEntry(opaqueRegions,
animatedGeometryRootToCover, e->mFixedPosFrameForLayerData);
+2 -12
View File
@@ -8,16 +8,6 @@
#include "LayoutLogging.h"
PRLogModuleInfo* GetLayoutLog()
{
static PRLogModuleInfo* log = nullptr;
if (!log) {
log = PR_NewLogModule("layout");
}
return log;
}
namespace mozilla {
namespace detail {
@@ -25,13 +15,13 @@ void LayoutLogWarning(const char* aStr, const char* aExpr,
const char* aFile, int32_t aLine)
{
if (aExpr) {
MOZ_LOG(GetLayoutLog(),
MOZ_LOG(sLayoutLog,
mozilla::LogLevel::Warning,
("[%d] WARNING: %s: '%s', file %s, line %d",
base::GetCurrentProcId(),
aStr, aExpr, aFile, aLine));
} else {
MOZ_LOG(GetLayoutLog(),
MOZ_LOG(sLayoutLog,
mozilla::LogLevel::Warning,
("[%d] WARNING: %s: file %s, line %d",
base::GetCurrentProcId(),
+3 -3
View File
@@ -11,7 +11,7 @@
/**
* Retrieves the log module to use for layout logging.
*/
PRLogModuleInfo* GetLayoutLog();
static mozilla::LazyLogModule sLayoutLog("layout");
/**
* Use the layout log to warn if a given condition is false.
@@ -22,7 +22,7 @@ PRLogModuleInfo* GetLayoutLog();
#ifdef DEBUG
#define LAYOUT_WARN_IF_FALSE(_cond, _msg) \
PR_BEGIN_MACRO \
if (MOZ_LOG_TEST(GetLayoutLog(), mozilla::LogLevel::Warning) && \
if (MOZ_LOG_TEST(sLayoutLog, mozilla::LogLevel::Warning) && \
!(_cond)) { \
mozilla::detail::LayoutLogWarning(_msg, #_cond, __FILE__, __LINE__); \
} \
@@ -42,7 +42,7 @@ PRLogModuleInfo* GetLayoutLog();
#ifdef DEBUG
#define LAYOUT_WARNING(_msg) \
PR_BEGIN_MACRO \
if (MOZ_LOG_TEST(GetLayoutLog(), mozilla::LogLevel::Warning)) { \
if (MOZ_LOG_TEST(sLayoutLog, mozilla::LogLevel::Warning)) { \
mozilla::detail::LayoutLogWarning(_msg, nullptr, __FILE__, __LINE__); \
} \
PR_END_MACRO
+12 -29
View File
@@ -56,33 +56,6 @@ RestyleTracker::Document() const {
#define RESTYLE_ARRAY_STACKSIZE 128
struct LaterSiblingCollector {
RestyleTracker* tracker;
nsTArray< RefPtr<dom::Element> >* elements;
};
static PLDHashOperator
CollectLaterSiblings(nsISupports* aElement,
nsAutoPtr<RestyleTracker::RestyleData>& aData,
void* aSiblingCollector)
{
dom::Element* element =
static_cast<dom::Element*>(aElement);
LaterSiblingCollector* collector =
static_cast<LaterSiblingCollector*>(aSiblingCollector);
// Only collect the entries that actually need restyling by us (and
// haven't, for example, already been restyled).
// It's important to not mess with the flags on entries not in our
// document.
if (element->GetCrossShadowCurrentDoc() == collector->tracker->Document() &&
element->HasFlag(collector->tracker->RestyleBit()) &&
(aData->mRestyleHint & eRestyle_LaterSiblings)) {
collector->elements->AppendElement(element);
}
return PL_DHASH_NEXT;
}
struct RestyleEnumerateData : RestyleTracker::Hints {
RefPtr<dom::Element> mElement;
#if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
@@ -265,8 +238,18 @@ RestyleTracker::DoProcessRestyles()
if (mHaveLaterSiblingRestyles) {
// Convert them to individual restyles on all the later siblings
nsAutoTArray<RefPtr<Element>, RESTYLE_ARRAY_STACKSIZE> laterSiblingArr;
LaterSiblingCollector siblingCollector = { this, &laterSiblingArr };
mPendingRestyles.Enumerate(CollectLaterSiblings, &siblingCollector);
for (auto iter = mPendingRestyles.Iter(); !iter.Done(); iter.Next()) {
auto element = static_cast<dom::Element*>(iter.Key());
// Only collect the entries that actually need restyling by us (and
// haven't, for example, already been restyled).
// It's important to not mess with the flags on entries not in our
// document.
if (element->GetCrossShadowCurrentDoc() == Document() &&
element->HasFlag(RestyleBit()) &&
(iter.Data()->mRestyleHint & eRestyle_LaterSiblings)) {
laterSiblingArr.AppendElement(element);
}
}
for (uint32_t i = 0; i < laterSiblingArr.Length(); ++i) {
Element* element = laterSiblingArr[i];
for (nsIContent* sibling = element->GetNextSibling();
+1 -5
View File
@@ -39,8 +39,8 @@
using namespace mozilla;
using namespace mozilla::dom;
static PRLogModuleInfo* gSelectionCaretsLog;
static const char* kSelectionCaretsLogModuleName = "SelectionCarets";
static mozilla::LazyLogModule gSelectionCaretsLog(kSelectionCaretsLogModuleName);
// To enable all the SELECTIONCARETS_LOG print statements, set the environment
// variable NSPR_LOG_MODULES=SelectionCarets:5
@@ -84,10 +84,6 @@ SelectionCarets::SelectionCarets(nsIPresShell* aPresShell)
{
MOZ_ASSERT(NS_IsMainThread());
if (!gSelectionCaretsLog) {
gSelectionCaretsLog = PR_NewLogModule(kSelectionCaretsLogModuleName);
}
SELECTIONCARETS_LOG("Constructor, PresShell=%p", mPresShell);
static bool addedPref = false;
+1 -5
View File
@@ -36,8 +36,8 @@
using namespace mozilla;
static PRLogModuleInfo* gTouchCaretLog;
static const char* kTouchCaretLogModuleName = "TouchCaret";
static mozilla::LazyLogModule gTouchCaretLog(kTouchCaretLogModuleName);
// To enable all the TOUCHCARET_LOG print statements, set the environment
// variable NSPR_LOG_MODULES=TouchCaret:5
@@ -79,10 +79,6 @@ TouchCaret::TouchCaret(nsIPresShell* aPresShell)
{
MOZ_ASSERT(NS_IsMainThread());
if (!gTouchCaretLog) {
gTouchCaretLog = PR_NewLogModule(kTouchCaretLogModuleName);
}
TOUCHCARET_LOG("Constructor, PresShell=%p", aPresShell);
static bool addedTouchCaretPref = false;
+12 -14
View File
@@ -8,7 +8,6 @@
#include "TouchManager.h"
#include "nsPresShell.h"
bool TouchManager::gPreventMouseEvents = false;
nsRefPtrHashtable<nsUint32HashKey, dom::Touch>* TouchManager::gCaptureTouchList;
/*static*/ void
@@ -74,21 +73,23 @@ EvictTouchPoint(RefPtr<dom::Touch>& aTouch,
}
}
static PLDHashOperator
AppendToTouchList(const uint32_t& aKey, RefPtr<dom::Touch>& aData, void *aTouchList)
static void
AppendToTouchList(WidgetTouchEvent::TouchArray* aTouchList)
{
WidgetTouchEvent::TouchArray* touches =
static_cast<WidgetTouchEvent::TouchArray*>(aTouchList);
aData->mChanged = false;
touches->AppendElement(aData);
return PL_DHASH_NEXT;
for (auto iter = TouchManager::gCaptureTouchList->Iter();
!iter.Done();
iter.Next()) {
RefPtr<dom::Touch>& touch = iter.Data();
touch->mChanged = false;
aTouchList->AppendElement(touch);
}
}
void
TouchManager::EvictTouches()
{
WidgetTouchEvent::AutoTouchArray touches;
gCaptureTouchList->Enumerate(&AppendToTouchList, &touches);
AppendToTouchList(&touches);
for (uint32_t i = 0; i < touches.Length(); ++i) {
EvictTouchPoint(touches[i], mDocument);
}
@@ -110,7 +111,7 @@ TouchManager::PreHandleEvent(WidgetEvent* aEvent,
// queue
if (touchEvent->touches.Length() == 1) {
WidgetTouchEvent::AutoTouchArray touches;
gCaptureTouchList->Enumerate(&AppendToTouchList, (void *)&touches);
AppendToTouchList(&touches);
for (uint32_t i = 0; i < touches.Length(); ++i) {
EvictTouchPoint(touches[i]);
}
@@ -182,9 +183,6 @@ TouchManager::PreHandleEvent(WidgetEvent* aEvent,
}
}
} else {
if (gPreventMouseEvents) {
*aStatus = nsEventStatus_eConsumeNoDefault;
}
return false;
}
}
@@ -218,7 +216,7 @@ TouchManager::PreHandleEvent(WidgetEvent* aEvent,
gCaptureTouchList->Remove(id);
}
// add any touches left in the touch list, but ensure changed=false
gCaptureTouchList->Enumerate(&AppendToTouchList, (void *)&touches);
AppendToTouchList(&touches);
break;
}
default:
-1
View File
@@ -30,7 +30,6 @@ public:
bool& aIsHandlingUserInput,
nsCOMPtr<nsIContent>& aCurrentEventContent);
static bool gPreventMouseEvents;
static nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Touch>* gCaptureTouchList;
private:
-1
View File
@@ -106,7 +106,6 @@ EXPORTS.mozilla += [
UNIFIED_SOURCES += [
'AccessibleCaret.cpp',
'AccessibleCaretEventHub.cpp',
'AccessibleCaretLogger.cpp',
'AccessibleCaretManager.cpp',
'ActiveLayerTracker.cpp',
'DisplayItemClip.cpp',
+1 -1
View File
@@ -1183,7 +1183,7 @@ nsBidiPresUtils::TraverseFrames(nsBlockFrame* aBlockFrame,
} else {
// For a non-leaf frame, recurse into TraverseFrames
nsIFrame* kid = frame->GetFirstPrincipalChild();
MOZ_ASSERT(!frame->GetFirstChild(nsIFrame::kOverflowList),
MOZ_ASSERT(!frame->GetChildList(nsIFrame::kOverflowList).FirstChild(),
"should have drained the overflow list above");
if (kid) {
const nsStyleTextReset* text = frame->StyleTextReset();
+4 -4
View File
@@ -8924,7 +8924,7 @@ nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame)
}
nsFrameItems fixedPlaceholders;
nsIFrame* firstFixed = prevPageContentFrame->GetFirstChild(nsIFrame::kFixedList);
nsIFrame* firstFixed = prevPageContentFrame->GetChildList(nsIFrame::kFixedList).FirstChild();
if (!firstFixed) {
return NS_OK;
}
@@ -9227,13 +9227,13 @@ nsCSSFrameConstructor::MaybeRecreateContainerForFrameRemoval(nsIFrame* aFrame,
// pseudo parent was created for the space, and should now be removed.
(IsWhitespaceFrame(aFrame) &&
parent->PrincipalChildList().OnlyChild()) ||
// If we're a table-column-group, then the GetFirstChild check above is
// If we're a table-column-group, then the OnlyChild check above is
// not going to catch cases when we're the first child.
(inFlowFrame->GetType() == nsGkAtoms::tableColGroupFrame &&
parent->GetFirstChild(nsIFrame::kColGroupList) == inFlowFrame) ||
parent->GetChildList(nsIFrame::kColGroupList).FirstChild() == inFlowFrame) ||
// Similar if we're a table-caption.
(inFlowFrame->IsTableCaption() &&
parent->GetFirstChild(nsIFrame::kCaptionList) == inFlowFrame)) {
parent->GetChildList(nsIFrame::kCaptionList).FirstChild() == inFlowFrame)) {
// We're the first or last frame in the pseudo. Need to reframe.
// Good enough to recreate frames for |parent|'s content
*aResult = RecreateFramesForContent(parent->GetContent(), true, aFlags,
+54 -80
View File
@@ -275,110 +275,84 @@ nsCounterManager::CounterListFor(const nsSubstring& aCounterName)
return counterList;
}
static PLDHashOperator
RecalcDirtyLists(const nsAString& aKey, nsCounterList* aList, void* aClosure)
{
if (aList->IsDirty())
aList->RecalcAll();
return PL_DHASH_NEXT;
}
void
nsCounterManager::RecalcAll()
{
mNames.EnumerateRead(RecalcDirtyLists, nullptr);
}
static PLDHashOperator
SetCounterStylesDirty(const nsAString& aKey,
nsCounterList* aList,
void* aClosure)
{
nsCounterNode* first = aList->First();
if (first) {
bool changed = false;
nsCounterNode* node = first;
do {
if (node->mType == nsCounterNode::USE) {
node->UseNode()->SetCounterStyleDirty();
changed = true;
}
} while ((node = aList->Next(node)) != first);
if (changed) {
aList->SetDirty();
for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) {
nsCounterList* list = iter.UserData();
if (list->IsDirty()) {
list->RecalcAll();
}
}
return PL_DHASH_NEXT;
}
void
nsCounterManager::SetAllCounterStylesDirty()
{
mNames.EnumerateRead(SetCounterStylesDirty, nullptr);
}
for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) {
nsCounterList* list = iter.UserData();
nsCounterNode* first = list->First();
if (first) {
bool changed = false;
nsCounterNode* node = first;
do {
if (node->mType == nsCounterNode::USE) {
node->UseNode()->SetCounterStyleDirty();
changed = true;
}
} while ((node = list->Next(node)) != first);
struct DestroyNodesData {
explicit DestroyNodesData(nsIFrame *aFrame)
: mFrame(aFrame)
, mDestroyedAny(false)
{
if (changed) {
list->SetDirty();
}
}
}
nsIFrame *mFrame;
bool mDestroyedAny;
};
static PLDHashOperator
DestroyNodesInList(const nsAString& aKey, nsCounterList* aList, void* aClosure)
{
DestroyNodesData *data = static_cast<DestroyNodesData*>(aClosure);
if (aList->DestroyNodesFor(data->mFrame)) {
data->mDestroyedAny = true;
aList->SetDirty();
}
return PL_DHASH_NEXT;
}
bool
nsCounterManager::DestroyNodesFor(nsIFrame *aFrame)
{
DestroyNodesData data(aFrame);
mNames.EnumerateRead(DestroyNodesInList, &data);
return data.mDestroyedAny;
bool destroyedAny = false;
for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) {
nsCounterList* list = iter.UserData();
if (list->DestroyNodesFor(aFrame)) {
destroyedAny = true;
list->SetDirty();
}
}
return destroyedAny;
}
#ifdef DEBUG
static PLDHashOperator
DumpList(const nsAString& aKey, nsCounterList* aList, void* aClosure)
{
printf("Counter named \"%s\":\n", NS_ConvertUTF16toUTF8(aKey).get());
nsCounterNode *node = aList->First();
if (node) {
int32_t i = 0;
do {
const char *types[] = { "RESET", "INCREMENT", "USE" };
printf(" Node #%d @%p frame=%p index=%d type=%s valAfter=%d\n"
" scope-start=%p scope-prev=%p",
i++, (void*)node, (void*)node->mPseudoFrame,
node->mContentIndex, types[node->mType], node->mValueAfter,
(void*)node->mScopeStart, (void*)node->mScopePrev);
if (node->mType == nsCounterNode::USE) {
nsAutoString text;
node->UseNode()->GetText(text);
printf(" text=%s", NS_ConvertUTF16toUTF8(text).get());
}
printf("\n");
} while ((node = aList->Next(node)) != aList->First());
}
return PL_DHASH_NEXT;
}
void
nsCounterManager::Dump()
{
printf("\n\nCounter Manager Lists:\n");
mNames.EnumerateRead(DumpList, nullptr);
for (auto iter = mNames.Iter(); !iter.Done(); iter.Next()) {
printf("Counter named \"%s\":\n",
NS_ConvertUTF16toUTF8(iter.Key()).get());
nsCounterList* list = iter.UserData();
nsCounterNode* node = list->First();
if (node) {
int32_t i = 0;
do {
const char* types[] = { "RESET", "INCREMENT", "USE" };
printf(" Node #%d @%p frame=%p index=%d type=%s valAfter=%d\n"
" scope-start=%p scope-prev=%p",
i++, (void*)node, (void*)node->mPseudoFrame,
node->mContentIndex, types[node->mType],
node->mValueAfter, (void*)node->mScopeStart,
(void*)node->mScopePrev);
if (node->mType == nsCounterNode::USE) {
nsAutoString text;
node->UseNode()->GetText(text);
printf(" text=%s", NS_ConvertUTF16toUTF8(text).get());
}
printf("\n");
} while ((node = list->Next(node)) != list->First());
}
}
printf("\n\n");
}
#endif
+109 -49
View File
@@ -105,6 +105,12 @@ SpammyLayoutWarningsEnabled()
}
#endif
void*
AnimatedGeometryRoot::operator new(size_t aSize, nsDisplayListBuilder* aBuilder)
{
return aBuilder->Allocate(aSize);
}
static inline CSSAngle
MakeCSSAngle(const nsCSSValue& aValue)
{
@@ -615,7 +621,8 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mCurrentTableItem(nullptr),
mCurrentFrame(aReferenceFrame),
mCurrentReferenceFrame(aReferenceFrame),
mCurrentAnimatedGeometryRoot(nullptr),
mCurrentAGR(&mRootAGR),
mRootAGR(aReferenceFrame, nullptr),
mDirtyRect(-1,-1,-1,-1),
mGlassDisplayItem(nullptr),
mPendingScrollInfoItems(nullptr),
@@ -652,7 +659,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
MOZ_COUNT_CTOR(nsDisplayListBuilder);
PL_InitArenaPool(&mPool, "displayListArena", 4096,
std::max(NS_ALIGNMENT_OF(void*),NS_ALIGNMENT_OF(double))-1);
RecomputeCurrentAnimatedGeometryRoot();
nsPresContext* pc = aReferenceFrame->PresContext();
nsIPresShell *shell = pc->PresShell();
@@ -664,6 +670,8 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
}
}
mFrameToAnimatedGeometryRootMap.Put(aReferenceFrame, &mRootAGR);
nsCSSRendering::BeginFrameTreesLocked();
PR_STATIC_ASSERT(nsDisplayItem::TYPE_MAX < (1 << nsDisplayItem::TYPE_BITS));
}
@@ -692,6 +700,68 @@ bool nsDisplayListBuilder::NeedToForceTransparentSurfaceForItem(nsDisplayItem* a
return aItem == mGlassDisplayItem || aItem->ClearsBackground();
}
AnimatedGeometryRoot*
nsDisplayListBuilder::WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aParent /* = nullptr */)
{
MOZ_ASSERT(IsAnimatedGeometryRoot(aAnimatedGeometryRoot));
AnimatedGeometryRoot* result = nullptr;
if (!mFrameToAnimatedGeometryRootMap.Get(aAnimatedGeometryRoot, &result)) {
MOZ_ASSERT(aAnimatedGeometryRoot != RootReferenceFrame());
AnimatedGeometryRoot* parent = aParent;
if (!parent) {
nsIFrame* parentFrame = nsLayoutUtils::GetCrossDocParentFrame(aAnimatedGeometryRoot);
if (parentFrame) {
nsIFrame* parentAGRFrame = FindAnimatedGeometryRootFrameFor(parentFrame);
parent = WrapAGRForFrame(parentAGRFrame);
}
}
result = new (this) AnimatedGeometryRoot(aAnimatedGeometryRoot, parent);
mFrameToAnimatedGeometryRootMap.Put(aAnimatedGeometryRoot, result);
}
MOZ_ASSERT(!aParent || result->mParentAGR == aParent);
return result;
}
AnimatedGeometryRoot*
nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsIFrame* aFrame)
{
if (!IsForPainting()) {
return &mRootAGR;
}
if (aFrame == mCurrentFrame) {
return mCurrentAGR;
}
AnimatedGeometryRoot* result = nullptr;
if (mFrameToAnimatedGeometryRootMap.Get(aFrame, &result)) {
return result;
}
nsIFrame* agrFrame = FindAnimatedGeometryRootFrameFor(aFrame);
result = WrapAGRForFrame(agrFrame);
mFrameToAnimatedGeometryRootMap.Put(aFrame, result);
return result;
}
AnimatedGeometryRoot*
nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsDisplayItem* aItem)
{
if (aItem->ShouldFixToViewport(this)) {
// Make its active scrolled root be the active scrolled root of
// the enclosing viewport, since it shouldn't be scrolled by scrolled
// frames in its document. InvalidateFixedBackgroundFramesFromList in
// nsGfxScrollFrame will not repaint this item when scrolling occurs.
nsIFrame* viewportFrame =
nsLayoutUtils::GetClosestFrameOfType(aItem->Frame(), nsGkAtoms::viewportFrame, RootReferenceFrame());
if (viewportFrame) {
return FindAnimatedGeometryRootFor(viewportFrame);
}
}
return FindAnimatedGeometryRootFor(aItem->Frame());
}
void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
nsIFrame* aFrame,
const nsRect& aDirtyRect)
@@ -1030,6 +1100,8 @@ IsStickyFrameActive(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsIFrame*
bool
nsDisplayListBuilder::IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParent)
{
if (aFrame == mReferenceFrame)
return true;
if (nsLayoutUtils::IsPopup(aFrame))
return true;
if (ActiveLayerTracker::IsOffsetOrMarginStyleAnimated(aFrame))
@@ -1079,57 +1151,43 @@ nsDisplayListBuilder::IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParen
return false;
}
bool
nsDisplayListBuilder::GetCachedAnimatedGeometryRoot(const nsIFrame* aFrame,
nsIFrame** aOutResult)
{
return mAnimatedGeometryRootCache.Get(const_cast<nsIFrame*>(aFrame), aOutResult);
}
static nsIFrame*
ComputeAnimatedGeometryRootFor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
bool aUseCache = false)
nsIFrame*
nsDisplayListBuilder::FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame)
{
nsIFrame* cursor = aFrame;
while (cursor != aBuilder->RootReferenceFrame()) {
if (aUseCache) {
nsIFrame* result;
if (aBuilder->GetCachedAnimatedGeometryRoot(cursor, &result)) {
return result;
}
}
while (cursor != RootReferenceFrame()) {
nsIFrame* next;
if (aBuilder->IsAnimatedGeometryRoot(cursor, &next))
if (IsAnimatedGeometryRoot(cursor, &next))
return cursor;
cursor = next;
}
return cursor;
}
nsIFrame*
nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsIFrame* aFrame)
{
if (aFrame == mCurrentFrame) {
return mCurrentAnimatedGeometryRoot;
}
nsIFrame* result = ComputeAnimatedGeometryRootFor(this, aFrame, true);
mAnimatedGeometryRootCache.Put(aFrame, result);
return result;
}
void
nsDisplayListBuilder::RecomputeCurrentAnimatedGeometryRoot()
{
// technically we only need to clear any part of the cache that relies on
// the AGR of mCurrentFrame (i.e. all entries in mAnimatedGeometryRootCache
// where the key frame is a descendant of mCurrentFrame) but doing that is
// complicated so we just clear the whole thing.
mAnimatedGeometryRootCache.Clear();
if (*mCurrentAGR != mCurrentFrame &&
IsAnimatedGeometryRoot(const_cast<nsIFrame*>(mCurrentFrame))) {
AnimatedGeometryRoot* oldAGR = mCurrentAGR;
mCurrentAGR = WrapAGRForFrame(const_cast<nsIFrame*>(mCurrentFrame), mCurrentAGR);
mCurrentAnimatedGeometryRoot = ComputeAnimatedGeometryRootFor(this, const_cast<nsIFrame *>(mCurrentFrame));
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(RootReferenceFrame(), mCurrentAnimatedGeometryRoot));
mAnimatedGeometryRootCache.Put(const_cast<nsIFrame*>(mCurrentFrame), mCurrentAnimatedGeometryRoot);
// Iterate the AGR cache and look for any objects that reference the old AGR and check
// to see if they need to be updated. AGRs can be in the cache multiple times, so we may
// end up doing the work multiple times for AGRs that don't change.
for (auto iter = mFrameToAnimatedGeometryRootMap.Iter(); !iter.Done(); iter.Next()) {
AnimatedGeometryRoot* cached = iter.UserData();
if (cached->mParentAGR == oldAGR && cached != mCurrentAGR) {
// It's possible that this cached AGR struct that has the old AGR as a parent
// should instead have mCurrentFrame has a parent.
nsIFrame* parent = FindAnimatedGeometryRootFrameFor(*cached);
MOZ_ASSERT(parent == mCurrentFrame || parent == *oldAGR);
if (parent == mCurrentFrame) {
cached->mParentAGR = mCurrentAGR;
}
}
}
}
}
void
@@ -2035,9 +2093,9 @@ nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame, &mToReferenceFrame);
// This can return the wrong result if the item override ShouldFixToViewport(),
// the item needs to set it again in its constructor.
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootForInit(this, aBuilder);
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(aFrame);
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(),
mAnimatedGeometryRoot), "Bad");
*mAnimatedGeometryRoot), "Bad");
NS_ASSERTION(aBuilder->GetDirtyRect().width >= 0 ||
!aBuilder->IsForPainting(), "dirty rect not set");
// The dirty rect is for mCurrentFrame, so we have to use
@@ -2172,6 +2230,7 @@ nsDisplayBackgroundImage::nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilde
const nsStyleBackground* aBackgroundStyle)
: nsDisplayImageContainer(aBuilder, aFrame)
, mBackgroundStyle(aBackgroundStyle)
, mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot)
, mLayer(aLayer)
{
MOZ_COUNT_CTOR(nsDisplayBackgroundImage);
@@ -2179,7 +2238,7 @@ nsDisplayBackgroundImage::nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilde
mBounds = GetBoundsInternal(aBuilder);
mDestArea = GetDestAreaInternal(aBuilder);
if (ShouldFixToViewport(aBuilder)) {
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder);
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(this);
}
}
@@ -3827,12 +3886,12 @@ RequiredLayerStateForChildren(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters,
const nsDisplayList& aList,
nsIFrame* aExpectedAnimatedGeometryRootForChildren)
AnimatedGeometryRoot* aExpectedAnimatedGeometryRootForChildren)
{
LayerState result = LAYER_INACTIVE;
for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
if (result == LAYER_INACTIVE &&
i->AnimatedGeometryRoot() != aExpectedAnimatedGeometryRootForChildren) {
i->GetAnimatedGeometryRoot() != aExpectedAnimatedGeometryRootForChildren) {
result = LAYER_ACTIVE;
}
@@ -4111,7 +4170,7 @@ nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
if (NeedsActiveLayer(aBuilder))
return LAYER_ACTIVE;
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList, AnimatedGeometryRoot());
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList, GetAnimatedGeometryRoot());
}
bool
@@ -4843,15 +4902,16 @@ nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder)
mReferenceFrame =
aBuilder->FindReferenceFrameFor(outerFrame);
mToReferenceFrame = mFrame->GetOffsetToCrossDoc(mReferenceFrame);
mAnimatedGeometryRootForChildren = mAnimatedGeometryRoot;
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(mFrame)) {
// This is an odd special case. If we are both IsFixedPosFrameInDisplayPort
// and transformed that we are our own AGR parent.
// We want our frame to be our AGR because FrameLayerBuilder uses our AGR to
// determine if we are inside a fixed pos subtree. If we use the outer AGR
// from outside the fixed pos subtree FLB can't tell that we are fixed pos.
mAnimatedGeometryRoot = mFrame;
mAnimatedGeometryRoot = mAnimatedGeometryRootForChildren;
} else {
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootForFrame(aBuilder, outerFrame);
mAnimatedGeometryRoot = mAnimatedGeometryRoot->mParentAGR;
}
mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;
}
@@ -5576,7 +5636,7 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
// different animated geometry root, we'll make this an active layer so the
// animation can be accelerated.
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters,
*mStoredList.GetChildren(), Frame());
*mStoredList.GetChildren(), mAnimatedGeometryRootForChildren);
}
bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
+100 -47
View File
@@ -107,6 +107,47 @@ typedef mozilla::EnumSet<mozilla::gfx::CompositionOp> BlendModeSet;
virtual const char* Name() override { return n; } \
virtual Type GetType() override { return e; }
/**
* Represents a frame that is considered to have (or will have) "animated geometry"
* for itself and descendant frames.
*
* For example the scrolled frames of scrollframes which are actively being scrolled
* fall into this category. Frames with certain CSS properties that are being animated
* (e.g. 'left'/'top' etc) are also placed in this category. Frames with different
* active geometry roots are in different PaintedLayers, so that we can animate the
* geometry root by changing its transform (either on the main thread or in the
* compositor).
*
* nsDisplayListBuilder constructs a tree of these (for fast traversals) and assigns
* one for each display item.
*
* The animated geometry root for a display item is required to be a descendant (or
* equal to) the item's ReferenceFrame(), which means that we will fall back to
* returning aItem->ReferenceFrame() when we can't find another animated geometry root.
*
* The animated geometry root isn't strongly defined for a frame as transforms and
* background-attachment:fixed can cause it to vary between display items for a given
* frame.
*/
struct AnimatedGeometryRoot
{
AnimatedGeometryRoot(nsIFrame* aFrame, AnimatedGeometryRoot* aParent)
: mFrame(aFrame)
, mParentAGR(aParent)
{}
operator nsIFrame*() { return mFrame; }
nsIFrame* operator ->() const { return mFrame; }
void* operator new(size_t aSize,
nsDisplayListBuilder* aBuilder) CPP_THROW_NEW;
nsIFrame* mFrame;
AnimatedGeometryRoot* mParentAGR;
};
/**
* This manages a display list and is passed as a parameter to
* nsIFrame::BuildDisplayList.
@@ -178,7 +219,7 @@ public:
EVENT_DELIVERY,
PLUGIN_GEOMETRY,
IMAGE_VISIBILITY,
OTHER
TRANSFORM_COMPUTATION
};
nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, bool aBuildCaret);
~nsDisplayListBuilder();
@@ -250,18 +291,6 @@ public:
const nsIFrame* FindReferenceFrameFor(const nsIFrame *aFrame,
nsPoint* aOffset = nullptr);
/**
* Returns whether a frame acts as an animated geometry root, optionally
* returning the next ancestor to check.
*/
bool IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParent = nullptr);
/**
* Returns the nearest ancestor frame to aFrame that is considered to have
* (or will have) animated geometry. This can return aFrame.
*/
nsIFrame* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
/**
* @return the root of the display list's frame (sub)tree, whose origin
* establishes the coordinate system for the display list
@@ -377,9 +406,13 @@ public:
const nsIFrame* GetCurrentFrame() { return mCurrentFrame; }
const nsIFrame* GetCurrentReferenceFrame() { return mCurrentReferenceFrame; }
const nsPoint& GetCurrentFrameOffsetToReferenceFrame() { return mCurrentOffsetToReferenceFrame; }
const nsIFrame* GetCurrentAnimatedGeometryRoot() {
return mCurrentAnimatedGeometryRoot;
AnimatedGeometryRoot* GetCurrentAnimatedGeometryRoot() {
return mCurrentAGR;
}
AnimatedGeometryRoot* GetRootAnimatedGeometryRoot() {
return &mRootAGR;
}
void RecomputeCurrentAnimatedGeometryRoot();
/**
@@ -606,6 +639,7 @@ public:
nsDisplayItem* aItem,
nsIFrame* aFrame,
nsCSSProperty aProperty);
/**
* A helper class to temporarily set the value of
* mIsAtRootOfPseudoStackingContext, and temporarily
@@ -622,10 +656,10 @@ public:
: mBuilder(aBuilder),
mPrevFrame(aBuilder->mCurrentFrame),
mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame),
mPrevAnimatedGeometryRoot(mBuilder->mCurrentAnimatedGeometryRoot),
mPrevLayerEventRegions(aBuilder->mLayerEventRegions),
mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame),
mPrevDirtyRect(aBuilder->mDirtyRect),
mPrevAGR(aBuilder->mCurrentAGR),
mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
mPrevAncestorHasApzAwareEventHandler(aBuilder->mAncestorHasApzAwareEventHandler)
{
@@ -641,14 +675,12 @@ public:
}
if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
if (aBuilder->IsAnimatedGeometryRoot(aForChild)) {
aBuilder->mCurrentAnimatedGeometryRoot = aForChild;
aBuilder->mCurrentAGR = aBuilder->WrapAGRForFrame(aForChild, aBuilder->mCurrentAGR);
}
} else {
aBuilder->mCurrentAnimatedGeometryRoot =
aBuilder->FindAnimatedGeometryRootFor(aForChild);
} else if (aForChild != aBuilder->mCurrentFrame) {
aBuilder->mCurrentAGR = aBuilder->FindAnimatedGeometryRootFor(aForChild);
}
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(),
aBuilder->mCurrentAnimatedGeometryRoot));
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(), *aBuilder->mCurrentAGR));
aBuilder->mCurrentFrame = aForChild;
aBuilder->mDirtyRect = aDirtyRect;
aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
@@ -665,15 +697,19 @@ public:
const nsIFrame* GetPrevAnimatedGeometryRoot() const {
return mPrevAnimatedGeometryRoot;
}
bool IsAnimatedGeometryRoot() const {
return *mBuilder->mCurrentAGR == mBuilder->mCurrentFrame;
}
~AutoBuildingDisplayList() {
mBuilder->mCurrentFrame = mPrevFrame;
mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame;
mBuilder->mLayerEventRegions = mPrevLayerEventRegions;
mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
mBuilder->mDirtyRect = mPrevDirtyRect;
mBuilder->mCurrentAGR = mPrevAGR;
mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext;
mBuilder->mAncestorHasApzAwareEventHandler = mPrevAncestorHasApzAwareEventHandler;
mBuilder->mCurrentAnimatedGeometryRoot = mPrevAnimatedGeometryRoot;
}
private:
nsDisplayListBuilder* mBuilder;
@@ -683,6 +719,7 @@ public:
nsDisplayLayerEventRegions* mPrevLayerEventRegions;
nsPoint mPrevOffset;
nsRect mPrevDirtyRect;
AnimatedGeometryRoot* mPrevAGR;
bool mPrevIsAtRootOfPseudoStackingContext;
bool mPrevAncestorHasApzAwareEventHandler;
};
@@ -975,14 +1012,6 @@ public:
*/
bool IsInWillChangeBudget(nsIFrame* aFrame, const nsSize& aSize);
/**
* Look up the cached animated geometry root for aFrame subject Store the
* nsIFrame* result into *aOutResult, and return true if the cache was hit.
* Return false if the cache was not hit.
*/
bool GetCachedAnimatedGeometryRoot(const nsIFrame* aFrame,
nsIFrame** aOutResult);
void SetCommittedScrollInfoItemList(nsDisplayList* aScrollInfoItemStorage) {
mCommittedScrollInfoItems = aScrollInfoItemStorage;
}
@@ -1066,6 +1095,30 @@ private:
void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
const nsRect& aDirtyRect);
/**
* Returns whether a frame acts as an animated geometry root, optionally
* returning the next ancestor to check.
*/
bool IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParent = nullptr);
/**
* Returns the nearest ancestor frame to aFrame that is considered to have
* (or will have) animated geometry. This can return aFrame.
*/
nsIFrame* FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame);
friend class nsDisplayCanvasBackgroundImage;
friend class nsDisplayBackgroundImage;
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
AnimatedGeometryRoot* WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aParent = nullptr);
friend class nsDisplayItem;
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
nsDataHashtable<nsPtrHashKey<nsIFrame>, AnimatedGeometryRoot*> mFrameToAnimatedGeometryRootMap;
struct PresShellState {
nsIPresShell* mPresShell;
nsIFrame* mCaretFrame;
@@ -1092,7 +1145,7 @@ private:
uint32_t mBudget;
};
nsIFrame* mReferenceFrame;
nsIFrame* const mReferenceFrame;
nsIFrame* mIgnoreScrollFrame;
nsDisplayLayerEventRegions* mLayerEventRegions;
PLArenaPool mPool;
@@ -1109,11 +1162,10 @@ private:
const nsIFrame* mCurrentReferenceFrame;
// The offset from mCurrentFrame to mCurrentReferenceFrame.
nsPoint mCurrentOffsetToReferenceFrame;
// The animated geometry root for mCurrentFrame.
nsIFrame* mCurrentAnimatedGeometryRoot;
// Cache for storing animated geometry roots for arbitrary frames
nsDataHashtable<nsPtrHashKey<nsIFrame>, nsIFrame*> mAnimatedGeometryRootCache;
AnimatedGeometryRoot* mCurrentAGR;
AnimatedGeometryRoot mRootAGR;
// will-change budget tracker
nsDataHashtable<nsPtrHashKey<nsPresContext>, DocumentWillChangeBudget>
mWillChangeBudget;
@@ -1695,11 +1747,15 @@ public:
*/
virtual const nsIFrame* ReferenceFrameForChildren() const { return mReferenceFrame; }
nsIFrame* AnimatedGeometryRoot() const {
AnimatedGeometryRoot* GetAnimatedGeometryRoot() const {
MOZ_ASSERT(mAnimatedGeometryRoot, "Must have cached AGR before accessing it!");
return mAnimatedGeometryRoot;
}
virtual struct AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const {
return GetAnimatedGeometryRoot();
}
/**
* Checks if this display item (or any children) contains content that might
* be rendered with component alpha (e.g. subpixel antialiasing). Returns the
@@ -1759,7 +1815,7 @@ protected:
const DisplayItemClip* mClip;
// Result of FindReferenceFrameFor(mFrame), if mFrame is non-null
const nsIFrame* mReferenceFrame;
nsIFrame* mAnimatedGeometryRoot;
struct AnimatedGeometryRoot* mAnimatedGeometryRoot;
// Result of ToReferenceFrame(mFrame), if mFrame is non-null
nsPoint mToReferenceFrame;
// This is the rectangle that needs to be painted.
@@ -2599,6 +2655,10 @@ public:
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) override;
AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override {
return mAnimatedGeometryRootForScrollMetadata;
}
protected:
typedef class mozilla::layers::ImageContainer ImageContainer;
typedef class mozilla::layers::ImageLayer ImageLayer;
@@ -2630,6 +2690,7 @@ protected:
nsCOMPtr<imgIContainer> mImage;
RefPtr<ImageContainer> mImageContainer;
LayoutDeviceRect mImageLayerDestRect;
AnimatedGeometryRoot* mAnimatedGeometryRootForScrollMetadata;
/* Bounds of this display item */
nsRect mBounds;
nsRect mDestArea;
@@ -3948,15 +4009,6 @@ public:
mFrame->Combines3DTransformWithAncestors()));
}
/**
* Whether this transform item forms a reference frame boundary.
* In other words, the reference frame of the contained items is our frame,
* and the reference frame of this item is some ancestor of our frame.
*/
bool IsReferenceFrameBoundary() {
return !mTransformGetter && !mIsTransformSeparator;
}
private:
void ComputeBounds(nsDisplayListBuilder* aBuilder);
void SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder);
@@ -3975,6 +4027,7 @@ private:
// Accumulated transform of ancestors on the preserves-3d chain.
Matrix4x4 mTransformPreserves3D;
ComputeTransformFunction mTransformGetter;
AnimatedGeometryRoot* mAnimatedGeometryRootForChildren;
nsRect mChildrenVisibleRect;
uint32_t mIndex;
nsRect mBounds;
+3 -9
View File
@@ -136,15 +136,9 @@ using namespace mozilla::dom;
#include "mozilla/Logging.h"
#ifdef NS_PRINTING
static PRLogModuleInfo *
GetPrintingLog()
{
static PRLogModuleInfo *sLog;
if (!sLog)
sLog = PR_NewLogModule("printing");
return sLog;
}
#define PR_PL(_p1) MOZ_LOG(GetPrintingLog(), mozilla::LogLevel::Debug, _p1);
static mozilla::LazyLogModule gPrintingLog("printing");
#define PR_PL(_p1) MOZ_LOG(gPrintingLog, mozilla::LogLevel::Debug, _p1);
#endif // NS_PRINTING
#define PRT_YESNO(_p) ((_p)?"YES":"NO")
+4 -4
View File
@@ -140,10 +140,10 @@ typedef struct CapturingContentInfo {
mozilla::StaticRefPtr<nsIContent> mContent;
} CapturingContentInfo;
// 0ff43c2e-5688-464f-a23f-a3de223df684
// ae50e013-b2f1-4d4e-94c7-77cbcdab1c23
#define NS_IPRESSHELL_IID \
{ 0x0ff43c2e, 0x5688, 0x464f, \
{ 0xa2, 0x3f, 0xa3, 0xde, 0x22, 0x3d, 0xf6, 0x84 } }
{ 0xae50e013, 0xb2f1, 0x4d4e, \
{ 0x94, 0xc7, 0x77, 0xcb, 0xcd, 0xab, 0x1c, 0x23 } }
// debug VerifyReflow flags
#define VERIFY_REFLOW_ON 0x01
@@ -1247,7 +1247,7 @@ public:
return mObservesMutationsForPrint;
}
virtual nsresult SetIsActive(bool aIsActive) = 0;
virtual nsresult SetIsActive(bool aIsActive, bool aIsHidden = true) = 0;
bool IsActive()
{
+2 -2
View File
@@ -162,7 +162,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
}
bool snap;
nsRect rect = aItem->GetBounds(aBuilder, &snap);
nsRect layerRect = rect - aItem->AnimatedGeometryRoot()->GetOffsetToCrossDoc(aItem->ReferenceFrame());
nsRect layerRect = rect - (*aItem->GetAnimatedGeometryRoot())->GetOffsetToCrossDoc(aItem->ReferenceFrame());
nscolor color;
nsRect vis = aItem->GetVisibleRect();
nsRect component = aItem->GetComponentAlphaBounds(aBuilder);
@@ -186,7 +186,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
component.x, component.y, component.width, component.height,
clip.ToString().get(),
aItem->IsUniform(aBuilder, &color) ? " uniform" : "",
aItem->ReferenceFrame(), aItem->AnimatedGeometryRoot());
aItem->ReferenceFrame(), *aItem->GetAnimatedGeometryRoot());
nsRegionRectIterator iter(opaque);
for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
+19 -74
View File
@@ -204,11 +204,11 @@ GridEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
// OK -- now, stomp on or restore the "grid" entries in kDisplayKTable,
// depending on whether the grid pref is enabled vs. disabled.
if (sIndexOfGridInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfGridInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfGridInDisplayTable].mKeyword =
isGridEnabled ? eCSSKeyword_grid : eCSSKeyword_UNKNOWN;
}
if (sIndexOfInlineGridInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfInlineGridInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfInlineGridInDisplayTable].mKeyword =
isGridEnabled ? eCSSKeyword_inline_grid : eCSSKeyword_UNKNOWN;
}
}
@@ -264,23 +264,23 @@ RubyEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
// OK -- now, stomp on or restore the "ruby" entries in kDisplayKTable,
// depending on whether the ruby pref is enabled vs. disabled.
if (sIndexOfRubyInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfRubyInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfRubyInDisplayTable].mKeyword =
isRubyEnabled ? eCSSKeyword_ruby : eCSSKeyword_UNKNOWN;
}
if (sIndexOfRubyBaseInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfRubyBaseInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfRubyBaseInDisplayTable].mKeyword =
isRubyEnabled ? eCSSKeyword_ruby_base : eCSSKeyword_UNKNOWN;
}
if (sIndexOfRubyBaseContainerInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfRubyBaseContainerInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfRubyBaseContainerInDisplayTable].mKeyword =
isRubyEnabled ? eCSSKeyword_ruby_base_container : eCSSKeyword_UNKNOWN;
}
if (sIndexOfRubyTextInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfRubyTextInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfRubyTextInDisplayTable].mKeyword =
isRubyEnabled ? eCSSKeyword_ruby_text : eCSSKeyword_UNKNOWN;
}
if (sIndexOfRubyTextContainerInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfRubyTextContainerInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfRubyTextContainerInDisplayTable].mKeyword =
isRubyEnabled ? eCSSKeyword_ruby_text_container : eCSSKeyword_UNKNOWN;
}
}
@@ -314,7 +314,7 @@ StickyEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
// OK -- now, stomp on or restore the "sticky" entry in kPositionKTable,
// depending on whether the sticky pref is enabled vs. disabled.
nsCSSProps::kPositionKTable[sIndexOfStickyInPositionTable] =
nsCSSProps::kPositionKTable[sIndexOfStickyInPositionTable].mKeyword =
isStickyEnabled ? eCSSKeyword_sticky : eCSSKeyword_UNKNOWN;
}
@@ -343,7 +343,7 @@ DisplayContentsEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
// OK -- now, stomp on or restore the "contents" entry in kDisplayKTable,
// depending on whether the pref is enabled vs. disabled.
if (sIndexOfContentsInDisplayTable >= 0) {
nsCSSProps::kDisplayKTable[sIndexOfContentsInDisplayTable] =
nsCSSProps::kDisplayKTable[sIndexOfContentsInDisplayTable].mKeyword =
isDisplayContentsEnabled ? eCSSKeyword_contents : eCSSKeyword_UNKNOWN;
}
}
@@ -378,10 +378,10 @@ TextAlignUnsafeEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
// OK -- now, stomp on or restore the "unsafe" entry in the keyword tables,
// depending on whether the pref is enabled vs. disabled.
MOZ_ASSERT(sIndexOfUnsafeInTextAlignTable >= 0);
nsCSSProps::kTextAlignKTable[sIndexOfUnsafeInTextAlignTable] =
nsCSSProps::kTextAlignKTable[sIndexOfUnsafeInTextAlignTable].mKeyword =
isTextAlignUnsafeEnabled ? eCSSKeyword_unsafe : eCSSKeyword_UNKNOWN;
MOZ_ASSERT(sIndexOfUnsafeInTextAlignLastTable >= 0);
nsCSSProps::kTextAlignLastKTable[sIndexOfUnsafeInTextAlignLastTable] =
nsCSSProps::kTextAlignLastKTable[sIndexOfUnsafeInTextAlignLastTable].mKeyword =
isTextAlignUnsafeEnabled ? eCSSKeyword_unsafe : eCSSKeyword_UNKNOWN;
}
@@ -427,16 +427,16 @@ FloatLogicalValuesEnabledPrefChangeCallback(const char* aPrefName,
// OK -- now, stomp on or restore the logical entries in the keyword tables,
// depending on whether the pref is enabled vs. disabled.
MOZ_ASSERT(sIndexOfInlineStartInFloatTable >= 0);
nsCSSProps::kFloatKTable[sIndexOfInlineStartInFloatTable] =
nsCSSProps::kFloatKTable[sIndexOfInlineStartInFloatTable].mKeyword =
isFloatLogicalValuesEnabled ? eCSSKeyword_inline_start : eCSSKeyword_UNKNOWN;
MOZ_ASSERT(sIndexOfInlineEndInFloatTable >= 0);
nsCSSProps::kFloatKTable[sIndexOfInlineEndInFloatTable] =
nsCSSProps::kFloatKTable[sIndexOfInlineEndInFloatTable].mKeyword =
isFloatLogicalValuesEnabled ? eCSSKeyword_inline_end : eCSSKeyword_UNKNOWN;
MOZ_ASSERT(sIndexOfInlineStartInClearTable >= 0);
nsCSSProps::kClearKTable[sIndexOfInlineStartInClearTable] =
nsCSSProps::kClearKTable[sIndexOfInlineStartInClearTable].mKeyword =
isFloatLogicalValuesEnabled ? eCSSKeyword_inline_start : eCSSKeyword_UNKNOWN;
MOZ_ASSERT(sIndexOfInlineEndInClearTable >= 0);
nsCSSProps::kClearKTable[sIndexOfInlineEndInClearTable] =
nsCSSProps::kClearKTable[sIndexOfInlineEndInClearTable].mKeyword =
isFloatLogicalValuesEnabled ? eCSSKeyword_inline_end : eCSSKeyword_UNKNOWN;
}
@@ -1311,7 +1311,7 @@ nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
if (parent->GetType() == nsGkAtoms::popupSetFrame) {
id = nsIFrame::kPopupList;
} else {
nsIFrame* firstPopup = parent->GetFirstChild(nsIFrame::kPopupList);
nsIFrame* firstPopup = parent->GetChildList(nsIFrame::kPopupList).FirstChild();
MOZ_ASSERT(!firstPopup || !firstPopup->GetNextSibling(),
"We assume popupList only has one child, but it has more.");
id = firstPopup == aChildFrame
@@ -1927,61 +1927,6 @@ nsLayoutUtils::IsScrollbarThumbLayerized(nsIFrame* aThumbFrame)
return reinterpret_cast<intptr_t>(aThumbFrame->Properties().Get(ScrollbarThumbLayerized()));
}
nsIFrame*
nsLayoutUtils::GetAnimatedGeometryRootForFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame)
{
return aBuilder->FindAnimatedGeometryRootFor(aFrame);
}
nsIFrame*
nsLayoutUtils::GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder,
uint32_t aFlags)
{
nsIFrame* f = aItem->Frame();
if (!(aFlags & AGR_IGNORE_BACKGROUND_ATTACHMENT_FIXED) &&
aItem->ShouldFixToViewport(aBuilder)) {
// Make its active scrolled root be the active scrolled root of
// the enclosing viewport, since it shouldn't be scrolled by scrolled
// frames in its document. InvalidateFixedBackgroundFramesFromList in
// nsGfxScrollFrame will not repaint this item when scrolling occurs.
nsIFrame* viewportFrame =
nsLayoutUtils::GetClosestFrameOfType(f, nsGkAtoms::viewportFrame, aBuilder->RootReferenceFrame());
if (viewportFrame) {
return GetAnimatedGeometryRootForFrame(aBuilder, viewportFrame);
}
}
if (aItem->GetType() == nsDisplayItem::TYPE_TRANSFORM &&
static_cast<nsDisplayTransform*>(aItem)->IsReferenceFrameBoundary() &&
f != aBuilder->RootReferenceFrame()) {
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(f);
if (parent) {
return GetAnimatedGeometryRootForFrame(aBuilder, parent);
}
}
return GetAnimatedGeometryRootForFrame(aBuilder, f);
}
nsIFrame*
nsLayoutUtils::GetAnimatedGeometryRootForInit(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder)
{
nsIFrame* f = aItem->Frame();
if (aItem->ShouldFixToViewport(aBuilder)) {
// Make its active scrolled root be the active scrolled root of
// the enclosing viewport, since it shouldn't be scrolled by scrolled
// frames in its document. InvalidateFixedBackgroundFramesFromList in
// nsGfxScrollFrame will not repaint this item when scrolling occurs.
nsIFrame* viewportFrame =
nsLayoutUtils::GetClosestFrameOfType(f, nsGkAtoms::viewportFrame, aBuilder->RootReferenceFrame());
if (viewportFrame) {
return GetAnimatedGeometryRootForFrame(aBuilder, viewportFrame);
}
}
return GetAnimatedGeometryRootForFrame(aBuilder, f);
}
// static
nsIScrollableFrame*
nsLayoutUtils::GetNearestScrollableFrameForDirection(nsIFrame* aFrame,
@@ -2788,7 +2733,7 @@ nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
return true;
}
nsDisplayListBuilder builder(root, nsDisplayListBuilder::OTHER,
nsDisplayListBuilder builder(root, nsDisplayListBuilder::TRANSFORM_COMPUTATION,
false/*don't build caret*/);
nsDisplayList list;
nsDisplayTransform* item =
@@ -3680,7 +3625,7 @@ AddBoxesForFrame(nsIFrame* aFrame,
if (pseudoType == nsCSSAnonBoxes::tableOuter) {
AddBoxesForFrame(aFrame->GetFirstPrincipalChild(), aCallback);
nsIFrame* kid = aFrame->GetFirstChild(nsIFrame::kCaptionList);
nsIFrame* kid = aFrame->GetChildList(nsIFrame::kCaptionList).FirstChild();
if (kid) {
AddBoxesForFrame(kid, aCallback);
}
@@ -3716,7 +3661,7 @@ nsLayoutUtils::GetFirstNonAnonymousFrame(nsIFrame* aFrame)
if (f) {
return f;
}
nsIFrame* kid = aFrame->GetFirstChild(nsIFrame::kCaptionList);
nsIFrame* kid = aFrame->GetChildList(nsIFrame::kCaptionList).FirstChild();
if (kid) {
f = GetFirstNonAnonymousFrame(kid);
if (f) {
-40
View File
@@ -538,46 +538,6 @@ public:
*/
static bool IsScrollbarThumbLayerized(nsIFrame* aThumbFrame);
/**
* Finds the nearest ancestor frame to aItem that is considered to have (or
* will have) "animated geometry". For example the scrolled frames of
* scrollframes which are actively being scrolled fall into this category.
* Frames with certain CSS properties that are being animated (e.g.
* 'left'/'top' etc) are also placed in this category.
* Frames with different active geometry roots are in different PaintedLayers,
* so that we can animate the geometry root by changing its transform (either
* on the main thread or in the compositor).
* The animated geometry root is required to be a descendant (or equal to)
* aItem's ReferenceFrame(), which means that we will fall back to
* returning aItem->ReferenceFrame() when we can't find another animated
* geometry root.
*/
enum {
/**
* If the AGR_IGNORE_BACKGROUND_ATTACHMENT_FIXED flag is set, then we
* do not do any special processing for background attachment fixed items,
* instead treating them like any other frame.
*/
AGR_IGNORE_BACKGROUND_ATTACHMENT_FIXED = 0x01
};
static nsIFrame* GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder,
uint32_t aFlags = 0);
/**
* Version of GetAnimatedGeometryRootFor that can be called in nsDisplayItem
* constructor, and only from there. Not valid for transform items, but they
* set their AGR in their constructor.
*/
static nsIFrame* GetAnimatedGeometryRootForInit(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder);
/**
* Finds the nearest ancestor frame to aFrame that is considered to have (or
* will have) "animated geometry". This could be aFrame.
*/
static nsIFrame* GetAnimatedGeometryRootForFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame);
/**
* GetScrollableFrameFor returns the scrollable frame for a scrolled frame
*/
+40 -60
View File
@@ -537,7 +537,7 @@ private:
bool PresShell::sDisableNonTestMouseEvents = false;
PRLogModuleInfo* PresShell::gLog;
mozilla::LazyLogModule PresShell::gLog("PresShell");
#ifdef DEBUG
static void
@@ -765,9 +765,7 @@ PresShell::PresShell()
mReflowCountMgr->SetPresShell(this);
#endif
mLoadBegin = TimeStamp::Now();
if (!gLog) {
gLog = PR_NewLogModule("PresShell");
}
mSelectionFlags = nsISelectionDisplay::DISPLAY_TEXT | nsISelectionDisplay::DISPLAY_IMAGES;
mIsThemeSupportDisabled = false;
mIsActive = true;
@@ -2476,7 +2474,7 @@ PresShell::BeginLoad(nsIDocument *aDocument)
tp = mPresContext->GetTextPerfMetrics();
}
bool shouldLog = gLog && MOZ_LOG_TEST(gLog, LogLevel::Debug);
bool shouldLog = MOZ_LOG_TEST(gLog, LogLevel::Debug);
if (shouldLog || tp) {
mLoadBegin = TimeStamp::Now();
}
@@ -2512,7 +2510,7 @@ PresShell::LoadComplete()
}
// log load
bool shouldLog = gLog && MOZ_LOG_TEST(gLog, LogLevel::Debug);
bool shouldLog = MOZ_LOG_TEST(gLog, LogLevel::Debug);
if (shouldLog || tp) {
TimeDuration loadTime = TimeStamp::Now() - mLoadBegin;
nsIURI* uri = mDocument->GetDocumentURI();
@@ -4338,21 +4336,6 @@ PresShell::ContentInserted(nsIDocument* aDocument,
VERIFY_STYLE_TREE;
}
PLDHashOperator
ReleasePointerCaptureFromRemovedContent(const uint32_t& aKey,
nsIPresShell::PointerCaptureInfo* aData,
void* aChildLink)
{
if (aChildLink && aData && aData->mOverrideContent) {
if (nsIContent* content = static_cast<nsIContent*>(aChildLink)) {
if (nsContentUtils::ContentIsDescendantOf(aData->mOverrideContent, content)) {
nsIPresShell::ReleasePointerCapturingContent(aKey, aData->mOverrideContent);
}
}
}
return PLDHashOperator::PL_DHASH_NEXT;
}
void
PresShell::ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
@@ -4399,7 +4382,17 @@ PresShell::ContentRemoved(nsIDocument *aDocument,
// We should check that aChild does not contain pointer capturing elements.
// If it does we should release the pointer capture for the elements.
gPointerCaptureList->EnumerateRead(ReleasePointerCaptureFromRemovedContent, aChild);
if (aChild) {
for (auto iter = gPointerCaptureList->Iter(); !iter.Done(); iter.Next()) {
nsIPresShell::PointerCaptureInfo* data = iter.UserData();
if (data && data->mOverrideContent &&
nsContentUtils::ContentIsDescendantOf(data->mOverrideContent,
aChild)) {
nsIPresShell::ReleasePointerCapturingContent(
iter.Key(), data->mOverrideContent);
}
}
}
bool didReconstruct;
mFrameConstructor->ContentRemoved(aContainer, aChild, oldNextSibling,
@@ -6586,22 +6579,6 @@ PresShell::RecordMouseLocation(WidgetGUIEvent* aEvent)
}
}
static PLDHashOperator
FindAnyTarget(const uint32_t& aKey, RefPtr<dom::Touch>& aData,
void* aAnyTarget)
{
if (aData) {
dom::EventTarget* target = aData->GetTarget();
if (target) {
nsCOMPtr<nsIContent>* content =
static_cast<nsCOMPtr<nsIContent>*>(aAnyTarget);
*content = do_QueryInterface(target);
return PL_DHASH_STOP;
}
}
return PL_DHASH_NEXT;
}
nsIFrame* GetNearestFrameContainingPresShell(nsIPresShell* aPresShell)
{
nsView* view = aPresShell->GetViewManager()->GetRootView();
@@ -7305,9 +7282,18 @@ PresShell::HandleEvent(nsIFrame* aFrame,
// the capture list
nsCOMPtr<nsIContent> anyTarget;
if (TouchManager::gCaptureTouchList->Count() > 0 && touchEvent->touches.Length() > 1) {
TouchManager::gCaptureTouchList->Enumerate(&FindAnyTarget, &anyTarget);
} else {
TouchManager::gPreventMouseEvents = false;
for (auto iter = TouchManager::gCaptureTouchList->Iter();
!iter.Done();
iter.Next()) {
RefPtr<dom::Touch>& touch = iter.Data();
if (touch) {
dom::EventTarget* target = touch->GetTarget();
if (target) {
anyTarget = do_QueryInterface(target);
break;
}
}
}
}
for (int32_t i = touchEvent->touches.Length(); i; ) {
@@ -8123,14 +8109,7 @@ PresShell::DispatchTouchEventToDOM(WidgetEvent* aEvent,
}
}
// if preventDefault was called on any of the events dispatched
// and this is touchstart, or the first touchmove, widget should consume
// other events that would be associated with this touch session
if (preventDefault && canPrevent) {
TouchManager::gPreventMouseEvents = true;
}
if (TouchManager::gPreventMouseEvents) {
*aStatus = nsEventStatus_eConsumeNoDefault;
} else {
*aStatus = nsEventStatus_eIgnore;
@@ -10615,7 +10594,7 @@ SetPluginIsActive(nsISupports* aSupports, void* aClosure)
}
nsresult
PresShell::SetIsActive(bool aIsActive)
PresShell::SetIsActive(bool aIsActive, bool aIsHidden)
{
NS_PRECONDITION(mDocument, "should only be called with a document");
@@ -10659,21 +10638,22 @@ PresShell::SetIsActive(bool aIsActive)
// and (ii) has easy access to the TabChild. So we use this
// notification to signal the TabChild to drop its layer tree and
// stop trying to repaint.
if (TabChild* tab = TabChild::GetFrom(this)) {
if (aIsActive) {
tab->MakeVisible();
if (!mIsZombie) {
if (nsIFrame* root = mFrameConstructor->GetRootFrame()) {
FrameLayerBuilder::InvalidateAllLayersForFrame(
nsLayoutUtils::GetDisplayRootFrame(root));
root->SchedulePaint();
if (aIsHidden) {
if (TabChild* tab = TabChild::GetFrom(this)) {
if (aIsActive) {
tab->MakeVisible();
if (!mIsZombie) {
if (nsIFrame* root = mFrameConstructor->GetRootFrame()) {
FrameLayerBuilder::InvalidateAllLayersForFrame(
nsLayoutUtils::GetDisplayRootFrame(root));
root->SchedulePaint();
}
}
} else {
tab->MakeHidden();
}
} else {
tab->MakeHidden();
}
}
return rv;
}
+2 -2
View File
@@ -335,7 +335,7 @@ public:
virtual void VerifyStyleTree() override;
#endif
static PRLogModuleInfo* gLog;
static mozilla::LazyLogModule gLog;
virtual void DisableNonTestMouseEvents(bool aDisable) override;
@@ -355,7 +355,7 @@ public:
virtual nscolor ComputeBackstopColor(nsView* aDisplayRoot) override;
virtual nsresult SetIsActive(bool aIsActive) override;
virtual nsresult SetIsActive(bool aIsActive, bool aIsHidden = true) override;
virtual bool GetIsViewportOverridden() override {
return (mMobileViewportManager != nullptr);
+2 -5
View File
@@ -74,8 +74,8 @@ using namespace mozilla::widget;
using namespace mozilla::ipc;
using namespace mozilla::layout;
static PRLogModuleInfo *gLog = nullptr;
#define LOG(...) MOZ_LOG(gLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
static mozilla::LazyLogModule sRefreshDriverLog("nsRefreshDriver");
#define LOG(...) MOZ_LOG(sRefreshDriverLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
#define DEFAULT_THROTTLED_FRAME_RATE 1
#define DEFAULT_RECOMPUTE_VISIBILITY_INTERVAL_MS 1000
@@ -774,9 +774,6 @@ GetFirstFrameDelay(imgIRequest* req)
/* static */ void
nsRefreshDriver::InitializeStatics()
{
if (!gLog) {
gLog = PR_NewLogModule("nsRefreshDriver");
}
}
/* static */ void
+1 -1
View File
@@ -25,7 +25,7 @@ var currentResize = -1;
var currentBoxSizing = 0;
var currentPointer = 0;
var resizeTypes = [ "horizontal", "vertical", "none", "inherit", "both" ];
var boxSizingTypes = [ "", "border-box", "padding-box" ];
var boxSizingTypes = [ "", "border-box" ];
var pointerTypes = [ synthesizeMouse, synthesizeTouch]
function doTheTest() {
+2
View File
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<div style="display:flex; justify-content: stretch end">a
+6
View File
@@ -0,0 +1,6 @@
<!DOCTYPE html>
<html>
<body>
<span style="justify-content: stretch end true; display: inline-flex;"><span style="writing-mode: vertical-rl; display: -moz-inline-box;">f</span></span>
</body>
</html>
@@ -599,6 +599,8 @@ load 1221112-1.html
load 1221112-2.html
load 1221874-1.html
load 1222783.xhtml
load 1223568-1.html
load 1223568-2.html
load details-display-none-summary-1.html
load details-display-none-summary-2.html
load details-display-none-summary-3.html
+3 -3
View File
@@ -107,7 +107,7 @@ static bool BlockHasAnyFloats(nsIFrame* aFrame)
nsBlockFrame* block = nsLayoutUtils::GetAsBlock(aFrame);
if (!block)
return false;
if (block->GetFirstChild(nsIFrame::kFloatList))
if (block->GetChildList(nsIFrame::kFloatList).FirstChild())
return true;
nsLineList::iterator line = block->begin_lines();
@@ -6316,7 +6316,7 @@ nsBlockFrame::RecoverFloats(nsFloatManager& aFloatManager, WritingMode aWM,
}
// Recurse into our overflow container children
for (nsIFrame* oc = GetFirstChild(kOverflowContainersList);
for (nsIFrame* oc = GetChildList(kOverflowContainersList).FirstChild();
oc; oc = oc->GetNextSibling()) {
RecoverFloatsFor(oc, aFloatManager, aWM, aContainerSize);
}
@@ -7251,7 +7251,7 @@ nsBlockFrame::DoCollectFloats(nsIFrame* aFrame, nsFrameList& aList,
}
DoCollectFloats(aFrame->GetFirstPrincipalChild(), aList, true);
DoCollectFloats(aFrame->GetFirstChild(kOverflowList), aList, true);
DoCollectFloats(aFrame->GetChildList(kOverflowList).FirstChild(), aList, true);
}
if (!aCollectSiblings)
break;
+1 -1
View File
@@ -241,7 +241,7 @@ public:
: nsDisplayBackgroundImage(aBuilder, aFrame, aLayer, aBg)
{
if (ShouldFixToViewport(aBuilder)) {
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder);
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(this);
}
}
+174 -128
View File
@@ -33,14 +33,7 @@ typedef nsFlexContainerFrame::FlexLine FlexLine;
typedef nsFlexContainerFrame::FlexboxAxisTracker FlexboxAxisTracker;
typedef nsFlexContainerFrame::StrutInfo StrutInfo;
static PRLogModuleInfo*
GetFlexContainerLog()
{
static PRLogModuleInfo *sLog;
if (!sLog)
sLog = PR_NewLogModule("nsFlexContainerFrame");
return sLog;
}
static mozilla::LazyLogModule gFlexContainerLog("nsFlexContainerFrame");
// XXXdholbert Some of this helper-stuff should be separated out into a general
// "main/cross-axis utils" header, shared by grid & flexbox?
@@ -280,22 +273,6 @@ public:
LogicalSize(mWM, aCrossSize, aMainSize);
}
/**
* Converts a "flex-relative" size (a main-axis & cross-axis size)
* into nsSize (using physical coordinates).
*
* @arg aMainSize The main-axis size.
* @arg aCrossSize The cross-axis size.
* @return A nsSize that represents the same size, using the corresponding
* physical coordinates.
*/
nsSize PhysicalSizeFromFlexRelativeSizes(nscoord aMainSize,
nscoord aCrossSize) const {
return IsMainAxisHorizontal() ?
nsSize(aMainSize, aCrossSize) :
nsSize(aCrossSize, aMainSize);
}
// Are my axes reversed with respect to what the author asked for?
// (We may reverse the axes in the FlexboxAxisTracker constructor and set
// this flag, to avoid reflowing our children in bottom-to-top order.)
@@ -938,13 +915,13 @@ GetFirstNonAnonBoxDescendant(nsIFrame* aFrame)
// the table, for use in DOM comparisons to things outside of the table.)
if (MOZ_UNLIKELY(aFrame->GetType() == nsGkAtoms::tableOuterFrame)) {
nsIFrame* captionDescendant =
GetFirstNonAnonBoxDescendant(aFrame->GetFirstChild(kCaptionList));
GetFirstNonAnonBoxDescendant(aFrame->GetChildList(kCaptionList).FirstChild());
if (captionDescendant) {
return captionDescendant;
}
} else if (MOZ_UNLIKELY(aFrame->GetType() == nsGkAtoms::tableFrame)) {
nsIFrame* colgroupDescendant =
GetFirstNonAnonBoxDescendant(aFrame->GetFirstChild(kColGroupList));
GetFirstNonAnonBoxDescendant(aFrame->GetChildList(kColGroupList).FirstChild());
if (colgroupDescendant) {
return colgroupDescendant;
}
@@ -1459,10 +1436,10 @@ nsFlexContainerFrame::
// Measure content, if needed (w/ intrinsic-width method or a reflow)
if (minSizeNeedsToMeasureContent || flexBasisNeedsToMeasureContent) {
if (aAxisTracker.IsMainAxisHorizontal()) {
nsRenderingContext rctx(
aPresContext->PresShell()->CreateReferenceRenderingContext());
if (minSizeNeedsToMeasureContent) {
resolvedMinSize = std::min(resolvedMinSize, aFlexItem.Frame()->GetMinISize(&rctx));
nscoord frameMinISize =
aFlexItem.Frame()->GetMinISize(aItemReflowState.rendContext);
resolvedMinSize = std::min(resolvedMinSize, frameMinISize);
}
NS_ASSERTION(!flexBasisNeedsToMeasureContent,
"flex-basis:auto should have been resolved in the "
@@ -1550,7 +1527,7 @@ nsFlexContainerFrame::
// establishes the container's baseline. Also save the ascent if this child
// needs to be baseline-aligned. (Else, we don't care about ascent/baseline.)
if (aFlexItem.Frame() == mFrames.FirstChild() ||
aFlexItem.GetAlignSelf() == NS_STYLE_ALIGN_ITEMS_BASELINE) {
aFlexItem.GetAlignSelf() == NS_STYLE_ALIGN_BASELINE) {
aFlexItem.SetAscent(childDesiredSize.BlockStartAscent());
}
@@ -1590,8 +1567,8 @@ FlexItem::FlexItem(nsHTMLReflowState& aFlexItemReflowState,
mIsStretched(false),
mIsStrut(false),
// mNeedsMinSizeAutoResolution is initialized in CheckForMinSizeAuto()
mWM(aFlexItemReflowState.GetWritingMode()),
mAlignSelf(aFlexItemReflowState.mStylePosition->mAlignSelf)
mWM(aFlexItemReflowState.GetWritingMode())
// mAlignSelf, see below
{
MOZ_ASSERT(mFrame, "expecting a non-null child frame");
MOZ_ASSERT(mFrame->GetType() != nsGkAtoms::placeholderFrame,
@@ -1599,6 +1576,18 @@ FlexItem::FlexItem(nsHTMLReflowState& aFlexItemReflowState,
MOZ_ASSERT(!(mFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW),
"out-of-flow frames should not be treated as flex items");
mAlignSelf = aFlexItemReflowState.mStylePosition->ComputedAlignSelf(
aFlexItemReflowState.mStyleDisplay,
mFrame->StyleContext()->GetParent());
if (MOZ_UNLIKELY(mAlignSelf == NS_STYLE_ALIGN_AUTO)) {
// Happens in rare edge cases when 'position' was ignored by the frame
// constructor (and the style system computed 'auto' based on 'position').
mAlignSelf = NS_STYLE_ALIGN_STRETCH;
}
// XXX strip off the <overflow-position> bit until we implement that
mAlignSelf &= ~NS_STYLE_ALIGN_FLAG_BITS;
SetFlexBaseSizeAndMainSize(aFlexBaseSize);
CheckForMinSizeAuto(aFlexItemReflowState, aAxisTracker);
@@ -1617,12 +1606,6 @@ FlexItem::FlexItem(nsHTMLReflowState& aFlexItemReflowState,
}
#endif // DEBUG
// Resolve "align-self: auto" to parent's "align-items" value.
if (mAlignSelf == NS_STYLE_ALIGN_SELF_AUTO) {
mAlignSelf =
mFrame->StyleContext()->GetParent()->StylePosition()->mAlignItems;
}
// If the flex item's inline axis is the same as the cross axis, then
// 'align-self:baseline' is identical to 'flex-start'. If that's the case, we
// just directly convert our align-self value here, so that we don't have to
@@ -1633,9 +1616,9 @@ FlexItem::FlexItem(nsHTMLReflowState& aFlexItemReflowState,
// FIXME: Once we support writing-mode (vertical text), this
// IsCrossAxisHorizontal check won't be sufficient anymore -- we'll actually
// need to compare our inline axis vs. the cross axis.
if (mAlignSelf == NS_STYLE_ALIGN_ITEMS_BASELINE &&
if (mAlignSelf == NS_STYLE_ALIGN_BASELINE &&
aAxisTracker.IsCrossAxisHorizontal()) {
mAlignSelf = NS_STYLE_ALIGN_ITEMS_FLEX_START;
mAlignSelf = NS_STYLE_ALIGN_FLEX_START;
}
}
@@ -1669,7 +1652,7 @@ FlexItem::FlexItem(nsIFrame* aChildFrame, nscoord aCrossSize,
mIsStrut(true), // (this is the constructor for making struts, after all)
mNeedsMinSizeAutoResolution(false),
mWM(aContainerWM),
mAlignSelf(NS_STYLE_ALIGN_ITEMS_FLEX_START)
mAlignSelf(NS_STYLE_ALIGN_FLEX_START)
{
MOZ_ASSERT(mFrame, "expecting a non-null child frame");
MOZ_ASSERT(NS_STYLE_VISIBILITY_COLLAPSE ==
@@ -1898,6 +1881,7 @@ private:
nscoord mPackingSpaceRemaining;
uint32_t mNumAutoMarginsInMainAxis;
uint32_t mNumPackingSpacesRemaining;
// XXX this should be uint16_t when we add explicit fallback handling
uint8_t mJustifyContent;
};
@@ -1931,6 +1915,7 @@ private:
nscoord mPackingSpaceRemaining;
uint32_t mNumPackingSpacesRemaining;
// XXX this should be uint16_t when we add explicit fallback handling
uint8_t mAlignContent;
};
@@ -2211,7 +2196,7 @@ FlexLine::FreezeOrRestoreEachFlexibleSize(const nscoord aTotalViolation,
void
FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize)
{
MOZ_LOG(GetFlexContainerLog(), LogLevel::Debug, ("ResolveFlexibleLengths\n"));
MOZ_LOG(gFlexContainerLog, LogLevel::Debug, ("ResolveFlexibleLengths\n"));
// Determine whether we're going to be growing or shrinking items.
const bool isUsingFlexGrow =
@@ -2259,7 +2244,7 @@ FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize)
availableFreeSpace -= item->GetMainSize();
}
MOZ_LOG(GetFlexContainerLog(), LogLevel::Debug,
MOZ_LOG(gFlexContainerLog, LogLevel::Debug,
(" available free space = %d\n", availableFreeSpace));
@@ -2371,7 +2356,7 @@ FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize)
}
}
MOZ_LOG(GetFlexContainerLog(), LogLevel::Debug,
MOZ_LOG(gFlexContainerLog, LogLevel::Debug,
(" Distributing available space:"));
// Since this loop only operates on unfrozen flex items, we can break as
// soon as we have seen all of them.
@@ -2419,7 +2404,7 @@ FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize)
availableFreeSpace -= sizeDelta;
item->SetMainSize(item->GetMainSize() + sizeDelta);
MOZ_LOG(GetFlexContainerLog(), LogLevel::Debug,
MOZ_LOG(gFlexContainerLog, LogLevel::Debug,
(" child %p receives %d, for a total of %d\n",
item, sizeDelta, item->GetMainSize()));
}
@@ -2429,7 +2414,7 @@ FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize)
// Fix min/max violations:
nscoord totalViolation = 0; // keeps track of adjustments for min/max
MOZ_LOG(GetFlexContainerLog(), LogLevel::Debug,
MOZ_LOG(gFlexContainerLog, LogLevel::Debug,
(" Checking for violations:"));
// Since this loop only operates on unfrozen flex items, we can break as
@@ -2458,7 +2443,7 @@ FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize)
FreezeOrRestoreEachFlexibleSize(totalViolation,
iterationCounter + 1 == mNumItems);
MOZ_LOG(GetFlexContainerLog(), LogLevel::Debug,
MOZ_LOG(gFlexContainerLog, LogLevel::Debug,
(" Total violation: %d\n", totalViolation));
if (mNumFrozenItems == mNumItems) {
@@ -2493,6 +2478,14 @@ MainAxisPositionTracker::
mNumPackingSpacesRemaining(0),
mJustifyContent(aJustifyContent)
{
// 'auto' behaves as 'stretch' which behaves as 'flex-start' in the main axis
if (mJustifyContent == NS_STYLE_JUSTIFY_AUTO) {
mJustifyContent = NS_STYLE_JUSTIFY_FLEX_START;
}
// XXX strip off the <overflow-position> bit until we implement that
mJustifyContent &= ~NS_STYLE_JUSTIFY_FLAG_BITS;
// mPackingSpaceRemaining is initialized to the container's main size. Now
// we'll subtract out the main sizes of our flex items, so that it ends up
// with the *actual* amount of packing space.
@@ -2511,20 +2504,27 @@ MainAxisPositionTracker::
// and 'space-around' behaves like 'center'. In those cases, it's simplest to
// just pretend we have a different 'justify-content' value and share code.
if (mPackingSpaceRemaining < 0) {
if (mJustifyContent == NS_STYLE_JUSTIFY_CONTENT_SPACE_BETWEEN) {
mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_FLEX_START;
} else if (mJustifyContent == NS_STYLE_JUSTIFY_CONTENT_SPACE_AROUND) {
mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_CENTER;
if (mJustifyContent == NS_STYLE_JUSTIFY_SPACE_BETWEEN) {
mJustifyContent = NS_STYLE_JUSTIFY_FLEX_START;
} else if (mJustifyContent == NS_STYLE_JUSTIFY_SPACE_AROUND) {
mJustifyContent = NS_STYLE_JUSTIFY_CENTER;
}
}
// Map 'start'/'end' to 'flex-start'/'flex-end'.
if (mJustifyContent == NS_STYLE_JUSTIFY_START) {
mJustifyContent = NS_STYLE_JUSTIFY_FLEX_START;
} else if (mJustifyContent == NS_STYLE_JUSTIFY_END) {
mJustifyContent = NS_STYLE_JUSTIFY_FLEX_END;
}
// If our main axis is (internally) reversed, swap the justify-content
// "flex-start" and "flex-end" behaviors:
if (aAxisTracker.AreAxesInternallyReversed()) {
if (mJustifyContent == NS_STYLE_JUSTIFY_CONTENT_FLEX_START) {
mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_FLEX_END;
} else if (mJustifyContent == NS_STYLE_JUSTIFY_CONTENT_FLEX_END) {
mJustifyContent = NS_STYLE_JUSTIFY_CONTENT_FLEX_START;
if (mJustifyContent == NS_STYLE_JUSTIFY_FLEX_START) {
mJustifyContent = NS_STYLE_JUSTIFY_FLEX_END;
} else if (mJustifyContent == NS_STYLE_JUSTIFY_FLEX_END) {
mJustifyContent = NS_STYLE_JUSTIFY_FLEX_START;
}
}
@@ -2534,25 +2534,31 @@ MainAxisPositionTracker::
mPackingSpaceRemaining != 0 &&
!aLine->IsEmpty()) {
switch (mJustifyContent) {
case NS_STYLE_JUSTIFY_CONTENT_FLEX_START:
case NS_STYLE_JUSTIFY_LEFT:
case NS_STYLE_JUSTIFY_RIGHT:
case NS_STYLE_JUSTIFY_BASELINE:
case NS_STYLE_JUSTIFY_LAST_BASELINE:
case NS_STYLE_JUSTIFY_SPACE_EVENLY:
NS_WARNING("NYI: justify-content:left/right/baseline/last-baseline/space-evenly");
case NS_STYLE_JUSTIFY_FLEX_START:
// All packing space should go at the end --> nothing to do here.
break;
case NS_STYLE_JUSTIFY_CONTENT_FLEX_END:
case NS_STYLE_JUSTIFY_FLEX_END:
// All packing space goes at the beginning
mPosition += mPackingSpaceRemaining;
break;
case NS_STYLE_JUSTIFY_CONTENT_CENTER:
case NS_STYLE_JUSTIFY_CENTER:
// Half the packing space goes at the beginning
mPosition += mPackingSpaceRemaining / 2;
break;
case NS_STYLE_JUSTIFY_CONTENT_SPACE_BETWEEN:
case NS_STYLE_JUSTIFY_SPACE_BETWEEN:
MOZ_ASSERT(mPackingSpaceRemaining >= 0,
"negative packing space should make us use 'flex-start' "
"instead of 'space-between'");
// 1 packing space between each flex item, no packing space at ends.
mNumPackingSpacesRemaining = aLine->NumItems() - 1;
break;
case NS_STYLE_JUSTIFY_CONTENT_SPACE_AROUND:
case NS_STYLE_JUSTIFY_SPACE_AROUND:
MOZ_ASSERT(mPackingSpaceRemaining >= 0,
"negative packing space should make us use 'center' "
"instead of 'space-around'");
@@ -2613,8 +2619,8 @@ void
MainAxisPositionTracker::TraversePackingSpace()
{
if (mNumPackingSpacesRemaining) {
MOZ_ASSERT(mJustifyContent == NS_STYLE_JUSTIFY_CONTENT_SPACE_BETWEEN ||
mJustifyContent == NS_STYLE_JUSTIFY_CONTENT_SPACE_AROUND,
MOZ_ASSERT(mJustifyContent == NS_STYLE_JUSTIFY_SPACE_BETWEEN ||
mJustifyContent == NS_STYLE_JUSTIFY_SPACE_AROUND,
"mNumPackingSpacesRemaining only applies for "
"space-between/space-around");
@@ -2646,6 +2652,14 @@ CrossAxisPositionTracker::
{
MOZ_ASSERT(aFirstLine, "null first line pointer");
// 'auto' behaves as 'stretch'
if (mAlignContent == NS_STYLE_ALIGN_AUTO) {
mAlignContent = NS_STYLE_ALIGN_STRETCH;
}
// XXX strip of the <overflow-position> bit until we implement that
mAlignContent &= ~NS_STYLE_ALIGN_FLAG_BITS;
if (aIsCrossSizeDefinite && !aFirstLine->getNext()) {
// "If the flex container has only a single line (even if it's a
// multi-line flex container) and has a definite cross size, the cross
@@ -2679,21 +2693,28 @@ CrossAxisPositionTracker::
// it's simplest to just pretend we have a different 'align-content' value
// and share code.
if (mPackingSpaceRemaining < 0) {
if (mAlignContent == NS_STYLE_ALIGN_CONTENT_SPACE_BETWEEN ||
mAlignContent == NS_STYLE_ALIGN_CONTENT_STRETCH) {
mAlignContent = NS_STYLE_ALIGN_CONTENT_FLEX_START;
} else if (mAlignContent == NS_STYLE_ALIGN_CONTENT_SPACE_AROUND) {
mAlignContent = NS_STYLE_ALIGN_CONTENT_CENTER;
if (mAlignContent == NS_STYLE_ALIGN_SPACE_BETWEEN ||
mAlignContent == NS_STYLE_ALIGN_STRETCH) {
mAlignContent = NS_STYLE_ALIGN_FLEX_START;
} else if (mAlignContent == NS_STYLE_ALIGN_SPACE_AROUND) {
mAlignContent = NS_STYLE_ALIGN_CENTER;
}
}
// Map 'start'/'end' to 'flex-start'/'flex-end'.
if (mAlignContent == NS_STYLE_ALIGN_START) {
mAlignContent = NS_STYLE_ALIGN_FLEX_START;
} else if (mAlignContent == NS_STYLE_ALIGN_END) {
mAlignContent = NS_STYLE_ALIGN_FLEX_END;
}
// If our cross axis is (internally) reversed, swap the align-content
// "flex-start" and "flex-end" behaviors:
if (aAxisTracker.AreAxesInternallyReversed()) {
if (mAlignContent == NS_STYLE_ALIGN_CONTENT_FLEX_START) {
mAlignContent = NS_STYLE_ALIGN_CONTENT_FLEX_END;
} else if (mAlignContent == NS_STYLE_ALIGN_CONTENT_FLEX_END) {
mAlignContent = NS_STYLE_ALIGN_CONTENT_FLEX_START;
if (mAlignContent == NS_STYLE_ALIGN_FLEX_START) {
mAlignContent = NS_STYLE_ALIGN_FLEX_END;
} else if (mAlignContent == NS_STYLE_ALIGN_FLEX_END) {
mAlignContent = NS_STYLE_ALIGN_FLEX_START;
}
}
@@ -2701,25 +2722,33 @@ CrossAxisPositionTracker::
// past any leading packing-space.
if (mPackingSpaceRemaining != 0) {
switch (mAlignContent) {
case NS_STYLE_ALIGN_CONTENT_FLEX_START:
case NS_STYLE_JUSTIFY_LEFT:
case NS_STYLE_JUSTIFY_RIGHT:
case NS_STYLE_ALIGN_SELF_START:
case NS_STYLE_ALIGN_SELF_END:
case NS_STYLE_ALIGN_SPACE_EVENLY:
case NS_STYLE_ALIGN_BASELINE:
case NS_STYLE_ALIGN_LAST_BASELINE:
NS_WARNING("NYI: align-self:left/right/self-start/self-end/space-evenly/baseline/last-baseline");
case NS_STYLE_ALIGN_FLEX_START:
// All packing space should go at the end --> nothing to do here.
break;
case NS_STYLE_ALIGN_CONTENT_FLEX_END:
case NS_STYLE_ALIGN_FLEX_END:
// All packing space goes at the beginning
mPosition += mPackingSpaceRemaining;
break;
case NS_STYLE_ALIGN_CONTENT_CENTER:
case NS_STYLE_ALIGN_CENTER:
// Half the packing space goes at the beginning
mPosition += mPackingSpaceRemaining / 2;
break;
case NS_STYLE_ALIGN_CONTENT_SPACE_BETWEEN:
case NS_STYLE_ALIGN_SPACE_BETWEEN:
MOZ_ASSERT(mPackingSpaceRemaining >= 0,
"negative packing space should make us use 'flex-start' "
"instead of 'space-between'");
// 1 packing space between each flex line, no packing space at ends.
mNumPackingSpacesRemaining = numLines - 1;
break;
case NS_STYLE_ALIGN_CONTENT_SPACE_AROUND: {
case NS_STYLE_ALIGN_SPACE_AROUND: {
MOZ_ASSERT(mPackingSpaceRemaining >= 0,
"negative packing space should make us use 'center' "
"instead of 'space-around'");
@@ -2739,7 +2768,7 @@ CrossAxisPositionTracker::
mNumPackingSpacesRemaining--;
break;
}
case NS_STYLE_ALIGN_CONTENT_STRETCH: {
case NS_STYLE_ALIGN_STRETCH: {
// Split space equally between the lines:
MOZ_ASSERT(mPackingSpaceRemaining > 0,
"negative packing space should make us use 'flex-start' "
@@ -2771,8 +2800,8 @@ void
CrossAxisPositionTracker::TraversePackingSpace()
{
if (mNumPackingSpacesRemaining) {
MOZ_ASSERT(mAlignContent == NS_STYLE_ALIGN_CONTENT_SPACE_BETWEEN ||
mAlignContent == NS_STYLE_ALIGN_CONTENT_SPACE_AROUND,
MOZ_ASSERT(mAlignContent == NS_STYLE_ALIGN_SPACE_BETWEEN ||
mAlignContent == NS_STYLE_ALIGN_SPACE_AROUND,
"mNumPackingSpacesRemaining only applies for "
"space-between/space-around");
@@ -2807,7 +2836,7 @@ FlexLine::ComputeCrossSizeAndBaseline(const FlexboxAxisTracker& aAxisTracker)
nscoord curOuterCrossSize =
item->GetOuterCrossSize(aAxisTracker.GetCrossAxis());
if (item->GetAlignSelf() == NS_STYLE_ALIGN_ITEMS_BASELINE &&
if (item->GetAlignSelf() == NS_STYLE_ALIGN_BASELINE &&
item->GetNumAutoMarginsInAxis(aAxisTracker.GetCrossAxis()) == 0) {
// FIXME: Once we support "writing-mode", we'll have to do baseline
// alignment in vertical flex containers here (w/ horizontal cross-axes).
@@ -2880,7 +2909,7 @@ FlexItem::ResolveStretchedCrossSize(nscoord aLineCrossSize,
// We stretch IFF we are align-self:stretch, have no auto margins in
// cross axis, and have cross-axis size property == "auto". If any of those
// conditions don't hold up, we won't stretch.
if (mAlignSelf != NS_STYLE_ALIGN_ITEMS_STRETCH ||
if (mAlignSelf != NS_STYLE_ALIGN_STRETCH ||
GetNumAutoMarginsInAxis(crossAxis) != 0 ||
eStyleUnit_Auto != aAxisTracker.ComputedCrossSize(mFrame).GetUnit()) {
return;
@@ -2959,33 +2988,46 @@ SingleLineCrossAxisPositionTracker::
uint8_t alignSelf = aItem.GetAlignSelf();
// NOTE: 'stretch' behaves like 'flex-start' once we've stretched any
// auto-sized items (which we've already done).
if (alignSelf == NS_STYLE_ALIGN_ITEMS_STRETCH) {
alignSelf = NS_STYLE_ALIGN_ITEMS_FLEX_START;
if (alignSelf == NS_STYLE_ALIGN_STRETCH) {
alignSelf = NS_STYLE_ALIGN_FLEX_START;
}
// Map 'start'/'end' to 'flex-start'/'flex-end'.
if (alignSelf == NS_STYLE_ALIGN_START) {
alignSelf = NS_STYLE_ALIGN_FLEX_START;
} else if (alignSelf == NS_STYLE_ALIGN_END) {
alignSelf = NS_STYLE_ALIGN_FLEX_END;
}
// If our cross axis is (internally) reversed, swap the align-self
// "flex-start" and "flex-end" behaviors:
if (aAxisTracker.AreAxesInternallyReversed()) {
if (alignSelf == NS_STYLE_ALIGN_ITEMS_FLEX_START) {
alignSelf = NS_STYLE_ALIGN_ITEMS_FLEX_END;
} else if (alignSelf == NS_STYLE_ALIGN_ITEMS_FLEX_END) {
alignSelf = NS_STYLE_ALIGN_ITEMS_FLEX_START;
if (alignSelf == NS_STYLE_ALIGN_FLEX_START) {
alignSelf = NS_STYLE_ALIGN_FLEX_END;
} else if (alignSelf == NS_STYLE_ALIGN_FLEX_END) {
alignSelf = NS_STYLE_ALIGN_FLEX_START;
}
}
switch (alignSelf) {
case NS_STYLE_ALIGN_ITEMS_FLEX_START:
case NS_STYLE_JUSTIFY_LEFT:
case NS_STYLE_JUSTIFY_RIGHT:
case NS_STYLE_ALIGN_SELF_START:
case NS_STYLE_ALIGN_SELF_END:
case NS_STYLE_ALIGN_LAST_BASELINE:
NS_WARNING("NYI: align-self:left/right/self-start/self-end/last-baseline");
case NS_STYLE_ALIGN_FLEX_START:
// No space to skip over -- we're done.
break;
case NS_STYLE_ALIGN_ITEMS_FLEX_END:
case NS_STYLE_ALIGN_FLEX_END:
mPosition += aLine.GetLineCrossSize() - aItem.GetOuterCrossSize(mAxis);
break;
case NS_STYLE_ALIGN_ITEMS_CENTER:
case NS_STYLE_ALIGN_CENTER:
// Note: If cross-size is odd, the "after" space will get the extra unit.
mPosition +=
(aLine.GetLineCrossSize() - aItem.GetOuterCrossSize(mAxis)) / 2;
break;
case NS_STYLE_ALIGN_ITEMS_BASELINE: {
case NS_STYLE_ALIGN_BASELINE: {
// Normally, baseline-aligned items are collectively aligned with the
// line's cross-start edge; however, if our cross axis is (internally)
// reversed, we instead align them with the cross-end edge.
@@ -3510,7 +3552,7 @@ nsFlexContainerFrame::SizeItemInCrossAxis(
MOZ_ASSERT(!aItem.HadMeasuringReflow(),
"We shouldn't need more than one measuring reflow");
if (aItem.GetAlignSelf() == NS_STYLE_ALIGN_ITEMS_STRETCH) {
if (aItem.GetAlignSelf() == NS_STYLE_ALIGN_STRETCH) {
// This item's got "align-self: stretch", so we probably imposed a
// stretched computed height on it during its previous reflow. We're
// not imposing that height for *this* measuring reflow, so we need to
@@ -3567,7 +3609,7 @@ nsFlexContainerFrame::SizeItemInCrossAxis(
// establishes the container's baseline. Also save the ascent if this child
// needs to be baseline-aligned. (Else, we don't care about baseline/ascent.)
if (aItem.Frame() == mFrames.FirstChild() ||
aItem.GetAlignSelf() == NS_STYLE_ALIGN_ITEMS_BASELINE) {
aItem.GetAlignSelf() == NS_STYLE_ALIGN_BASELINE) {
aItem.SetAscent(childDesiredSize.BlockStartAscent());
}
}
@@ -3609,7 +3651,7 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
MarkInReflow();
DO_GLOBAL_REFLOW_COUNT("nsFlexContainerFrame");
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
MOZ_LOG(GetFlexContainerLog(), LogLevel::Debug,
MOZ_LOG(gFlexContainerLog, LogLevel::Debug,
("Reflow() for nsFlexContainerFrame %p\n", this));
if (IsFrameTreeTooDeep(aReflowState, aDesiredSize, aStatus)) {
@@ -3830,7 +3872,8 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
// scope of a particular flex line)
CrossAxisPositionTracker
crossAxisPosnTracker(lines.getFirst(),
aReflowState.mStylePosition->mAlignContent,
aReflowState.mStylePosition->ComputedAlignContent(
aReflowState.mStyleDisplay),
contentBoxCrossSize, isCrossSizeDefinite,
aAxisTracker);
@@ -3869,7 +3912,9 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
// Main-Axis Alignment - Flexbox spec section 9.5
// ==============================================
line->PositionItemsInMainAxis(aReflowState.mStylePosition->mJustifyContent,
auto justifyContent =
aReflowState.mStylePosition->ComputedJustifyContent(aReflowState.mStyleDisplay);
line->PositionItemsInMainAxis(justifyContent,
aContentBoxMainSize,
aAxisTracker);
@@ -3909,6 +3954,7 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
// writing-mode/GetLogicalSkipSides. We add it lower down, after we've
// established baseline and decided whether bottom border-padding fits (if
// we're fragmented).
const nscoord blockEndContainerBP = containerBP.BEnd(flexWM);
const LogicalSides skipSides =
GetLogicalSkipSides(&aReflowState) | LogicalSides(eLogicalSideBitsBEnd);
containerBP.ApplySkipSides(skipSides);
@@ -3984,20 +4030,14 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
}
}
// XXXdholbert preserving the physical-coords var "containerBorderPadding"
// for now, while it has usages; removing it & its usages in bug 1155312.
nsMargin containerBorderPadding(aReflowState.ComputedPhysicalBorderPadding());
containerBorderPadding.ApplySkipSides(GetSkipSides(&aReflowState));
nsSize desiredContentBoxSize =
aAxisTracker.PhysicalSizeFromFlexRelativeSizes(aContentBoxMainSize,
contentBoxCrossSize);
aDesiredSize.Width() = desiredContentBoxSize.width +
containerBorderPadding.LeftRight();
// Does *NOT* include bottom border/padding yet (we add that a bit lower down)
aDesiredSize.Height() = desiredContentBoxSize.height +
containerBorderPadding.top;
// Compute flex container's desired size (in its own writing-mode),
// starting w/ content-box size & growing from there:
LogicalSize desiredSizeInFlexWM =
aAxisTracker.LogicalSizeFromFlexRelativeSizes(aContentBoxMainSize,
contentBoxCrossSize);
// Add border/padding (w/ skipSides already applied):
desiredSizeInFlexWM.ISize(flexWM) += containerBP.IStartEnd(flexWM);
desiredSizeInFlexWM.BSize(flexWM) += containerBP.BStartEnd(flexWM);
if (flexContainerAscent == nscoord_MIN) {
// Still don't have our baseline set -- this happens if we have no
@@ -4007,38 +4047,44 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
NS_WARN_IF_FALSE(lines.getFirst()->IsEmpty(),
"Have flex items but didn't get an ascent - that's odd "
"(or there are just gigantic sizes involved)");
// Per spec, just use the bottom of content-box.
flexContainerAscent = aDesiredSize.Height();
// Per spec, synthesize baseline from the flex container's content box
// (i.e. use block-end side of content-box)
// XXXdholbert This only makes sense if parent's writing mode is
// horizontal (& even then, really we should be using the BSize in terms
// of the parent's writing mode, not ours). Clean up in bug 1155322.
flexContainerAscent = desiredSizeInFlexWM.BSize(flexWM);
}
// XXXdholbert flexContainerAscent needs to be in terms of
// our parent's writing-mode here. See bug 1155322.
aDesiredSize.SetBlockStartAscent(flexContainerAscent);
// Now: If we're complete, add bottom border/padding to desired height
// (unless that pushes us over available height, in which case we become
// incomplete (unless we already weren't asking for any height, in which case
// we stay complete to avoid looping forever)).
// Now: If we're complete, add bottom border/padding to desired height (which
// we skipped via skipSides) -- unless that pushes us over available height,
// in which case we become incomplete (unless we already weren't asking for
// any height, in which case we stay complete to avoid looping forever).
// NOTE: If we're auto-height, we allow our bottom border/padding to push us
// over the available height without requesting a continuation, for
// consistency with the behavior of "display:block" elements.
if (NS_FRAME_IS_COMPLETE(aStatus)) {
// NOTE: We can't use containerBorderPadding.bottom for this, because if
// we're auto-height, ApplySkipSides will have zeroed it (because it
// assumed we might get a continuation). We have the correct value in
// aReflowState.ComputedPhyiscalBorderPadding().bottom, though, so we use that.
nscoord desiredHeightWithBottomBP =
aDesiredSize.Height() + aReflowState.ComputedPhysicalBorderPadding().bottom;
nscoord desiredBSizeWithBEndBP =
desiredSizeInFlexWM.BSize(flexWM) + blockEndContainerBP;
if (aReflowState.AvailableHeight() == NS_UNCONSTRAINEDSIZE ||
aDesiredSize.Height() == 0 ||
desiredHeightWithBottomBP <= aReflowState.AvailableHeight() ||
aReflowState.ComputedHeight() == NS_INTRINSICSIZE) {
// Update desired height to include bottom border/padding
aDesiredSize.Height() = desiredHeightWithBottomBP;
if (aReflowState.AvailableBSize() == NS_UNCONSTRAINEDSIZE ||
desiredSizeInFlexWM.BSize(flexWM) == 0 ||
desiredBSizeWithBEndBP <= aReflowState.AvailableBSize() ||
aReflowState.ComputedBSize() == NS_INTRINSICSIZE) {
// Update desired height to include block-end border/padding
desiredSizeInFlexWM.BSize(flexWM) = desiredBSizeWithBEndBP;
} else {
// We couldn't fit bottom border/padding, so we'll need a continuation.
NS_FRAME_SET_INCOMPLETE(aStatus);
}
}
// Convert flex container's final desired size to parent's WM, for outparam.
aDesiredSize.SetSize(flexWM, desiredSizeInFlexWM);
// Overflow area = union(my overflow area, kids' overflow areas)
aDesiredSize.SetOverflowAreasToDesiredBounds();
for (nsIFrame* childFrame : mFrames) {
+7 -23
View File
@@ -214,9 +214,9 @@ bool nsFrame::GetShowEventTargetFrameBorder()
* Note: the log module is created during library initialization which
* means that you cannot perform logging before then.
*/
static PRLogModuleInfo* gLogModule;
mozilla::LazyLogModule nsFrame::sFrameLogModule("frame");
static PRLogModuleInfo* gStyleVerifyTreeLogModuleInfo;
static mozilla::LazyLogModule sStyleVerifyTreeLogModuleInfo("styleverifytree");
static uint32_t gStyleVerifyTreeEnable = 0x55;
@@ -224,10 +224,7 @@ bool
nsFrame::GetVerifyStyleTreeEnable()
{
if (gStyleVerifyTreeEnable == 0x55) {
if (nullptr == gStyleVerifyTreeLogModuleInfo) {
gStyleVerifyTreeLogModuleInfo = PR_NewLogModule("styleverifytree");
gStyleVerifyTreeEnable = 0 != gStyleVerifyTreeLogModuleInfo->level;
}
gStyleVerifyTreeEnable = 0 != (int)((mozilla::LogModule*)sStyleVerifyTreeLogModuleInfo)->Level();
}
return gStyleVerifyTreeEnable;
}
@@ -238,15 +235,6 @@ nsFrame::SetVerifyStyleTreeEnable(bool aEnabled)
gStyleVerifyTreeEnable = aEnabled;
}
PRLogModuleInfo*
nsFrame::GetLogModuleInfo()
{
if (nullptr == gLogModule) {
gLogModule = PR_NewLogModule("frame");
}
return gLogModule;
}
#endif
NS_DECLARE_FRAME_PROPERTY(AbsoluteContainingBlockProperty,
@@ -2530,13 +2518,9 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
// return early.
if (aBuilder->IsBuildingLayerEventRegions()) {
MOZ_ASSERT(buildingForChild.GetPrevAnimatedGeometryRoot() ==
aBuilder->FindAnimatedGeometryRootFor(child->GetParent()));
// If this frame has a different animated geometry root than its parent,
// make sure we accumulate event regions for its layer.
nsIFrame *animatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(child);
if (animatedGeometryRoot != buildingForChild.GetPrevAnimatedGeometryRoot()) {
if (buildingForChild.IsAnimatedGeometryRoot()) {
nsDisplayLayerEventRegions* eventRegions =
new (aBuilder) nsDisplayLayerEventRegions(aBuilder, child);
eventRegions->AddFrame(aBuilder, child);
@@ -9151,7 +9135,7 @@ GetTagName(nsFrame* aFrame, nsIContent* aContent, int aResultSize,
void
nsFrame::Trace(const char* aMethod, bool aEnter)
{
if (NS_FRAME_LOG_TEST(GetLogModuleInfo(), NS_FRAME_TRACE_CALLS)) {
if (NS_FRAME_LOG_TEST(sFrameLogModule, NS_FRAME_TRACE_CALLS)) {
char tagbuf[40];
GetTagName(this, mContent, sizeof(tagbuf), tagbuf);
PR_LogPrint("%s: %s %s", tagbuf, aEnter ? "enter" : "exit", aMethod);
@@ -9161,7 +9145,7 @@ nsFrame::Trace(const char* aMethod, bool aEnter)
void
nsFrame::Trace(const char* aMethod, bool aEnter, nsReflowStatus aStatus)
{
if (NS_FRAME_LOG_TEST(GetLogModuleInfo(), NS_FRAME_TRACE_CALLS)) {
if (NS_FRAME_LOG_TEST(sFrameLogModule, NS_FRAME_TRACE_CALLS)) {
char tagbuf[40];
GetTagName(this, mContent, sizeof(tagbuf), tagbuf);
PR_LogPrint("%s: %s %s, status=%scomplete%s",
@@ -9174,7 +9158,7 @@ nsFrame::Trace(const char* aMethod, bool aEnter, nsReflowStatus aStatus)
void
nsFrame::TraceMsg(const char* aFormatString, ...)
{
if (NS_FRAME_LOG_TEST(GetLogModuleInfo(), NS_FRAME_TRACE_CALLS)) {
if (NS_FRAME_LOG_TEST(sFrameLogModule, NS_FRAME_TRACE_CALLS)) {
// Format arguments into a buffer
char argbuf[200];
va_list ap;
+5 -12
View File
@@ -30,12 +30,12 @@
#define NS_FRAME_TRACE_CHILD_REFLOW 0x4
#define NS_FRAME_TRACE_NEW_FRAMES 0x8
#define NS_FRAME_LOG_TEST(_lm,_bit) (int((_lm)->level) & (_bit))
#define NS_FRAME_LOG_TEST(_lm,_bit) (int(((mozilla::LogModule*)_lm)->Level()) & (_bit))
#ifdef DEBUG
#define NS_FRAME_LOG(_bit,_args) \
PR_BEGIN_MACRO \
if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) { \
if (NS_FRAME_LOG_TEST(nsFrame::sFrameLogModule,_bit)) { \
PR_LogPrint _args; \
} \
PR_END_MACRO
@@ -52,14 +52,14 @@
// XXX remove me
#define NS_FRAME_TRACE_MSG(_bit,_args) \
PR_BEGIN_MACRO \
if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) { \
if (NS_FRAME_LOG_TEST(nsFrame::sFrameLogModule,_bit)) { \
TraceMsg _args; \
} \
PR_END_MACRO
#define NS_FRAME_TRACE(_bit,_args) \
PR_BEGIN_MACRO \
if (NS_FRAME_LOG_TEST(nsFrame::GetLogModuleInfo(),_bit)) { \
if (NS_FRAME_LOG_TEST(nsFrame::sFrameLogModule,_bit)) { \
TraceMsg _args; \
} \
PR_END_MACRO
@@ -711,14 +711,7 @@ public:
*/
static void SetVerifyStyleTreeEnable(bool aEnabled);
/**
* The frame class and related classes share an nspr log module
* for logging frame activity.
*
* Note: the log module is created during library initialization which
* means that you cannot perform logging before then.
*/
static PRLogModuleInfo* GetLogModuleInfo();
static mozilla::LazyLogModule sFrameLogModule;
// Show frame borders when rendering
static void ShowFrameBorders(bool aEnable);
+1 -1
View File
@@ -4770,7 +4770,7 @@ ScrollFrameHelper::ReflowFinished()
mMayHaveDirtyFixedChildren = false;
nsIFrame* parentFrame = mOuter->GetParent();
for (nsIFrame* fixedChild =
parentFrame->GetFirstChild(nsIFrame::kFixedList);
parentFrame->GetChildList(nsIFrame::kFixedList).FirstChild();
fixedChild; fixedChild = fixedChild->GetNextSibling()) {
// force a reflow of the fixed child
presContext->PresShell()->
+525 -58
View File
@@ -231,6 +231,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::Tracks
explicit Tracks(LogicalAxis aAxis) : mAxis(aAxis) {}
void Initialize(const TrackSizingFunctions& aFunctions,
nscoord aGridGap,
uint32_t aNumTracks,
nscoord aContentBoxSize);
@@ -587,6 +588,19 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::Tracks
LineRange GridArea::* aRange,
IntrinsicISizeType aConstraint);
/**
* Apply 'align/justify-content', whichever is relevant for this axis.
* https://drafts.csswg.org/css-align-3/#propdef-align-content
*/
void AlignJustifyContent(const nsHTMLReflowState& aReflowState,
const LogicalSize& aContainerSize);
nscoord SumOfGridGaps() const {
auto len = mSizes.Length();
return MOZ_LIKELY(len > 1) ? (len - 1) * mGridGap : 0;
}
#ifdef DEBUG
void Dump() const
{
@@ -599,6 +613,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::Tracks
#endif
nsAutoTArray<TrackSize, 32> mSizes;
nscoord mGridGap;
LogicalAxis mAxis;
};
@@ -800,13 +815,13 @@ IsNameWithStartSuffix(const nsString& aString, uint32_t* aIndex)
static nscoord
GridLinePosition(uint32_t aLine, const nsTArray<TrackSize>& aTrackSizes)
{
const uint32_t endIndex = aLine;
MOZ_ASSERT(endIndex <= aTrackSizes.Length(), "aTrackSizes is too small");
nscoord pos = 0;
for (uint32_t i = 0; i < endIndex; ++i) {
pos += aTrackSizes[i].mBase;
MOZ_ASSERT(aTrackSizes.Length() > 0, "There are no lines in this grid");
MOZ_ASSERT(aLine <= aTrackSizes.Length(), "aTrackSizes is too small");
if (aLine == aTrackSizes.Length()) {
const TrackSize& sz = aTrackSizes[aLine - 1];
return sz.mPosition + sz.mBase;
}
return pos;
return aTrackSizes[aLine].mPosition;
}
/**
@@ -829,6 +844,288 @@ GetDisplayFlagsForGridItem(nsIFrame* aFrame)
return nsIFrame::DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT;
}
static nscoord
SpaceToFill(WritingMode aWM, const LogicalSize& aSize, nscoord aMargin,
LogicalAxis aAxis, nscoord aCBSize)
{
nscoord size = aAxis == eLogicalAxisBlock ? aSize.BSize(aWM)
: aSize.ISize(aWM);
return aCBSize - (size + aMargin);
}
static bool
AlignJustifySelf(uint8_t aAlignment, bool aOverflowSafe, LogicalAxis aAxis,
bool aSameSide, nscoord aCBSize, const nsHTMLReflowState& aRS,
const LogicalSize& aChildSize, LogicalSize* aContentSize,
LogicalPoint* aPos)
{
MOZ_ASSERT(aAlignment != NS_STYLE_ALIGN_AUTO, "unexpected 'auto' "
"computed value for normal flow grid item");
MOZ_ASSERT(aAlignment != NS_STYLE_ALIGN_LEFT &&
aAlignment != NS_STYLE_ALIGN_RIGHT,
"caller should map that to the corresponding START/END");
// Map some alignment values to 'start' / 'end'.
switch (aAlignment) {
case NS_STYLE_ALIGN_SELF_START: // align/justify-self: self-start
aAlignment = MOZ_LIKELY(aSameSide) ? NS_STYLE_ALIGN_START
: NS_STYLE_ALIGN_END;
break;
case NS_STYLE_ALIGN_SELF_END: // align/justify-self: self-end
aAlignment = MOZ_LIKELY(aSameSide) ? NS_STYLE_ALIGN_END
: NS_STYLE_ALIGN_START;
break;
case NS_STYLE_ALIGN_FLEX_START: // same as 'start' for Grid
aAlignment = NS_STYLE_ALIGN_START;
break;
case NS_STYLE_ALIGN_FLEX_END: // same as 'end' for Grid
aAlignment = NS_STYLE_ALIGN_END;
break;
}
// XXX try to condense this code a bit by adding the necessary convenience
// methods? (bug 1209710)
// Get the item's margin corresponding to the container's start/end side.
const LogicalMargin margin = aRS.ComputedLogicalMargin();
WritingMode wm = aRS.GetWritingMode();
nscoord marginStart, marginEnd;
if (aAxis == eLogicalAxisBlock) {
if (MOZ_LIKELY(aSameSide)) {
marginStart = margin.BStart(wm);
marginEnd = margin.BEnd(wm);
} else {
marginStart = margin.BEnd(wm);
marginEnd = margin.BStart(wm);
}
} else {
if (MOZ_LIKELY(aSameSide)) {
marginStart = margin.IStart(wm);
marginEnd = margin.IEnd(wm);
} else {
marginStart = margin.IEnd(wm);
marginEnd = margin.IStart(wm);
}
}
// https://drafts.csswg.org/css-align-3/#overflow-values
// This implements <overflow-position> = 'safe'.
if (MOZ_UNLIKELY(aOverflowSafe) && aAlignment != NS_STYLE_ALIGN_START) {
nscoord space = SpaceToFill(wm, aChildSize, marginStart + marginEnd,
aAxis, aCBSize);
// XXX we might want to include == 0 here as an optimization -
// I need to see what the baseline/last-baseline code looks like first.
if (space < 0) {
aAlignment = NS_STYLE_ALIGN_START;
}
}
// Set the position and size (aPos/aContentSize) for the requested alignment.
bool didResize = false;
nscoord offset = 0;
switch (aAlignment) {
case NS_STYLE_ALIGN_BASELINE:
case NS_STYLE_ALIGN_LAST_BASELINE:
NS_WARNING("NYI: baseline/last-baseline for grid (bug 1151204)"); // XXX
case NS_STYLE_ALIGN_START:
offset = marginStart;
break;
case NS_STYLE_ALIGN_END: {
nscoord size = aAxis == eLogicalAxisBlock ? aChildSize.BSize(wm)
: aChildSize.ISize(wm);
offset = aCBSize - (size + marginEnd);
break;
}
case NS_STYLE_ALIGN_CENTER:
offset = SpaceToFill(wm, aChildSize, marginStart + marginEnd,
aAxis, aCBSize) / 2;
break;
case NS_STYLE_ALIGN_STRETCH: {
offset = marginStart;
const auto& styleMargin = aRS.mStyleMargin->mMargin;
if (aAxis == eLogicalAxisBlock
? (aRS.mStylePosition->BSize(wm).GetUnit() == eStyleUnit_Auto &&
styleMargin.GetBStartUnit(wm) != eStyleUnit_Auto &&
styleMargin.GetBEndUnit(wm) != eStyleUnit_Auto)
: (aRS.mStylePosition->ISize(wm).GetUnit() == eStyleUnit_Auto &&
styleMargin.GetIStartUnit(wm) != eStyleUnit_Auto &&
styleMargin.GetIEndUnit(wm) != eStyleUnit_Auto)) {
nscoord size = aAxis == eLogicalAxisBlock ? aChildSize.BSize(wm)
: aChildSize.ISize(wm);
nscoord gap = aCBSize - (size + marginStart + marginEnd);
if (gap > 0) {
// Note: The ComputedMax* values are always content-box max values,
// even for box-sizing:border-box.
LogicalMargin bp = aRS.ComputedLogicalBorderPadding();
// XXX ApplySkipSides is probably not very useful here since we
// might not have created any next-in-flow yet. Use the reflow status
// instead? Do all fragments stretch? (bug 1144096).
bp.ApplySkipSides(aRS.frame->GetLogicalSkipSides());
nscoord bpInAxis = aAxis == eLogicalAxisBlock ? bp.BStartEnd(wm)
: bp.IStartEnd(wm);
nscoord contentSize = size - bpInAxis;
NS_ASSERTION(contentSize >= 0, "huh?");
const nscoord unstretchedContentSize = contentSize;
contentSize += gap;
nscoord max = aAxis == eLogicalAxisBlock ? aRS.ComputedMaxBSize()
: aRS.ComputedMaxISize();
if (MOZ_UNLIKELY(contentSize > max)) {
contentSize = max;
gap = contentSize - unstretchedContentSize;
}
// |gap| is now how much the content size is actually allowed to grow.
didResize = gap > 0;
if (didResize) {
(aAxis == eLogicalAxisBlock ? aContentSize->BSize(wm)
: aContentSize->ISize(wm)) = contentSize;
if (MOZ_UNLIKELY(!aSameSide)) {
offset += gap;
}
}
}
}
break;
}
default:
MOZ_ASSERT_UNREACHABLE("unknown align-/justify-self value");
}
if (offset != 0) {
nscoord& pos = aAxis == eLogicalAxisBlock ? aPos->B(wm) : aPos->I(wm);
pos += MOZ_LIKELY(aSameSide) ? offset : -offset;
}
return didResize;
}
static bool
SameSide(WritingMode aContainerWM, LogicalSide aContainerSide,
WritingMode aChildWM, LogicalSide aChildSide)
{
MOZ_ASSERT(aContainerWM.PhysicalAxis(GetAxis(aContainerSide)) ==
aChildWM.PhysicalAxis(GetAxis(aChildSide)));
return aContainerWM.PhysicalSide(aContainerSide) ==
aChildWM.PhysicalSide(aChildSide);
}
static Maybe<LogicalAxis>
AlignSelf(uint8_t aAlignSelf, const LogicalRect& aCB, const WritingMode aCBWM,
const nsHTMLReflowState& aRS, const LogicalSize& aSize,
LogicalSize* aContentSize, LogicalPoint* aPos)
{
Maybe<LogicalAxis> resizedAxis;
auto alignSelf = aAlignSelf;
bool overflowSafe = alignSelf & NS_STYLE_ALIGN_SAFE;
alignSelf &= ~NS_STYLE_ALIGN_FLAG_BITS;
MOZ_ASSERT(alignSelf != NS_STYLE_ALIGN_LEFT &&
alignSelf != NS_STYLE_ALIGN_RIGHT,
"Grid's 'align-self' axis is never parallel to the container's "
"inline axis, so these should've computed to 'start' already");
if (MOZ_UNLIKELY(alignSelf == NS_STYLE_ALIGN_AUTO)) {
// Happens in rare edge cases when 'position' was ignored by the frame
// constructor (and the style system computed 'auto' based on 'position').
alignSelf = NS_STYLE_ALIGN_STRETCH;
}
WritingMode childWM = aRS.GetWritingMode();
bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM);
// |sameSide| is true if the container's start side in this axis is the same
// as the child's start side, in the child's parallel axis.
bool sameSide = SameSide(aCBWM, eLogicalSideBStart,
childWM, isOrthogonal ? eLogicalSideIStart
: eLogicalSideBStart);
LogicalAxis axis = isOrthogonal ? eLogicalAxisInline : eLogicalAxisBlock;
if (AlignJustifySelf(alignSelf, overflowSafe, axis, sameSide,
aCB.BSize(aCBWM), aRS, aSize, aContentSize, aPos)) {
resizedAxis.emplace(axis);
}
return resizedAxis;
}
static Maybe<LogicalAxis>
JustifySelf(uint8_t aJustifySelf, const LogicalRect& aCB, const WritingMode aCBWM,
const nsHTMLReflowState& aRS, const LogicalSize& aSize,
LogicalSize* aContentSize, LogicalPoint* aPos)
{
Maybe<LogicalAxis> resizedAxis;
auto justifySelf = aJustifySelf;
bool overflowSafe = justifySelf & NS_STYLE_JUSTIFY_SAFE;
justifySelf &= ~NS_STYLE_JUSTIFY_FLAG_BITS;
if (MOZ_UNLIKELY(justifySelf == NS_STYLE_ALIGN_AUTO)) {
// Happens in rare edge cases when 'position' was ignored by the frame
// constructor (and the style system computed 'auto' based on 'position').
justifySelf = NS_STYLE_ALIGN_STRETCH;
}
WritingMode childWM = aRS.GetWritingMode();
bool isOrthogonal = aCBWM.IsOrthogonalTo(childWM);
// |sameSide| is true if the container's start side in this axis is the same
// as the child's start side, in the child's parallel axis.
bool sameSide = SameSide(aCBWM, eLogicalSideIStart,
childWM, isOrthogonal ? eLogicalSideBStart
: eLogicalSideIStart);
// Grid's 'justify-self' axis is always parallel to the container's inline
// axis, so justify-self:left|right always applies.
switch (justifySelf) {
case NS_STYLE_JUSTIFY_LEFT:
justifySelf = aCBWM.IsBidiLTR() ? NS_STYLE_JUSTIFY_START
: NS_STYLE_JUSTIFY_END;
break;
case NS_STYLE_JUSTIFY_RIGHT:
justifySelf = aCBWM.IsBidiLTR() ? NS_STYLE_JUSTIFY_END
: NS_STYLE_JUSTIFY_START;
break;
}
LogicalAxis axis = isOrthogonal ? eLogicalAxisBlock : eLogicalAxisInline;
if (AlignJustifySelf(justifySelf, overflowSafe, axis, sameSide,
aCB.ISize(aCBWM), aRS, aSize, aContentSize, aPos)) {
resizedAxis.emplace(axis);
}
return resizedAxis;
}
static uint16_t
GetAlignJustifyValue(uint16_t aAlignment, const WritingMode aWM,
const bool aIsAlign, bool* aOverflowSafe)
{
*aOverflowSafe = aAlignment & NS_STYLE_ALIGN_SAFE;
aAlignment &= (NS_STYLE_ALIGN_ALL_BITS & ~NS_STYLE_ALIGN_FLAG_BITS);
// Map some alignment values to 'start' / 'end'.
switch (aAlignment) {
case NS_STYLE_ALIGN_LEFT:
case NS_STYLE_ALIGN_RIGHT: {
MOZ_ASSERT(!aIsAlign, "Grid container's 'align-contents' axis is never "
"parallel to its inline axis, so these should've computed to "
"'start' already");
bool isStart = aWM.IsBidiLTR() == (aAlignment == NS_STYLE_ALIGN_LEFT);
return isStart ? NS_STYLE_ALIGN_START : NS_STYLE_ALIGN_END;
}
case NS_STYLE_ALIGN_FLEX_START: // same as 'start' for Grid
return NS_STYLE_ALIGN_START;
case NS_STYLE_ALIGN_FLEX_END: // same as 'end' for Grid
return NS_STYLE_ALIGN_END;
}
return aAlignment;
}
static uint16_t
GetAlignJustifyFallbackIfAny(uint16_t aAlignment, const WritingMode aWM,
const bool aIsAlign, bool* aOverflowSafe)
{
uint16_t fallback = aAlignment >> NS_STYLE_ALIGN_ALL_SHIFT;
if (fallback) {
return GetAlignJustifyValue(fallback, aWM, aIsAlign, aOverflowSafe);
}
// https://drafts.csswg.org/css-align-3/#fallback-alignment
switch (aAlignment) {
case NS_STYLE_ALIGN_STRETCH:
case NS_STYLE_ALIGN_SPACE_BETWEEN:
return NS_STYLE_ALIGN_START;
case NS_STYLE_ALIGN_SPACE_AROUND:
case NS_STYLE_ALIGN_SPACE_EVENLY:
return NS_STYLE_ALIGN_CENTER;
}
return 0;
}
//----------------------------------------------------------------------
// Frame class boilerplate
@@ -1613,6 +1910,7 @@ nsGridContainerFrame::TrackSize::Initialize(nscoord aPercentageBasis,
void
nsGridContainerFrame::Tracks::Initialize(
const TrackSizingFunctions& aFunctions,
nscoord aGridGap,
uint32_t aNumTracks,
nscoord aContentBoxSize)
{
@@ -1646,6 +1944,11 @@ nsGridContainerFrame::Tracks::Initialize(
aFunctions.mAutoMinSizing,
aFunctions.mAutoMaxSizing);
}
mGridGap = aGridGap;
// XXX allow negative values? pending outcome of www-style thread:
// https://lists.w3.org/Archives/Public/www-style/2015Oct/0028.html
MOZ_ASSERT(mGridGap >= nscoord(0), "negative grid gap");
}
/**
@@ -1776,8 +2079,12 @@ nsGridContainerFrame::Tracks::CalculateSizes(
ResolveIntrinsicSize(aState, aGridItems, aFunctions, aRange, percentageBasis,
aConstraint);
if (aConstraint != nsLayoutUtils::MIN_ISIZE) {
DistributeFreeSpace(aContentBoxSize);
StretchFlexibleTracks(aState, aGridItems, aFunctions, aContentBoxSize);
nscoord freeSpace = aContentBoxSize;
if (freeSpace != NS_UNCONSTRAINEDSIZE) {
freeSpace -= SumOfGridGaps();
}
DistributeFreeSpace(freeSpace);
StretchFlexibleTracks(aState, aGridItems, aFunctions, freeSpace);
}
}
@@ -1787,10 +2094,11 @@ nsGridContainerFrame::CalculateTrackSizes(GridReflowState& aState,
IntrinsicISizeType aConstraint)
{
const WritingMode& wm = aState.mWM;
aState.mCols.Initialize(aState.mColFunctions, mGridColEnd,
aContentBox.ISize(wm));
aState.mRows.Initialize(aState.mRowFunctions, mGridRowEnd,
aContentBox.BSize(wm));
const nsStylePosition* stylePos = aState.mGridStyle;
aState.mCols.Initialize(aState.mColFunctions, stylePos->mGridColumnGap,
mGridColEnd, aContentBox.ISize(wm));
aState.mRows.Initialize(aState.mRowFunctions, stylePos->mGridRowGap,
mGridRowEnd, aContentBox.BSize(wm));
aState.mCols.CalculateSizes(aState, mGridItems, aState.mColFunctions,
aContentBox.ISize(wm), &GridArea::mCols,
@@ -2280,27 +2588,153 @@ nsGridContainerFrame::Tracks::StretchFlexibleTracks(
}
}
void
nsGridContainerFrame::Tracks::AlignJustifyContent(
const nsHTMLReflowState& aReflowState,
const LogicalSize& aContainerSize)
{
if (mSizes.IsEmpty()) {
return;
}
const bool isAlign = mAxis == eLogicalAxisBlock;
auto stylePos = aReflowState.mStylePosition;
const auto valueAndFallback = isAlign ?
stylePos->ComputedAlignContent(aReflowState.mStyleDisplay) :
stylePos->ComputedJustifyContent(aReflowState.mStyleDisplay);
WritingMode wm = aReflowState.GetWritingMode();
bool overflowSafe;
auto alignment = ::GetAlignJustifyValue(valueAndFallback, wm, isAlign,
&overflowSafe);
if (alignment == NS_STYLE_ALIGN_AUTO) {
alignment = NS_STYLE_ALIGN_START;
}
// Compute the free space and count auto-sized tracks.
size_t numAutoTracks = 0;
nscoord space;
if (alignment != NS_STYLE_ALIGN_START) {
nscoord trackSizeSum = 0;
for (const TrackSize& sz : mSizes) {
trackSizeSum += sz.mBase;
if (sz.mState & TrackSize::eAutoMaxSizing) {
++numAutoTracks;
}
}
nscoord cbSize = isAlign ? aContainerSize.BSize(wm)
: aContainerSize.ISize(wm);
space = cbSize - trackSizeSum - SumOfGridGaps();
// Use the fallback value instead when applicable.
if (space < 0 ||
(alignment == NS_STYLE_ALIGN_SPACE_BETWEEN && mSizes.Length() == 1)) {
auto fallback = ::GetAlignJustifyFallbackIfAny(valueAndFallback, wm,
isAlign, &overflowSafe);
if (fallback) {
alignment = fallback;
}
}
if (space == 0 || (space < 0 && overflowSafe)) {
// XXX check that this makes sense also for [last-]baseline (bug 1151204).
alignment = NS_STYLE_ALIGN_START;
}
}
// Optimize the cases where we just need to set each track's position.
nscoord pos = 0;
bool distribute = true;
switch (alignment) {
case NS_STYLE_ALIGN_BASELINE:
case NS_STYLE_ALIGN_LAST_BASELINE:
NS_WARNING("'NYI: baseline/last-baseline' (bug 1151204)"); // XXX
case NS_STYLE_ALIGN_START:
distribute = false;
break;
case NS_STYLE_ALIGN_END:
pos = space;
distribute = false;
break;
case NS_STYLE_ALIGN_CENTER:
pos = space / 2;
distribute = false;
break;
case NS_STYLE_ALIGN_STRETCH:
distribute = numAutoTracks != 0;
break;
}
if (!distribute) {
for (TrackSize& sz : mSizes) {
sz.mPosition = pos;
pos += sz.mBase + mGridGap;
}
return;
}
// Distribute free space to/between tracks and set their position.
MOZ_ASSERT(space > 0, "should've handled that on the fallback path above");
nscoord between, roundingError;
switch (alignment) {
case NS_STYLE_ALIGN_STRETCH: {
MOZ_ASSERT(numAutoTracks > 0, "we handled numAutoTracks == 0 above");
nscoord spacePerTrack;
roundingError = NSCoordDivRem(space, numAutoTracks, &spacePerTrack);
for (TrackSize& sz : mSizes) {
sz.mPosition = pos;
if (!(sz.mState & TrackSize::eAutoMaxSizing)) {
pos += sz.mBase + mGridGap;
continue;
}
nscoord stretch = spacePerTrack;
if (roundingError) {
roundingError -= 1;
stretch += 1;
}
nscoord newBase = sz.mBase + stretch;
sz.mBase = newBase;
pos += newBase + mGridGap;
}
MOZ_ASSERT(!roundingError, "we didn't distribute all rounding error?");
return;
}
case NS_STYLE_ALIGN_SPACE_BETWEEN:
MOZ_ASSERT(mSizes.Length() > 1, "should've used a fallback above");
roundingError = NSCoordDivRem(space, mSizes.Length() - 1, &between);
break;
case NS_STYLE_ALIGN_SPACE_AROUND:
roundingError = NSCoordDivRem(space, mSizes.Length(), &between);
pos = between / 2;
break;
case NS_STYLE_ALIGN_SPACE_EVENLY:
roundingError = NSCoordDivRem(space, mSizes.Length() + 1, &between);
pos = between;
break;
default:
MOZ_ASSERT_UNREACHABLE("unknown align-/justify-content value");
between = 0; // just to avoid a compiler warning
}
between += mGridGap;
for (TrackSize& sz : mSizes) {
sz.mPosition = pos;
nscoord spacing = between;
if (roundingError) {
roundingError -= 1;
spacing += 1;
}
pos += sz.mBase + spacing;
}
MOZ_ASSERT(!roundingError, "we didn't distribute all rounding error?");
}
void
nsGridContainerFrame::LineRange::ToPositionAndLength(
const nsTArray<TrackSize>& aTrackSizes, nscoord* aPos, nscoord* aLength) const
{
MOZ_ASSERT(mStart != kAutoLine && mEnd != kAutoLine,
"expected a definite LineRange");
nscoord pos = 0;
const uint32_t start = mStart;
uint32_t i = 0;
for (; i < start; ++i) {
pos += aTrackSizes[i].mBase;
}
*aPos = pos;
nscoord length = 0;
const uint32_t end = mEnd;
MOZ_ASSERT(end <= aTrackSizes.Length(), "aTrackSizes isn't large enough");
for (; i < end; ++i) {
length += aTrackSizes[i].mBase;
}
*aLength = length;
MOZ_ASSERT(mStart < mEnd);
nscoord startPos = aTrackSizes[mStart].mPosition;
const TrackSize& sz = aTrackSizes[mEnd - 1];
*aPos = startPos;
*aLength = (sz.mPosition + sz.mBase) - startPos;
}
nscoord
@@ -2309,13 +2743,10 @@ nsGridContainerFrame::LineRange::ToLength(
{
MOZ_ASSERT(mStart != kAutoLine && mEnd != kAutoLine,
"expected a definite LineRange");
nscoord length = 0;
const uint32_t end = mEnd;
MOZ_ASSERT(end <= aTrackSizes.Length(), "aTrackSizes isn't large enough");
for (uint32_t i = mStart; i < end; ++i) {
length += aTrackSizes[i].mBase;
}
return length;
MOZ_ASSERT(mStart < mEnd);
nscoord startPos = aTrackSizes[mStart].mPosition;
const TrackSize& sz = aTrackSizes[mEnd - 1];
return (sz.mPosition + sz.mBase) - startPos;
}
void
@@ -2392,6 +2823,7 @@ nsGridContainerFrame::ReflowChildren(GridReflowState& aState,
(aContentArea.Size(wm) +
aState.mReflowState->ComputedLogicalBorderPadding().Size(wm)).GetPhysicalSize(wm);
nsPresContext* pc = PresContext();
nsStyleContext* containerSC = StyleContext();
for (; !aState.mIter.AtEnd(); aState.mIter.Next()) {
nsIFrame* child = *aState.mIter;
const bool isGridItem = child->GetType() != nsGkAtoms::placeholderFrame;
@@ -2408,36 +2840,63 @@ nsGridContainerFrame::ReflowChildren(GridReflowState& aState,
}
WritingMode childWM = child->GetWritingMode();
LogicalSize childCBSize = cb.Size(wm).ConvertTo(childWM, wm);
nsHTMLReflowState childRS(pc, *aState.mReflowState, child, childCBSize);
const LogicalMargin margin = childRS.ComputedLogicalMargin();
if (childRS.ComputedBSize() == NS_AUTOHEIGHT && MOZ_LIKELY(isGridItem)) {
// XXX the start of an align-self:stretch impl. Needs min-/max-bsize
// clamping though, and check the prop value is actually 'stretch'!
LogicalMargin bp = childRS.ComputedLogicalBorderPadding();
bp.ApplySkipSides(child->GetLogicalSkipSides());
nscoord bSize = childCBSize.BSize(childWM) - bp.BStartEnd(childWM) -
margin.BStartEnd(childWM);
childRS.SetComputedBSize(std::max(bSize, 0));
}
// XXX temporary workaround to avoid being INCOMPLETE until we have
// support for fragmentation (bug 1144096)
childCBSize.BSize(childWM) = NS_UNCONSTRAINEDSIZE;
Maybe<nsHTMLReflowState> childRS; // Maybe<> so we can reuse the space
childRS.emplace(pc, *aState.mReflowState, child, childCBSize);
// We need the width of the child before we can correctly convert
// the writing-mode of its origin, so we reflow at (0, 0) using a dummy
// containerSize, and then pass the correct position to FinishReflowChild.
nsHTMLReflowMetrics childSize(childRS);
Maybe<nsHTMLReflowMetrics> childSize; // Maybe<> so we can reuse the space
childSize.emplace(*childRS);
nsReflowStatus childStatus;
const nsSize dummyContainerSize;
ReflowChild(child, pc, childSize, childRS, childWM, LogicalPoint(childWM),
ReflowChild(child, pc, *childSize, *childRS, childWM, LogicalPoint(childWM),
dummyContainerSize, 0, childStatus);
LogicalPoint childPos =
cb.Origin(wm).ConvertTo(childWM, wm,
containerSize - childSize.PhysicalSize() -
margin.Size(childWM).GetPhysicalSize(childWM));
childPos.I(childWM) += margin.IStart(childWM);
childPos.B(childWM) += margin.BStart(childWM);
childRS.ApplyRelativePositioning(&childPos, containerSize);
FinishReflowChild(child, pc, childSize, &childRS, childWM, childPos,
containerSize - childSize->PhysicalSize());
// Apply align/justify-self and reflow again if that affects the size.
if (isGridItem) {
LogicalSize oldSize = childSize->Size(childWM); // from the ReflowChild()
LogicalSize newContentSize(childWM);
auto align = childRS->mStylePosition->ComputedAlignSelf(
childRS->mStyleDisplay, containerSC);
Maybe<LogicalAxis> alignResize =
AlignSelf(align, cb, wm, *childRS, oldSize, &newContentSize, &childPos);
auto justify = childRS->mStylePosition->ComputedJustifySelf(
childRS->mStyleDisplay, containerSC);
Maybe<LogicalAxis> justifyResize =
JustifySelf(justify, cb, wm, *childRS, oldSize, &newContentSize, &childPos);
if (alignResize || justifyResize) {
FinishReflowChild(child, pc, *childSize, childRS.ptr(), childWM,
LogicalPoint(childWM), containerSize,
NS_FRAME_NO_MOVE_FRAME | NS_FRAME_NO_SIZE_VIEW);
childSize.reset(); // In reverse declaration order since it runs
childRS.reset(); // destructors.
childRS.emplace(pc, *aState.mReflowState, child, childCBSize);
if ((alignResize && alignResize.value() == eLogicalAxisBlock) ||
(justifyResize && justifyResize.value() == eLogicalAxisBlock)) {
childRS->SetComputedBSize(newContentSize.BSize(childWM));
childRS->SetBResize(true);
}
if ((alignResize && alignResize.value() == eLogicalAxisInline) ||
(justifyResize && justifyResize.value() == eLogicalAxisInline)) {
childRS->SetComputedISize(newContentSize.ISize(childWM));
childRS->SetIResize(true);
}
childSize.emplace(*childRS);
ReflowChild(child, pc, *childSize, *childRS, childWM,
LogicalPoint(childWM), dummyContainerSize, 0, childStatus);
}
}
childRS->ApplyRelativePositioning(&childPos, containerSize);
FinishReflowChild(child, pc, *childSize, childRS.ptr(), childWM, childPos,
containerSize, 0);
ConsiderChildOverflow(aDesiredSize.mOverflowAreas, child);
// XXX deal with 'childStatus' not being COMPLETE
// XXX deal with 'childStatus' not being COMPLETE (bug 1144096)
}
if (IsAbsoluteContainer()) {
@@ -2531,6 +2990,11 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
LogicalRect contentArea(wm, bp.IStart(wm), bp.BStart(wm),
computedISize, bSize);
// Apply 'align/justify-content' to the grid.
gridReflowState.mCols.AlignJustifyContent(aReflowState, contentArea.Size(wm));
gridReflowState.mRows.AlignJustifyContent(aReflowState, contentArea.Size(wm));
gridReflowState.mIter.Reset(GridItemCSSOrderIterator::eIncludeAll);
ReflowChildren(gridReflowState, contentArea, aDesiredSize, aStatus);
@@ -2551,14 +3015,17 @@ nsGridContainerFrame::IntrinsicISize(nsRenderingContext* aRenderingContext,
if (mGridColEnd == 0) {
return 0;
}
state.mCols.Initialize(state.mColFunctions, mGridColEnd,
NS_UNCONSTRAINEDSIZE);
state.mCols.Initialize(state.mColFunctions, state.mGridStyle->mGridColumnGap,
mGridColEnd, NS_UNCONSTRAINEDSIZE);
state.mIter.Reset();
state.mCols.CalculateSizes(state, mGridItems, state.mColFunctions,
NS_UNCONSTRAINEDSIZE, &GridArea::mCols,
aConstraint);
TranslatedLineRange allTracks(0, mGridColEnd);
return allTracks.ToLength(state.mCols.mSizes);
nscoord length = 0;
for (const TrackSize& sz : state.mCols.mSizes) {
length += sz.mBase;
}
return length + state.mCols.SumOfGridGaps();
}
nscoord
+1
View File
@@ -82,6 +82,7 @@ public:
nscoord mBase;
nscoord mLimit;
nscoord mPosition; // zero until we apply 'align/justify-content'
StateBits mState;
};
+9 -19
View File
@@ -18,7 +18,6 @@
#include "nsFontMetrics.h"
#include "nsBlockFrame.h"
#include "nsLineBox.h"
#include "nsFlexContainerFrame.h"
#include "nsImageFrame.h"
#include "nsTableFrame.h"
#include "nsTableCellFrame.h"
@@ -1486,8 +1485,8 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
// We need to compute it. It's important we do this, because if it's
// percentage-based this computed value may be different from the
// computed value calculated using the absolute containing block height.
boxBSize = ComputeBSizeValue(blockContentSize.BSize(wm),
insideBoxSizing, styleBSize) +
boxBSize = nsLayoutUtils::ComputeBSizeValue(blockContentSize.BSize(wm),
insideBoxSizing, styleBSize) +
insideBoxSizing + outsideBoxSizing;
}
@@ -2072,18 +2071,6 @@ IsSideCaption(nsIFrame* aFrame, const nsStyleDisplay* aStyleDisplay,
captionSide == NS_STYLE_CAPTION_SIDE_RIGHT;
}
static nsFlexContainerFrame*
GetFlexContainer(nsIFrame* aFrame)
{
nsIFrame* parent = aFrame->GetParent();
if (!parent ||
parent->GetType() != nsGkAtoms::flexContainerFrame) {
return nullptr;
}
return static_cast<nsFlexContainerFrame*>(parent);
}
// Flex items resolve block-axis percentage margin & padding against the flex
// container's block-size (which is the containing block block-size).
// For everything else: the CSS21 spec requires that margin and padding
@@ -2340,8 +2327,9 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
}
const nsFlexContainerFrame* flexContainerFrame = GetFlexContainer(frame);
if (flexContainerFrame) {
nsIFrame* parent = frame->GetParent();
nsIAtom* parentFrameType = parent ? parent->GetType() : nullptr;
if (parentFrameType == nsGkAtoms::flexContainerFrame) {
computeSizeFlags =
ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
@@ -2377,11 +2365,13 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
NS_ASSERTION(ComputedBSize() == NS_UNCONSTRAINEDSIZE ||
ComputedBSize() >= 0, "Bogus block-size");
// Exclude inline tables and flex items from the block margin calculations
// Exclude inline tables, side captions, flex and grid items from block
// margin calculations.
if (isBlock &&
!IsSideCaption(frame, mStyleDisplay, cbwm) &&
mStyleDisplay->mDisplay != NS_STYLE_DISPLAY_INLINE_TABLE &&
!flexContainerFrame) {
parentFrameType != nsGkAtoms::flexContainerFrame &&
parentFrameType != nsGkAtoms::gridContainerFrame) {
CalculateBlockSideMargins(aFrameType);
}
}
+1 -5
View File
@@ -1072,16 +1072,12 @@ public:
*/
void GetCrossDocChildLists(nsTArray<ChildList>* aLists);
// XXXbz this method should go away
nsIFrame* GetFirstChild(ChildListID aListID) const {
return GetChildList(aListID).FirstChild();
}
// XXXmats this method should also go away then
nsIFrame* GetLastChild(ChildListID aListID) const {
return GetChildList(aListID).LastChild();
}
nsIFrame* GetFirstPrincipalChild() const {
return GetFirstChild(kPrincipalList);
return GetChildList(kPrincipalList).FirstChild();
}
// The individual concrete child lists.
+2 -2
View File
@@ -22,8 +22,8 @@
#include "nsIPrintSettings.h"
#include "mozilla/Logging.h"
extern PRLogModuleInfo *GetLayoutPrintingLog();
#define PR_PL(_p1) MOZ_LOG(GetLayoutPrintingLog(), mozilla::LogLevel::Debug, _p1)
extern mozilla::LazyLogModule gLayoutPrintingLog;
#define PR_PL(_p1) MOZ_LOG(gLayoutPrintingLog, mozilla::LogLevel::Debug, _p1)
using namespace mozilla;
using namespace mozilla::gfx;
+4 -11
View File
@@ -94,14 +94,7 @@ using mozilla::DefaultXDisplay;
#undef CreateEvent
#endif
static PRLogModuleInfo *
GetObjectFrameLog()
{
static PRLogModuleInfo *sLog;
if (!sLog)
sLog = PR_NewLogModule("nsPluginFrame");
return sLog;
}
static mozilla::LazyLogModule sPluginFrameLog("nsPluginFrame");
using namespace mozilla;
using namespace mozilla::gfx;
@@ -160,13 +153,13 @@ nsPluginFrame::nsPluginFrame(nsStyleContext* aContext)
, mReflowCallbackPosted(false)
, mIsHiddenDueToScroll(false)
{
MOZ_LOG(GetObjectFrameLog(), LogLevel::Debug,
MOZ_LOG(sPluginFrameLog, LogLevel::Debug,
("Created new nsPluginFrame %p\n", this));
}
nsPluginFrame::~nsPluginFrame()
{
MOZ_LOG(GetObjectFrameLog(), LogLevel::Debug,
MOZ_LOG(sPluginFrameLog, LogLevel::Debug,
("nsPluginFrame %p deleted\n", this));
}
@@ -196,7 +189,7 @@ nsPluginFrame::Init(nsIContent* aContent,
nsContainerFrame* aParent,
nsIFrame* aPrevInFlow)
{
MOZ_LOG(GetObjectFrameLog(), LogLevel::Debug,
MOZ_LOG(sPluginFrameLog, LogLevel::Debug,
("Initializing nsPluginFrame %p for content %p\n", this, aContent));
nsPluginFrameSuper::Init(aContent, aParent, aPrevInFlow);
+3 -9
View File
@@ -42,15 +42,9 @@ static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printsettings-se
//
#include "mozilla/Logging.h"
PRLogModuleInfo *
GetLayoutPrintingLog()
{
static PRLogModuleInfo *sLog;
if (!sLog)
sLog = PR_NewLogModule("printing-layout");
return sLog;
}
#define PR_PL(_p1) MOZ_LOG(GetLayoutPrintingLog(), mozilla::LogLevel::Debug, _p1)
mozilla::LazyLogModule gLayoutPrintingLog("printing-layout");
#define PR_PL(_p1) MOZ_LOG(gLayoutPrintingLog, mozilla::LogLevel::Debug, _p1)
nsSimplePageSequenceFrame*
NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
+1 -1
View File
@@ -1154,7 +1154,7 @@ CanTextCrossFrameBoundary(nsIFrame* aFrame, nsIAtom* aType)
if (continuesTextRun) {
result.mFrameToScan = aFrame->GetFirstPrincipalChild();
result.mOverflowFrameToScan =
aFrame->GetFirstChild(nsIFrame::kOverflowList);
aFrame->GetChildList(nsIFrame::kOverflowList).FirstChild();
NS_WARN_IF_FALSE(!result.mOverflowFrameToScan,
"Scanning overflow inline frames is something we should avoid");
result.mScanSiblings = true;
+3 -7
View File
@@ -577,17 +577,13 @@ static void GetKeywordsForProperty(const nsCSSProperty aProperty,
// Shorthand props have no keywords.
return;
}
const nsCSSProps::KTableValue *keywordTable =
const nsCSSProps::KTableEntry* keywordTable =
nsCSSProps::kKeywordTableTable[aProperty];
if (keywordTable) {
size_t i = 0;
while (nsCSSKeyword(keywordTable[i]) != eCSSKeyword_UNKNOWN) {
nsCSSKeyword word = nsCSSKeyword(keywordTable[i]);
for (size_t i = 0; keywordTable[i].mKeyword != eCSSKeyword_UNKNOWN; ++i) {
nsCSSKeyword word = keywordTable[i].mKeyword;
InsertNoDuplicates(aArray,
NS_ConvertASCIItoUTF16(nsCSSKeywords::GetStringValue(word)));
// Increment counter by 2, because in this table every second
// element is a nsCSSKeyword.
i += 2;
}
}
}
+3 -9
View File
@@ -17,15 +17,9 @@
#include "mozilla/Logging.h"
#define DUMP_LAYOUT_LEVEL 9 // this turns on the dumping of each doucment's layout info
static PRLogModuleInfo *
GetPrintingLog()
{
static PRLogModuleInfo *sLog;
if (!sLog)
sLog = PR_NewLogModule("printing");
return sLog;
}
#define PR_PL(_p1) MOZ_LOG(GetPrintingLog(), mozilla::LogLevel::Debug, _p1);
static mozilla::LazyLogModule gPrintingLog("printing");
#define PR_PL(_p1) MOZ_LOG(gPrintingLog, mozilla::LogLevel::Debug, _p1);
//---------------------------------------------------
//-- nsPrintData Class Impl
+4 -10
View File
@@ -138,15 +138,9 @@ using namespace mozilla::dom;
#define DUMP_LAYOUT_LEVEL 9 // this turns on the dumping of each doucment's layout info
#ifndef PR_PL
static PRLogModuleInfo *
GetPrintingLog()
{
static PRLogModuleInfo *sLog;
if (!sLog)
sLog = PR_NewLogModule("printing");
return sLog;
}
#define PR_PL(_p1) MOZ_LOG(GetPrintingLog(), mozilla::LogLevel::Debug, _p1);
static mozilla::LazyLogModule gPrintingLog("printing")
#define PR_PL(_p1) MOZ_LOG(gPrintingLog, mozilla::LogLevel::Debug, _p1);
#endif
#ifdef EXTENDED_DEBUG_PRINTING
@@ -1698,7 +1692,7 @@ nsPrintEngine::SetupToPrintContent()
NS_ENSURE_SUCCESS(rv, rv);
}
if (MOZ_LOG_TEST(GetPrintingLog(), LogLevel::Debug)) {
if (MOZ_LOG_TEST(gPrintingLog, LogLevel::Debug)) {
float calcRatio = 0.0f;
if (mPrt->mPrintDocList.Length() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) {
nsPrintObject* smallestPO = FindSmallestSTF();
@@ -46,18 +46,6 @@
</div></td>
<td id="bspadding"><div>
<!-- box-sizing: padding-box -->
<div style="width: 37px">A B</div>
<div style="width: auto">A B</div>
<div style="width: auto">A<br>B</div>
<div style="width: auto">A B</div>
<div style="width: 37px">A B</div>
<div style="width: 38px">A B</div>
<div style="width: 48px">A B</div>
</div></td>
<td id="bsborder"><div>
<!-- box-sizing: border-box -->
<div style="width: 37px">A B</div>
@@ -13,7 +13,6 @@
td > div { width: 100px; }
td#bscontent > div > div { box-sizing: content-box; }
td#bspadding > div > div { box-sizing: padding-box; }
td#bsborder > div > div { box-sizing: border-box; }
td > div > div {
@@ -47,18 +46,6 @@
</div></td>
<td id="bspadding"><div>
<!-- box-sizing: padding-box -->
<div style="width: auto">A B</div>
<div style="width: -moz-max-content">A B</div>
<div style="width: -moz-min-content">A B</div>
<div style="width: -moz-fit-content">A B</div>
<div style="width: -moz-available">A B</div>
<div style="width: 50px">A B</div>
<div style="width: 60%">A B</div>
</div></td>
<td id="bsborder"><div>
<!-- box-sizing: border-box -->
<div style="width: auto">A B</div>
@@ -39,17 +39,6 @@
</td>
<td id="bspadding">
<!-- box-sizing: padding-box -->
<table><tr><td><div>A B</div></td></tr></table>
<table><tr><td><div>A B</div></td></tr></table>
<table><tr><td><div>A<br>B</div></td></tr></table>
<table><tr><td><div>A B</div></td></tr></table>
<table><tr><td><div>A B</div></td></tr></table>
<table><tr><td><div style="width: 138px">A B</div></td></tr></table>
</td>
<td id="bsborder">
<!-- box-sizing: border-box -->
<table><tr><td><div>A B</div></td></tr></table>
@@ -11,7 +11,6 @@
td { border: 1px solid; padding: 1px solid; }
td#bscontent td > div { box-sizing: content-box; }
td#bspadding td > div { box-sizing: padding-box; }
td#bsborder td > div { box-sizing: border-box; }
td td > div {
@@ -43,17 +42,6 @@
</td>
<td id="bspadding">
<!-- box-sizing: padding-box -->
<table><tr><td><div style="width: auto">A B</div></td></tr></table>
<table><tr><td><div style="width: -moz-max-content">A B</div></td></tr></table>
<table><tr><td><div style="width: -moz-min-content">A B</div></td></tr></table>
<table><tr><td><div style="width: -moz-fit-content">A B</div></td></tr></table>
<table><tr><td><div style="width: -moz-available">A B</div></td></tr></table>
<table><tr><td><div style="width: 150px">A B</div></td></tr></table>
</td>
<td id="bsborder">
<!-- box-sizing: border-box -->
<table><tr><td><div style="width: auto">A B</div></td></tr></table>
@@ -13,7 +13,6 @@
td > div { width: 100px; }
td#bscontent > div > div { box-sizing: content-box; }
td#bspadding > div > div { box-sizing: padding-box; }
td#bsborder > div > div { box-sizing: border-box; }
td > div > div {
@@ -47,18 +46,6 @@
</div></td>
<td id="bspadding"><div>
<!-- box-sizing: padding-box -->
<div style="width: auto">A B</div>
<div style="width: -moz-max-content">A B</div>
<div style="width: -moz-min-content">A B</div>
<div style="width: -moz-fit-content">A B</div>
<div style="width: -moz-available">A B</div>
<div style="width: 50px">A B</div>
<div style="width: 60%">A B</div>
</div></td>
<td id="bsborder"><div>
<!-- box-sizing: border-box -->
<div style="width: auto">A B</div>
@@ -48,18 +48,6 @@
</div></td>
<td id="bspadding"><div>
<!-- box-sizing: padding-box -->
<div>A B</div>
<div>A B</div>
<div>A<br>B</div>
<div>A B</div>
<div style="width: 37px">A B</div>
<div style="width: 38px">A B</div>
<div style="width: 48px">A B</div>
</div></td>
<td id="bsborder"><div>
<!-- box-sizing: border-box -->
<div>A B</div>
@@ -14,7 +14,6 @@
direction: rtl; position: relative; }
td#bscontent > div > div { box-sizing: content-box; }
td#bspadding > div > div { box-sizing: padding-box; }
td#bsborder > div > div { box-sizing: border-box; }
td > div > div {
@@ -59,18 +58,6 @@
</div></td>
<td id="bspadding"><div>
<!-- box-sizing: padding-box -->
<div style="width: auto">A B</div>
<div style="width: -moz-max-content">A B</div>
<div style="width: -moz-min-content">A B</div>
<div style="width: -moz-fit-content">A B</div>
<div style="width: -moz-available">A B</div>
<div style="width: 50px">A B</div>
<div style="width: 60%">A B</div>
</div></td>
<td id="bsborder"><div>
<!-- box-sizing: border-box -->
<div style="width: auto">A B</div>
@@ -43,10 +43,5 @@ hbox {
<div><hbox class="cb" style="height:29px;">content-box 20px</hbox></div>
<div><hbox class="pb" style="height:16px;">padding-box 20px</hbox></div>
<div><hbox class="pb" style="height:46px;">padding-box 50px</hbox></div>
<div><hbox class="pb" style="height:16px;">padding-box 20px</hbox></div>
</body>
</html>
@@ -25,11 +25,6 @@ hbox {
background:pink;
}
.pb {
box-sizing:padding-box;
background:cyan;
}
</style>
</head>
<body>
@@ -44,10 +39,5 @@ hbox {
<div><hbox class="cb" style="max-height:20px;">content-box 20px</hbox></div>
<div><hbox class="pb" style="height:20px;">padding-box 20px</hbox></div>
<div><hbox class="pb" style="min-height:50px;">padding-box 50px</hbox></div>
<div><hbox class="pb" style="max-height:20px;">padding-box 20px</hbox></div>
</body>
</html>
@@ -9,26 +9,14 @@
box-sizing:border-box;
}
#paddingBox {
background:gold;
height:100px;
box-sizing:padding-box;
}
</style>
<div id="borderBox"></div>
<p id="heightWidth1"></p>
<div id="paddingBox"></div>
<p id="heightWidth2"></p>
<script>
var divs = document.getElementsByTagName("div");
var textEle1 = document.getElementById("heightWidth1");
textEle1.innerHTML += "height = " + getComputedStyle(divs[0]).height;
textEle1.innerHTML += ", width = " + getComputedStyle(divs[0]).width;
var textEle2 = document.getElementById("heightWidth2");
textEle2.innerHTML += "height = " + getComputedStyle(divs[1]).height;
textEle2.innerHTML += ", width = " + getComputedStyle(divs[1]).width;
</script>
@@ -10,27 +10,14 @@
border: 20px solid gold;
}
#paddingBox {
background:gold;
height:100px;
box-sizing:padding-box;
padding: 20px;
}
</style>
<div id="borderBox"></div>
<p id="heightWidth1"></p>
<div id="paddingBox"></div>
<p id="heightWidth2"></p>
<script>
var divs = document.getElementsByTagName("div");
var textEle1 = document.getElementById("heightWidth1");
textEle1.innerHTML += "height = " + getComputedStyle(divs[0]).height;
textEle1.innerHTML += ", width = " + getComputedStyle(divs[0]).width;
var textEle2 = document.getElementById("heightWidth2");
textEle2.innerHTML += "height = " + getComputedStyle(divs[1]).height;
textEle2.innerHTML += ", width = " + getComputedStyle(divs[1]).width;
</script>
+1 -1
View File
@@ -4,6 +4,6 @@
<img src="lime100x100.png"
style="height: 200px; display: block; visibility: hidden;
padding: 30px;
box-sizing: padding-box;">
box-sizing: border-box;">
</div>
</body>
+1 -1
View File
@@ -4,6 +4,6 @@
<img src="lime100x100.png"
style="height: 200px; display: block; visibility: hidden;
padding: 15% 30px;
box-sizing: padding-box;">
box-sizing: border-box;">
</div>
</body>
+1 -1
View File
@@ -4,6 +4,6 @@
<img src="lime100x100.png"
style="height: 200px; display: block; visibility: hidden;
padding: calc(15%) 30px;
box-sizing: padding-box;">
box-sizing: border-box;">
</div>
</body>
+1 -1
View File
@@ -4,6 +4,6 @@
<img src="lime100x100.png"
style="height: 200px; display: block; visibility: hidden;
padding: calc(10% + 10px) 30px;
box-sizing: padding-box;">
box-sizing: border-box;">
</div>
</body>
+1 -1
View File
@@ -4,6 +4,6 @@
<img src="lime100x100.png"
style="height: 200px; display: block; visibility: hidden;
padding: calc(30px);
box-sizing: padding-box;">
box-sizing: border-box;">
</div>
</body>
@@ -32,7 +32,7 @@
.inline { display:inline; }
.columns { -moz-columns:2; columns:2; height:4em; }
.contents { display:contents; }
.contents { display:contents; align-items:inherit; justify-items:inherit; }
.c1 { color:lime; }
.c2 { background:blue; color:pink; }
@@ -30,6 +30,7 @@ body,html { color:black; background:white; font-size:16px; padding:0; margin:0;
position: absolute;
left: 13px; top: 31px;
height: 12px; width: 44px;
background: blue;
}
.abs {
@@ -82,64 +83,64 @@ span {
<div style="float:left">
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="b abs">b</span>
</div>
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="c abs">c</span>
</div>
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="d abs">d</span>
</div>
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="e abs">e</span>
</div>
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="f abs">f</span>
</div>
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="g abs">g</span>
</div>
</div><div style="float:left">
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="b abs">b</span>
</div>
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="c abs">c</span>
</div>
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="d abs">d</span>
</div>
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="e abs">e</span>
</div>
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="f abs">f</span>
</div>
<div class="grid">
<span class="a">a</span>
<span class="a"></span>
<span class="g abs">g</span>
</div>

Some files were not shown because too many files have changed in this diff Show More