mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:25:44 +00:00
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:
@@ -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();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
box-sizing: padding-box;
|
||||
box-sizing: border-box;
|
||||
min-height: 100vh;
|
||||
padding: 0 48px;
|
||||
align-items: center;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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())) {
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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
@@ -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
|
||||
******************************************************************************/
|
||||
|
||||
@@ -220,6 +220,9 @@ private:
|
||||
|
||||
virtual bool
|
||||
DeallocPBlobStreamChild(PBlobStreamChild* aActor) override;
|
||||
|
||||
virtual bool
|
||||
RecvCreatedFromKnownBlob() override;
|
||||
};
|
||||
|
||||
// Only let ContentChild call BlobChild::Startup() and ensure that
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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,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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -30,7 +30,6 @@ public:
|
||||
bool& aIsHandlingUserInput,
|
||||
nsCOMPtr<nsIContent>& aCurrentEventContent);
|
||||
|
||||
static bool gPreventMouseEvents;
|
||||
static nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Touch>* gCaptureTouchList;
|
||||
|
||||
private:
|
||||
|
||||
@@ -106,7 +106,6 @@ EXPORTS.mozilla += [
|
||||
UNIFIED_SOURCES += [
|
||||
'AccessibleCaret.cpp',
|
||||
'AccessibleCaretEventHub.cpp',
|
||||
'AccessibleCaretLogger.cpp',
|
||||
'AccessibleCaretManager.cpp',
|
||||
'ActiveLayerTracker.cpp',
|
||||
'DisplayItemClip.cpp',
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<div style="display:flex; justify-content: stretch end">a
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -241,7 +241,7 @@ public:
|
||||
: nsDisplayBackgroundImage(aBuilder, aFrame, aLayer, aBg)
|
||||
{
|
||||
if (ShouldFixToViewport(aBuilder)) {
|
||||
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder);
|
||||
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()->
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -82,6 +82,7 @@ public:
|
||||
|
||||
nscoord mBase;
|
||||
nscoord mLimit;
|
||||
nscoord mPosition; // zero until we apply 'align/justify-content'
|
||||
StateBits mState;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user