mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1251797 - Don't fault struct out of rule tree if all of the potential physical property destinations already have a winning value in the cascade. r=heycam (b64f25ae75)
- Bug 1257688 part 0: Add an "IsLegacyBox" accessor to nsFlexContainerFrame, to enable special handling of display:-webkit-box & display:-webkit-inline-box. r=mats (f728070412)
- Bug 1257688 part 1: Change "-webkit-box-pack" & "-webkit-box-align" to alias their -moz equivalents, & change nsFlexContainerFrame to respect them in a -webkit-box. r=mats (fda7e641bb)
- Bug 1174248 - Apply RTL resizer failure only to GTK2. r=karlt (5f264b52bc)
- Bug 1234941 part 1: Add reftests for "-webkit-box" rendering, with -webkit-box-orient unset. r=heycam (bbdb2737a0)
- Bug 1234941 part 2: Add reftests for "-webkit-box" rendering, with -webkit-box-orient:horizontal. r=heycam (815f24f010)
- Bug 1234941 part 3: Add reftests for "-webkit-box" rendering, with -webkit-box-orient:vertical. r=heycam (a4f71266b9)
- Bug 1257688 part 2: Enable "-webkit-box-pack: justify" sections of -webkit-box reftests, & fix reference cases to use 'space-between' (the modern equivalent). (no review) (7641615ec0)
- Bug 1257688 part 3: Change "-webkit-box-ordinal-group" to alias its -moz equivalent, & change nsFlexContainerFrame to respect it in a -webkit-box. r=mats (90797264fe)
- Bug 1257688 part 4: Add reftests for -webkit-box-ordinal-group inside of display:-webkit-box. r=mats (7623b7a5dd)
- Bug 1257688 part 5: Change "-webkit-box-flex" to alias its -moz equivalent, & change nsFlexContainerFrame to use it instead of flex-shrink & flex-grow in a -webkit-box. r=mats (dabf0415f3)
- Bug 1257688 part 6: Add reftest for -webkit-box-flex inside of display:-webkit-box. r=mats (06d1384d0b)
- Bug 1257688 followup: Fix typo in <title>s in webkit-box-ordinal-group reftests. (no review, test-metadata only) (b8753af073)
- Bug 1262049 part 1: Back out bug 1208344 in its entirety, and mark -webkit-box-orient:vertical reftests as failing (for now). (no review) (fd3890a164)
- Bug 1262049 part 2: Add -webkit-box-orient & -webkit-box-direction as aliases for -moz versions, in the style system (but not yet honored by flexbox layout). r=mats (33e137427f)
- Bug 1262049 part 3: Refactor FlexboxAxisTracker constructor to take pointer to nsFlexContainerFrame. r=mats (0e9a26b85d)
- Bug 1262049 part 4: Refactor some of FlexboxAxisTracker constructor's logic into a helper method. r=mats (c298827ed2)
- Bug 1264837 Part 1 - Remove nsTextBoxFrameSuper. r=dholbert (dc64371da6)
- Bug 1264837 Part 2 - Remove nsColorControlFrameSuper. r=dholbert (166c5c13c3)
- Bug 1264837 Part 3 - Remove nsFormControlFrameSuper. r=dholbert (70c4c13c79)
- Bug 1264837 Part 4 - Remove nsImageControlFrameSuper. r=dholbert (68af4648e6)
- Bug 1264837 Part 5 - Remove nsFlexContainerFrameSuper. r=dholbert (ef7b1a912e)
- Bug 1261553 - Don't return from OnVisibilityChanged implementations without calling the superclass implementation. r=mstange (033d4cdf72)
- Bug 1264837 Part 6 - Remove ImageFrameSuper. r=dholbert (cbf002ba56)
- Bug 1264837 Part 7 - Remove nsInlineFrameBase r=dholbert (42e277593f)
- Bug 1262049 part 5: Honor -webkit-box-orient & -webkit-box-direction when determining axes for a -webkit-box flexbox. r=mats (a4f03722ed)
- Bug 1262049 part 6: Add reftest for -webkit-box-direction. (no review) (d41936d107)
- Bug 1266248 part 1: Rename MapSinglePropertyInto() args, to make src-vs-target distinctions clearer. r=heycam (2d46c21c34)
- Bug 1266248 part 2: Add assertion to verify that MapSinglePropertyInto() isn't called with a logical target-property. r=heycam (c51b780a2b)
- Bug 1264837 Part 8 - Remove nsPluginFrameSuper. r=dholbert (615738f0f0)
- Bug 1264837 Part 9 - Remove nsRubyBaseFrameSuper. r=dholbert (0fb30cf0a3)
- Bug 1264837 Part 10 - Remove nsRubyContentFrameSuper. r=dholbert (df02f9983c)
- Bug 1264837 Part 11 - Remove nsRubyFrameSuper. r=dholbert (684a20009b)
- Bug 1264837 Part 12 - Remove nsRubyTextContainerFrameSuper. r=dholbert (4961565c4b)
- Bug 1264837 Part 13 - Remove nsRubyTextFrameSuper. r=dholbert (aa9e863378)
- bits of 1261230 (cffbacd922)
- Bug 1264837 Part 14 - Remove nsSubDocumentFrameSuper. r=dholbert (2ddc0b2028)
- Bug 1264837 Part 15 - Remove nsVideoFrameBase r=dholbert (c1246fd0bc)
- Bug 1264837 Part 16 - Remove ViewportFrame::Super. r=dholbert (dff457b117)
- Bug 1264837 Part 17 - Remove nsSVGAFrameBase. r=dholbert (0df66e92c5)
- Bug 1253590, part 1 - Generalize AutoReferenceLoopDetector to allow it to be used to limit reference chain lengths. r=longsonr (e1673d2e9e)
- Bug 1253590, part 2 - Use the new AutoReferenceLimiter helper to limit clip path reference chain lengths. r=longsonr (4e03ec9001)
- Bug 1253590, part 3 - Crashtest for long clipPath reference chains. r=longsonr (c4da0e1dc4)
- Bug 1253590, part 4 - Follow-up to return the correct type. r=bustage (61c7fd965a)
- Bug 1264837 Part 18 - Remove nsSVGClipPathFrameBase. r=dholbert (ec78340590)
- Bug 1264837 Part 19 - Remove nsSVGContainerFrameBase. r=dholbert (57c5c44826)
- Bug 1264837 Part 20 - Remove nsSVGFilterFrameBase. r=dholbert (5f41a15a86)
- Bug 1264837 Part 21 - Remove nsSVGForeignObjectFrameBase. r=dholbert (c9aeb556ce)
- Bug 1264837 Part 22 - Remove nsSVGGenericContainerFrameBase. r=dholbert (bd4e21975d)
- Bug 1264837 Part 23 - Remove nsSVGGFrameBase. r=dholbert (bed40424fd)
- Bug 1264837 Part 24 - Remove nsSVGGradientFrameBase. r=dholbert (a9a7d3e0d4)
- Bug 1264837 Part 25 - Remove nsSVGLinearGradientFrameBase. r=dholbert (a48ed6b6b2)
- Bug 1264837 Part 26 - Remove nsSVGRadialGradientFrameBase. r=dholbert (76181ad3b2)
- Bug 1264837 Part 27 - Remove nsSVGImageFrameBase. r=dholbert (5aaa32517d)
- Bug 1242256 - ensure images in patterns and masks animate properly. r=jwatt,seth (cc40ee9520)
- Bug 1264837 Part 28 - Remove nsSVGInnerSVGFrameBase. r=dholbert (04b9d9b5fb)
- Bug 1264837 Part 29 - Remove nsSVGMarkerFrameBase. r=dholbert (bc28eca472)
- Bug 1264837 Part 30 - Remove nsSVGMarkerAnonChildFrameBase. r=dholbert (6898a93a31)
- Bug 1264837 Part 31 - Remove nsSVGMaskFrameBase. r=dholbert (26d0e7a5e1)
- Bug 1264837 Part 32 - Remove nsSVGOuterSVGFrameBase. r=dholbert (a473ae8be3)
- Bug 1264837 Part 33 - Remove nsSVGOuterSVGAnonChildFrameBase. r=dholbert (8c6cca5e9b)
- Bug 1264837 Part 34 - Remove nsSVGPaintServerFrameBase. r=dholbert (eab458bfab)
- Bug 1264837 Part 35 - Remove nsSVGPathGeometryFrameBase. r=dholbert (e5245d2be0)
- Bug 1264837 Part 36 - Remove nsSVGPatternFrameBase. r=dholbert (2df37d4056)
- Bug 1264837 Part 37 - Remove nsSVGStopFrameBase. r=dholbert (e367dba151)
- Bug 1264837 Part 38 - Remove nsSVGSwitchFrameBase. r=dholbert (7ffe7a731a)
- Bug 1264837 Part 39 - Remove nsSVGUseFrameBase. r=dholbert (b4445728e3)
- Bug 1264837 Part 40 - Remove SVGFEContainerFrameBase. r=dholbert (ee08ef9caf)
- Bug 1264837 Part 41 - Remove SVGFEImageFrameBase. r=dholbert (010f79b418)
- Bug 1264837 Part 42 - Remove SVGFELeafFrameBase. r=dholbert (949aeba02d)
- Bug 1264837 Part 44 - Remove SVGTextFrameBase. r=dholbert (bfd0603d44)
- Bug 1264837 Part 45 - Remove SVGViewFrameBase. r=dholbert (151f3c95b2)
- Bug 1265591 patch 1 - Remove Internal/External versions of ReconstructStyleData. r=heycam (a91f96e3b3)
- Bug 1265591 patch 2 - Rename nsIPresShell::ReconstructStyleData to RestyleForCSSRuleChanges. r=heycam (8ad2bc3021)
- Bug 1265591 patch 3 - Make the comment describing RestyleForCSSRuleChanges match reality. r=heycam (2ef053622d)
- Bug 1251150. Add crash annotations if image visibility is re-entering. r=mats (975a3e98d7)
- Bug 1261554 (Part 1) - Prepare for implementing in-displayport visibility tracking. r=mstange (b139489249)
- Bug 1261554 (Part 2) - Mark frames which are added to the display list when painting to the window as having Visibility::IN_DISPLAYPORT. r=mstange (4c8185bf0e)
- Bug 1259529 - Clean up the APZ minimap rendering code a bit. No functional changes. r=BenWa (9b99c27777)
- Bug 1256532 - Show the critical displayport in the APZ minimap as well. r=BenWa (9b131616a0)
- Bug 1251886 - Correct inputFrameID selection when using e10s r=daoshengmu (9e042f6af3)
- Bug 1261554 (Part 3) - Visualize Visibility::IN_DISPLAYPORT regions in the APZ minimap visibility debugger. r=botond (f9b72319e1)
- Bug 1261554 (Followup) - Fix memory reporting for PresShell::mVisibleRegions. r=me (6fc953c1de)
- Bug 1259529 - Ensure that the APZ minimap for subframes remains scaled to the visible portion of the composition bounds. r=BenWa (9f156773cf)
- Bug 1251150. Back out crash annotations used to try to diagnose crash. (db6ba80214)
- missing bits of Bug 1258476 - Optimize CreateRangePaintInfo by generating display lists for the minimum amount of range subtrees rather than for the range common ancestor. r=tn (2ded969082)
- Bug 1237821. Use displayport getter for image visibility in the (unused) display list builder based image visibility code. r=botond (a634182065)
- Bug 1253995 - Display stale image in nsImageFrame if we have a new src but haven't decoded it yet - r=seth (6add357448)
- Bug 1261703. When moving flex frame, position its view as well as any child views. r=dholbert (abd586f55f)
- bug 1246772 - work around x87 floating point truncation issues in gecko r=dholbert (de38865a9f)
- missing bits of 1202908 (4a254234f7)
- Bug 1249134: Remove support for -webkit-appearance as an alias for -moz-appearance, since the two prefixed properties behave differently in practice. r=heycam (7fd6826fb0)
- Bug 1249937 - Rename LayerComposite::SetShadowTransform to SetShadowBaseTransform. r=botond (c91f175b8d)
- Bug 1260335 - On perspective ContainerLayers, the clip deferred from their child layer needs to be affected by the perspective layer's async transforms. r=botond (ee1a19e113)
- Bug 1260335 - Add a comment that explains why the perspective child can't have more than one frame metrics. r=mattwoodrow (639d9ede24)
- Bug 1148978 - Remove plugin window update composition deferment. r=mattwoodrow (01e7da3570)
- Bug 1263515 - Destroy the compositor earlier in RecvWillStop when it still has a valid widget. r=jnicol (c14135bf7c)
- Bug 1258440 - Don't attempt to hide plugin windows when switching trees if the previous remote layer tree didn't contain plugin windows. Fixes a tpaint regression. r=mconley (929db2fdf2)
- Bug 1260976 - Make nsTransitionManager use Keyframe objects to set up transitions; r=heycam (3b8ef91fe9)
- Bug 1265611 - Make TransitionProperty() and ToValue() safe when mProperties is not set; r=heycam (37d234aad4)
- Bug 1259675 - Clean up InternalTransitionEvent r=masayuki (f6526d4dfa)
- Bug 1260976 - Remove some references to properties within nsTransitionManager; r=heycam (6c0f84fb17)
- Bug 1182856 - Part 4: Refactor code in nsTransitionManager::StyleContextChanged(). r=heycam (ee0f4d76fd)
- Bug 1182856 - Part 5: Avoid unnecessary transition update if display:none. r=heycam (5e01fff5cc)
- Bug 1182856 - Part 6: Revise tests for display:none in test_transitions.html. r=heycam (ac2dfe8e47)
- Bug 1182856 - Part 7: Test. r=cam (2aed7d5ae6)
- Bug 1265611 - Don't trigger transitions for properties that are disabled; r=heycam (dabf201421)
- Bug 1247533 - Annotate intentional switch fallthrough to suppress -Wimplicit-fallthrough warning in layout/style/. r=dbaron (a0b748bea2)
- Bug 1264830 - Part 1: Add an nsStyleAutoArray array type, similar to AutoTArray<...,1> but memmovable. r=bholley (ad4eb0692c)
- Bug 1264830 - Part 2: Change nsStyleImageLayers::mLayers to use nsStyleAutoArray. r=bholley (963a9e4033)
- Bug 1264830 - Part 3: Change nsStyleDisplay::{mTransitions,mAnimations} to use nsStyleAutoArray. r=bholley (396812da9d)
- Bug 1264830 - Part 4: Change nsStyleDisplay::mWillChange to use nsTArray. r=bholley (7dead8570f)
- Bug 1264830 - Part 5: Require all style structs be memmovable. r=bholley (8fdd844d1c)
- Bug 1244628: compare nsStyleImageLayers::mAttachmentCount in nsStyleImageLayers::CalcDifference. r=dbaron. (11e2bb1665)
- Bug 1252739 - nsStyleImageLayers::HasLayerWithImage should return true when we have mask-image:<element-reference> | <gradient>; r=dbaron (904b65a0e5)
- cleanup empty line (8263e0793e)
- Bug 1261392 - Define gettid for all Linux builds. r=bgirard (781ae95acc)
This commit is contained in:
@@ -7,4 +7,3 @@
|
||||
/ssltunnel
|
||||
/xpcshell
|
||||
/XUL
|
||||
|
||||
|
||||
@@ -285,9 +285,8 @@ nsImageLoadingContent::OnUnlockedDraw()
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame->GetVisibility() == Visibility::APPROXIMATELY_VISIBLE) {
|
||||
// This frame is already marked visible; there's nothing to do.
|
||||
return;
|
||||
if (frame->IsVisibleOrMayBecomeVisibleSoon()) {
|
||||
return; // Nothing to do.
|
||||
}
|
||||
|
||||
nsPresContext* presContext = frame->PresContext();
|
||||
@@ -300,7 +299,7 @@ nsImageLoadingContent::OnUnlockedDraw()
|
||||
return;
|
||||
}
|
||||
|
||||
presShell->EnsureFrameInApproximatelyVisibleList(frame);
|
||||
presShell->MarkFrameVisibleInDisplayPort(frame);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -527,7 +526,7 @@ nsImageLoadingContent::FrameDestroyed(nsIFrame* aFrame)
|
||||
|
||||
nsIPresShell* presShell = presContext ? presContext->GetPresShell() : nullptr;
|
||||
if (presShell) {
|
||||
presShell->RemoveFrameFromApproximatelyVisibleList(aFrame);
|
||||
presShell->MarkFrameNonvisible(aFrame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1423,12 +1422,13 @@ nsImageLoadingContent::OnVisibilityChange(Visibility aNewVisibility,
|
||||
const Maybe<OnNonvisible>& aNonvisibleAction)
|
||||
{
|
||||
switch (aNewVisibility) {
|
||||
case Visibility::APPROXIMATELY_VISIBLE:
|
||||
case Visibility::MAY_BECOME_VISIBLE:
|
||||
case Visibility::IN_DISPLAYPORT:
|
||||
TrackImage(mCurrentRequest);
|
||||
TrackImage(mPendingRequest);
|
||||
break;
|
||||
|
||||
case Visibility::APPROXIMATELY_NONVISIBLE:
|
||||
case Visibility::NONVISIBLE:
|
||||
UntrackImage(mCurrentRequest, aNonvisibleAction);
|
||||
UntrackImage(mPendingRequest, aNonvisibleAction);
|
||||
break;
|
||||
@@ -1454,11 +1454,11 @@ nsImageLoadingContent::TrackImage(imgIRequest* aImage)
|
||||
}
|
||||
|
||||
// We only want to track this request if we're visible. Ordinarily we check
|
||||
// the visible count, but that requires a frame; in cases where
|
||||
// whether our frame considers itself visible, but in cases where
|
||||
// GetOurPrimaryFrame() cannot obtain a frame (e.g. <feImage>), we assume
|
||||
// we're visible if FrameCreated() was called.
|
||||
nsIFrame* frame = GetOurPrimaryFrame();
|
||||
if ((frame && frame->GetVisibility() == Visibility::APPROXIMATELY_NONVISIBLE) ||
|
||||
if ((frame && !frame->IsVisibleOrMayBecomeVisibleSoon()) ||
|
||||
(!frame && !mFrameCreateCalled)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,9 +47,9 @@ TransitionEvent::Constructor(const GlobalObject& aGlobal,
|
||||
e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable);
|
||||
|
||||
InternalTransitionEvent* internalEvent = e->mEvent->AsTransitionEvent();
|
||||
internalEvent->propertyName = aParam.mPropertyName;
|
||||
internalEvent->elapsedTime = aParam.mElapsedTime;
|
||||
internalEvent->pseudoElement = aParam.mPseudoElement;
|
||||
internalEvent->mPropertyName = aParam.mPropertyName;
|
||||
internalEvent->mElapsedTime = aParam.mElapsedTime;
|
||||
internalEvent->mPseudoElement = aParam.mPseudoElement;
|
||||
|
||||
e->SetTrusted(trusted);
|
||||
return e.forget();
|
||||
@@ -58,7 +58,7 @@ TransitionEvent::Constructor(const GlobalObject& aGlobal,
|
||||
NS_IMETHODIMP
|
||||
TransitionEvent::GetPropertyName(nsAString& aPropertyName)
|
||||
{
|
||||
aPropertyName = mEvent->AsTransitionEvent()->propertyName;
|
||||
aPropertyName = mEvent->AsTransitionEvent()->mPropertyName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -72,13 +72,13 @@ TransitionEvent::GetElapsedTime(float* aElapsedTime)
|
||||
float
|
||||
TransitionEvent::ElapsedTime()
|
||||
{
|
||||
return mEvent->AsTransitionEvent()->elapsedTime;
|
||||
return mEvent->AsTransitionEvent()->mElapsedTime;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TransitionEvent::GetPseudoElement(nsAString& aPseudoElement)
|
||||
{
|
||||
aPseudoElement = mEvent->AsTransitionEvent()->pseudoElement;
|
||||
aPseudoElement = mEvent->AsTransitionEvent()->mPseudoElement;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -2657,7 +2657,7 @@ nsHTMLDocument::TearingDownEditor(nsIEditor *aEditor)
|
||||
|
||||
presShell->SetAgentStyleSheets(agentSheets);
|
||||
|
||||
presShell->ReconstructStyleData();
|
||||
presShell->RestyleForCSSRuleChanges();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2821,7 +2821,7 @@ nsHTMLDocument::EditingStateChanged()
|
||||
rv = presShell->SetAgentStyleSheets(agentSheets);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
presShell->ReconstructStyleData();
|
||||
presShell->RestyleForCSSRuleChanges();
|
||||
|
||||
// Adjust focused element with new style but blur event shouldn't be fired
|
||||
// until mEditingState is modified with newState.
|
||||
|
||||
@@ -72,3 +72,5 @@ load 880544-3.svg
|
||||
load 880544-4.svg
|
||||
load 880544-5.svg
|
||||
load 898915-1.svg
|
||||
# Disabled for now due to it taking a very long time to run - bug 1259356
|
||||
#load long-clipPath-reference-chain.svg
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<title>Test very long clipPath chain - MAY CRASH</title>
|
||||
<script><![CDATA[
|
||||
|
||||
// This script creates a very long chain of clipPath elements to test whether
|
||||
// that causes a stack overflow that crashes the UA. The first clipPath clips
|
||||
// to a 50x100 rect, the last to a 25x100 rect. If a UA was to apply the
|
||||
// entire clipPath chain (unlikely) a rect 25x100 would be rendered.
|
||||
//
|
||||
// At the time of writing, Firefox would treat the entire chain of clipPaths as
|
||||
// invalid due to its excessive length, and refuse to render the referencing
|
||||
// element at all. One alternative would be to ignore the clipPath reference
|
||||
// and render the referencing element without any clipping. Another
|
||||
// alternative would be to break the chain and clip the referencing element,
|
||||
// but only using the first X clipPaths in the chain (in which case a 50x100
|
||||
// rect would be rendered).
|
||||
|
||||
var chainLength = 100000;
|
||||
|
||||
var SVG_NS = "http://www.w3.org/2000/svg";
|
||||
var template = document.createElementNS(SVG_NS, "clipPath");
|
||||
var templatesRect = document.createElementNS(SVG_NS, "rect");
|
||||
templatesRect.setAttribute("width", "100");
|
||||
templatesRect.setAttribute("height", "100");
|
||||
template.appendChild(templatesRect);
|
||||
|
||||
function createClipPath(index) {
|
||||
var cp = template.cloneNode(true);
|
||||
cp.id = "c" + index;
|
||||
cp.setAttribute("clip-path", "url(#c" + (index + 1) + ")");
|
||||
return cp;
|
||||
}
|
||||
|
||||
var de = document.documentElement;
|
||||
|
||||
for (var i = chainLength; i > 0; --i) {
|
||||
var cp = createClipPath(i);
|
||||
|
||||
if (i == chainLength) {
|
||||
cp.firstChild.setAttribute("width", "25");
|
||||
}
|
||||
else if (i == 1) {
|
||||
cp.firstChild.setAttribute("width", "50");
|
||||
}
|
||||
|
||||
de.appendChild(cp);
|
||||
}
|
||||
|
||||
]]></script>
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
<!-- We don't expect the following element to render at all -->
|
||||
<rect width="500" height="500" clip-path="url(#c1)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -2879,7 +2879,7 @@ nsHTMLEditor::AddOverrideStyleSheet(const nsAString& aURL)
|
||||
// (This checks if already exists)
|
||||
ps->AddOverrideStyleSheet(sheet);
|
||||
|
||||
ps->ReconstructStyleData();
|
||||
ps->RestyleForCSSRuleChanges();
|
||||
|
||||
// Save as the last-loaded sheet
|
||||
mLastOverrideStyleSheetURL = aURL;
|
||||
@@ -2924,7 +2924,7 @@ nsHTMLEditor::RemoveOverrideStyleSheet(const nsAString &aURL)
|
||||
NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
ps->RemoveOverrideStyleSheet(sheet);
|
||||
ps->ReconstructStyleData();
|
||||
ps->RestyleForCSSRuleChanges();
|
||||
|
||||
// Remove it from our internal list
|
||||
return rv;
|
||||
|
||||
@@ -234,7 +234,7 @@ SetShadowTransform(Layer* aLayer, LayerToParentLayerMatrix4x4 aTransform)
|
||||
aTransform.PostScale(1.0f / aLayer->GetPostXScale(),
|
||||
1.0f / aLayer->GetPostYScale(),
|
||||
1);
|
||||
aLayer->AsLayerComposite()->SetShadowTransform(aTransform.ToUnknownMatrix());
|
||||
aLayer->AsLayerComposite()->SetShadowBaseTransform(aTransform.ToUnknownMatrix());
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -642,7 +642,7 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint)
|
||||
if (ContainerLayer* c = aLayer->AsContainerLayer()) {
|
||||
matrix.PostScale(c->GetInheritedXScale(), c->GetInheritedYScale(), 1);
|
||||
}
|
||||
layerComposite->SetShadowTransform(matrix);
|
||||
layerComposite->SetShadowBaseTransform(matrix);
|
||||
layerComposite->SetShadowTransformSetByAnimation(true);
|
||||
break;
|
||||
}
|
||||
@@ -811,6 +811,11 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer,
|
||||
// The final clip for the layer is the intersection of these clips.
|
||||
Maybe<ParentLayerIntRect> asyncClip = aLayer->GetClipRect();
|
||||
|
||||
// If we are a perspective transform ContainerLayer, apply the clip deferred
|
||||
// from our child (if there is any) before we iterate over our frame metrics,
|
||||
// because this clip is subject to all async transforms of this layer.
|
||||
asyncClip = IntersectMaybeRects(asyncClip, clipDeferredFromChildren);
|
||||
|
||||
// The transform of a mask layer is relative to the masked layer's parent
|
||||
// layer. So whenever we apply an async transform to a layer, we need to
|
||||
// apply that same transform to the layer's own mask layer.
|
||||
@@ -934,6 +939,12 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer,
|
||||
// our scroll clip to it instead of to this layer (see bug 1168263).
|
||||
// A layer with a perspective transform shouldn't have multiple
|
||||
// children with FrameMetrics, nor a child with multiple FrameMetrics.
|
||||
// (A child with multiple FrameMetrics would mean that there's *another*
|
||||
// scrollable element between the one with the CSS perspective and the
|
||||
// transformed element. But you'd have to use preserve-3d on the inner
|
||||
// scrollable element in order to have the perspective apply to the
|
||||
// transformed child, and preserve-3d is not supported on scrollable
|
||||
// elements, so this case can't occur.)
|
||||
MOZ_ASSERT(!aClipDeferredToParent);
|
||||
aClipDeferredToParent = Some(clip);
|
||||
} else {
|
||||
@@ -958,8 +969,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer,
|
||||
}
|
||||
|
||||
if (hasAsyncTransform || clipDeferredFromChildren) {
|
||||
aLayer->AsLayerComposite()->SetShadowClipRect(
|
||||
IntersectMaybeRects(asyncClip, clipDeferredFromChildren));
|
||||
aLayer->AsLayerComposite()->SetShadowClipRect(asyncClip);
|
||||
}
|
||||
|
||||
if (hasAsyncTransform) {
|
||||
@@ -1426,7 +1436,7 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
|
||||
|
||||
gfx::Matrix4x4 trans = rootComposite->GetShadowBaseTransform();
|
||||
trans *= gfx::Matrix4x4::From2D(mWorldTransform);
|
||||
rootComposite->SetShadowTransform(trans);
|
||||
rootComposite->SetShadowBaseTransform(trans);
|
||||
|
||||
if (gfxPrefs::CollectScrollTransforms()) {
|
||||
RecordShadowTransforms(root);
|
||||
|
||||
@@ -141,8 +141,7 @@ template<class ContainerT> void
|
||||
ContainerRenderVR(ContainerT* aContainer,
|
||||
LayerManagerComposite* aManager,
|
||||
const gfx::IntRect& aClipRect,
|
||||
RefPtr<gfx::VRHMDInfo> aHMD,
|
||||
int32_t aInputFrameID)
|
||||
RefPtr<gfx::VRHMDInfo> aHMD)
|
||||
{
|
||||
int32_t inputFrameID = -1;
|
||||
|
||||
@@ -273,11 +272,29 @@ ContainerRenderVR(ContainerT* aContainer,
|
||||
surfaceRect.width, surfaceRect.height));
|
||||
layerToRender->RenderLayer(surfaceRect);
|
||||
|
||||
CompositableHost *ch = layerToRender->GetCompositableHost();
|
||||
if (ch) {
|
||||
int32_t compositableInputFrameID = ch->GetLastInputFrameID();
|
||||
if (compositableInputFrameID != -1) {
|
||||
inputFrameID = compositableInputFrameID;
|
||||
// Search all children recursively until we find the canvas with
|
||||
// an inputFrameID
|
||||
std::stack<LayerComposite*> searchLayers;
|
||||
searchLayers.push(layerToRender);
|
||||
while (!searchLayers.empty() && inputFrameID == -1) {
|
||||
LayerComposite* searchLayer = searchLayers.top();
|
||||
searchLayers.pop();
|
||||
if (searchLayer) {
|
||||
searchLayers.push(searchLayer->GetFirstChildComposite());
|
||||
Layer* sibling = searchLayer->GetLayer();
|
||||
if (sibling) {
|
||||
sibling = sibling->GetNextSibling();
|
||||
}
|
||||
if (sibling) {
|
||||
searchLayers.push(sibling->AsLayerComposite());
|
||||
}
|
||||
CompositableHost *ch = searchLayer->GetCompositableHost();
|
||||
if (ch) {
|
||||
int32_t compositableInputFrameID = ch->GetLastInputFrameID();
|
||||
if (compositableInputFrameID != -1) {
|
||||
inputFrameID = compositableInputFrameID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,6 +474,22 @@ ContainerPrepare(ContainerT* aContainer,
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RectPainter> void
|
||||
DrawRegion(CSSIntRegion* aRegion,
|
||||
gfx::Color aColor,
|
||||
const RectPainter& aRectPainter)
|
||||
{
|
||||
MOZ_ASSERT(aRegion);
|
||||
|
||||
// Iterate through and draw the rects in the region using the provided lambda.
|
||||
for (CSSIntRegion::RectIterator iterator = aRegion->RectIter();
|
||||
!iterator.Done();
|
||||
iterator.Next())
|
||||
{
|
||||
aRectPainter(iterator.Get(), aColor);
|
||||
}
|
||||
}
|
||||
|
||||
template<class ContainerT> void
|
||||
RenderMinimap(ContainerT* aContainer, LayerManagerComposite* aManager,
|
||||
const RenderTargetIntRect& aClipRect, Layer* aLayer)
|
||||
@@ -481,9 +514,11 @@ RenderMinimap(ContainerT* aContainer, LayerManagerComposite* aManager,
|
||||
gfx::Color tileActiveColor(1, 1, 1, 0.4f);
|
||||
gfx::Color tileBorderColor(0, 0, 0, 0.1f);
|
||||
gfx::Color pageBorderColor(0, 0, 0);
|
||||
gfx::Color criticalDisplayPortColor(1.f, 1.f, 0);
|
||||
gfx::Color displayPortColor(0, 1.f, 0);
|
||||
gfx::Color viewPortColor(0, 0, 1.f, 0.3f);
|
||||
gfx::Color visibilityColor(1.f, 0, 0);
|
||||
gfx::Color approxVisibilityColor(1.f, 0, 0);
|
||||
gfx::Color inDisplayPortVisibilityColor(1.f, 1.f, 0);
|
||||
|
||||
// Rects
|
||||
const FrameMetrics& fm = aLayer->GetFrameMetrics(0);
|
||||
@@ -491,6 +526,10 @@ RenderMinimap(ContainerT* aContainer, LayerManagerComposite* aManager,
|
||||
LayerRect scrollRect = fm.GetScrollableRect() * fm.LayersPixelsPerCSSPixel();
|
||||
LayerRect viewRect = ParentLayerRect(scrollOffset, compositionBounds.Size()) / LayerToParentLayerScale(1);
|
||||
LayerRect dp = (fm.GetDisplayPort() + fm.GetScrollOffset()) * fm.LayersPixelsPerCSSPixel();
|
||||
Maybe<LayerRect> cdp;
|
||||
if (!fm.GetCriticalDisplayPort().IsEmpty()) {
|
||||
cdp = Some((fm.GetCriticalDisplayPort() + fm.GetScrollOffset()) * fm.LayersPixelsPerCSSPixel());
|
||||
}
|
||||
|
||||
// Don't render trivial minimap. They can show up from textboxes and other tiny frames.
|
||||
if (viewRect.width < 64 && viewRect.height < 64) {
|
||||
@@ -502,41 +541,32 @@ RenderMinimap(ContainerT* aContainer, LayerManagerComposite* aManager,
|
||||
float scaleFactor;
|
||||
float scaleFactorX;
|
||||
float scaleFactorY;
|
||||
scaleFactorX = 100.f / scrollRect.width;
|
||||
scaleFactorY = ((viewRect.height) - 2 * verticalPadding) / scrollRect.height;
|
||||
Rect dest = Rect(aClipRect.ToUnknownRect());
|
||||
if (aLayer->GetEffectiveClipRect()) {
|
||||
dest = Rect(aLayer->GetEffectiveClipRect().value().ToUnknownRect());
|
||||
} else {
|
||||
dest = aContainer->GetEffectiveTransform().Inverse().TransformBounds(dest);
|
||||
}
|
||||
dest = dest.Intersect(compositionBounds.ToUnknownRect());
|
||||
scaleFactorX = std::min(100.f, dest.width - (2 * horizontalPadding)) / scrollRect.width;
|
||||
scaleFactorY = (dest.height - (2 * verticalPadding)) / scrollRect.height;
|
||||
scaleFactor = std::min(scaleFactorX, scaleFactorY);
|
||||
if (scaleFactor <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Matrix4x4 transform = Matrix4x4::Scaling(scaleFactor, scaleFactor, 1);
|
||||
transform.PostTranslate(horizontalPadding + compositionBounds.x, verticalPadding + compositionBounds.y, 0);
|
||||
transform.PostTranslate(horizontalPadding + dest.x, verticalPadding + dest.y, 0);
|
||||
|
||||
Rect clipRect = aContainer->GetEffectiveTransform().TransformBounds(
|
||||
transform.TransformBounds(scrollRect.ToUnknownRect()));
|
||||
Rect transformedScrollRect = transform.TransformBounds(scrollRect.ToUnknownRect());
|
||||
|
||||
Rect clipRect = aContainer->GetEffectiveTransform().TransformBounds(transformedScrollRect);
|
||||
clipRect.width++;
|
||||
clipRect.height++;
|
||||
|
||||
Rect r;
|
||||
r = transform.TransformBounds(scrollRect.ToUnknownRect());
|
||||
compositor->FillRect(r, backgroundColor, clipRect, aContainer->GetEffectiveTransform());
|
||||
|
||||
/* Disabled because on long pages SlowDrawRect becomes a bottleneck.
|
||||
int tileW = gfxPrefs::LayersTileWidth();
|
||||
int tileH = gfxPrefs::LayersTileHeight();
|
||||
|
||||
for (int x = scrollRect.x; x < scrollRect.XMost(); x += tileW) {
|
||||
for (int y = scrollRect.y; y < scrollRect.YMost(); y += tileH) {
|
||||
LayerRect tileRect = LayerRect(x - x % tileW, y - y % tileH, tileW, tileH);
|
||||
r = transform.TransformBounds(tileRect.ToUnknownRect());
|
||||
if (tileRect.Intersects(dp)) {
|
||||
compositor->FillRect(r, tileActiveColor, clipRect, aContainer->GetEffectiveTransform());
|
||||
}
|
||||
compositor->SlowDrawRect(r, tileBorderColor, clipRect, aContainer->GetEffectiveTransform());
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Render the scrollable area.
|
||||
r = transform.TransformBounds(scrollRect.ToUnknownRect());
|
||||
compositor->SlowDrawRect(r, pageBorderColor, clipRect, aContainer->GetEffectiveTransform());
|
||||
compositor->FillRect(transformedScrollRect, backgroundColor, clipRect, aContainer->GetEffectiveTransform());
|
||||
compositor->SlowDrawRect(transformedScrollRect, pageBorderColor, clipRect, aContainer->GetEffectiveTransform());
|
||||
|
||||
// If enabled, render information about visibility.
|
||||
if (gfxPrefs::APZMinimapVisibilityEnabled()) {
|
||||
@@ -547,31 +577,34 @@ RenderMinimap(ContainerT* aContainer, LayerManagerComposite* aManager,
|
||||
|
||||
ScrollableLayerGuid guid = controller->GetGuid();
|
||||
|
||||
// Get the approximately visible region.
|
||||
static CSSIntRegion emptyRegion;
|
||||
CSSIntRegion* visibleRegion = aManager->GetApproximatelyVisibleRegion(guid);
|
||||
if (!visibleRegion) {
|
||||
visibleRegion = &emptyRegion;
|
||||
}
|
||||
|
||||
// Iterate through and draw the rects in the region.
|
||||
for (CSSIntRegion::RectIterator iterator = visibleRegion->RectIter();
|
||||
!iterator.Done();
|
||||
iterator.Next())
|
||||
{
|
||||
CSSIntRect rect = iterator.Get();
|
||||
LayerRect scaledRect = rect * fm.LayersPixelsPerCSSPixel();
|
||||
auto rectPainter = [&](const CSSIntRect& aRect, const gfx::Color& aColor) {
|
||||
LayerRect scaledRect = aRect * fm.LayersPixelsPerCSSPixel();
|
||||
Rect r = transform.TransformBounds(scaledRect.ToUnknownRect());
|
||||
compositor->FillRect(r, visibilityColor, clipRect, aContainer->GetEffectiveTransform());
|
||||
}
|
||||
compositor->FillRect(r, aColor, clipRect, aContainer->GetEffectiveTransform());
|
||||
};
|
||||
|
||||
// Draw the approximately visible region.
|
||||
CSSIntRegion* approxVisibleRegion =
|
||||
aManager->GetVisibleRegion(VisibilityCounter::MAY_BECOME_VISIBLE, guid);
|
||||
DrawRegion(approxVisibleRegion, approxVisibilityColor, rectPainter);
|
||||
|
||||
// Draw the in-displayport visible region.
|
||||
CSSIntRegion* inDisplayPortVisibleRegion =
|
||||
aManager->GetVisibleRegion(VisibilityCounter::IN_DISPLAYPORT, guid);
|
||||
DrawRegion(inDisplayPortVisibleRegion, inDisplayPortVisibilityColor, rectPainter);
|
||||
}
|
||||
|
||||
// Render the displayport.
|
||||
r = transform.TransformBounds(dp.ToUnknownRect());
|
||||
Rect r = transform.TransformBounds(dp.ToUnknownRect());
|
||||
compositor->FillRect(r, tileActiveColor, clipRect, aContainer->GetEffectiveTransform());
|
||||
r = transform.TransformBounds(dp.ToUnknownRect());
|
||||
compositor->SlowDrawRect(r, displayPortColor, clipRect, aContainer->GetEffectiveTransform());
|
||||
|
||||
// Render the critical displayport if there is one
|
||||
if (cdp) {
|
||||
r = transform.TransformBounds(cdp->ToUnknownRect());
|
||||
compositor->SlowDrawRect(r, criticalDisplayPortColor, clipRect, aContainer->GetEffectiveTransform());
|
||||
}
|
||||
|
||||
// Render the viewport.
|
||||
r = transform.TransformBounds(viewRect.ToUnknownRect());
|
||||
compositor->SlowDrawRect(r, viewPortColor, clipRect, aContainer->GetEffectiveTransform(), 2);
|
||||
@@ -750,7 +783,7 @@ ContainerRender(ContainerT* aContainer,
|
||||
|
||||
RefPtr<gfx::VRHMDInfo> hmdInfo = gfx::VRManager::Get()->GetDevice(aContainer->GetVRDeviceID());
|
||||
if (hmdInfo && hmdInfo->GetConfiguration().IsValid()) {
|
||||
ContainerRenderVR(aContainer, aManager, aClipRect, hmdInfo, aContainer->GetInputFrameID());
|
||||
ContainerRenderVR(aContainer, aManager, aClipRect, hmdInfo);
|
||||
aContainer->mPrepared = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "nsRegion.h" // for nsIntRegion
|
||||
#include "nscore.h" // for nsAString, etc
|
||||
#include "LayerTreeInvalidation.h"
|
||||
#include "Visibility.h"
|
||||
|
||||
class gfxContext;
|
||||
|
||||
@@ -219,10 +220,17 @@ public:
|
||||
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
||||
}
|
||||
|
||||
void ClearApproximatelyVisibleRegions(uint64_t aLayersId,
|
||||
const Maybe<uint32_t>& aPresShellId)
|
||||
void ClearVisibleRegions(uint64_t aLayersId,
|
||||
const Maybe<uint32_t>& aPresShellId)
|
||||
{
|
||||
for (auto iter = mVisibleRegions.Iter(); !iter.Done(); iter.Next()) {
|
||||
for (auto iter = mApproximatelyVisibleRegions.Iter(); !iter.Done(); iter.Next()) {
|
||||
if (iter.Key().mLayersId == aLayersId &&
|
||||
(!aPresShellId || iter.Key().mPresShellId == *aPresShellId)) {
|
||||
iter.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto iter = mInDisplayPortVisibleRegions.Iter(); !iter.Done(); iter.Next()) {
|
||||
if (iter.Key().mLayersId == aLayersId &&
|
||||
(!aPresShellId || iter.Key().mPresShellId == *aPresShellId)) {
|
||||
iter.Remove();
|
||||
@@ -230,18 +238,35 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion)
|
||||
void UpdateVisibleRegion(VisibilityCounter aCounter,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion)
|
||||
{
|
||||
CSSIntRegion* regionForScrollFrame = mVisibleRegions.LookupOrAdd(aGuid);
|
||||
VisibleRegions& regions = aCounter == VisibilityCounter::MAY_BECOME_VISIBLE
|
||||
? mApproximatelyVisibleRegions
|
||||
: mInDisplayPortVisibleRegions;
|
||||
|
||||
CSSIntRegion* regionForScrollFrame = regions.LookupOrAdd(aGuid);
|
||||
MOZ_ASSERT(regionForScrollFrame);
|
||||
|
||||
*regionForScrollFrame = aRegion;
|
||||
}
|
||||
|
||||
CSSIntRegion* GetApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid)
|
||||
CSSIntRegion* GetVisibleRegion(VisibilityCounter aCounter,
|
||||
const ScrollableLayerGuid& aGuid)
|
||||
{
|
||||
return mVisibleRegions.Get(aGuid);
|
||||
static CSSIntRegion emptyRegion;
|
||||
|
||||
VisibleRegions& regions = aCounter == VisibilityCounter::MAY_BECOME_VISIBLE
|
||||
? mApproximatelyVisibleRegions
|
||||
: mInDisplayPortVisibleRegions;
|
||||
|
||||
CSSIntRegion* region = regions.Get(aGuid);
|
||||
if (!region) {
|
||||
region = &emptyRegion;
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
Compositor* GetCompositor() const
|
||||
@@ -382,7 +407,8 @@ private:
|
||||
|
||||
typedef nsClassHashtable<nsGenericHashKey<ScrollableLayerGuid>,
|
||||
CSSIntRegion> VisibleRegions;
|
||||
VisibleRegions mVisibleRegions;
|
||||
VisibleRegions mApproximatelyVisibleRegions;
|
||||
VisibleRegions mInDisplayPortVisibleRegions;
|
||||
|
||||
UniquePtr<FPSState> mFPS;
|
||||
|
||||
@@ -491,7 +517,7 @@ public:
|
||||
mShadowClipRect = aRect;
|
||||
}
|
||||
|
||||
void SetShadowTransform(const gfx::Matrix4x4& aMatrix)
|
||||
void SetShadowBaseTransform(const gfx::Matrix4x4& aMatrix)
|
||||
{
|
||||
mShadowTransform = aMatrix;
|
||||
}
|
||||
|
||||
@@ -727,29 +727,28 @@ CompositorBridgeChild::SendRequestNotifyAfterRemotePaint()
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeChild::SendClearApproximatelyVisibleRegions(uint64_t aLayersId,
|
||||
uint32_t aPresShellId)
|
||||
CompositorBridgeChild::SendClearVisibleRegions(uint64_t aLayersId,
|
||||
uint32_t aPresShellId)
|
||||
{
|
||||
MOZ_ASSERT(mCanSend);
|
||||
if (!mCanSend) {
|
||||
return true;
|
||||
}
|
||||
return PCompositorBridgeChild::SendClearApproximatelyVisibleRegions(aLayersId,
|
||||
aPresShellId);
|
||||
return PCompositorBridgeChild::SendClearVisibleRegions(aLayersId, aPresShellId);
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeChild::SendNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion)
|
||||
CompositorBridgeChild::SendUpdateVisibleRegion(VisibilityCounter aCounter,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion)
|
||||
{
|
||||
MOZ_ASSERT(mCanSend);
|
||||
if (!mCanSend) {
|
||||
return true;
|
||||
}
|
||||
return PCompositorBridgeChild::SendNotifyApproximatelyVisibleRegion(aGuid, aRegion);
|
||||
return PCompositorBridgeChild::SendUpdateVisibleRegion(aCounter, aGuid, aRegion);
|
||||
}
|
||||
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
@@ -126,9 +126,10 @@ public:
|
||||
bool SendStopFrameTimeRecording(const uint32_t& startIndex, nsTArray<float>* intervals);
|
||||
bool SendNotifyRegionInvalidated(const nsIntRegion& region);
|
||||
bool SendRequestNotifyAfterRemotePaint();
|
||||
bool SendClearApproximatelyVisibleRegions(uint64_t aLayersId, uint32_t aPresShellId);
|
||||
bool SendNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
|
||||
const mozilla::CSSIntRegion& aRegion);
|
||||
bool SendClearVisibleRegions(uint64_t aLayersId, uint32_t aPresShellId);
|
||||
bool SendUpdateVisibleRegion(VisibilityCounter aCounter,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const mozilla::CSSIntRegion& aRegion);
|
||||
bool IsSameProcess() const;
|
||||
|
||||
static void ShutDown();
|
||||
|
||||
@@ -701,7 +701,6 @@ CompositorBridgeParent::CompositorBridgeParent(nsIWidget* aWidget,
|
||||
, mCompositorScheduler(nullptr)
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
||||
, mLastPluginUpdateLayerTreeId(0)
|
||||
, mPluginUpdateResponsePending(false)
|
||||
, mDeferPluginWindows(false)
|
||||
, mPluginWindowsHidden(false)
|
||||
#endif
|
||||
@@ -785,6 +784,8 @@ CompositorBridgeParent::RecvWillClose()
|
||||
|
||||
if (mCompositor) {
|
||||
mCompositor->DetachWidget();
|
||||
mCompositor->Destroy();
|
||||
mCompositor = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -897,19 +898,19 @@ CompositorBridgeParent::RecvStopFrameTimeRecording(const uint32_t& aStartIndex,
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeParent::RecvClearApproximatelyVisibleRegions(const uint64_t& aLayersId,
|
||||
const uint32_t& aPresShellId)
|
||||
CompositorBridgeParent::RecvClearVisibleRegions(const uint64_t& aLayersId,
|
||||
const uint32_t& aPresShellId)
|
||||
{
|
||||
ClearApproximatelyVisibleRegions(aLayersId, Some(aPresShellId));
|
||||
ClearVisibleRegions(aLayersId, Some(aPresShellId));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeParent::ClearApproximatelyVisibleRegions(const uint64_t& aLayersId,
|
||||
const Maybe<uint32_t>& aPresShellId)
|
||||
CompositorBridgeParent::ClearVisibleRegions(const uint64_t& aLayersId,
|
||||
const Maybe<uint32_t>& aPresShellId)
|
||||
{
|
||||
if (mLayerManager) {
|
||||
mLayerManager->ClearApproximatelyVisibleRegions(aLayersId, aPresShellId);
|
||||
mLayerManager->ClearVisibleRegions(aLayersId, aPresShellId);
|
||||
|
||||
// We need to recomposite to update the minimap.
|
||||
ScheduleComposition();
|
||||
@@ -917,16 +918,25 @@ CompositorBridgeParent::ClearApproximatelyVisibleRegions(const uint64_t& aLayers
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorBridgeParent::RecvNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion)
|
||||
CompositorBridgeParent::RecvUpdateVisibleRegion(const VisibilityCounter& aCounter,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion)
|
||||
{
|
||||
UpdateVisibleRegion(aCounter, aGuid, aRegion);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeParent::UpdateVisibleRegion(const VisibilityCounter& aCounter,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion)
|
||||
{
|
||||
if (mLayerManager) {
|
||||
mLayerManager->UpdateApproximatelyVisibleRegion(aGuid, aRegion);
|
||||
mLayerManager->UpdateVisibleRegion(aCounter, aGuid, aRegion);
|
||||
|
||||
// We need to recomposite to update the minimap.
|
||||
ScheduleComposition();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1175,7 +1185,7 @@ CompositorBridgeParent::SetShadowProperties(Layer* aLayer)
|
||||
// FIXME: Bug 717688 -- Do these updates in LayerTransactionParent::RecvUpdate.
|
||||
LayerComposite* layerComposite = aLayer->AsLayerComposite();
|
||||
// Set the layerComposite's base transform to the layer's base transform.
|
||||
layerComposite->SetShadowTransform(aLayer->GetBaseTransform());
|
||||
layerComposite->SetShadowBaseTransform(aLayer->GetBaseTransform());
|
||||
layerComposite->SetShadowTransformSetByAnimation(false);
|
||||
layerComposite->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
|
||||
layerComposite->SetShadowClipRect(aLayer->GetClipRect());
|
||||
@@ -1213,20 +1223,6 @@ CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRec
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
||||
// Still waiting on plugin update confirmation
|
||||
if (mPluginUpdateResponsePending) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hasRemoteContent = false;
|
||||
bool pluginsUpdatedFlag = true;
|
||||
AutoResolveRefLayers resolve(mCompositionManager, this,
|
||||
&hasRemoteContent,
|
||||
&pluginsUpdatedFlag);
|
||||
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
||||
/*
|
||||
* AutoResolveRefLayers handles two tasks related to Windows and Linux
|
||||
* plugin window management:
|
||||
@@ -1239,27 +1235,20 @@ CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRec
|
||||
* since plugin clipping can depend on chrome (for example, due to tab modal
|
||||
* prompts). Updates in step 2 are applied via an async ipc message sent
|
||||
* to the main thread.
|
||||
* Windows specific: The compositor will wait for confirmation that plugin
|
||||
* updates have been applied before painting. Deferment of painting is
|
||||
* indicated by the mPluginUpdateResponsePending flag. The main thread
|
||||
* messages back using the RemotePluginsReady async ipc message.
|
||||
* This is neccessary since plugin windows can leave remnants of window
|
||||
* content if moved after the underlying window paints.
|
||||
*/
|
||||
if (pluginsUpdatedFlag) {
|
||||
mPluginUpdateResponsePending = true;
|
||||
return;
|
||||
}
|
||||
bool hasRemoteContent = false;
|
||||
bool updatePluginsFlag = true;
|
||||
AutoResolveRefLayers resolve(mCompositionManager, this,
|
||||
&hasRemoteContent,
|
||||
&updatePluginsFlag);
|
||||
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
||||
// We do not support plugins in local content. When switching tabs
|
||||
// to local pages, hide every plugin associated with the window.
|
||||
if (!hasRemoteContent && BrowserTabsRemoteAutostart() &&
|
||||
mCachedPluginData.Length()) {
|
||||
Unused << SendHideAllPlugins((uintptr_t)GetWidget());
|
||||
mCachedPluginData.Clear();
|
||||
// Wait for confirmation the hide operation is complete.
|
||||
mPluginUpdateResponsePending = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1343,7 +1332,6 @@ bool
|
||||
CompositorBridgeParent::RecvRemotePluginsReady()
|
||||
{
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
|
||||
mPluginUpdateResponsePending = false;
|
||||
ScheduleComposition();
|
||||
return true;
|
||||
#else
|
||||
@@ -1770,7 +1758,7 @@ EraseLayerState(uint64_t aId)
|
||||
if (iter != sIndirectLayerTrees.end()) {
|
||||
CompositorBridgeParent* parent = iter->second.mParent;
|
||||
if (parent) {
|
||||
parent->ClearApproximatelyVisibleRegions(aId, Nothing());
|
||||
parent->ClearVisibleRegions(aId, Nothing());
|
||||
}
|
||||
|
||||
sIndirectLayerTrees.erase(iter);
|
||||
@@ -1953,31 +1941,38 @@ public:
|
||||
virtual bool RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex) override { return true; }
|
||||
virtual bool RecvStopFrameTimeRecording(const uint32_t& aStartIndex, InfallibleTArray<float>* intervals) override { return true; }
|
||||
|
||||
virtual bool RecvClearApproximatelyVisibleRegions(const uint64_t& aLayersId,
|
||||
const uint32_t& aPresShellId) override
|
||||
virtual bool RecvClearVisibleRegions(const uint64_t& aLayersId,
|
||||
const uint32_t& aPresShellId) override
|
||||
{
|
||||
CompositorBridgeParent* parent;
|
||||
{ // scope lock
|
||||
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||
parent = sIndirectLayerTrees[aLayersId].mParent;
|
||||
}
|
||||
if (parent) {
|
||||
parent->ClearApproximatelyVisibleRegions(aLayersId, Some(aPresShellId));
|
||||
|
||||
if (!parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parent->ClearVisibleRegions(aLayersId, Some(aPresShellId));
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool RecvNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion) override
|
||||
virtual bool RecvUpdateVisibleRegion(const VisibilityCounter& aCounter,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion) override
|
||||
{
|
||||
CompositorBridgeParent* parent;
|
||||
{ // scope lock
|
||||
MonitorAutoLock lock(*sIndirectLayerTreesLock);
|
||||
parent = sIndirectLayerTrees[aGuid.mLayersId].mParent;
|
||||
}
|
||||
if (parent) {
|
||||
return parent->RecvNotifyApproximatelyVisibleRegion(aGuid, aRegion);
|
||||
|
||||
if (!parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parent->UpdateVisibleRegion(aCounter, aGuid, aRegion);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2474,6 +2469,11 @@ CompositorBridgeParent::UpdatePluginWindowState(uint64_t aId)
|
||||
}
|
||||
|
||||
if (!lts.mPluginData.Length()) {
|
||||
// Don't hide plugins if the previous remote layer tree didn't contain any.
|
||||
if (!mCachedPluginData.Length()) {
|
||||
PLUGINS_LOG("[%" PRIu64 "] nothing to hide", aId);
|
||||
return false;
|
||||
}
|
||||
// We will pass through here in cases where the previous shadow layer
|
||||
// tree contained visible plugins and the new tree does not. All we need
|
||||
// to do here is hide the plugins for the old tree, so don't waste time
|
||||
@@ -2562,7 +2562,6 @@ CompositorBridgeParent::HideAllPluginWindows()
|
||||
return;
|
||||
}
|
||||
mDeferPluginWindows = true;
|
||||
mPluginUpdateResponsePending = true;
|
||||
mPluginWindowsHidden = true;
|
||||
Unused << SendHideAllPlugins((uintptr_t)GetWidget());
|
||||
ScheduleComposition();
|
||||
|
||||
@@ -258,12 +258,16 @@ public:
|
||||
// @see CrossProcessCompositorBridgeParent::RecvRequestNotifyAfterRemotePaint
|
||||
virtual bool RecvRequestNotifyAfterRemotePaint() override { return true; };
|
||||
|
||||
virtual bool RecvClearApproximatelyVisibleRegions(const uint64_t& aLayersId,
|
||||
const uint32_t& aPresShellId) override;
|
||||
void ClearApproximatelyVisibleRegions(const uint64_t& aLayersId,
|
||||
const Maybe<uint32_t>& aPresShellId);
|
||||
virtual bool RecvNotifyApproximatelyVisibleRegion(const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion) override;
|
||||
virtual bool RecvClearVisibleRegions(const uint64_t& aLayersId,
|
||||
const uint32_t& aPresShellId) override;
|
||||
void ClearVisibleRegions(const uint64_t& aLayersId,
|
||||
const Maybe<uint32_t>& aPresShellId);
|
||||
virtual bool RecvUpdateVisibleRegion(const VisibilityCounter& aCounter,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion) override;
|
||||
void UpdateVisibleRegion(const VisibilityCounter& aCounter,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const CSSIntRegion& aRegion);
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
||||
@@ -599,9 +603,6 @@ protected:
|
||||
nsIntPoint mPluginsLayerOffset;
|
||||
nsIntRegion mPluginsLayerVisibleRegion;
|
||||
nsTArray<PluginWindowData> mCachedPluginData;
|
||||
// indicates if we are currently waiting on a plugin update confirmation.
|
||||
// When this is true, composition is currently on hold.
|
||||
bool mPluginUpdateResponsePending;
|
||||
// indicates if plugin window visibility and metric updates are currently
|
||||
// being defered due to a scroll operation.
|
||||
bool mDeferPluginWindows;
|
||||
|
||||
@@ -25,6 +25,7 @@ using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasi
|
||||
using mozilla::CSSIntRegion from "Units.h";
|
||||
using mozilla::LayoutDeviceIntPoint from "Units.h";
|
||||
using mozilla::LayoutDeviceIntRegion from "Units.h";
|
||||
using mozilla::VisibilityCounter from "VisibilityIPC.h";
|
||||
using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
|
||||
using class mozilla::layers::FrameUniformityData from "mozilla/layers/FrameUniformityData.h";
|
||||
|
||||
@@ -173,15 +174,18 @@ parent:
|
||||
*/
|
||||
async RequestNotifyAfterRemotePaint();
|
||||
|
||||
// The child clears the 'approximately visible' regions associated with the
|
||||
// provided layers ID and pres shell ID (i.e., the regions for all view IDs
|
||||
// associated with those IDs).
|
||||
async ClearApproximatelyVisibleRegions(uint64_t layersId, uint32_t presShellId);
|
||||
// The child sends a request to clear the visible regions (approximate,
|
||||
// in-displayport, etc.) associated with the provided layers ID and pres shell
|
||||
// ID (i.e., the regions for all view IDs associated with those IDs).
|
||||
async ClearVisibleRegions(uint64_t layersId, uint32_t presShellId);
|
||||
|
||||
// The child sends a region containing rects associated with the provided
|
||||
// scrollable layer GUID that the child considers 'approximately visible'.
|
||||
// scrollable layer GUID that the child considers visible in the sense
|
||||
// specified by |counter|.
|
||||
// We visualize this information in the APZ minimap.
|
||||
async NotifyApproximatelyVisibleRegion(ScrollableLayerGuid guid, CSSIntRegion region);
|
||||
async UpdateVisibleRegion(VisibilityCounter counter,
|
||||
ScrollableLayerGuid guid,
|
||||
CSSIntRegion region);
|
||||
|
||||
child:
|
||||
// Send back Compositor Frame Metrics from APZCs so tiled layers can
|
||||
|
||||
@@ -526,6 +526,12 @@ HMDInfoOculus::SubmitFrame(RenderTargetSet *aRTSet, int32_t aInputFrameID)
|
||||
RenderTargetSetOculus *rts = static_cast<RenderTargetSetOculus*>(aRTSet);
|
||||
MOZ_ASSERT(rts->hmd != nullptr);
|
||||
MOZ_ASSERT(rts->textureSet != nullptr);
|
||||
MOZ_ASSERT(aInputFrameID >= 0);
|
||||
if (aInputFrameID < 0) {
|
||||
// Sanity check to prevent invalid memory access on builds with assertions
|
||||
// disabled.
|
||||
aInputFrameID = 0;
|
||||
}
|
||||
|
||||
VRHMDSensorState sensorState = mLastSensorState[aInputFrameID % kMaxLatencyFrames];
|
||||
// It is possible to get a cache miss on mLastSensorState if latency is
|
||||
@@ -535,6 +541,7 @@ HMDInfoOculus::SubmitFrame(RenderTargetSet *aRTSet, int32_t aInputFrameID)
|
||||
// un-viewable and a more accurate pose prediction is not likely to
|
||||
// compensate.
|
||||
ovrLayerEyeFov layer;
|
||||
memset(&layer, 0, sizeof(layer));
|
||||
layer.Header.Type = ovrLayerType_EyeFov;
|
||||
layer.Header.Flags = 0;
|
||||
layer.ColorTexture[0] = rts->textureSet;
|
||||
@@ -607,6 +614,7 @@ VRHMDManagerOculus::Init()
|
||||
mOculusThread = already_AddRefed<nsIThread>(thread);
|
||||
|
||||
ovrInitParams params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.Flags = ovrInit_RequestVersion;
|
||||
params.RequestedMinorVersion = OVR_MINOR_VERSION;
|
||||
params.LogCallback = nullptr;
|
||||
|
||||
@@ -543,6 +543,7 @@ VRHMDManagerOculus050::Init()
|
||||
mOculusThread = already_AddRefed<nsIThread>(thread);
|
||||
|
||||
ovrInitParams params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.Flags = ovrInit_RequestVersion;
|
||||
params.RequestedMinorVersion = LIBOVR_MINOR_VERSION;
|
||||
params.LogCallback = nullptr;
|
||||
|
||||
+20
-17
@@ -45,7 +45,6 @@
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsPresArena.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsMargin.h"
|
||||
#include "nsFrameState.h"
|
||||
|
||||
@@ -358,22 +357,25 @@ public:
|
||||
bool GetAuthorStyleDisabled() const;
|
||||
|
||||
/*
|
||||
* Called when stylesheets are added/removed/enabled/disabled to rebuild
|
||||
* all style data for a given pres shell without necessarily reconstructing
|
||||
* all of the frames. This will not reconstruct style synchronously; if
|
||||
* you need to do that, call FlushPendingNotifications to flush out style
|
||||
* reresolves.
|
||||
* Called when stylesheets are added/removed/enabled/disabled to
|
||||
* recompute style and clear other cached data as needed. This will
|
||||
* not reconstruct style synchronously; if you need to do that, call
|
||||
* FlushPendingNotifications to flush out style reresolves.
|
||||
*
|
||||
* This handles the the addition and removal of the various types of
|
||||
* style rules that can be in CSS style sheets, such as @font-face
|
||||
* rules and @counter-style rules.
|
||||
*
|
||||
* It requires that StyleSheetAdded, StyleSheetRemoved,
|
||||
* StyleSheetApplicableStateChanged, StyleRuleAdded, StyleRuleRemoved,
|
||||
* or StyleRuleChanged has been called on the style sheets that have
|
||||
* changed.
|
||||
*
|
||||
* // XXXbz why do we have this on the interface anyway? The only consumer
|
||||
* is calling AddOverrideStyleSheet/RemoveOverrideStyleSheet, and I think
|
||||
* those should just handle reconstructing style data...
|
||||
*/
|
||||
virtual void ReconstructStyleDataExternal();
|
||||
void ReconstructStyleDataInternal();
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
void ReconstructStyleData() { ReconstructStyleDataInternal(); }
|
||||
#else
|
||||
void ReconstructStyleData() { ReconstructStyleDataExternal(); }
|
||||
#endif
|
||||
void RestyleForCSSRuleChanges();
|
||||
|
||||
/**
|
||||
* Update the style set somehow to take into account changed prefs which
|
||||
@@ -1588,11 +1590,12 @@ public:
|
||||
virtual void RebuildApproximateFrameVisibility(nsRect* aRect = nullptr,
|
||||
bool aRemoveOnly = false) = 0;
|
||||
|
||||
/// Ensures @aFrame is in the list of approximately visible frames.
|
||||
virtual void EnsureFrameInApproximatelyVisibleList(nsIFrame* aFrame) = 0;
|
||||
/// Adds @aFrame to the list of frames which were visible within the
|
||||
/// displayport during the last paint.
|
||||
virtual void MarkFrameVisibleInDisplayPort(nsIFrame* aFrame) = 0;
|
||||
|
||||
/// Removes @aFrame from the list of approximately visible frames if present.
|
||||
virtual void RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame) = 0;
|
||||
/// Marks @aFrame nonvisible and removes it from all lists of visible frames.
|
||||
virtual void MarkFrameNonvisible(nsIFrame* aFrame) = 0;
|
||||
|
||||
/// Whether we should assume all frames are visible.
|
||||
virtual bool AssumeAllFramesVisible() = 0;
|
||||
|
||||
+219
-209
@@ -1184,8 +1184,9 @@ PresShell::Destroy()
|
||||
mSynthMouseMoveEvent.Revoke();
|
||||
|
||||
mUpdateApproximateFrameVisibilityEvent.Revoke();
|
||||
mNotifyCompositorOfVisibleRegionsChangeEvent.Revoke();
|
||||
|
||||
ClearApproximatelyVisibleFramesList(Some(OnNonvisible::DISCARD_IMAGES));
|
||||
ClearVisibleFramesSets(Some(OnNonvisible::DISCARD_IMAGES));
|
||||
|
||||
if (mCaret) {
|
||||
mCaret->Terminate();
|
||||
@@ -1343,7 +1344,7 @@ nsIPresShell::SetAuthorStyleDisabled(bool aStyleDisabled)
|
||||
{
|
||||
if (aStyleDisabled != mStyleSet->GetAuthorStyleDisabled()) {
|
||||
mStyleSet->SetAuthorStyleDisabled(aStyleDisabled);
|
||||
ReconstructStyleData();
|
||||
RestyleForCSSRuleChanges();
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
mozilla::services::GetObserverService();
|
||||
@@ -1452,7 +1453,7 @@ PresShell::AddUserSheet(nsISupports* aSheet)
|
||||
|
||||
mStyleSet->EndUpdate();
|
||||
|
||||
ReconstructStyleData();
|
||||
RestyleForCSSRuleChanges();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1468,7 +1469,7 @@ PresShell::AddAgentSheet(nsISupports* aSheet)
|
||||
}
|
||||
|
||||
mStyleSet->AppendStyleSheet(SheetType::Agent, sheet);
|
||||
ReconstructStyleData();
|
||||
RestyleForCSSRuleChanges();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1491,7 +1492,7 @@ PresShell::AddAuthorSheet(nsISupports* aSheet)
|
||||
mStyleSet->AppendStyleSheet(SheetType::Doc, sheet);
|
||||
}
|
||||
|
||||
ReconstructStyleData();
|
||||
RestyleForCSSRuleChanges();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1504,7 +1505,7 @@ PresShell::RemoveSheet(SheetType aType, nsISupports* aSheet)
|
||||
}
|
||||
|
||||
mStyleSet->RemoveStyleSheet(aType, sheet);
|
||||
ReconstructStyleData();
|
||||
RestyleForCSSRuleChanges();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@@ -2407,7 +2408,7 @@ PresShell::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
|
||||
if (aUpdateType & UPDATE_STYLE) {
|
||||
mStyleSet->EndUpdate();
|
||||
if (mStylesHaveChanged || !mChangedScopeStyleRoots.IsEmpty())
|
||||
ReconstructStyleData();
|
||||
RestyleForCSSRuleChanges();
|
||||
}
|
||||
|
||||
mFrameConstructor->EndUpdate();
|
||||
@@ -4440,7 +4441,7 @@ PresShell::ReconstructFrames(void)
|
||||
}
|
||||
|
||||
void
|
||||
nsIPresShell::ReconstructStyleDataInternal()
|
||||
nsIPresShell::RestyleForCSSRuleChanges()
|
||||
{
|
||||
AutoTArray<RefPtr<mozilla::dom::Element>,1> scopeRoots;
|
||||
mChangedScopeStyleRoots.SwapElements(scopeRoots);
|
||||
@@ -4490,12 +4491,6 @@ nsIPresShell::ReconstructStyleDataInternal()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsIPresShell::ReconstructStyleDataExternal()
|
||||
{
|
||||
ReconstructStyleDataInternal();
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::RecordStyleSheetChange(StyleSheetHandle aStyleSheet)
|
||||
{
|
||||
@@ -4575,6 +4570,71 @@ PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame) const
|
||||
return mFrameConstructor->GetPlaceholderFrameFor(aFrame);
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::NotifyCompositorOfVisibleRegionsChange()
|
||||
{
|
||||
mNotifyCompositorOfVisibleRegionsChangeEvent.Revoke();
|
||||
|
||||
if (!mVisibleRegions) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve the layers ID and pres shell ID.
|
||||
TabChild* tabChild = TabChild::GetFrom(this);
|
||||
if (!tabChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t layersId = tabChild->LayersId();
|
||||
const uint32_t presShellId = GetPresShellId();
|
||||
|
||||
// Retrieve the CompositorBridgeChild.
|
||||
LayerManager* layerManager = GetLayerManager();
|
||||
if (!layerManager) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClientLayerManager* clientLayerManager = layerManager->AsClientLayerManager();
|
||||
if (!clientLayerManager) {
|
||||
return;
|
||||
}
|
||||
|
||||
CompositorBridgeChild* compositorChild = clientLayerManager->GetCompositorBridgeChild();
|
||||
if (!compositorChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear the old visible regions associated with this document.
|
||||
compositorChild->SendClearVisibleRegions(layersId, presShellId);
|
||||
|
||||
// Send the new visible regions to the compositor.
|
||||
for (auto iter = mVisibleRegions->mApproximate.ConstIter();
|
||||
!iter.Done();
|
||||
iter.Next()) {
|
||||
const ViewID viewId = iter.Key();
|
||||
const CSSIntRegion* region = iter.UserData();
|
||||
MOZ_ASSERT(region);
|
||||
|
||||
const ScrollableLayerGuid guid(layersId, presShellId, viewId);
|
||||
|
||||
compositorChild->SendUpdateVisibleRegion(VisibilityCounter::MAY_BECOME_VISIBLE,
|
||||
guid, *region);
|
||||
}
|
||||
|
||||
for (auto iter = mVisibleRegions->mInDisplayPort.ConstIter();
|
||||
!iter.Done();
|
||||
iter.Next()) {
|
||||
const ViewID viewId = iter.Key();
|
||||
const CSSIntRegion* region = iter.UserData();
|
||||
MOZ_ASSERT(region);
|
||||
|
||||
const ScrollableLayerGuid guid(layersId, presShellId, viewId);
|
||||
|
||||
compositorChild->SendUpdateVisibleRegion(VisibilityCounter::IN_DISPLAYPORT,
|
||||
guid, *region);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresShell::RenderDocument(const nsRect& aRect, uint32_t aFlags,
|
||||
nscolor aBackgroundColor,
|
||||
@@ -4686,6 +4746,9 @@ PresShell::RenderDocument(const nsRect& aRect, uint32_t aFlags,
|
||||
nsLayoutUtils::PaintFrame(&rc, rootFrame, nsRegion(aRect),
|
||||
aBackgroundColor, flags);
|
||||
|
||||
// We don't call NotifyCompositorOfVisibleRegionsChange here because we're
|
||||
// not painting to the window, and hence there should be no change.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -4838,12 +4901,12 @@ PresShell::CreateRangePaintInfo(nsIDOMRange* aRange,
|
||||
ancestorFrame = ancestorFrame->GetParent();
|
||||
}
|
||||
|
||||
if (!ancestorFrame)
|
||||
if (!ancestorFrame) {
|
||||
return nullptr;
|
||||
|
||||
auto info = MakeUnique<RangePaintInfo>(range, ancestorFrame);
|
||||
}
|
||||
|
||||
// get a display list containing the range
|
||||
auto info = MakeUnique<RangePaintInfo>(range, ancestorFrame);
|
||||
info->mBuilder.SetIncludeAllOutOfFlows();
|
||||
if (aForPrimarySelection) {
|
||||
info->mBuilder.SetSelectedFramesOnly();
|
||||
@@ -5576,17 +5639,14 @@ PresShell::ProcessSynthMouseMoveEvent(bool aFromScroll)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
AddFrameToVisibleRegions(nsIFrame* aFrame,
|
||||
nsViewManager* aViewManager,
|
||||
Maybe<VisibleRegions>& aVisibleRegions)
|
||||
void
|
||||
PresShell::AddFrameToVisibleRegions(nsIFrame* aFrame, VisibilityCounter aForCounter)
|
||||
{
|
||||
if (!aVisibleRegions) {
|
||||
if (!mVisibleRegions) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aFrame);
|
||||
MOZ_ASSERT(aViewManager);
|
||||
|
||||
// Retrieve the view ID for this frame (which we obtain from the enclosing
|
||||
// scrollable frame).
|
||||
@@ -5621,20 +5681,22 @@ AddFrameToVisibleRegions(nsIFrame* aFrame,
|
||||
return;
|
||||
}
|
||||
|
||||
CSSIntRegion* regionForView = aVisibleRegions->LookupOrAdd(viewID);
|
||||
VisibleRegions& regions = aForCounter == VisibilityCounter::MAY_BECOME_VISIBLE
|
||||
? mVisibleRegions->mApproximate
|
||||
: mVisibleRegions->mInDisplayPort;
|
||||
CSSIntRegion* regionForView = regions.LookupOrAdd(viewID);
|
||||
MOZ_ASSERT(regionForView);
|
||||
|
||||
regionForView->OrWith(CSSPixel::FromAppUnitsRounded(frameRectInScrolledFrameSpace));
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PresShell::MarkFramesInListApproximatelyVisible(const nsDisplayList& aList,
|
||||
Maybe<VisibleRegions>& aVisibleRegions)
|
||||
PresShell::MarkFramesInListApproximatelyVisible(const nsDisplayList& aList)
|
||||
{
|
||||
for (nsDisplayItem* item = aList.GetBottom(); item; item = item->GetAbove()) {
|
||||
nsDisplayList* sublist = item->GetChildren();
|
||||
if (sublist) {
|
||||
MarkFramesInListApproximatelyVisible(*sublist, aVisibleRegions);
|
||||
MarkFramesInListApproximatelyVisible(*sublist);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -5652,128 +5714,56 @@ PresShell::MarkFramesInListApproximatelyVisible(const nsDisplayList& aList,
|
||||
presShell->mApproximatelyVisibleFrames.PutEntry(frame);
|
||||
if (presShell->mApproximatelyVisibleFrames.Count() > count) {
|
||||
// The frame was added to mApproximatelyVisibleFrames, so increment its visible count.
|
||||
frame->IncApproximateVisibleCount();
|
||||
frame->IncVisibilityCount(VisibilityCounter::MAY_BECOME_VISIBLE);
|
||||
}
|
||||
|
||||
AddFrameToVisibleRegions(frame, presShell->mViewManager, aVisibleRegions);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::ReportBadStateDuringVisibilityUpdate()
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
gfxCriticalNote << "Got null frame in frame visibility: off-main-thread";
|
||||
}
|
||||
if (mIsZombie) {
|
||||
gfxCriticalNote << "Got null frame in frame visibility: mIsZombie";
|
||||
}
|
||||
if (mIsDestroying) {
|
||||
gfxCriticalNote << "Got null frame in frame visibility: mIsDestroying";
|
||||
}
|
||||
if (mIsReflowing) {
|
||||
gfxCriticalNote << "Got null frame in frame visibility: mIsReflowing";
|
||||
}
|
||||
if (mPaintingIsFrozen) {
|
||||
gfxCriticalNote << "Got null frame in frame visibility: mPaintingIsFrozen";
|
||||
}
|
||||
if (mForwardingContainer) {
|
||||
gfxCriticalNote << "Got null frame in frame visibility: mForwardingContainer";
|
||||
}
|
||||
if (mIsNeverPainting) {
|
||||
gfxCriticalNote << "Got null frame in frame visibility: mIsNeverPainting";
|
||||
}
|
||||
if (mIsDocumentGone) {
|
||||
gfxCriticalNote << "Got null frame in frame visibility: mIsDocumentGone";
|
||||
}
|
||||
if (!nsContentUtils::IsSafeToRunScript()) {
|
||||
gfxCriticalNote << "Got null frame in frame visibility: not safe to run script";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::SetInFrameVisibilityUpdate(bool aState)
|
||||
{
|
||||
mInFrameVisibilityUpdate = aState;
|
||||
}
|
||||
|
||||
static void
|
||||
NotifyCompositorOfVisibleRegionsChange(PresShell* aPresShell,
|
||||
const Maybe<VisibleRegions>& aRegions)
|
||||
{
|
||||
if (!aRegions) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aPresShell);
|
||||
|
||||
// Retrieve the layers ID and pres shell ID.
|
||||
TabChild* tabChild = TabChild::GetFrom(aPresShell);
|
||||
if (!tabChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t layersId = tabChild->LayersId();
|
||||
const uint32_t presShellId = aPresShell->GetPresShellId();
|
||||
|
||||
// Retrieve the CompositorBridgeChild.
|
||||
LayerManager* layerManager = aPresShell->GetLayerManager();
|
||||
if (!layerManager) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClientLayerManager* clientLayerManager = layerManager->AsClientLayerManager();
|
||||
if (!clientLayerManager) {
|
||||
return;
|
||||
}
|
||||
|
||||
CompositorBridgeChild* compositorChild = clientLayerManager->GetCompositorBridgeChild();
|
||||
if (!compositorChild) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear the old approximately visible regions associated with this document.
|
||||
compositorChild->SendClearApproximatelyVisibleRegions(layersId, presShellId);
|
||||
|
||||
// Send the new approximately visible regions to the compositor.
|
||||
for (auto iter = aRegions->ConstIter(); !iter.Done(); iter.Next()) {
|
||||
const ViewID viewId = iter.Key();
|
||||
const CSSIntRegion* region = iter.UserData();
|
||||
MOZ_ASSERT(region);
|
||||
|
||||
const ScrollableLayerGuid guid(layersId, presShellId, viewId);
|
||||
|
||||
compositorChild->SendNotifyApproximatelyVisibleRegion(guid, *region);
|
||||
presShell->AddFrameToVisibleRegions(frame, VisibilityCounter::MAY_BECOME_VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PresShell::DecApproximateVisibleCount(VisibleFrames& aFrames,
|
||||
Maybe<OnNonvisible> aNonvisibleAction
|
||||
/* = Nothing() */)
|
||||
PresShell::DecVisibleCount(const VisibleFrames& aFrames,
|
||||
VisibilityCounter aCounter,
|
||||
Maybe<OnNonvisible> aNonvisibleAction /* = Nothing() */)
|
||||
{
|
||||
for (auto iter = aFrames.Iter(); !iter.Done(); iter.Next()) {
|
||||
for (auto iter = aFrames.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
nsIFrame* frame = iter.Get()->GetKey();
|
||||
|
||||
if (MOZ_UNLIKELY(!frame)) {
|
||||
// We are about to crash, annotate crash report with some info that might
|
||||
// help debug the crash (bug 1251150)
|
||||
ReportBadStateDuringVisibilityUpdate();
|
||||
}
|
||||
|
||||
SetInFrameVisibilityUpdate(true);
|
||||
|
||||
// Decrement the frame's visible count if we're still tracking its
|
||||
// visibility. (We may not be, if the frame disabled visibility tracking
|
||||
// after we added it to the visible frames list.)
|
||||
if (frame->TrackingVisibility()) {
|
||||
frame->DecApproximateVisibleCount(aNonvisibleAction);
|
||||
frame->DecVisibilityCount(aCounter, aNonvisibleAction);
|
||||
}
|
||||
|
||||
SetInFrameVisibilityUpdate(false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::InitVisibleRegionsIfVisualizationEnabled(VisibilityCounter aForCounter)
|
||||
{
|
||||
// If we're visualizing visible regions, initialize a
|
||||
// VisibleRegionsContainer to store them. Visibility-related functions we
|
||||
// call will only do the work of populating this object and sending it to
|
||||
// the compositor if we've created it, so we don't need to check the prefs
|
||||
// everywhere.
|
||||
if (!gfxPrefs::APZMinimap() ||
|
||||
!gfxPrefs::APZMinimapVisibilityEnabled()) {
|
||||
mVisibleRegions = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mVisibleRegions) {
|
||||
// Clear the regions we're about to update. We don't want to clear both,
|
||||
// or the two visibility tracking methods will interfere with each other.
|
||||
VisibleRegions& regions = aForCounter == VisibilityCounter::MAY_BECOME_VISIBLE
|
||||
? mVisibleRegions->mApproximate
|
||||
: mVisibleRegions->mInDisplayPort;
|
||||
regions.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
mVisibleRegions = MakeUnique<VisibleRegionsContainer>();
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::RebuildApproximateFrameVisibilityDisplayList(const nsDisplayList& aList)
|
||||
{
|
||||
@@ -5785,70 +5775,72 @@ PresShell::RebuildApproximateFrameVisibilityDisplayList(const nsDisplayList& aLi
|
||||
VisibleFrames oldApproximatelyVisibleFrames;
|
||||
mApproximatelyVisibleFrames.SwapElements(oldApproximatelyVisibleFrames);
|
||||
|
||||
// If we're visualizing visible regions, create a VisibleRegions object to
|
||||
// store information about them. The functions we call will populate this
|
||||
// object and send it to the compositor only if it's Some(), so we don't
|
||||
// need to check the prefs everywhere.
|
||||
Maybe<VisibleRegions> visibleRegions;
|
||||
if (gfxPrefs::APZMinimap() && gfxPrefs::APZMinimapVisibilityEnabled()) {
|
||||
visibleRegions.emplace();
|
||||
}
|
||||
InitVisibleRegionsIfVisualizationEnabled(VisibilityCounter::MAY_BECOME_VISIBLE);
|
||||
|
||||
MarkFramesInListApproximatelyVisible(aList, visibleRegions);
|
||||
MarkFramesInListApproximatelyVisible(aList);
|
||||
|
||||
DecApproximateVisibleCount(oldApproximatelyVisibleFrames);
|
||||
DecVisibleCount(oldApproximatelyVisibleFrames,
|
||||
VisibilityCounter::MAY_BECOME_VISIBLE);
|
||||
|
||||
NotifyCompositorOfVisibleRegionsChange(this, visibleRegions);
|
||||
NotifyCompositorOfVisibleRegionsChange();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
PresShell::ClearApproximateFrameVisibilityVisited(nsView* aView, bool aClear)
|
||||
PresShell::ClearVisibleFramesForUnvisitedPresShells(nsView* aView, bool aClear)
|
||||
{
|
||||
nsViewManager* vm = aView->GetViewManager();
|
||||
if (aClear) {
|
||||
PresShell* presShell = static_cast<PresShell*>(vm->GetPresShell());
|
||||
if (!presShell->mApproximateFrameVisibilityVisited) {
|
||||
presShell->ClearApproximatelyVisibleFramesList();
|
||||
presShell->ClearVisibleFramesSets();
|
||||
}
|
||||
presShell->mApproximateFrameVisibilityVisited = false;
|
||||
}
|
||||
for (nsView* v = aView->GetFirstChild(); v; v = v->GetNextSibling()) {
|
||||
ClearApproximateFrameVisibilityVisited(v, v->GetViewManager() != vm);
|
||||
ClearVisibleFramesForUnvisitedPresShells(v, v->GetViewManager() != vm);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::ClearApproximatelyVisibleFramesList(Maybe<OnNonvisible> aNonvisibleAction
|
||||
/* = Nothing() */)
|
||||
PresShell::ClearVisibleFramesSets(Maybe<OnNonvisible> aNonvisibleAction
|
||||
/* = Nothing() */)
|
||||
{
|
||||
if (mInFrameVisibilityUpdate) {
|
||||
gfxCriticalNoteOnce << "ClearApproximatelyVisibleFramesList is re-entering on "
|
||||
<< (NS_IsMainThread() ? "" : "non-") << "main thread";
|
||||
}
|
||||
DecApproximateVisibleCount(mApproximatelyVisibleFrames, aNonvisibleAction);
|
||||
DecVisibleCount(mApproximatelyVisibleFrames,
|
||||
VisibilityCounter::MAY_BECOME_VISIBLE,
|
||||
aNonvisibleAction);
|
||||
mApproximatelyVisibleFrames.Clear();
|
||||
|
||||
DecVisibleCount(mInDisplayPortFrames,
|
||||
VisibilityCounter::IN_DISPLAYPORT,
|
||||
aNonvisibleAction);
|
||||
mInDisplayPortFrames.Clear();
|
||||
|
||||
if (mVisibleRegions) {
|
||||
mVisibleRegions->mApproximate.Clear();
|
||||
mVisibleRegions->mInDisplayPort.Clear();
|
||||
NotifyCompositorOfVisibleRegionsChange();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
|
||||
const nsRect& aRect,
|
||||
Maybe<VisibleRegions>& aVisibleRegions,
|
||||
bool aRemoveOnly /* = false */)
|
||||
{
|
||||
MOZ_ASSERT(aFrame->PresContext()->PresShell() == this, "wrong presshell");
|
||||
|
||||
if (aFrame->TrackingVisibility() &&
|
||||
aFrame->StyleVisibility()->IsVisible() &&
|
||||
(!aRemoveOnly || aFrame->GetVisibility() == Visibility::APPROXIMATELY_VISIBLE)) {
|
||||
(!aRemoveOnly || aFrame->IsVisibleOrMayBecomeVisibleSoon())) {
|
||||
MOZ_ASSERT(!AssumeAllFramesVisible());
|
||||
uint32_t count = mApproximatelyVisibleFrames.Count();
|
||||
mApproximatelyVisibleFrames.PutEntry(aFrame);
|
||||
if (mApproximatelyVisibleFrames.Count() > count) {
|
||||
// The frame was added to mApproximatelyVisibleFrames, so increment its visible count.
|
||||
aFrame->IncApproximateVisibleCount();
|
||||
aFrame->IncVisibilityCount(VisibilityCounter::MAY_BECOME_VISIBLE);
|
||||
}
|
||||
|
||||
AddFrameToVisibleRegions(aFrame, mViewManager, aVisibleRegions);
|
||||
AddFrameToVisibleRegions(aFrame, VisibilityCounter::MAY_BECOME_VISIBLE);
|
||||
}
|
||||
|
||||
nsSubDocumentFrame* subdocFrame = do_QueryFrame(aFrame);
|
||||
@@ -5917,7 +5909,7 @@ PresShell::MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
|
||||
}
|
||||
}
|
||||
}
|
||||
MarkFramesInSubtreeApproximatelyVisible(child, r, aVisibleRegions);
|
||||
MarkFramesInSubtreeApproximatelyVisible(child, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5934,35 +5926,24 @@ PresShell::RebuildApproximateFrameVisibility(nsRect* aRect,
|
||||
return;
|
||||
}
|
||||
|
||||
if (mInFrameVisibilityUpdate) {
|
||||
gfxCriticalNoteOnce << "RebuildApproximateFrameVisibility is re-entering on "
|
||||
<< (NS_IsMainThread() ? "" : "non-") << "main thread";
|
||||
}
|
||||
|
||||
// Remove the entries of the mApproximatelyVisibleFrames hashtable and put
|
||||
// them in oldApproximatelyVisibleFrames.
|
||||
VisibleFrames oldApproximatelyVisibleFrames;
|
||||
mApproximatelyVisibleFrames.SwapElements(oldApproximatelyVisibleFrames);
|
||||
|
||||
// If we're visualizing visible regions, create a VisibleRegions object to
|
||||
// store information about them. The functions we call will populate this
|
||||
// object and send it to the compositor only if it's Some(), so we don't
|
||||
// need to check the prefs everywhere.
|
||||
Maybe<VisibleRegions> visibleRegions;
|
||||
if (gfxPrefs::APZMinimap() && gfxPrefs::APZMinimapVisibilityEnabled()) {
|
||||
visibleRegions.emplace();
|
||||
}
|
||||
InitVisibleRegionsIfVisualizationEnabled(VisibilityCounter::MAY_BECOME_VISIBLE);
|
||||
|
||||
nsRect vis(nsPoint(0, 0), rootFrame->GetSize());
|
||||
if (aRect) {
|
||||
vis = *aRect;
|
||||
}
|
||||
|
||||
MarkFramesInSubtreeApproximatelyVisible(rootFrame, vis, visibleRegions, aRemoveOnly);
|
||||
MarkFramesInSubtreeApproximatelyVisible(rootFrame, vis, aRemoveOnly);
|
||||
|
||||
DecApproximateVisibleCount(oldApproximatelyVisibleFrames);
|
||||
DecVisibleCount(oldApproximatelyVisibleFrames,
|
||||
VisibilityCounter::MAY_BECOME_VISIBLE);
|
||||
|
||||
NotifyCompositorOfVisibleRegionsChange(this, visibleRegions);
|
||||
NotifyCompositorOfVisibleRegionsChange();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -5986,12 +5967,12 @@ PresShell::DoUpdateApproximateFrameVisibility(bool aRemoveOnly)
|
||||
// call update on that frame
|
||||
nsIFrame* rootFrame = GetRootFrame();
|
||||
if (!rootFrame) {
|
||||
ClearApproximatelyVisibleFramesList(Some(OnNonvisible::DISCARD_IMAGES));
|
||||
ClearVisibleFramesSets(Some(OnNonvisible::DISCARD_IMAGES));
|
||||
return;
|
||||
}
|
||||
|
||||
RebuildApproximateFrameVisibility(/* aRect = */ nullptr, aRemoveOnly);
|
||||
ClearApproximateFrameVisibilityVisited(rootFrame->GetView(), true);
|
||||
ClearVisibleFramesForUnvisitedPresShells(rootFrame->GetView(), true);
|
||||
|
||||
#ifdef DEBUG_FRAME_VISIBILITY_DISPLAY_LIST
|
||||
// This can be used to debug the frame walker by comparing beforeFrameList
|
||||
@@ -6005,7 +5986,8 @@ PresShell::DoUpdateApproximateFrameVisibility(bool aRemoveOnly)
|
||||
if (rootScroll) {
|
||||
nsIContent* content = rootScroll->GetContent();
|
||||
if (content) {
|
||||
Unused << nsLayoutUtils::GetDisplayPort(content, &updateRect, RelativeTo::ScrollFrame);
|
||||
Unused << nsLayoutUtils::GetDisplayPortForVisibilityTesting(content, &updateRect,
|
||||
RelativeTo::ScrollFrame);
|
||||
}
|
||||
|
||||
if (IgnoringViewportScrolling()) {
|
||||
@@ -6020,7 +6002,7 @@ PresShell::DoUpdateApproximateFrameVisibility(bool aRemoveOnly)
|
||||
|
||||
RebuildApproximateFrameVisibilityDisplayList(list);
|
||||
|
||||
ClearApproximateFrameVisibilityVisited(rootFrame->GetView(), true);
|
||||
ClearVisibleFramesForUnvisitedPresShells(rootFrame->GetView(), true);
|
||||
|
||||
list.DeleteAll();
|
||||
#endif
|
||||
@@ -6125,14 +6107,16 @@ PresShell::ScheduleApproximateFrameVisibilityUpdateNow()
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::EnsureFrameInApproximatelyVisibleList(nsIFrame* aFrame)
|
||||
PresShell::MarkFrameVisibleInDisplayPort(nsIFrame* aFrame)
|
||||
{
|
||||
if (!aFrame->TrackingVisibility()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (AssumeAllFramesVisible()) {
|
||||
aFrame->IncApproximateVisibleCount();
|
||||
if (aFrame->GetVisibility() != Visibility::IN_DISPLAYPORT) {
|
||||
aFrame->IncVisibilityCount(VisibilityCounter::IN_DISPLAYPORT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6145,20 +6129,31 @@ PresShell::EnsureFrameInApproximatelyVisibleList(nsIFrame* aFrame)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mInFrameVisibilityUpdate) {
|
||||
gfxCriticalNoteOnce << "EnsureFrameInApproximatelyVisibleList is re-entering on "
|
||||
<< (NS_IsMainThread() ? "" : "non-") << "main thread";
|
||||
if (!mInDisplayPortFrames.Contains(aFrame)) {
|
||||
MOZ_ASSERT(!AssumeAllFramesVisible());
|
||||
mInDisplayPortFrames.PutEntry(aFrame);
|
||||
aFrame->IncVisibilityCount(VisibilityCounter::IN_DISPLAYPORT);
|
||||
}
|
||||
|
||||
if (!mApproximatelyVisibleFrames.Contains(aFrame)) {
|
||||
MOZ_ASSERT(!AssumeAllFramesVisible());
|
||||
mApproximatelyVisibleFrames.PutEntry(aFrame);
|
||||
aFrame->IncApproximateVisibleCount();
|
||||
AddFrameToVisibleRegions(aFrame, VisibilityCounter::IN_DISPLAYPORT);
|
||||
}
|
||||
|
||||
static void
|
||||
RemoveFrameFromVisibleSet(nsIFrame* aFrame,
|
||||
VisibleFrames& aSet,
|
||||
VisibilityCounter aCounter)
|
||||
{
|
||||
uint32_t count = aSet.Count();
|
||||
aSet.RemoveEntry(aFrame);
|
||||
|
||||
if (aFrame->TrackingVisibility() && aSet.Count() < count) {
|
||||
aFrame->DecVisibilityCount(aCounter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame)
|
||||
PresShell::MarkFrameNonvisible(nsIFrame* aFrame)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Make sure it's in this pres shell.
|
||||
@@ -6171,24 +6166,16 @@ PresShell::RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame)
|
||||
|
||||
if (AssumeAllFramesVisible()) {
|
||||
MOZ_ASSERT(mApproximatelyVisibleFrames.Count() == 0,
|
||||
"Shouldn't have any frames in the table");
|
||||
"Shouldn't have any frames in the approximate visibility set");
|
||||
MOZ_ASSERT(mInDisplayPortFrames.Count() == 0,
|
||||
"Shouldn't have any frames in the in-displayport visibility set");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mInFrameVisibilityUpdate) {
|
||||
gfxCriticalNoteOnce << "RemoveFrameFromApproximatelyVisibleList is re-entering on "
|
||||
<< (NS_IsMainThread() ? "" : "non-") << "main thread";
|
||||
}
|
||||
|
||||
uint32_t count = mApproximatelyVisibleFrames.Count();
|
||||
mApproximatelyVisibleFrames.RemoveEntry(aFrame);
|
||||
|
||||
if (aFrame->TrackingVisibility() &&
|
||||
mApproximatelyVisibleFrames.Count() < count) {
|
||||
// aFrame was in the hashtable, and we're still tracking its visibility,
|
||||
// so we need to decrement its visible count.
|
||||
aFrame->DecApproximateVisibleCount();
|
||||
}
|
||||
RemoveFrameFromVisibleSet(aFrame, mApproximatelyVisibleFrames,
|
||||
VisibilityCounter::MAY_BECOME_VISIBLE);
|
||||
RemoveFrameFromVisibleSet(aFrame, mInDisplayPortFrames,
|
||||
VisibilityCounter::IN_DISPLAYPORT);
|
||||
}
|
||||
|
||||
class nsAutoNotifyDidPaint
|
||||
@@ -6376,8 +6363,30 @@ PresShell::Paint(nsView* aViewToPaint,
|
||||
}
|
||||
|
||||
if (frame) {
|
||||
// Remove the entries of the mInDisplayPortFrames hashtable and put them
|
||||
// in oldInDisplayPortFrames.
|
||||
VisibleFrames oldInDisplayPortFrames;
|
||||
mInDisplayPortFrames.SwapElements(oldInDisplayPortFrames);
|
||||
|
||||
InitVisibleRegionsIfVisualizationEnabled(VisibilityCounter::IN_DISPLAYPORT);
|
||||
|
||||
// We can paint directly into the widget using its layer manager.
|
||||
nsLayoutUtils::PaintFrame(nullptr, frame, aDirtyRegion, bgcolor, flags);
|
||||
|
||||
DecVisibleCount(oldInDisplayPortFrames, VisibilityCounter::IN_DISPLAYPORT);
|
||||
|
||||
if (mVisibleRegions &&
|
||||
!mNotifyCompositorOfVisibleRegionsChangeEvent.IsPending()) {
|
||||
// Asynchronously notify the compositor of the new visible regions,
|
||||
// since this is happening during a paint and updating the visible
|
||||
// regions triggers a recomposite.
|
||||
RefPtr<nsRunnableMethod<PresShell>> event =
|
||||
NS_NewRunnableMethod(this, &PresShell::NotifyCompositorOfVisibleRegionsChange);
|
||||
if (NS_SUCCEEDED(NS_DispatchToMainThread(event))) {
|
||||
mNotifyCompositorOfVisibleRegionsChangeEvent = event;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9024,6 +9033,7 @@ void
|
||||
PresShell::Freeze()
|
||||
{
|
||||
mUpdateApproximateFrameVisibilityEvent.Revoke();
|
||||
mNotifyCompositorOfVisibleRegionsChangeEvent.Revoke();
|
||||
|
||||
MaybeReleaseCapturingContent();
|
||||
|
||||
@@ -11047,11 +11057,6 @@ PresShell::UpdateImageLockingState()
|
||||
nsresult rv = mDocument->SetImageLockingState(locked);
|
||||
|
||||
if (locked) {
|
||||
if (mInFrameVisibilityUpdate) {
|
||||
gfxCriticalNoteOnce << "UpdateImageLockingState is re-entering on "
|
||||
<< (NS_IsMainThread() ? "" : "non-") << "main thread";
|
||||
}
|
||||
|
||||
// Request decodes for visible image frames; we want to start decoding as
|
||||
// quickly as possible when we get foregrounded to minimize flashing.
|
||||
for (auto iter = mApproximatelyVisibleFrames.Iter(); !iter.Done(); iter.Next()) {
|
||||
@@ -11091,6 +11096,11 @@ PresShell::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
|
||||
*aPresShellSize += mCaret->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
*aPresShellSize += mApproximatelyVisibleFrames.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
*aPresShellSize += mInDisplayPortFrames.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
*aPresShellSize += mVisibleRegions
|
||||
? mVisibleRegions->mApproximate.ShallowSizeOfIncludingThis(aMallocSizeOf) +
|
||||
mVisibleRegions->mInDisplayPort.ShallowSizeOfIncludingThis(aMallocSizeOf)
|
||||
: 0;
|
||||
*aPresShellSize += mFramesToDirty.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
*aPresShellSize += aArenaObjectsSize->mOther;
|
||||
|
||||
|
||||
+34
-14
@@ -38,6 +38,7 @@
|
||||
#include "mozilla/StyleSetHandle.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "MobileViewportManager.h"
|
||||
#include "Visibility.h"
|
||||
#include "ZoomConstraintsClient.h"
|
||||
|
||||
class nsRange;
|
||||
@@ -79,6 +80,8 @@ class PresShell final : public nsIPresShell,
|
||||
template <typename T> using Maybe = mozilla::Maybe<T>;
|
||||
using Nothing = mozilla::Nothing;
|
||||
using OnNonvisible = mozilla::OnNonvisible;
|
||||
template <typename T> using UniquePtr = mozilla::UniquePtr<T>;
|
||||
using VisibilityCounter = mozilla::VisibilityCounter;
|
||||
using VisibleFrames = mozilla::VisibleFrames;
|
||||
using VisibleRegions = mozilla::VisibleRegions;
|
||||
|
||||
@@ -402,8 +405,8 @@ public:
|
||||
void RebuildApproximateFrameVisibility(nsRect* aRect = nullptr,
|
||||
bool aRemoveOnly = false) override;
|
||||
|
||||
void EnsureFrameInApproximatelyVisibleList(nsIFrame* aFrame) override;
|
||||
void RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame) override;
|
||||
void MarkFrameVisibleInDisplayPort(nsIFrame* aFrame) override;
|
||||
void MarkFrameNonvisible(nsIFrame* aFrame) override;
|
||||
|
||||
bool AssumeAllFramesVisible() override;
|
||||
|
||||
@@ -765,27 +768,46 @@ protected:
|
||||
void UpdateApproximateFrameVisibility();
|
||||
void DoUpdateApproximateFrameVisibility(bool aRemoveOnly);
|
||||
|
||||
void ClearApproximatelyVisibleFramesList(Maybe<mozilla::OnNonvisible> aNonvisibleAction
|
||||
= Nothing());
|
||||
static void ClearApproximateFrameVisibilityVisited(nsView* aView, bool aClear);
|
||||
static void MarkFramesInListApproximatelyVisible(const nsDisplayList& aList,
|
||||
Maybe<VisibleRegions>& aVisibleRegions);
|
||||
void ClearVisibleFramesSets(Maybe<OnNonvisible> aNonvisibleAction = Nothing());
|
||||
static void ClearVisibleFramesForUnvisitedPresShells(nsView* aView, bool aClear);
|
||||
static void MarkFramesInListApproximatelyVisible(const nsDisplayList& aList);
|
||||
void MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
|
||||
const nsRect& aRect,
|
||||
Maybe<VisibleRegions>& aVisibleRegions,
|
||||
bool aRemoveOnly = false);
|
||||
|
||||
void DecApproximateVisibleCount(VisibleFrames& aFrames,
|
||||
Maybe<OnNonvisible> aNonvisibleAction = Nothing());
|
||||
void ReportBadStateDuringVisibilityUpdate();
|
||||
void SetInFrameVisibilityUpdate(bool aState);
|
||||
void DecVisibleCount(const VisibleFrames& aFrames,
|
||||
VisibilityCounter aCounter,
|
||||
Maybe<OnNonvisible> aNonvisibleAction = Nothing());
|
||||
|
||||
void InitVisibleRegionsIfVisualizationEnabled(VisibilityCounter aForCounter);
|
||||
void AddFrameToVisibleRegions(nsIFrame* aFrame, VisibilityCounter aForCounter);
|
||||
void NotifyCompositorOfVisibleRegionsChange();
|
||||
|
||||
nsRevocableEventPtr<nsRunnableMethod<PresShell>> mUpdateApproximateFrameVisibilityEvent;
|
||||
nsRevocableEventPtr<nsRunnableMethod<PresShell>> mNotifyCompositorOfVisibleRegionsChangeEvent;
|
||||
|
||||
// A set of frames that were visible or could be visible soon at the time
|
||||
// that we last did an approximate frame visibility update.
|
||||
VisibleFrames mApproximatelyVisibleFrames;
|
||||
|
||||
// A set of frames that were visible in the displayport the last time we painted.
|
||||
VisibleFrames mInDisplayPortFrames;
|
||||
|
||||
struct VisibleRegionsContainer
|
||||
{
|
||||
// The approximately visible regions calculated during the last update to
|
||||
// approximate frame visibility.
|
||||
VisibleRegions mApproximate;
|
||||
|
||||
// The in-displayport visible regions calculated during the last paint.
|
||||
VisibleRegions mInDisplayPort;
|
||||
};
|
||||
|
||||
// The most recent visible regions we've computed. Only non-null if the APZ
|
||||
// minimap visibility visualization was enabled during the last visibility
|
||||
// update.
|
||||
UniquePtr<VisibleRegionsContainer> mVisibleRegions;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Methods for dispatching KeyboardEvent and BeforeAfterKeyboardEvent.
|
||||
@@ -952,8 +974,6 @@ protected:
|
||||
// Whether the widget has received a paint message yet.
|
||||
bool mHasReceivedPaintMessage : 1;
|
||||
|
||||
bool mInFrameVisibilityUpdate : 1;
|
||||
|
||||
static bool sDisableNonTestMouseEvents;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
using mozilla::dom::Element;
|
||||
|
||||
nsColorControlFrame::nsColorControlFrame(nsStyleContext* aContext):
|
||||
nsColorControlFrameSuper(aContext)
|
||||
nsColorControlFrame::nsColorControlFrame(nsStyleContext* aContext)
|
||||
: nsHTMLButtonControlFrame(aContext)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@ NS_IMPL_FRAMEARENA_HELPERS(nsColorControlFrame)
|
||||
NS_QUERYFRAME_HEAD(nsColorControlFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsColorControlFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsColorControlFrameSuper)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsHTMLButtonControlFrame)
|
||||
|
||||
|
||||
void nsColorControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
|
||||
nsContentUtils::DestroyAnonymousContent(&mColorContent);
|
||||
nsColorControlFrameSuper::DestroyFrom(aDestructRoot);
|
||||
nsHTMLButtonControlFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
nsIAtom*
|
||||
@@ -126,7 +126,7 @@ nsColorControlFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
aNameSpaceID == kNameSpaceID_None && nsGkAtoms::value == aAttribute) {
|
||||
UpdateColor();
|
||||
}
|
||||
return nsColorControlFrameSuper::AttributeChanged(aNameSpaceID, aAttribute,
|
||||
return nsHTMLButtonControlFrame::AttributeChanged(aNameSpaceID, aAttribute,
|
||||
aModType);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,11 +14,9 @@ namespace mozilla {
|
||||
enum class CSSPseudoElementType : uint8_t;
|
||||
} // namespace mozilla
|
||||
|
||||
typedef nsHTMLButtonControlFrame nsColorControlFrameSuper;
|
||||
|
||||
// Class which implements the input type=color
|
||||
|
||||
class nsColorControlFrame final : public nsColorControlFrameSuper,
|
||||
class nsColorControlFrame final : public nsHTMLButtonControlFrame,
|
||||
public nsIAnonymousContentCreator
|
||||
{
|
||||
typedef mozilla::CSSPseudoElementType CSSPseudoElementType;
|
||||
|
||||
@@ -17,8 +17,8 @@ using namespace mozilla;
|
||||
|
||||
//#define FCF_NOISY
|
||||
|
||||
nsFormControlFrame::nsFormControlFrame(nsStyleContext* aContext) :
|
||||
nsFormControlFrameSuper(aContext)
|
||||
nsFormControlFrame::nsFormControlFrame(nsStyleContext* aContext)
|
||||
: nsAtomicContainerFrame(aContext)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ nsFormControlFrame::~nsFormControlFrame()
|
||||
nsIAtom*
|
||||
nsFormControlFrame::GetType() const
|
||||
{
|
||||
return nsGkAtoms::formControlFrame;
|
||||
return nsGkAtoms::formControlFrame;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -37,12 +37,12 @@ nsFormControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
// Unregister the access key registered in reflow
|
||||
nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), false);
|
||||
nsFormControlFrameSuper::DestroyFrom(aDestructRoot);
|
||||
nsAtomicContainerFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsFormControlFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsFormControlFrameSuper)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsAtomicContainerFrame)
|
||||
|
||||
/* virtual */ nscoord
|
||||
nsFormControlFrame::GetMinISize(nsRenderingContext *aRenderingContext)
|
||||
|
||||
@@ -11,14 +11,12 @@
|
||||
#include "nsAtomicContainerFrame.h"
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
typedef nsAtomicContainerFrame nsFormControlFrameSuper;
|
||||
|
||||
/**
|
||||
/**
|
||||
* nsFormControlFrame is the base class for radio buttons and
|
||||
* checkboxes. It also has two static methods (RegUnRegAccessKey and
|
||||
* GetScreenHeight) that are used by other form controls.
|
||||
*/
|
||||
class nsFormControlFrame : public nsFormControlFrameSuper,
|
||||
class nsFormControlFrame : public nsAtomicContainerFrame,
|
||||
public nsIFormControlFrame
|
||||
{
|
||||
public:
|
||||
@@ -33,7 +31,7 @@ public:
|
||||
|
||||
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
||||
{
|
||||
return nsFormControlFrameSuper::IsFrameOfType(aFlags &
|
||||
return nsAtomicContainerFrame::IsFrameOfType(aFlags &
|
||||
~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
|
||||
}
|
||||
|
||||
@@ -68,11 +66,11 @@ public:
|
||||
const mozilla::LogicalSize& aPadding,
|
||||
bool aShrinkWrap) override;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Respond to a gui event
|
||||
* @see nsIFrame::HandleEvent
|
||||
*/
|
||||
virtual nsresult HandleEvent(nsPresContext* aPresContext,
|
||||
virtual nsresult HandleEvent(nsPresContext* aPresContext,
|
||||
mozilla::WidgetGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus) override;
|
||||
|
||||
@@ -117,7 +115,7 @@ protected:
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Utility methods for managing checkboxes and radiobuttons
|
||||
//-------------------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
/**
|
||||
* Get the state of the checked attribute.
|
||||
* @param aState set to true if the checked attribute is set,
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
typedef nsImageFrame nsImageControlFrameSuper;
|
||||
class nsImageControlFrame : public nsImageControlFrameSuper,
|
||||
class nsImageControlFrame : public nsImageFrame,
|
||||
public nsIFormControlFrame
|
||||
{
|
||||
public:
|
||||
@@ -56,13 +55,13 @@ public:
|
||||
nsIFrame::Cursor& aCursor) override;
|
||||
// nsIFormContromFrame
|
||||
virtual void SetFocus(bool aOn, bool aRepaint) override;
|
||||
virtual nsresult SetFormProperty(nsIAtom* aName,
|
||||
virtual nsresult SetFormProperty(nsIAtom* aName,
|
||||
const nsAString& aValue) override;
|
||||
};
|
||||
|
||||
|
||||
nsImageControlFrame::nsImageControlFrame(nsStyleContext* aContext):
|
||||
nsImageControlFrameSuper(aContext)
|
||||
nsImageControlFrame::nsImageControlFrame(nsStyleContext* aContext)
|
||||
: nsImageFrame(aContext)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -76,7 +75,7 @@ nsImageControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
if (!GetPrevInFlow()) {
|
||||
nsFormControlFrame::RegUnRegAccessKey(this, false);
|
||||
}
|
||||
nsImageControlFrameSuper::DestroyFrom(aDestructRoot);
|
||||
nsImageFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
@@ -92,12 +91,12 @@ nsImageControlFrame::Init(nsIContent* aContent,
|
||||
nsContainerFrame* aParent,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsImageControlFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
||||
nsImageFrame::Init(aContent, aParent, aPrevInFlow);
|
||||
|
||||
if (aPrevInFlow) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mContent->SetProperty(nsGkAtoms::imageClickedPoint,
|
||||
new nsIntPoint(0, 0),
|
||||
nsINode::DeleteProperty<nsIntPoint>);
|
||||
@@ -105,7 +104,7 @@ nsImageControlFrame::Init(nsIContent* aContent,
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsImageControlFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsImageControlFrameSuper)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsImageFrame)
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
a11y::AccType
|
||||
@@ -122,7 +121,7 @@ nsImageControlFrame::AccessibleType()
|
||||
nsIAtom*
|
||||
nsImageControlFrame::GetType() const
|
||||
{
|
||||
return nsGkAtoms::imageControlFrame;
|
||||
return nsGkAtoms::imageControlFrame;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -136,10 +135,10 @@ nsImageControlFrame::Reflow(nsPresContext* aPresContext,
|
||||
if (!GetPrevInFlow() && (mState & NS_FRAME_FIRST_REFLOW)) {
|
||||
nsFormControlFrame::RegUnRegAccessKey(this, true);
|
||||
}
|
||||
return nsImageControlFrameSuper::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
return nsImageFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsresult
|
||||
nsImageControlFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
WidgetGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus)
|
||||
@@ -175,11 +174,10 @@ nsImageControlFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
TranslateEventCoords(pt, *lastClickPoint);
|
||||
}
|
||||
}
|
||||
return nsImageControlFrameSuper::HandleEvent(aPresContext, aEvent,
|
||||
aEventStatus);
|
||||
return nsImageFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
nsImageControlFrame::SetFocus(bool aOn, bool aRepaint)
|
||||
{
|
||||
}
|
||||
|
||||
+28
-12
@@ -8,6 +8,8 @@
|
||||
* possible visibility states of a frame. @OnNonvisible is an enumeration that
|
||||
* allows callers to request a specific action when a frame transitions from
|
||||
* visible to nonvisible.
|
||||
*
|
||||
* IPC serializers are available in VisibilityIPC.h.
|
||||
*/
|
||||
|
||||
#ifndef mozilla_layout_generic_Visibility_h
|
||||
@@ -18,21 +20,35 @@ namespace mozilla {
|
||||
// Visibility states for frames.
|
||||
enum class Visibility : uint8_t
|
||||
{
|
||||
// Indicates that we're not tracking visibility for this frame.
|
||||
// We're not tracking visibility for this frame.
|
||||
UNTRACKED,
|
||||
|
||||
// Indicates that the frame is probably nonvisible. Visible frames *may* be
|
||||
// APPROXIMATELY_NONVISIBLE because approximate visibility is not updated
|
||||
// synchronously. Some truly nonvisible frames may be marked
|
||||
// APPROXIMATELY_VISIBLE instead if our heuristics lead us to think they may
|
||||
// be visible soon.
|
||||
APPROXIMATELY_NONVISIBLE,
|
||||
// This frame is nonvisible - i.e., it was not within the displayport as of
|
||||
// the last paint (in which case it'd be IN_DISPLAYPORT) and our heuristics
|
||||
// aren't telling us that it may become visible soon (in which case it'd be
|
||||
// MAY_BECOME_VISIBLE).
|
||||
NONVISIBLE,
|
||||
|
||||
// Indicates that the frame is either visible now or is likely to be visible
|
||||
// soon according to our heuristics. As with APPROXIMATELY_NONVISIBLE, it's
|
||||
// important to note that approximately visibility is not updated
|
||||
// synchronously, so this information may be out of date.
|
||||
APPROXIMATELY_VISIBLE
|
||||
// This frame is nonvisible now, but our heuristics tell us it may become
|
||||
// visible soon. These heuristics are updated on a relatively slow timer, so a
|
||||
// frame being marked MAY_BECOME_VISIBLE does not imply any particular
|
||||
// relationship between the frame and the displayport.
|
||||
MAY_BECOME_VISIBLE,
|
||||
|
||||
// This frame was within the displayport as of the last paint. That doesn't
|
||||
// necessarily mean that the frame is visible - it may still lie outside the
|
||||
// viewport - but it does mean that the user may scroll the frame into view
|
||||
// asynchronously at any time (due to APZ), so for most purposes such a frame
|
||||
// should be treated as truly visible.
|
||||
IN_DISPLAYPORT
|
||||
};
|
||||
|
||||
// The subset of the states in @Visibility which have a per-frame counter. This
|
||||
// is used in the implementation of visibility tracking.
|
||||
enum class VisibilityCounter : uint8_t
|
||||
{
|
||||
MAY_BECOME_VISIBLE,
|
||||
IN_DISPLAYPORT
|
||||
};
|
||||
|
||||
// Requested actions when frames transition to the nonvisible state.
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
/**
|
||||
* Declares IPC serializers for the visibility-related types in Visibility.h.
|
||||
* These are separated out to reduce the number of moz.build files that need to
|
||||
* include chromium IPC headers, since Visibility.h is included from nsIFrame.h
|
||||
* which is widely included.
|
||||
*/
|
||||
|
||||
#ifndef mozilla_layout_generic_VisibilityIPC_h
|
||||
#define mozilla_layout_generic_VisibilityIPC_h
|
||||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
|
||||
#include "Visibility.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::VisibilityCounter>
|
||||
{
|
||||
typedef mozilla::VisibilityCounter paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, uint8_t(aParam));
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
uint8_t valueAsByte;
|
||||
if (ReadParam(aMsg, aIter, &valueAsByte)) {
|
||||
*aResult = paramType(valueAsByte);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // mozilla_layout_generic_VisibilityIPC_h
|
||||
@@ -98,6 +98,7 @@ EXPORTS += [
|
||||
'ScrollbarActivity.h',
|
||||
'ScrollSnap.h',
|
||||
'Visibility.h',
|
||||
'VisibilityIPC.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
|
||||
@@ -78,6 +78,89 @@ kAxisOrientationToSidesMap[eNumAxisOrientationTypes][eNumAxisEdges] = {
|
||||
|
||||
// Helper structs / classes / methods
|
||||
// ==================================
|
||||
// Returns true iff the given nsStyleDisplay has display:-webkit-{inline-}-box.
|
||||
static inline bool
|
||||
IsDisplayValueLegacyBox(const nsStyleDisplay* aStyleDisp)
|
||||
{
|
||||
return aStyleDisp->mDisplay == NS_STYLE_DISPLAY_WEBKIT_BOX ||
|
||||
aStyleDisp->mDisplay == NS_STYLE_DISPLAY_WEBKIT_INLINE_BOX;
|
||||
}
|
||||
|
||||
// Helper to check whether our nsFlexContainerFrame is emulating a legacy
|
||||
// -webkit-{inline-}box, in which case we should use legacy CSS properties
|
||||
// instead of the modern ones. The params are are the nsStyleDisplay and the
|
||||
// nsStyleContext associated with the nsFlexContainerFrame itself.
|
||||
static inline bool
|
||||
IsLegacyBox(const nsStyleDisplay* aStyleDisp,
|
||||
nsStyleContext* aStyleContext)
|
||||
{
|
||||
// Trivial case: just check "display" directly.
|
||||
if (IsDisplayValueLegacyBox(aStyleDisp)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If this frame is for a scrollable element, then it will actually have
|
||||
// "display:block", and its *parent* will have the real flex-flavored display
|
||||
// value. So in that case, check the parent to find out if we're legacy.
|
||||
if (aStyleDisp->mDisplay == NS_STYLE_DISPLAY_BLOCK) {
|
||||
nsStyleContext* parentStyleContext = aStyleContext->GetParent();
|
||||
NS_ASSERTION(parentStyleContext &&
|
||||
aStyleContext->GetPseudo() == nsCSSAnonBoxes::scrolledContent,
|
||||
"The only way a nsFlexContainerFrame can have 'display:block' "
|
||||
"should be if it's the inner part of a scrollable element");
|
||||
if (IsDisplayValueLegacyBox(parentStyleContext->StyleDisplay())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns the "align-items" value that's equivalent to the legacy "box-align"
|
||||
// value in the given style struct.
|
||||
static uint8_t
|
||||
ConvertLegacyStyleToAlignItems(const nsStyleXUL* aStyleXUL)
|
||||
{
|
||||
// -[moz|webkit]-box-align corresponds to modern "align-items"
|
||||
switch (aStyleXUL->mBoxAlign) {
|
||||
case NS_STYLE_BOX_ALIGN_STRETCH:
|
||||
return NS_STYLE_ALIGN_STRETCH;
|
||||
case NS_STYLE_BOX_ALIGN_START:
|
||||
return NS_STYLE_ALIGN_FLEX_START;
|
||||
case NS_STYLE_BOX_ALIGN_CENTER:
|
||||
return NS_STYLE_ALIGN_CENTER;
|
||||
case NS_STYLE_BOX_ALIGN_BASELINE:
|
||||
return NS_STYLE_ALIGN_BASELINE;
|
||||
case NS_STYLE_BOX_ALIGN_END:
|
||||
return NS_STYLE_ALIGN_FLEX_END;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("Unrecognized mBoxAlign enum value");
|
||||
// Fall back to default value of "align-items" property:
|
||||
return NS_STYLE_ALIGN_STRETCH;
|
||||
}
|
||||
|
||||
// Returns the "justify-content" value that's equivalent to the legacy
|
||||
// "box-pack" value in the given style struct.
|
||||
static uint8_t
|
||||
ConvertLegacyStyleToJustifyContent(const nsStyleXUL* aStyleXUL)
|
||||
{
|
||||
// -[moz|webkit]-box-pack corresponds to modern "justify-content"
|
||||
switch (aStyleXUL->mBoxPack) {
|
||||
case NS_STYLE_BOX_PACK_START:
|
||||
return NS_STYLE_ALIGN_FLEX_START;
|
||||
case NS_STYLE_BOX_PACK_CENTER:
|
||||
return NS_STYLE_ALIGN_CENTER;
|
||||
case NS_STYLE_BOX_PACK_END:
|
||||
return NS_STYLE_ALIGN_FLEX_END;
|
||||
case NS_STYLE_BOX_PACK_JUSTIFY:
|
||||
return NS_STYLE_ALIGN_SPACE_BETWEEN;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("Unrecognized mBoxPack enum value");
|
||||
// Fall back to default value of "justify-content" property:
|
||||
return NS_STYLE_ALIGN_FLEX_START;
|
||||
}
|
||||
|
||||
// Indicates whether advancing along the given axis is equivalent to
|
||||
// increasing our X or Y position (as opposed to decreasing it).
|
||||
@@ -156,7 +239,7 @@ PhysicalCoordFromFlexRelativeCoord(nscoord aFlexRelativeCoord,
|
||||
// Encapsulates our flex container's main & cross axes.
|
||||
class MOZ_STACK_CLASS nsFlexContainerFrame::FlexboxAxisTracker {
|
||||
public:
|
||||
FlexboxAxisTracker(const nsStylePosition* aStylePosition,
|
||||
FlexboxAxisTracker(const nsFlexContainerFrame* aFlexContainer,
|
||||
const WritingMode& aWM);
|
||||
|
||||
// Accessors:
|
||||
@@ -287,6 +370,15 @@ private:
|
||||
FlexboxAxisTracker(const FlexboxAxisTracker&) = delete;
|
||||
FlexboxAxisTracker& operator=(const FlexboxAxisTracker&) = delete;
|
||||
|
||||
// Helpers for constructor which determine the orientation of our axes, based
|
||||
// on legacy box properties (-webkit-box-orient, -webkit-box-direction) or
|
||||
// modern flexbox properties (flex-direction, flex-wrap) depending on whether
|
||||
// the flex container is a "legacy box" (as determined by IsLegacyBox).
|
||||
void InitAxesFromLegacyProps(const nsFlexContainerFrame* aFlexContainer,
|
||||
const WritingMode& aWM);
|
||||
void InitAxesFromModernProps(const nsFlexContainerFrame* aFlexContainer,
|
||||
const WritingMode& aWM);
|
||||
|
||||
// XXXdholbert [BEGIN DEPRECATED]
|
||||
AxisOrientationType mMainAxis;
|
||||
AxisOrientationType mCrossAxis;
|
||||
@@ -890,6 +982,29 @@ BuildStrutInfoFromCollapsedItems(const FlexLine* aFirstLine,
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience function to get either the "order" or the "box-ordinal-group"
|
||||
// property-value for a flex item (depending on whether the container is a
|
||||
// modern flex container or a legacy box).
|
||||
static int32_t
|
||||
GetOrderOrBoxOrdinalGroup(nsIFrame* aFlexItem, bool aIsLegacyBox)
|
||||
{
|
||||
if (aIsLegacyBox) {
|
||||
// We'll be using mBoxOrdinal, which has type uint32_t. However, the modern
|
||||
// 'order' property (whose functionality we're co-opting) has type int32_t.
|
||||
// So: if we happen to have a uint32_t value that's greater than INT32_MAX,
|
||||
// we clamp it rather than letting it overflow. Chances are, this is just
|
||||
// an author using BIG_VALUE anyway, so the clamped value should be fine.
|
||||
// (particularly since sufficiently-huge values are busted in Chrome/WebKit
|
||||
// per https://bugs.chromium.org/p/chromium/issues/detail?id=599645 )
|
||||
uint32_t clampedBoxOrdinal = std::min(aFlexItem->StyleXUL()->mBoxOrdinal,
|
||||
static_cast<uint32_t>(INT32_MAX));
|
||||
return static_cast<int32_t>(clampedBoxOrdinal);
|
||||
}
|
||||
|
||||
// Normal case: just use modern 'order' property.
|
||||
return aFlexItem->StylePosition()->mOrder;
|
||||
}
|
||||
|
||||
// Helper-function to find the first non-anonymous-box descendent of aFrame.
|
||||
static nsIFrame*
|
||||
GetFirstNonAnonBoxDescendant(nsIFrame* aFrame)
|
||||
@@ -954,6 +1069,11 @@ IsOrderLEQWithDOMFallback(nsIFrame* aFrame1,
|
||||
{
|
||||
MOZ_ASSERT(aFrame1->IsFlexItem() && aFrame2->IsFlexItem(),
|
||||
"this method only intended for comparing flex items");
|
||||
MOZ_ASSERT(aFrame1->GetParent() == aFrame2->GetParent(),
|
||||
"this method only intended for comparing siblings");
|
||||
nsStyleContext* parentFrameSC = aFrame1->GetParent()->StyleContext();
|
||||
bool isInLegacyBox = IsLegacyBox(parentFrameSC->StyleDisplay(),
|
||||
parentFrameSC);
|
||||
|
||||
if (aFrame1 == aFrame2) {
|
||||
// Anything is trivially LEQ itself, so we return "true" here... but it's
|
||||
@@ -967,8 +1087,8 @@ IsOrderLEQWithDOMFallback(nsIFrame* aFrame1,
|
||||
nsIFrame* aRealFrame1 = nsPlaceholderFrame::GetRealFrameFor(aFrame1);
|
||||
nsIFrame* aRealFrame2 = nsPlaceholderFrame::GetRealFrameFor(aFrame2);
|
||||
|
||||
int32_t order1 = aRealFrame1->StylePosition()->mOrder;
|
||||
int32_t order2 = aRealFrame2->StylePosition()->mOrder;
|
||||
int32_t order1 = GetOrderOrBoxOrdinalGroup(aRealFrame1, isInLegacyBox);
|
||||
int32_t order2 = GetOrderOrBoxOrdinalGroup(aRealFrame2, isInLegacyBox);
|
||||
|
||||
if (order1 != order2) {
|
||||
return order1 < order2;
|
||||
@@ -1035,13 +1155,18 @@ IsOrderLEQ(nsIFrame* aFrame1,
|
||||
{
|
||||
MOZ_ASSERT(aFrame1->IsFlexItem() && aFrame2->IsFlexItem(),
|
||||
"this method only intended for comparing flex items");
|
||||
MOZ_ASSERT(aFrame1->GetParent() == aFrame2->GetParent(),
|
||||
"this method only intended for comparing siblings");
|
||||
nsStyleContext* parentFrameSC = aFrame1->GetParent()->StyleContext();
|
||||
bool isInLegacyBox = IsLegacyBox(parentFrameSC->StyleDisplay(),
|
||||
parentFrameSC);
|
||||
|
||||
// If we've got a placeholder frame, use its out-of-flow frame's 'order' val.
|
||||
nsIFrame* aRealFrame1 = nsPlaceholderFrame::GetRealFrameFor(aFrame1);
|
||||
nsIFrame* aRealFrame2 = nsPlaceholderFrame::GetRealFrameFor(aFrame2);
|
||||
|
||||
int32_t order1 = aRealFrame1->StylePosition()->mOrder;
|
||||
int32_t order2 = aRealFrame2->StylePosition()->mOrder;
|
||||
int32_t order1 = GetOrderOrBoxOrdinalGroup(aRealFrame1, isInLegacyBox);
|
||||
int32_t order2 = GetOrderOrBoxOrdinalGroup(aRealFrame2, isInLegacyBox);
|
||||
|
||||
return order1 <= order2;
|
||||
}
|
||||
@@ -1049,7 +1174,7 @@ IsOrderLEQ(nsIFrame* aFrame1,
|
||||
bool
|
||||
nsFlexContainerFrame::IsHorizontal()
|
||||
{
|
||||
const FlexboxAxisTracker axisTracker(StylePosition(), GetWritingMode());
|
||||
const FlexboxAxisTracker axisTracker(this, GetWritingMode());
|
||||
return axisTracker.IsMainAxisHorizontal();
|
||||
}
|
||||
|
||||
@@ -1069,9 +1194,15 @@ nsFlexContainerFrame::GenerateFlexItemForChild(
|
||||
|
||||
// FLEX GROW & SHRINK WEIGHTS
|
||||
// --------------------------
|
||||
const nsStylePosition* stylePos = aChildFrame->StylePosition();
|
||||
float flexGrow = stylePos->mFlexGrow;
|
||||
float flexShrink = stylePos->mFlexShrink;
|
||||
float flexGrow, flexShrink;
|
||||
if (IsLegacyBox(aParentReflowState.mStyleDisplay, mStyleContext)) {
|
||||
flexGrow = flexShrink = aChildFrame->StyleXUL()->mBoxFlex;
|
||||
} else {
|
||||
const nsStylePosition* stylePos = aChildFrame->StylePosition();
|
||||
flexGrow = stylePos->mFlexGrow;
|
||||
flexShrink = stylePos->mFlexShrink;
|
||||
}
|
||||
|
||||
WritingMode childWM = childRS.GetWritingMode();
|
||||
|
||||
// MAIN SIZES (flex base size, min/max size)
|
||||
@@ -1576,14 +1707,28 @@ 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(
|
||||
mFrame->StyleContext()->GetParent());
|
||||
if (MOZ_LIKELY(mAlignSelf == NS_STYLE_ALIGN_NORMAL)) {
|
||||
mAlignSelf = NS_STYLE_ALIGN_STRETCH;
|
||||
}
|
||||
const nsHTMLReflowState* containerRS = aFlexItemReflowState.parentReflowState;
|
||||
if (IsLegacyBox(containerRS->mStyleDisplay,
|
||||
containerRS->frame->StyleContext())) {
|
||||
// For -webkit-box/-webkit-inline-box, we need to:
|
||||
// (1) Use "-webkit-box-align" instead of "align-items" to determine the
|
||||
// container's cross-axis alignment behavior.
|
||||
// (2) Suppress the ability for flex items to override that with their own
|
||||
// cross-axis alignment. (The legacy box model doesn't support this.)
|
||||
// So, each FlexItem simply copies the container's converted "align-items"
|
||||
// value and disregards their own "align-self" property.
|
||||
const nsStyleXUL* containerStyleXUL = containerRS->frame->StyleXUL();
|
||||
mAlignSelf = ConvertLegacyStyleToAlignItems(containerStyleXUL);
|
||||
} else {
|
||||
mAlignSelf = aFlexItemReflowState.mStylePosition->ComputedAlignSelf(
|
||||
mFrame->StyleContext()->GetParent());
|
||||
if (MOZ_LIKELY(mAlignSelf == NS_STYLE_ALIGN_NORMAL)) {
|
||||
mAlignSelf = NS_STYLE_ALIGN_STRETCH;
|
||||
}
|
||||
|
||||
// XXX strip off the <overflow-position> bit until we implement that
|
||||
mAlignSelf &= ~NS_STYLE_ALIGN_FLAG_BITS;
|
||||
// XXX strip off the <overflow-position> bit until we implement that
|
||||
mAlignSelf &= ~NS_STYLE_ALIGN_FLAG_BITS;
|
||||
}
|
||||
|
||||
SetFlexBaseSizeAndMainSize(aFlexBaseSize);
|
||||
CheckForMinSizeAuto(aFlexItemReflowState, aAxisTracker);
|
||||
@@ -1940,7 +2085,7 @@ public:
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsFlexContainerFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsFlexContainerFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsFlexContainerFrameSuper)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsFlexContainerFrame)
|
||||
|
||||
@@ -3058,12 +3203,92 @@ BlockDirToAxisOrientation(WritingMode::BlockDir aBlockDir)
|
||||
return eAxis_TB; // in case of unforseen error, assume English TTB block-flow
|
||||
}
|
||||
|
||||
FlexboxAxisTracker::FlexboxAxisTracker(const nsStylePosition* aStylePosition,
|
||||
const WritingMode& aWM)
|
||||
FlexboxAxisTracker::FlexboxAxisTracker(
|
||||
const nsFlexContainerFrame* aFlexContainer,
|
||||
const WritingMode& aWM)
|
||||
: mWM(aWM),
|
||||
mAreAxesInternallyReversed(false)
|
||||
{
|
||||
uint32_t flexDirection = aStylePosition->mFlexDirection;
|
||||
if (IsLegacyBox(aFlexContainer->StyleDisplay(),
|
||||
aFlexContainer->StyleContext())) {
|
||||
InitAxesFromLegacyProps(aFlexContainer, aWM);
|
||||
} else {
|
||||
InitAxesFromModernProps(aFlexContainer, aWM);
|
||||
}
|
||||
|
||||
// Master switch to enable/disable bug 983427's code for reversing our axes
|
||||
// and reversing some logic, to avoid reflowing children in bottom-to-top
|
||||
// order. (This switch can be removed eventually, but for now, it allows
|
||||
// this special-case code path to be compared against the normal code path.)
|
||||
static bool sPreventBottomToTopChildOrdering = true;
|
||||
|
||||
if (sPreventBottomToTopChildOrdering) {
|
||||
// If either axis is bottom-to-top, we flip both axes (and set a flag
|
||||
// so that we can flip some logic to make the reversal transparent).
|
||||
if (eAxis_BT == mMainAxis || eAxis_BT == mCrossAxis) {
|
||||
mMainAxis = GetReverseAxis(mMainAxis);
|
||||
mCrossAxis = GetReverseAxis(mCrossAxis);
|
||||
mAreAxesInternallyReversed = true;
|
||||
mIsMainAxisReversed = !mIsMainAxisReversed;
|
||||
mIsCrossAxisReversed = !mIsCrossAxisReversed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FlexboxAxisTracker::InitAxesFromLegacyProps(
|
||||
const nsFlexContainerFrame* aFlexContainer,
|
||||
const WritingMode& aWM)
|
||||
{
|
||||
const nsStyleXUL* styleXUL = aFlexContainer->StyleXUL();
|
||||
|
||||
const bool boxOrientIsVertical = (styleXUL->mBoxOrient ==
|
||||
NS_STYLE_BOX_ORIENT_VERTICAL);
|
||||
const bool wmIsVertical = aWM.IsVertical();
|
||||
|
||||
// If box-orient agrees with our writing-mode, then we're "row-oriented"
|
||||
// (i.e. the flexbox main axis is the same as our writing mode's inline
|
||||
// direction). Otherwise, we're column-oriented (i.e. the flexbox's main
|
||||
// axis is perpendicular to the writing-mode's inline direction).
|
||||
mIsRowOriented = (boxOrientIsVertical == wmIsVertical);
|
||||
|
||||
// XXXdholbert BEGIN CODE TO SET DEPRECATED MEMBER-VARS
|
||||
if (boxOrientIsVertical) {
|
||||
mMainAxis = eAxis_TB;
|
||||
mCrossAxis = eAxis_LR;
|
||||
} else {
|
||||
mMainAxis = eAxis_LR;
|
||||
mCrossAxis = eAxis_TB;
|
||||
}
|
||||
// "direction: rtl" (in a horizontal -webkit-box) reverses the main axis.
|
||||
// (Note this we don't toggle "mIsMainAxisReversed" for this condition,
|
||||
// because the main axis will still match aWM's inline direction.)
|
||||
if (aWM.IsBidiLTR()) {
|
||||
mMainAxis = GetReverseAxis(mMainAxis);
|
||||
}
|
||||
// XXXdholbert END CODE TO SET DEPRECATED MEMBER-VARS
|
||||
|
||||
// Legacy flexbox can use "-webkit-box-direction: reverse" to reverse the
|
||||
// main axis (so it runs in the reverse direction of the inline axis):
|
||||
if (styleXUL->mBoxDirection == NS_STYLE_BOX_DIRECTION_REVERSE) {
|
||||
mMainAxis = GetReverseAxis(mMainAxis);
|
||||
mIsMainAxisReversed = true;
|
||||
} else {
|
||||
mIsMainAxisReversed = false;
|
||||
}
|
||||
|
||||
// Legacy flexbox does not support reversing the cross axis -- it has no
|
||||
// equivalent of modern flexbox's "flex-wrap: wrap-reverse".
|
||||
mIsCrossAxisReversed = false;
|
||||
}
|
||||
|
||||
void
|
||||
FlexboxAxisTracker::InitAxesFromModernProps(
|
||||
const nsFlexContainerFrame* aFlexContainer,
|
||||
const WritingMode& aWM)
|
||||
{
|
||||
const nsStylePosition* stylePos = aFlexContainer->StylePosition();
|
||||
uint32_t flexDirection = stylePos->mFlexDirection;
|
||||
|
||||
// Inline dimension ("start-to-end"):
|
||||
// (NOTE: I'm intentionally not calling these "inlineAxis"/"blockAxis", since
|
||||
@@ -3111,30 +3336,12 @@ FlexboxAxisTracker::FlexboxAxisTracker(const nsStylePosition* aStylePosition,
|
||||
}
|
||||
|
||||
// "flex-wrap: wrap-reverse" reverses our cross axis.
|
||||
if (aStylePosition->mFlexWrap == NS_STYLE_FLEX_WRAP_WRAP_REVERSE) {
|
||||
if (stylePos->mFlexWrap == NS_STYLE_FLEX_WRAP_WRAP_REVERSE) {
|
||||
mCrossAxis = GetReverseAxis(mCrossAxis);
|
||||
mIsCrossAxisReversed = true;
|
||||
} else {
|
||||
mIsCrossAxisReversed = false;
|
||||
}
|
||||
|
||||
// Master switch to enable/disable bug 983427's code for reversing our axes
|
||||
// and reversing some logic, to avoid reflowing children in bottom-to-top
|
||||
// order. (This switch can be removed eventually, but for now, it allows
|
||||
// this special-case code path to be compared against the normal code path.)
|
||||
static bool sPreventBottomToTopChildOrdering = true;
|
||||
|
||||
if (sPreventBottomToTopChildOrdering) {
|
||||
// If either axis is bottom-to-top, we flip both axes (and set a flag
|
||||
// so that we can flip some logic to make the reversal transparent).
|
||||
if (eAxis_BT == mMainAxis || eAxis_BT == mCrossAxis) {
|
||||
mMainAxis = GetReverseAxis(mMainAxis);
|
||||
mCrossAxis = GetReverseAxis(mCrossAxis);
|
||||
mAreAxesInternallyReversed = true;
|
||||
mIsMainAxisReversed = !mIsMainAxisReversed;
|
||||
mIsCrossAxisReversed = !mIsCrossAxisReversed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allocates a new FlexLine, adds it to the given LinkedList (at the front or
|
||||
@@ -3647,8 +3854,7 @@ nsFlexContainerFrame::Reflow(nsPresContext* aPresContext,
|
||||
SortChildrenIfNeeded<IsOrderLEQWithDOMFallback>();
|
||||
}
|
||||
|
||||
const FlexboxAxisTracker axisTracker(aReflowState.mStylePosition,
|
||||
aReflowState.GetWritingMode());
|
||||
const FlexboxAxisTracker axisTracker(this, aReflowState.GetWritingMode());
|
||||
|
||||
// If we're being fragmented into a constrained BSize, then subtract off
|
||||
// borderpadding BStart from that constrained BSize, to get the available
|
||||
@@ -3858,11 +4064,14 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
for (FlexLine* line = lines.getFirst(); line; line = line->getNext()) {
|
||||
const auto justifyContent = IsLegacyBox(aReflowState.mStyleDisplay,
|
||||
mStyleContext) ?
|
||||
ConvertLegacyStyleToJustifyContent(StyleXUL()) :
|
||||
aReflowState.mStylePosition->ComputedJustifyContent();
|
||||
|
||||
for (FlexLine* line = lines.getFirst(); line; line = line->getNext()) {
|
||||
// Main-Axis Alignment - Flexbox spec section 9.5
|
||||
// ==============================================
|
||||
auto justifyContent = aReflowState.mStylePosition->ComputedJustifyContent();
|
||||
line->PositionItemsInMainAxis(justifyContent,
|
||||
aContentBoxMainSize,
|
||||
aAxisTracker);
|
||||
@@ -4069,6 +4278,7 @@ nsFlexContainerFrame::MoveFlexItemToFinalPosition(
|
||||
logicalOffsets, &aFramePos,
|
||||
aContainerSize);
|
||||
aItem.Frame()->SetPosition(outerWM, aFramePos, aContainerSize);
|
||||
PositionFrameView(aItem.Frame());
|
||||
PositionChildViews(aItem.Frame());
|
||||
}
|
||||
|
||||
@@ -4186,7 +4396,7 @@ nsFlexContainerFrame::GetMinISize(nsRenderingContext* aRenderingContext)
|
||||
DISPLAY_MIN_WIDTH(this, minWidth);
|
||||
|
||||
const nsStylePosition* stylePos = StylePosition();
|
||||
const FlexboxAxisTracker axisTracker(stylePos, GetWritingMode());
|
||||
const FlexboxAxisTracker axisTracker(this, GetWritingMode());
|
||||
|
||||
for (nsIFrame* childFrame : mFrames) {
|
||||
nscoord childMinWidth =
|
||||
@@ -4217,7 +4427,7 @@ nsFlexContainerFrame::GetPrefISize(nsRenderingContext* aRenderingContext)
|
||||
// Whenever anything happens that might change it, set it to
|
||||
// NS_INTRINSIC_WIDTH_UNKNOWN (like nsBlockFrame::MarkIntrinsicISizesDirty
|
||||
// does)
|
||||
const FlexboxAxisTracker axisTracker(StylePosition(), GetWritingMode());
|
||||
const FlexboxAxisTracker axisTracker(this, GetWritingMode());
|
||||
|
||||
for (nsIFrame* childFrame : mFrames) {
|
||||
nscoord childPrefWidth =
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* version 2.0 (the "License"). You can obtain a copy of the License at
|
||||
* http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* rendering object for CSS "display: flex" */
|
||||
/* rendering object for CSS "display: flex" and "display: -webkit-box" */
|
||||
|
||||
#ifndef nsFlexContainerFrame_h___
|
||||
#define nsFlexContainerFrame_h___
|
||||
@@ -20,9 +20,27 @@ class LogicalPoint;
|
||||
nsContainerFrame* NS_NewFlexContainerFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
typedef nsContainerFrame nsFlexContainerFrameSuper;
|
||||
|
||||
class nsFlexContainerFrame : public nsFlexContainerFrameSuper {
|
||||
/**
|
||||
* This is the rendering object used for laying out elements with
|
||||
* "display: flex" or "display: inline-flex".
|
||||
*
|
||||
* We also use this class for elements with "display: -webkit-box" or
|
||||
* "display: -webkit-inline-box" (but not "-moz-box" / "-moz-inline-box" --
|
||||
* those are rendered with old-school XUL frame classes).
|
||||
*
|
||||
* Note: we represent the -webkit-box family of properties (-webkit-box-orient,
|
||||
* -webkit-box-flex, etc.) as aliases for their -moz equivalents. And for
|
||||
* -webkit-{inline-}box containers, nsFlexContainerFrame will honor those
|
||||
* "legacy" properties for alignment/flexibility/etc. *instead of* honoring the
|
||||
* modern flexbox & alignment properties. For brevity, many comments in
|
||||
* nsFlexContainerFrame.cpp simply refer to these properties using their
|
||||
* "-webkit" versions, since we're mostly expecting to encounter them in that
|
||||
* form. (Technically, the "-moz" versions of these properties *can* influence
|
||||
* layout here as well (since that's what the -webkit versions are aliased to)
|
||||
* -- but only inside of a "display:-webkit-{inline-}box" container.)
|
||||
*/
|
||||
class nsFlexContainerFrame : public nsContainerFrame {
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
NS_DECL_QUERYFRAME_TARGET(nsFlexContainerFrame)
|
||||
@@ -62,8 +80,8 @@ public:
|
||||
|
||||
protected:
|
||||
// Protected constructor & destructor
|
||||
explicit nsFlexContainerFrame(nsStyleContext* aContext) :
|
||||
nsFlexContainerFrameSuper(aContext)
|
||||
explicit nsFlexContainerFrame(nsStyleContext* aContext)
|
||||
: nsContainerFrame(aContext)
|
||||
{}
|
||||
virtual ~nsFlexContainerFrame();
|
||||
|
||||
|
||||
+77
-38
@@ -414,7 +414,7 @@ nsFrame::~nsFrame()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsFrame);
|
||||
|
||||
MOZ_ASSERT(GetVisibility() != Visibility::APPROXIMATELY_VISIBLE,
|
||||
MOZ_ASSERT(!IsVisibleOrMayBecomeVisibleSoon(),
|
||||
"Visible nsFrame is being destroyed");
|
||||
|
||||
NS_IF_RELEASE(mContent);
|
||||
@@ -553,7 +553,7 @@ nsFrame::Init(nsIContent* aContent,
|
||||
|
||||
if (HasAnyStateBits(NS_FRAME_IN_POPUP) && TrackingVisibility()) {
|
||||
// Assume all frames in popups are visible.
|
||||
IncApproximateVisibleCount();
|
||||
IncVisibilityCount(VisibilityCounter::IN_DISPLAYPORT);
|
||||
}
|
||||
}
|
||||
const nsStyleDisplay *disp = StyleDisplay();
|
||||
@@ -606,7 +606,7 @@ nsFrame::Init(nsIContent* aContent,
|
||||
|
||||
if (PresContext()->PresShell()->AssumeAllFramesVisible() &&
|
||||
TrackingVisibility()) {
|
||||
IncApproximateVisibleCount();
|
||||
IncVisibilityCount(VisibilityCounter::IN_DISPLAYPORT);
|
||||
}
|
||||
|
||||
DidSetStyleContext(nullptr);
|
||||
@@ -733,8 +733,8 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
// frame reconstruction induced by style changes.
|
||||
DisableVisibilityTracking();
|
||||
|
||||
// Ensure that we're not in the approximately visible list anymore.
|
||||
PresContext()->GetPresShell()->RemoveFrameFromApproximatelyVisibleList(this);
|
||||
// Ensure that we're not in the visible list anymore.
|
||||
PresContext()->GetPresShell()->MarkFrameNonvisible(this);
|
||||
|
||||
shell->NotifyDestroyingFrame(this);
|
||||
|
||||
@@ -1476,6 +1476,18 @@ nsIFrame::GetCrossDocChildLists(nsTArray<ChildList>* aLists)
|
||||
GetChildLists(aLists);
|
||||
}
|
||||
|
||||
static Visibility
|
||||
VisibilityStateAsVisibility(const nsIFrame::VisibilityState& aState)
|
||||
{
|
||||
if (aState.mInDisplayPortCounter > 0) {
|
||||
return Visibility::IN_DISPLAYPORT; // Takes priority over MAY_BECOME_VISIBLE.
|
||||
}
|
||||
if (aState.mApproximateCounter > 0) {
|
||||
return Visibility::MAY_BECOME_VISIBLE;
|
||||
}
|
||||
return Visibility::NONVISIBLE;
|
||||
}
|
||||
|
||||
Visibility
|
||||
nsIFrame::GetVisibility() const
|
||||
{
|
||||
@@ -1485,14 +1497,12 @@ nsIFrame::GetVisibility() const
|
||||
|
||||
bool isSet = false;
|
||||
FrameProperties props = Properties();
|
||||
uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet);
|
||||
VisibilityState state = props.Get(VisibilityStateProperty(), &isSet);
|
||||
|
||||
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
|
||||
"if NS_FRAME_VISIBILITY_IS_TRACKED is set");
|
||||
|
||||
return visibleCount > 0
|
||||
? Visibility::APPROXIMATELY_VISIBLE
|
||||
: Visibility::APPROXIMATELY_NONVISIBLE;
|
||||
return VisibilityStateAsVisibility(state);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1504,7 +1514,7 @@ nsIFrame::UpdateVisibilitySynchronously()
|
||||
}
|
||||
|
||||
if (presShell->AssumeAllFramesVisible()) {
|
||||
presShell->EnsureFrameInApproximatelyVisibleList(this);
|
||||
presShell->MarkFrameVisibleInDisplayPort(this);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1545,9 +1555,9 @@ nsIFrame::UpdateVisibilitySynchronously()
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
presShell->EnsureFrameInApproximatelyVisibleList(this);
|
||||
presShell->MarkFrameVisibleInDisplayPort(this);
|
||||
} else {
|
||||
presShell->RemoveFrameFromApproximatelyVisibleList(this);
|
||||
presShell->MarkFrameNonvisible(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1566,7 +1576,7 @@ nsIFrame::EnableVisibilityTracking()
|
||||
// Add the state bit so we know to track visibility for this frame, and
|
||||
// initialize the frame property.
|
||||
AddStateBits(NS_FRAME_VISIBILITY_IS_TRACKED);
|
||||
props.Set(VisibilityStateProperty(), 0);
|
||||
props.Set(VisibilityStateProperty(), VisibilityState{0, 0});
|
||||
|
||||
nsIPresShell* presShell = PresContext()->PresShell();
|
||||
if (!presShell) {
|
||||
@@ -1589,66 +1599,87 @@ nsIFrame::DisableVisibilityTracking()
|
||||
|
||||
bool isSet = false;
|
||||
FrameProperties props = Properties();
|
||||
uint32_t visibleCount = props.Remove(VisibilityStateProperty(), &isSet);
|
||||
VisibilityState state = props.Remove(VisibilityStateProperty(), &isSet);
|
||||
|
||||
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
|
||||
"if NS_FRAME_VISIBILITY_IS_TRACKED is set");
|
||||
|
||||
RemoveStateBits(NS_FRAME_VISIBILITY_IS_TRACKED);
|
||||
|
||||
if (visibleCount == 0) {
|
||||
return; // We were nonvisible.
|
||||
Visibility previousVisibility = VisibilityStateAsVisibility(state);
|
||||
if (previousVisibility == Visibility::NONVISIBLE) {
|
||||
return; // We were already nonvisible.
|
||||
}
|
||||
|
||||
// We were visible, so send an OnVisibilityChange() notification.
|
||||
OnVisibilityChange(Visibility::APPROXIMATELY_NONVISIBLE);
|
||||
OnVisibilityChange(Visibility::NONVISIBLE);
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::DecApproximateVisibleCount(Maybe<OnNonvisible> aNonvisibleAction
|
||||
/* = Nothing() */)
|
||||
nsIFrame::DecVisibilityCount(VisibilityCounter aCounter,
|
||||
Maybe<OnNonvisible> aNonvisibleAction /* = Nothing() */)
|
||||
{
|
||||
MOZ_ASSERT(GetStateBits() & NS_FRAME_VISIBILITY_IS_TRACKED);
|
||||
|
||||
bool isSet = false;
|
||||
FrameProperties props = Properties();
|
||||
uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet);
|
||||
VisibilityState state = props.Get(VisibilityStateProperty(), &isSet);
|
||||
|
||||
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
|
||||
"if NS_FRAME_VISIBILITY_IS_TRACKED is set");
|
||||
MOZ_ASSERT(visibleCount > 0, "Frame is already nonvisible and we're "
|
||||
"decrementing its visible count?");
|
||||
MOZ_ASSERT_IF(aCounter == VisibilityCounter::MAY_BECOME_VISIBLE,
|
||||
state.mApproximateCounter > 0);
|
||||
MOZ_ASSERT_IF(aCounter == VisibilityCounter::IN_DISPLAYPORT,
|
||||
state.mInDisplayPortCounter > 0);
|
||||
|
||||
visibleCount--;
|
||||
props.Set(VisibilityStateProperty(), visibleCount);
|
||||
if (visibleCount > 0) {
|
||||
return;
|
||||
Visibility previousVisibility = VisibilityStateAsVisibility(state);
|
||||
|
||||
if (aCounter == VisibilityCounter::MAY_BECOME_VISIBLE) {
|
||||
state.mApproximateCounter--;
|
||||
} else {
|
||||
state.mInDisplayPortCounter--;
|
||||
}
|
||||
|
||||
// We just became nonvisible, so send an OnVisibilityChange() notification.
|
||||
OnVisibilityChange(Visibility::APPROXIMATELY_NONVISIBLE, aNonvisibleAction);
|
||||
props.Set(VisibilityStateProperty(), state);
|
||||
|
||||
Visibility newVisibility = VisibilityStateAsVisibility(state);
|
||||
if (newVisibility == previousVisibility) {
|
||||
return; // Nothing changed.
|
||||
}
|
||||
|
||||
// Our visibility just changed, so send an OnVisibilityChange() notification.
|
||||
OnVisibilityChange(newVisibility, aNonvisibleAction);
|
||||
}
|
||||
|
||||
void
|
||||
nsIFrame::IncApproximateVisibleCount()
|
||||
nsIFrame::IncVisibilityCount(VisibilityCounter aCounter)
|
||||
{
|
||||
MOZ_ASSERT(GetStateBits() & NS_FRAME_VISIBILITY_IS_TRACKED);
|
||||
|
||||
bool isSet = false;
|
||||
FrameProperties props = Properties();
|
||||
uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet);
|
||||
VisibilityState state = props.Get(VisibilityStateProperty(), &isSet);
|
||||
|
||||
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
|
||||
"if NS_FRAME_VISIBILITY_IS_TRACKED is set");
|
||||
|
||||
visibleCount++;
|
||||
props.Set(VisibilityStateProperty(), visibleCount);
|
||||
if (visibleCount > 1) {
|
||||
return;
|
||||
Visibility previousVisibility = VisibilityStateAsVisibility(state);
|
||||
|
||||
if (aCounter == VisibilityCounter::MAY_BECOME_VISIBLE) {
|
||||
state.mApproximateCounter++;
|
||||
} else {
|
||||
state.mInDisplayPortCounter++;
|
||||
}
|
||||
|
||||
// We just became visible, so send an OnVisibilityChange() notification.
|
||||
OnVisibilityChange(Visibility::APPROXIMATELY_VISIBLE);
|
||||
props.Set(VisibilityStateProperty(), state);
|
||||
|
||||
Visibility newVisibility = VisibilityStateAsVisibility(state);
|
||||
if (newVisibility == previousVisibility) {
|
||||
return; // Nothing changed.
|
||||
}
|
||||
|
||||
// Our visibility just changed, so send an OnVisibilityChange() notification.
|
||||
OnVisibilityChange(newVisibility);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2683,6 +2714,14 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
!PresContext()->GetTheme()->WidgetIsContainer(ourDisp->mAppearance))
|
||||
return;
|
||||
|
||||
// Since we're now sure that we're adding this frame to the display list
|
||||
// (which means we're painting it, modulo occlusion), mark it as visible
|
||||
// within the displayport.
|
||||
if (aBuilder->IsPaintingToWindow() && child->TrackingVisibility()) {
|
||||
nsIPresShell* shell = child->PresContext()->PresShell();
|
||||
shell->MarkFrameVisibleInDisplayPort(child);
|
||||
}
|
||||
|
||||
// Child is composited if it's transformed, partially transparent, or has
|
||||
// SVG effects or a blend mode..
|
||||
const nsStyleDisplay* disp = child->StyleDisplay();
|
||||
@@ -9166,7 +9205,7 @@ nsIFrame::AddInPopupStateBitToDescendants(nsIFrame* aFrame)
|
||||
if (!aFrame->HasAnyStateBits(NS_FRAME_IN_POPUP) &&
|
||||
aFrame->TrackingVisibility()) {
|
||||
// Assume all frames in popups are visible.
|
||||
aFrame->IncApproximateVisibleCount();
|
||||
aFrame->IncVisibilityCount(VisibilityCounter::IN_DISPLAYPORT);
|
||||
}
|
||||
|
||||
aFrame->AddStateBits(NS_FRAME_IN_POPUP);
|
||||
@@ -9196,7 +9235,7 @@ nsIFrame::RemoveInPopupStateBitFromDescendants(nsIFrame* aFrame)
|
||||
if (aFrame->TrackingVisibility()) {
|
||||
// We assume all frames in popups are visible, so this decrement balances
|
||||
// out the increment in AddInPopupStateBitToDescendants above.
|
||||
aFrame->DecApproximateVisibleCount();
|
||||
aFrame->DecVisibilityCount(VisibilityCounter::IN_DISPLAYPORT);
|
||||
}
|
||||
|
||||
AutoTArray<nsIFrame::ChildList,4> childListArray;
|
||||
|
||||
+35
-11
@@ -424,6 +424,7 @@ public:
|
||||
template<typename T=void>
|
||||
using PropertyDescriptor = const mozilla::FramePropertyDescriptor<T>*;
|
||||
using Visibility = mozilla::Visibility;
|
||||
using VisibilityCounter = mozilla::VisibilityCounter;
|
||||
|
||||
typedef mozilla::FrameProperties FrameProperties;
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
@@ -1106,6 +1107,15 @@ public:
|
||||
/// for the possible return values and their meanings.
|
||||
Visibility GetVisibility() const;
|
||||
|
||||
/// @return true if this frame is either in the displayport now or may
|
||||
/// become visible soon.
|
||||
bool IsVisibleOrMayBecomeVisibleSoon() const
|
||||
{
|
||||
Visibility visibility = GetVisibility();
|
||||
return visibility == Visibility::MAY_BECOME_VISIBLE ||
|
||||
visibility == Visibility::IN_DISPLAYPORT;
|
||||
}
|
||||
|
||||
/// Update the visibility state of this frame synchronously.
|
||||
/// XXX(seth): Avoid using this method; we should be relying on the refresh
|
||||
/// driver for visibility updates. This method, which replaces
|
||||
@@ -1114,11 +1124,17 @@ public:
|
||||
/// the old image visibility code.
|
||||
void UpdateVisibilitySynchronously();
|
||||
|
||||
// A frame property which stores the visibility state of this frame. Right
|
||||
// now that consists of an approximate visibility counter represented as a
|
||||
// uint32_t. When the visibility of this frame is not being tracked, this
|
||||
// property is absent.
|
||||
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(VisibilityStateProperty, uint32_t);
|
||||
struct VisibilityState
|
||||
{
|
||||
unsigned int mApproximateCounter : 16;
|
||||
unsigned int mInDisplayPortCounter : 16;
|
||||
};
|
||||
|
||||
// A frame property which stores the visibility state of this frame, which
|
||||
// consists of a VisibilityState value that stores counters for each type of
|
||||
// visibility we track. When the visibility of this frame is not being
|
||||
// tracked, this property is absent.
|
||||
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(VisibilityStateProperty, VisibilityState);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -1163,12 +1179,19 @@ public:
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* We track the approximate visibility of frames using a counter; if it's
|
||||
* non-zero, then the frame is considered visible. Using a counter allows us
|
||||
* to account for situations where the frame may be visible in more than one
|
||||
* place (for example, via -moz-element), and it simplifies the
|
||||
* We track the visibility of frames using counters; if any of the counters
|
||||
* are non-zero, then the frame is considered visible. Using counters allows
|
||||
* us to account for situations where the frame may be visible in more than
|
||||
* one place (for example, via -moz-element), and it simplifies the
|
||||
* implementation of our approximate visibility tracking algorithms.
|
||||
*
|
||||
* There are two visibility counters for each frame: the approximate counter
|
||||
* (which is based on our heuristics for which frames may become visible
|
||||
* "soon"), and the in-displayport counter (which records if the frame was
|
||||
* within the displayport at the last paint).
|
||||
*
|
||||
*
|
||||
* @param aCounter Which counter to increment or decrement.
|
||||
* @param aNonvisibleAction A requested action if the frame has become
|
||||
* nonvisible. If Nothing(), no action is
|
||||
* requested. If DISCARD_IMAGES is specified, the
|
||||
@@ -1176,8 +1199,9 @@ public:
|
||||
* associated with to discard their surfaces if
|
||||
* possible.
|
||||
*/
|
||||
void DecApproximateVisibleCount(Maybe<OnNonvisible> aNonvisibleAction = Nothing());
|
||||
void IncApproximateVisibleCount();
|
||||
void DecVisibilityCount(VisibilityCounter aCounter,
|
||||
Maybe<OnNonvisible> aNonvisibleAction = Nothing());
|
||||
void IncVisibilityCount(VisibilityCounter aCounter);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -136,7 +136,7 @@ NS_IMPL_FRAMEARENA_HELPERS(nsImageFrame)
|
||||
|
||||
|
||||
nsImageFrame::nsImageFrame(nsStyleContext* aContext) :
|
||||
ImageFrameSuper(aContext),
|
||||
nsAtomicContainerFrame(aContext),
|
||||
mComputedSize(0, 0),
|
||||
mIntrinsicRatio(0, 0),
|
||||
mDisplayingIcon(false),
|
||||
@@ -158,7 +158,7 @@ nsImageFrame::~nsImageFrame()
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsImageFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsImageFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(ImageFrameSuper)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsAtomicContainerFrame)
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
a11y::AccType
|
||||
@@ -222,13 +222,13 @@ nsImageFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
if (mDisplayingIcon)
|
||||
gIconLoad->RemoveIconObserver(this);
|
||||
|
||||
ImageFrameSuper::DestroyFrom(aDestructRoot);
|
||||
nsAtomicContainerFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
void
|
||||
nsImageFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
{
|
||||
ImageFrameSuper::DidSetStyleContext(aOldStyleContext);
|
||||
nsAtomicContainerFrame::DidSetStyleContext(aOldStyleContext);
|
||||
|
||||
if (!mImage) {
|
||||
// We'll pick this change up whenever we do get an image.
|
||||
@@ -258,7 +258,7 @@ nsImageFrame::Init(nsIContent* aContent,
|
||||
nsContainerFrame* aParent,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
ImageFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
||||
nsAtomicContainerFrame::Init(aContent, aParent, aPrevInFlow);
|
||||
|
||||
mListener = new nsImageListener(this);
|
||||
|
||||
@@ -557,12 +557,12 @@ nsImageFrame::OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage)
|
||||
// This is valid and for the current request, so update our stored image
|
||||
// container, orienting according to our style.
|
||||
mImage = nsLayoutUtils::OrientImage(aImage, StyleVisibility()->mImageOrientation);
|
||||
|
||||
|
||||
intrinsicSizeChanged = UpdateIntrinsicSize(mImage);
|
||||
intrinsicSizeChanged = UpdateIntrinsicRatio(mImage) || intrinsicSizeChanged;
|
||||
} else {
|
||||
// We no longer have a valid image, so release our stored image container.
|
||||
mImage = nullptr;
|
||||
mImage = mPrevImage = nullptr;
|
||||
|
||||
// Have to size to 0,0 so that GetDesiredSize recalculates the size.
|
||||
mIntrinsicSize.width.SetCoordValue(0);
|
||||
@@ -586,6 +586,8 @@ nsImageFrame::OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage)
|
||||
// so we're ready to request a decode.
|
||||
MaybeDecodeForPredictedSize();
|
||||
}
|
||||
|
||||
mPrevImage = nullptr;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -675,7 +677,7 @@ nsImageFrame::NotifyNewCurrentRequest(imgIRequest *aRequest,
|
||||
intrinsicSizeChanged = UpdateIntrinsicRatio(mImage) || intrinsicSizeChanged;
|
||||
} else {
|
||||
// We no longer have a valid image, so release our stored image container.
|
||||
mImage = nullptr;
|
||||
mImage = mPrevImage = nullptr;
|
||||
|
||||
// Have to size to 0,0 so that GetDesiredSize recalculates the size
|
||||
mIntrinsicSize.width.SetCoordValue(0);
|
||||
@@ -696,6 +698,8 @@ nsImageFrame::NotifyNewCurrentRequest(imgIRequest *aRequest,
|
||||
// so we're ready to request a decode.
|
||||
MaybeDecodeForPredictedSize();
|
||||
}
|
||||
|
||||
mPrevImage = nullptr;
|
||||
}
|
||||
// Update border+content to account for image change
|
||||
InvalidateFrame();
|
||||
@@ -714,7 +718,7 @@ nsImageFrame::MaybeDecodeForPredictedSize()
|
||||
return; // We won't draw anything, so no point in decoding.
|
||||
}
|
||||
|
||||
if (GetVisibility() != Visibility::APPROXIMATELY_VISIBLE) {
|
||||
if (!IsVisibleOrMayBecomeVisibleSoon()) {
|
||||
return; // We're not visible, so don't decode.
|
||||
}
|
||||
|
||||
@@ -1486,7 +1490,8 @@ static void PaintDebugImageMap(nsIFrame* aFrame, DrawTarget* aDrawTarget,
|
||||
|
||||
void
|
||||
nsDisplayImage::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx) {
|
||||
nsRenderingContext* aCtx)
|
||||
{
|
||||
uint32_t flags = imgIContainer::FLAG_NONE;
|
||||
if (aBuilder->ShouldSyncDecodeImages()) {
|
||||
flags |= imgIContainer::FLAG_SYNC_DECODE;
|
||||
@@ -1498,6 +1503,17 @@ nsDisplayImage::Paint(nsDisplayListBuilder* aBuilder,
|
||||
DrawResult result = static_cast<nsImageFrame*>(mFrame)->
|
||||
PaintImage(*aCtx, ToReferenceFrame(), mVisibleRect, mImage, flags);
|
||||
|
||||
if (result == DrawResult::NOT_READY ||
|
||||
result == DrawResult::INCOMPLETE ||
|
||||
result == DrawResult::TEMPORARY_ERROR) {
|
||||
// If the current image failed to paint because it's still loading or
|
||||
// decoding, try painting the previous image.
|
||||
if (mPrevImage) {
|
||||
result = static_cast<nsImageFrame*>(mFrame)->
|
||||
PaintImage(*aCtx, ToReferenceFrame(), mVisibleRect, mPrevImage, flags);
|
||||
}
|
||||
}
|
||||
|
||||
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
|
||||
}
|
||||
|
||||
@@ -1692,6 +1708,12 @@ nsImageFrame::PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt,
|
||||
map->Draw(this, *drawTarget, black, strokeOptions);
|
||||
}
|
||||
|
||||
if (result == DrawResult::SUCCESS) {
|
||||
mPrevImage = aImage;
|
||||
} else if (result == DrawResult::BAD_IMAGE) {
|
||||
mPrevImage = nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1746,7 +1768,7 @@ nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
} else {
|
||||
aLists.Content()->AppendNewToTop(new (aBuilder)
|
||||
nsDisplayImage(aBuilder, this, mImage));
|
||||
nsDisplayImage(aBuilder, this, mImage, mPrevImage));
|
||||
|
||||
// If we were previously displaying an icon, we're not anymore
|
||||
if (mDisplayingIcon) {
|
||||
@@ -1998,7 +2020,7 @@ nsImageFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
return ImageFrameSuper::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||
return nsAtomicContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -2035,8 +2057,8 @@ nsImageFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
int32_t aModType)
|
||||
{
|
||||
nsresult rv = ImageFrameSuper::AttributeChanged(aNameSpaceID,
|
||||
aAttribute, aModType);
|
||||
nsresult rv = nsAtomicContainerFrame::AttributeChanged(aNameSpaceID,
|
||||
aAttribute, aModType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@@ -2057,16 +2079,18 @@ nsImageFrame::OnVisibilityChange(Visibility aNewVisibility,
|
||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
|
||||
if (!imageLoader) {
|
||||
MOZ_ASSERT_UNREACHABLE("Should have an nsIImageLoadingContent");
|
||||
nsAtomicContainerFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||
return;
|
||||
}
|
||||
|
||||
imageLoader->OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||
|
||||
if (aNewVisibility == Visibility::APPROXIMATELY_VISIBLE) {
|
||||
if (aNewVisibility == Visibility::MAY_BECOME_VISIBLE ||
|
||||
aNewVisibility == Visibility::IN_DISPLAYPORT) {
|
||||
MaybeDecodeForPredictedSize();
|
||||
}
|
||||
|
||||
ImageFrameSuper::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||
nsAtomicContainerFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||
}
|
||||
|
||||
nsIAtom*
|
||||
|
||||
@@ -58,10 +58,8 @@ private:
|
||||
nsImageFrame *mFrame;
|
||||
};
|
||||
|
||||
typedef nsAtomicContainerFrame ImageFrameSuper;
|
||||
|
||||
class nsImageFrame : public ImageFrameSuper,
|
||||
public nsIReflowCallback {
|
||||
class nsImageFrame : public nsAtomicContainerFrame
|
||||
, public nsIReflowCallback {
|
||||
public:
|
||||
template <typename T> using Maybe = mozilla::Maybe<T>;
|
||||
using Nothing = mozilla::Nothing;
|
||||
@@ -119,7 +117,7 @@ public:
|
||||
|
||||
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
||||
{
|
||||
return ImageFrameSuper::IsFrameOfType(aFlags &
|
||||
return nsAtomicContainerFrame::IsFrameOfType(aFlags &
|
||||
~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
|
||||
}
|
||||
|
||||
@@ -333,6 +331,7 @@ private:
|
||||
nsCOMPtr<imgINotificationObserver> mListener;
|
||||
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<imgIContainer> mPrevImage;
|
||||
nsSize mComputedSize;
|
||||
mozilla::IntrinsicSize mIntrinsicSize;
|
||||
nsSize mIntrinsicRatio;
|
||||
@@ -413,8 +412,11 @@ public:
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
|
||||
nsDisplayImage(nsDisplayListBuilder* aBuilder, nsImageFrame* aFrame,
|
||||
imgIContainer* aImage)
|
||||
: nsDisplayImageContainer(aBuilder, aFrame), mImage(aImage) {
|
||||
imgIContainer* aImage, imgIContainer* aPrevImage)
|
||||
: nsDisplayImageContainer(aBuilder, aFrame)
|
||||
, mImage(aImage)
|
||||
, mPrevImage(aPrevImage)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsDisplayImage);
|
||||
}
|
||||
virtual ~nsDisplayImage() {
|
||||
@@ -463,6 +465,7 @@ public:
|
||||
NS_DISPLAY_DECL_NAME("Image", TYPE_IMAGE)
|
||||
private:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<imgIContainer> mPrevImage;
|
||||
};
|
||||
|
||||
#endif /* nsImageFrame_h___ */
|
||||
|
||||
@@ -71,7 +71,7 @@ nsInlineFrame::InvalidateFrame(uint32_t aDisplayItemKey)
|
||||
svgTextFrame->InvalidateFrame();
|
||||
return;
|
||||
}
|
||||
nsInlineFrameBase::InvalidateFrame(aDisplayItemKey);
|
||||
nsContainerFrame::InvalidateFrame(aDisplayItemKey);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -84,7 +84,7 @@ nsInlineFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayIte
|
||||
svgTextFrame->InvalidateFrame();
|
||||
return;
|
||||
}
|
||||
nsInlineFrameBase::InvalidateFrameWithRect(aRect, aDisplayItemKey);
|
||||
nsContainerFrame::InvalidateFrameWithRect(aRect, aDisplayItemKey);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
@@ -482,7 +482,7 @@ nsInlineFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
int32_t aModType)
|
||||
{
|
||||
nsresult rv =
|
||||
nsInlineFrameBase::AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
||||
nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
|
||||
@@ -13,15 +13,13 @@
|
||||
|
||||
class nsLineLayout;
|
||||
|
||||
typedef nsContainerFrame nsInlineFrameBase;
|
||||
|
||||
/**
|
||||
* Inline frame class.
|
||||
*
|
||||
* This class manages a list of child frames that are inline frames. Working with
|
||||
* nsLineLayout, the class will reflow and place inline frames on a line.
|
||||
*/
|
||||
class nsInlineFrame : public nsInlineFrameBase
|
||||
class nsInlineFrame : public nsContainerFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_QUERYFRAME_TARGET(nsInlineFrame)
|
||||
|
||||
@@ -150,7 +150,7 @@ protected:
|
||||
};
|
||||
|
||||
nsPluginFrame::nsPluginFrame(nsStyleContext* aContext)
|
||||
: nsPluginFrameSuper(aContext)
|
||||
: nsFrame(aContext)
|
||||
, mInstanceOwner(nullptr)
|
||||
, mReflowCallbackPosted(false)
|
||||
, mIsHiddenDueToScroll(false)
|
||||
@@ -168,7 +168,7 @@ nsPluginFrame::~nsPluginFrame()
|
||||
NS_QUERYFRAME_HEAD(nsPluginFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsPluginFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIObjectFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsPluginFrameSuper)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsFrame)
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
a11y::AccType
|
||||
@@ -194,7 +194,7 @@ nsPluginFrame::Init(nsIContent* aContent,
|
||||
MOZ_LOG(sPluginFrameLog, LogLevel::Debug,
|
||||
("Initializing nsPluginFrame %p for content %p\n", this, aContent));
|
||||
|
||||
nsPluginFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
||||
nsFrame::Init(aContent, aParent, aPrevInFlow);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -223,7 +223,7 @@ nsPluginFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
mBackgroundSink->Destroy();
|
||||
}
|
||||
|
||||
nsPluginFrameSuper::DestroyFrom(aDestructRoot);
|
||||
nsFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
@@ -239,7 +239,7 @@ nsPluginFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
}
|
||||
}
|
||||
|
||||
nsPluginFrameSuper::DidSetStyleContext(aOldStyleContext);
|
||||
nsFrame::DidSetStyleContext(aOldStyleContext);
|
||||
}
|
||||
|
||||
nsIAtom*
|
||||
@@ -737,7 +737,7 @@ nsPluginFrame::IsFocusable(int32_t *aTabIndex, bool aWithMouse)
|
||||
{
|
||||
if (aTabIndex)
|
||||
*aTabIndex = -1;
|
||||
return nsPluginFrameSuper::IsFocusable(aTabIndex, aWithMouse);
|
||||
return nsFrame::IsFocusable(aTabIndex, aWithMouse);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -853,7 +853,7 @@ nsPluginFrame::DidReflow(nsPresContext* aPresContext,
|
||||
objContent->HasNewFrame(this);
|
||||
}
|
||||
|
||||
nsPluginFrameSuper::DidReflow(aPresContext, aReflowState, aStatus);
|
||||
nsFrame::DidReflow(aPresContext, aReflowState, aStatus);
|
||||
|
||||
// The view is created hidden; once we have reflowed it and it has been
|
||||
// positioned then we show it.
|
||||
@@ -1674,7 +1674,7 @@ nsPluginFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
rv = nsPluginFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
|
||||
rv = nsFrame::HandleEvent(aPresContext, anEvent, anEventStatus);
|
||||
return rv;
|
||||
#endif
|
||||
|
||||
@@ -1698,10 +1698,10 @@ nsPluginFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = nsPluginFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
|
||||
rv = nsFrame::HandleEvent(aPresContext, anEvent, anEventStatus);
|
||||
|
||||
// We need to be careful from this point because the call to
|
||||
// nsPluginFrameSuper::HandleEvent() might have killed us.
|
||||
// nsFrame::HandleEvent() might have killed us.
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (anEvent->mMessage == eMouseUp) {
|
||||
@@ -1786,7 +1786,7 @@ nsPluginFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return nsPluginFrameSuper::GetCursor(aPoint, aCursor);
|
||||
return nsFrame::GetCursor(aPoint, aCursor);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -42,13 +42,11 @@ class LayerManager;
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
typedef nsFrame nsPluginFrameSuper;
|
||||
|
||||
class PluginFrameDidCompositeObserver;
|
||||
|
||||
class nsPluginFrame : public nsPluginFrameSuper,
|
||||
public nsIObjectFrame,
|
||||
public nsIReflowCallback
|
||||
class nsPluginFrame : public nsFrame
|
||||
, public nsIObjectFrame
|
||||
, public nsIReflowCallback
|
||||
{
|
||||
public:
|
||||
typedef mozilla::LayerState LayerState;
|
||||
@@ -91,7 +89,7 @@ public:
|
||||
|
||||
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
||||
{
|
||||
return nsPluginFrameSuper::IsFrameOfType(aFlags &
|
||||
return nsFrame::IsFrameOfType(aFlags &
|
||||
~(nsIFrame::eReplaced | nsIFrame::eReplacedSizing));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ using namespace mozilla;
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsRubyBaseFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsRubyBaseFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsRubyBaseFrameSuper)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsRubyContentFrame)
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsRubyBaseFrame)
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
#include "nsRubyContentFrame.h"
|
||||
|
||||
typedef nsRubyContentFrame nsRubyBaseFrameSuper;
|
||||
|
||||
/**
|
||||
* Factory function.
|
||||
* @return a newly allocated nsRubyBaseFrame (infallible)
|
||||
@@ -20,7 +18,7 @@ typedef nsRubyContentFrame nsRubyBaseFrameSuper;
|
||||
nsContainerFrame* NS_NewRubyBaseFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
class nsRubyBaseFrame final : public nsRubyBaseFrameSuper
|
||||
class nsRubyBaseFrame final : public nsRubyContentFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
@@ -38,7 +36,7 @@ protected:
|
||||
friend nsContainerFrame* NS_NewRubyBaseFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext* aContext);
|
||||
explicit nsRubyBaseFrame(nsStyleContext* aContext)
|
||||
: nsRubyBaseFrameSuper(aContext) {}
|
||||
: nsRubyContentFrame(aContext) {}
|
||||
};
|
||||
|
||||
#endif /* nsRubyBaseFrame_h___ */
|
||||
|
||||
@@ -24,7 +24,7 @@ nsRubyContentFrame::IsFrameOfType(uint32_t aFlags) const
|
||||
if (aFlags & eBidiInlineContainer) {
|
||||
return false;
|
||||
}
|
||||
return nsRubyContentFrameSuper::IsFrameOfType(aFlags);
|
||||
return nsInlineFrame::IsFrameOfType(aFlags);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
|
||||
#include "nsInlineFrame.h"
|
||||
|
||||
typedef nsInlineFrame nsRubyContentFrameSuper;
|
||||
|
||||
class nsRubyContentFrame : public nsRubyContentFrameSuper
|
||||
class nsRubyContentFrame : public nsInlineFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_ABSTRACT_FRAME(nsRubyContentFrame)
|
||||
@@ -30,7 +28,7 @@ public:
|
||||
|
||||
protected:
|
||||
explicit nsRubyContentFrame(nsStyleContext* aContext)
|
||||
: nsRubyContentFrameSuper(aContext) {}
|
||||
: nsInlineFrame(aContext) {}
|
||||
};
|
||||
|
||||
#endif /* nsRubyContentFrame_h___ */
|
||||
|
||||
@@ -26,7 +26,7 @@ using namespace mozilla;
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsRubyFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsRubyFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsRubyFrameSuper)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsInlineFrame)
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsRubyFrame)
|
||||
|
||||
@@ -54,7 +54,7 @@ nsRubyFrame::IsFrameOfType(uint32_t aFlags) const
|
||||
if (aFlags & eBidiInlineContainer) {
|
||||
return false;
|
||||
}
|
||||
return nsRubyFrameSuper::IsFrameOfType(aFlags);
|
||||
return nsInlineFrame::IsFrameOfType(aFlags);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FRAME_DUMP
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
|
||||
class nsRubyBaseContainerFrame;
|
||||
|
||||
typedef nsInlineFrame nsRubyFrameSuper;
|
||||
|
||||
/**
|
||||
* Factory function.
|
||||
* @return a newly allocated nsRubyFrame (infallible)
|
||||
@@ -22,7 +20,7 @@ typedef nsInlineFrame nsRubyFrameSuper;
|
||||
nsContainerFrame* NS_NewRubyFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
class nsRubyFrame final : public nsRubyFrameSuper
|
||||
class nsRubyFrame final : public nsInlineFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
@@ -55,7 +53,7 @@ protected:
|
||||
friend nsContainerFrame* NS_NewRubyFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext* aContext);
|
||||
explicit nsRubyFrame(nsStyleContext* aContext)
|
||||
: nsRubyFrameSuper(aContext) {}
|
||||
: nsInlineFrame(aContext) {}
|
||||
|
||||
void ReflowSegment(nsPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
|
||||
@@ -60,14 +60,14 @@ nsRubyTextContainerFrame::IsFrameOfType(uint32_t aFlags) const
|
||||
if (aFlags & eSupportsCSSTransforms) {
|
||||
return false;
|
||||
}
|
||||
return nsRubyTextContainerFrameSuper::IsFrameOfType(aFlags);
|
||||
return nsContainerFrame::IsFrameOfType(aFlags);
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
nsRubyTextContainerFrame::SetInitialChildList(ChildListID aListID,
|
||||
nsFrameList& aChildList)
|
||||
{
|
||||
nsRubyTextContainerFrameSuper::SetInitialChildList(aListID, aChildList);
|
||||
nsContainerFrame::SetInitialChildList(aListID, aChildList);
|
||||
if (aListID == kPrincipalList) {
|
||||
UpdateSpanFlag();
|
||||
}
|
||||
@@ -77,7 +77,7 @@ nsRubyTextContainerFrame::SetInitialChildList(ChildListID aListID,
|
||||
nsRubyTextContainerFrame::AppendFrames(ChildListID aListID,
|
||||
nsFrameList& aFrameList)
|
||||
{
|
||||
nsRubyTextContainerFrameSuper::AppendFrames(aListID, aFrameList);
|
||||
nsContainerFrame::AppendFrames(aListID, aFrameList);
|
||||
UpdateSpanFlag();
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ nsRubyTextContainerFrame::InsertFrames(ChildListID aListID,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsFrameList& aFrameList)
|
||||
{
|
||||
nsRubyTextContainerFrameSuper::InsertFrames(aListID, aPrevFrame, aFrameList);
|
||||
nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
|
||||
UpdateSpanFlag();
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ nsRubyTextContainerFrame::InsertFrames(ChildListID aListID,
|
||||
nsRubyTextContainerFrame::RemoveFrame(ChildListID aListID,
|
||||
nsIFrame* aOldFrame)
|
||||
{
|
||||
nsRubyTextContainerFrameSuper::RemoveFrame(aListID, aOldFrame);
|
||||
nsContainerFrame::RemoveFrame(aListID, aOldFrame);
|
||||
UpdateSpanFlag();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
#include "nsBlockFrame.h"
|
||||
|
||||
typedef nsContainerFrame nsRubyTextContainerFrameSuper;
|
||||
|
||||
/**
|
||||
* Factory function.
|
||||
* @return a newly allocated nsRubyTextContainerFrame (infallible)
|
||||
@@ -20,7 +18,7 @@ typedef nsContainerFrame nsRubyTextContainerFrameSuper;
|
||||
nsContainerFrame* NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
class nsRubyTextContainerFrame final : public nsRubyTextContainerFrameSuper
|
||||
class nsRubyTextContainerFrame final : public nsContainerFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
@@ -59,7 +57,7 @@ protected:
|
||||
NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext* aContext);
|
||||
explicit nsRubyTextContainerFrame(nsStyleContext* aContext)
|
||||
: nsRubyTextContainerFrameSuper(aContext)
|
||||
: nsContainerFrame(aContext)
|
||||
, mISize(0) {}
|
||||
|
||||
void UpdateSpanFlag();
|
||||
|
||||
@@ -22,7 +22,7 @@ using namespace mozilla;
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsRubyTextFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsRubyTextFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsRubyTextFrameSuper)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsRubyContentFrame)
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsRubyTextFrame)
|
||||
|
||||
@@ -70,7 +70,7 @@ nsRubyTextFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
return;
|
||||
}
|
||||
|
||||
nsRubyTextFrameSuper::BuildDisplayList(aBuilder, aDirtyRect, aLists);
|
||||
nsRubyContentFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
@@ -85,8 +85,7 @@ nsRubyTextFrame::Reflow(nsPresContext* aPresContext,
|
||||
// the content is no longer the same, until next reflow triggered by
|
||||
// some other change. In general, we always reflow all the frames we
|
||||
// created. There might be other problems if we don't do that.
|
||||
nsRubyTextFrameSuper::Reflow(aPresContext, aDesiredSize,
|
||||
aReflowState, aStatus);
|
||||
nsRubyContentFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
||||
|
||||
if (IsAutoHidden()) {
|
||||
// Reset the ISize. The BSize is not changed so that it won't
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
#include "nsRubyContentFrame.h"
|
||||
|
||||
typedef nsRubyContentFrame nsRubyTextFrameSuper;
|
||||
|
||||
/**
|
||||
* Factory function.
|
||||
* @return a newly allocated nsRubyTextFrame (infallible)
|
||||
@@ -20,7 +18,7 @@ typedef nsRubyContentFrame nsRubyTextFrameSuper;
|
||||
nsContainerFrame* NS_NewRubyTextFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
class nsRubyTextFrame final : public nsRubyTextFrameSuper
|
||||
class nsRubyTextFrame final : public nsRubyContentFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
@@ -53,7 +51,7 @@ protected:
|
||||
friend nsContainerFrame* NS_NewRubyTextFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext* aContext);
|
||||
explicit nsRubyTextFrame(nsStyleContext* aContext)
|
||||
: nsRubyTextFrameSuper(aContext) {}
|
||||
: nsRubyContentFrame(aContext) {}
|
||||
};
|
||||
|
||||
#endif /* nsRubyTextFrame_h___ */
|
||||
|
||||
@@ -57,7 +57,7 @@ GetDocumentFromView(nsView* aView)
|
||||
}
|
||||
|
||||
nsSubDocumentFrame::nsSubDocumentFrame(nsStyleContext* aContext)
|
||||
: nsSubDocumentFrameSuper(aContext)
|
||||
: nsAtomicContainerFrame(aContext)
|
||||
, mIsInline(false)
|
||||
, mPostedReflowCallback(false)
|
||||
, mDidCreateDoc(false)
|
||||
@@ -75,7 +75,7 @@ nsSubDocumentFrame::AccessibleType()
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsSubDocumentFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsSubDocumentFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsSubDocumentFrameSuper)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsAtomicContainerFrame)
|
||||
|
||||
class AsyncFrameInit : public nsRunnable
|
||||
{
|
||||
@@ -108,7 +108,7 @@ nsSubDocumentFrame::Init(nsIContent* aContent,
|
||||
nsCOMPtr<nsIDOMHTMLFrameElement> frameElem = do_QueryInterface(aContent);
|
||||
mIsInline = frameElem ? false : true;
|
||||
|
||||
nsSubDocumentFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
||||
nsAtomicContainerFrame::Init(aContent, aParent, aPrevInFlow);
|
||||
|
||||
// We are going to create an inner view. If we need a view for the
|
||||
// OuterFrame but we wait for the normal view creation path in
|
||||
@@ -689,7 +689,7 @@ nsSubDocumentFrame::GetIntrinsicSize()
|
||||
if (subDocRoot) {
|
||||
return subDocRoot->GetIntrinsicSize();
|
||||
}
|
||||
return nsSubDocumentFrameSuper::GetIntrinsicSize();
|
||||
return nsAtomicContainerFrame::GetIntrinsicSize();
|
||||
}
|
||||
|
||||
/* virtual */ nsSize
|
||||
@@ -699,7 +699,7 @@ nsSubDocumentFrame::GetIntrinsicRatio()
|
||||
if (subDocRoot) {
|
||||
return subDocRoot->GetIntrinsicRatio();
|
||||
}
|
||||
return nsSubDocumentFrameSuper::GetIntrinsicRatio();
|
||||
return nsAtomicContainerFrame::GetIntrinsicRatio();
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
@@ -747,10 +747,10 @@ nsSubDocumentFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
aBorder,
|
||||
aPadding);
|
||||
}
|
||||
return nsSubDocumentFrameSuper::ComputeSize(aRenderingContext, aWM,
|
||||
aCBSize, aAvailableISize,
|
||||
aMargin, aBorder, aPadding,
|
||||
aFlags);
|
||||
return nsAtomicContainerFrame::ComputeSize(aRenderingContext, aWM,
|
||||
aCBSize, aAvailableISize,
|
||||
aMargin, aBorder, aPadding,
|
||||
aFlags);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -955,18 +955,16 @@ public:
|
||||
if (!mPresShell->IsDestroying() && mFrameElement->IsInComposedDoc()) {
|
||||
mPresShell->FlushPendingNotifications(Flush_Frames);
|
||||
}
|
||||
|
||||
// Either the frame has been constructed by now, or it never will be.
|
||||
// Either way, we want to clear the stashed views.
|
||||
|
||||
// Either the frame has been constructed by now, or it never will be,
|
||||
// either way we want to clear the stashed views.
|
||||
mFrameLoader->SetDetachedSubdocFrame(nullptr, nullptr);
|
||||
|
||||
|
||||
nsSubDocumentFrame* frame = do_QueryFrame(mFrameElement->GetPrimaryFrame());
|
||||
if ((!frame && mHideViewerIfFrameless) ||
|
||||
mPresShell->IsDestroying()) {
|
||||
// Either the frame element has no nsIFrame or the presshell is being
|
||||
// destroyed. Hide the nsFrameLoader, which destroys the presentation,
|
||||
// and clear our references to the stashed presentation.
|
||||
// destroyed. Hide the nsFrameLoader, which destroys the presentation.
|
||||
mFrameLoader->Hide();
|
||||
}
|
||||
return NS_OK;
|
||||
@@ -1015,7 +1013,7 @@ nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
}
|
||||
}
|
||||
|
||||
nsSubDocumentFrameSuper::DestroyFrom(aDestructRoot);
|
||||
nsAtomicContainerFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
CSSIntSize
|
||||
|
||||
@@ -12,12 +12,10 @@
|
||||
#include "nsFrameLoader.h"
|
||||
#include "Units.h"
|
||||
|
||||
typedef nsAtomicContainerFrame nsSubDocumentFrameSuper;
|
||||
|
||||
/******************************************************************************
|
||||
* nsSubDocumentFrame
|
||||
*****************************************************************************/
|
||||
class nsSubDocumentFrame : public nsSubDocumentFrameSuper,
|
||||
class nsSubDocumentFrame : public nsAtomicContainerFrame,
|
||||
public nsIReflowCallback
|
||||
{
|
||||
public:
|
||||
@@ -37,7 +35,7 @@ public:
|
||||
|
||||
virtual bool IsFrameOfType(uint32_t aFlags) const override
|
||||
{
|
||||
return nsSubDocumentFrameSuper::IsFrameOfType(aFlags &
|
||||
return nsAtomicContainerFrame::IsFrameOfType(aFlags &
|
||||
~(nsIFrame::eReplaced |
|
||||
nsIFrame::eReplacedSizing |
|
||||
nsIFrame::eReplacedContainsBlock));
|
||||
|
||||
@@ -75,7 +75,7 @@ SwapScaleWidthHeightForRotation(IntSize& aSize, VideoInfo::Rotation aDegrees)
|
||||
}
|
||||
|
||||
nsVideoFrame::nsVideoFrame(nsStyleContext* aContext)
|
||||
: nsVideoFrameBase(aContext)
|
||||
: nsContainerFrame(aContext)
|
||||
{
|
||||
EnableVisibilityTracking();
|
||||
}
|
||||
@@ -87,7 +87,7 @@ nsVideoFrame::~nsVideoFrame()
|
||||
NS_QUERYFRAME_HEAD(nsVideoFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsVideoFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsVideoFrameBase)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||
|
||||
nsresult
|
||||
nsVideoFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
||||
@@ -178,7 +178,7 @@ nsVideoFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
nsContentUtils::DestroyAnonymousContent(&mCaptionDiv);
|
||||
nsContentUtils::DestroyAnonymousContent(&mVideoControls);
|
||||
nsContentUtils::DestroyAnonymousContent(&mPosterImage);
|
||||
nsVideoFrameBase::DestroyFrom(aDestructRoot);
|
||||
nsContainerFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -655,7 +655,7 @@ nsVideoFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
if (aAttribute == nsGkAtoms::poster && HasVideoElement()) {
|
||||
UpdatePosterSource(true);
|
||||
}
|
||||
return nsVideoFrameBase::AttributeChanged(aNameSpaceID,
|
||||
return nsContainerFrame::AttributeChanged(aNameSpaceID,
|
||||
aAttribute,
|
||||
aModType);
|
||||
}
|
||||
@@ -666,12 +666,13 @@ nsVideoFrame::OnVisibilityChange(Visibility aNewVisibility,
|
||||
{
|
||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mPosterImage);
|
||||
if (!imageLoader) {
|
||||
nsContainerFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||
return;
|
||||
}
|
||||
|
||||
imageLoader->OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||
|
||||
nsVideoFrameBase::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||
nsContainerFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
|
||||
}
|
||||
|
||||
bool nsVideoFrame::HasVideoElement() {
|
||||
|
||||
@@ -26,9 +26,8 @@ class nsAString;
|
||||
class nsPresContext;
|
||||
class nsDisplayItem;
|
||||
|
||||
typedef nsContainerFrame nsVideoFrameBase;
|
||||
|
||||
class nsVideoFrame : public nsVideoFrameBase, public nsIAnonymousContentCreator
|
||||
class nsVideoFrame : public nsContainerFrame
|
||||
, public nsIAnonymousContentCreator
|
||||
{
|
||||
public:
|
||||
template <typename T> using Maybe = mozilla::Maybe<T>;
|
||||
|
||||
@@ -36,7 +36,7 @@ ViewportFrame::Init(nsIContent* aContent,
|
||||
nsContainerFrame* aParent,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
Super::Init(aContent, aParent, aPrevInFlow);
|
||||
nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
|
||||
|
||||
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(this);
|
||||
if (parent) {
|
||||
|
||||
@@ -27,8 +27,6 @@ public:
|
||||
NS_DECL_QUERYFRAME
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
||||
typedef nsContainerFrame Super;
|
||||
|
||||
explicit ViewportFrame(nsStyleContext* aContext)
|
||||
: nsContainerFrame(aContext)
|
||||
{}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>Reference: Perspective scrolling with nested clips</title>
|
||||
|
||||
<style>
|
||||
|
||||
html {
|
||||
padding: 50px 0 3000px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.scrollbox {
|
||||
width: 600px;
|
||||
height: 500px;
|
||||
perspective: 1px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.transformed {
|
||||
will-change: transform;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin: 200px 100px;
|
||||
border: 10px solid black;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
height: 4000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="scrollbox">
|
||||
<div class="transformed"></div>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.scrollingElement.scrollTop = 250;
|
||||
</script>
|
||||
@@ -0,0 +1,49 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
reftest-async-scroll
|
||||
reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="800" reftest-displayport-h="1000"
|
||||
reftest-async-scroll-x="0" reftest-async-scroll-y="250">
|
||||
<meta charset="utf-8">
|
||||
<title>Perspective scrolling with nested clips</title>
|
||||
|
||||
<style>
|
||||
|
||||
html {
|
||||
padding: 50px 0 3000px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.scrollbox {
|
||||
width: 600px;
|
||||
height: 500px;
|
||||
perspective: 1px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.transformed {
|
||||
will-change: transform;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin: 200px 100px;
|
||||
border: 10px solid black;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
height: 4000px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="scrollbox"
|
||||
reftest-displayport-x="0" reftest-displayport-y="0"
|
||||
reftest-displayport-w="600" reftest-displayport-h="2000"
|
||||
reftest-async-scroll-x="0" reftest-async-scroll-y="0">
|
||||
|
||||
<div class="transformed"></div>
|
||||
<div class="spacer"></div>
|
||||
|
||||
</div>
|
||||
@@ -30,6 +30,7 @@ skip-if(!asyncPan) == position-fixed-iframe-2.html position-fixed-iframe-2-ref.h
|
||||
skip-if(!asyncPan) == position-fixed-in-scroll-container.html position-fixed-in-scroll-container-ref.html
|
||||
fuzzy(1,60000) skip-if(!asyncPan) == group-opacity-surface-size-1.html group-opacity-surface-size-1-ref.html
|
||||
skip-if(!asyncPan) == offscreen-prerendered-active-opacity.html offscreen-prerendered-active-opacity-ref.html
|
||||
fuzzy-if(Android,7,4) skip-if(!asyncPan) == perspective-scrolling-4.html perspective-scrolling-4-ref.html
|
||||
|
||||
# for the following tests, we want to disable the low-precision buffer
|
||||
# as it will expand the displayport beyond what the test specifies in
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
skip-if(B2G||Mulet) fails-if(Android) == resize.html resize-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet||Android) == resize.html resize-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
# an offset seems to apply to the native resizer on windows so skip this test for now
|
||||
skip-if(B2G||Mulet) fails-if(Android) skip-if(winWidget) fuzzy-if(cocoaWidget,1,33) == resize-background.html resize-background-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fails-if(Android) != ltr.html rtl.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fails-if(Android) != ltr-scrollbar.html rtl-scrollbar.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fails-if(Android) != in-ltr-doc-scrollbar.html in-rtl-doc-scrollbar.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fails-if(Android) != ltr.html no-resize.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fails-if(Android) fails-if(gtkWidget) != rtl.html no-resize.html # bug 834724 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet||Android) skip-if(winWidget) fuzzy-if(cocoaWidget,1,33) == resize-background.html resize-background-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet||Android) != ltr.html rtl.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet||Android) != ltr-scrollbar.html rtl-scrollbar.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet||Android) != in-ltr-doc-scrollbar.html in-rtl-doc-scrollbar.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet||Android) != ltr.html no-resize.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet||Android) fails-if(xulRuntime.widgetToolkit=="gtk2") != rtl.html no-resize.html # bug 834724 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
== rtl.html rtl-dynamic-attr.html
|
||||
== rtl.html rtl-dynamic-style.html
|
||||
== rtl.html in-dynamic-rtl-doc.html
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# access-key tests are no use on OS X because access keys are not indicated visually
|
||||
skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)) != accesskey-1.xul accesskey-1-notref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)) == accesskey-2.xul accesskey-2-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
# no real XUL theme on Android so we just skip
|
||||
skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)||Android) != accesskey-1.xul accesskey-1-notref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)||Android) == accesskey-2.xul accesskey-2-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
# accesskey-3 fails because of defects in XUL bidi support
|
||||
fails-if(!cocoaWidget) skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)) == accesskey-3.xul accesskey-3-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)) != accesskey-3.xul accesskey-3-notref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)) == accesskey-4.xul accesskey-4-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)) != accesskey-4.xul accesskey-4-notref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == align-baseline-1.xul align-baseline-1-ref.xul # test for bug 494901 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fails-if(Android) skip-if(B2G||Mulet) == setsize.xul setsize-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fails-if(!cocoaWidget) skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)||Android) == accesskey-3.xul accesskey-3-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)||Android) != accesskey-3.xul accesskey-3-notref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)||Android) == accesskey-4.xul accesskey-4-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(cocoaWidget||((B2G&&browserIsRemote)||Mulet)||Android) != accesskey-4.xul accesskey-4-notref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if((B2G&&browserIsRemote)||Mulet||Android) == align-baseline-1.xul align-baseline-1-ref.xul # test for bug 494901 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet||Android) == setsize.xul setsize-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
||||
@@ -246,7 +246,7 @@ include marquee/reftest.list
|
||||
|
||||
# native-theme/
|
||||
# skipping for B2G since something around radio-nonnative.html makes the whole suite hang
|
||||
skip-if(B2G||Mulet) include native-theme/reftest.list # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Android||Mulet) include native-theme/reftest.list # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
||||
# netwerk/
|
||||
include ../../netwerk/test/reftest/reftest.list
|
||||
@@ -373,17 +373,20 @@ include ../../widget/reftests/reftest.list
|
||||
# xml-stylesheet/
|
||||
include ../../content/test/reftest/xml-stylesheet/reftest.list
|
||||
|
||||
# xul-document-load/
|
||||
include xul-document-load/reftest.list
|
||||
# xul-document-load/ (no XUL theme on Android)
|
||||
skip-if(Android) include xul-document-load/reftest.list
|
||||
|
||||
# xul/
|
||||
include xul/reftest.list
|
||||
# xul/ (no XUL theme on Android)
|
||||
skip-if(Android) include xul/reftest.list
|
||||
|
||||
# xul
|
||||
include ../xul/reftest/reftest.list
|
||||
# xul (no XUL theme on Android)
|
||||
skip-if(Android) include ../xul/reftest/reftest.list
|
||||
|
||||
# xul grid
|
||||
include ../xul/grid/reftests/reftest.list
|
||||
# xul grid (no XUL theme on Android)
|
||||
skip-if(Android) include ../xul/grid/reftests/reftest.list
|
||||
|
||||
# -webkit-box & associated properties (mapped to modern flexbox)
|
||||
include webkit-box/reftest.list
|
||||
|
||||
# -webkit-gradient expressions
|
||||
include webkit-gradient/reftest.list
|
||||
|
||||
@@ -19,6 +19,22 @@ fails == webkit-box-anon-flex-items-3.html webkit-box-anon-flex-items-3-ref.html
|
||||
== webkit-box-align-horiz-1b.html webkit-box-align-horiz-1-ref.html
|
||||
== webkit-box-align-vert-1.html webkit-box-align-vert-1-ref.html
|
||||
|
||||
# Tests for "-webkit-box-direction":
|
||||
== webkit-box-direction-1.html webkit-box-direction-1-ref.html
|
||||
|
||||
# Tests for "-webkit-box-flex" (flexibility of items)
|
||||
== webkit-box-flex-1.html webkit-box-flex-1-ref.html
|
||||
|
||||
# Tests for "-webkit-box-ordinal-group"
|
||||
== webkit-box-ordinal-group-1.html webkit-box-ordinal-group-1-ref.html
|
||||
# XXXdholbert The following test fails because we accept "0" as a valid value
|
||||
# for -webkit-box-ordinal-group (unlike Chrome/Blink), because that's simply
|
||||
# how its aliased property (-moz-box-ordinal-group) behaves. This shouldn't
|
||||
# matter in practice; it could only cause trouble if sites accidentally depend
|
||||
# on the "0" value being rejected.
|
||||
fails == webkit-box-ordinal-group-2.html webkit-box-ordinal-group-2-ref.html
|
||||
== webkit-box-ordinal-group-3.html webkit-box-ordinal-group-3-ref.html
|
||||
|
||||
# Tests for "-webkit-box-pack" (main-axis alignment):
|
||||
== webkit-box-pack-horiz-1a.html webkit-box-pack-horiz-1-ref.html
|
||||
== webkit-box-pack-horiz-1b.html webkit-box-pack-horiz-1-ref.html
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Reference
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: flex;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
/* auto width */
|
||||
height: 1em;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
font-size: 50%;
|
||||
width: 2em;
|
||||
/* auto height */
|
||||
}
|
||||
|
||||
.bastart { align-items: flex-start; }
|
||||
.bacenter { align-items: center; }
|
||||
.baend { align-items: flex-end; }
|
||||
.babaseline { align-items: baseline; }
|
||||
.bastretch { align-items: stretch; }
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-align -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: -webkit-box-align: start -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bastart">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bastart" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bastart" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bastart" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: -webkit-box-align: center -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bacenter">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bacenter" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bacenter" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bacenter" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: -webkit-box-align: end -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box baend">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box baend" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box baend" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box baend" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FIFTH ROW: -webkit-box-align: baseline -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box babaseline">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box babaseline" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box babaseline" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box babaseline" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
<!-- SIXTH ROW: -webkit-box-align: stretch -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bastretch">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bastretch" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bastretch" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bastretch" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Test: horizontally-oriented "display: -webkit-box" container,
|
||||
with all the various -webkit-box-align values.
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: -webkit-box;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
/* auto width */
|
||||
height: 1em;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
font-size: 50%;
|
||||
width: 2em;
|
||||
/* auto height */
|
||||
}
|
||||
|
||||
.bastart { -webkit-box-align: start; }
|
||||
.bacenter { -webkit-box-align: center; }
|
||||
.baend { -webkit-box-align: end; }
|
||||
.babaseline { -webkit-box-align: baseline; }
|
||||
.bastretch { -webkit-box-align: stretch; }
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-align -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: -webkit-box-align: start -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bastart">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bastart" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bastart" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bastart" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: -webkit-box-align: center -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bacenter">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bacenter" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bacenter" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bacenter" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: -webkit-box-align: end -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box baend">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box baend" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box baend" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box baend" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FIFTH ROW: -webkit-box-align: baseline -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box babaseline">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box babaseline" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box babaseline" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box babaseline" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
<!-- SIXTH ROW: -webkit-box-align: stretch -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bastretch">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bastretch" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bastretch" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bastretch" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,174 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Test: horizontally-oriented "display: -webkit-box" container,
|
||||
with all the various -webkit-box-align values.
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: horizontal;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
/* auto width */
|
||||
height: 1em;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
font-size: 50%;
|
||||
width: 2em;
|
||||
/* auto height */
|
||||
}
|
||||
|
||||
.bastart { -webkit-box-align: start; }
|
||||
.bacenter { -webkit-box-align: center; }
|
||||
.baend { -webkit-box-align: end; }
|
||||
.babaseline { -webkit-box-align: baseline; }
|
||||
.bastretch { -webkit-box-align: stretch; }
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-align -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: -webkit-box-align: start -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bastart">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bastart" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bastart" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bastart" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: -webkit-box-align: center -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bacenter">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bacenter" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bacenter" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bacenter" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: -webkit-box-align: end -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box baend">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box baend" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box baend" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box baend" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FIFTH ROW: -webkit-box-align: baseline -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box babaseline">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box babaseline" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box babaseline" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box babaseline" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
<!-- SIXTH ROW: -webkit-box-align: stretch -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bastretch">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bastretch" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bastretch" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bastretch" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,173 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Reference
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
/* auto width */
|
||||
height: 1em;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
font-size: 50%;
|
||||
width: 2em;
|
||||
/* auto height */
|
||||
}
|
||||
|
||||
.bastart { align-items: flex-start; }
|
||||
.bacenter { align-items: center; }
|
||||
.baend { align-items: flex-end; }
|
||||
.babaseline { align-items: baseline; }
|
||||
.bastretch { align-items: stretch; }
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-align -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: -webkit-box-align: start -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bastart">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bastart" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bastart" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bastart" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: -webkit-box-align: center -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bacenter">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bacenter" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bacenter" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bacenter" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: -webkit-box-align: end -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box baend">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box baend" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box baend" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box baend" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FIFTH ROW: -webkit-box-align: baseline -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box babaseline">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box babaseline" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box babaseline" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box babaseline" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
<!-- SIXTH ROW: -webkit-box-align: stretch -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bastretch">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bastretch" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bastretch" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bastretch" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,174 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Test: vertically-oriented "display: -webkit-box" container,
|
||||
with all the various -webkit-box-align values.
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
/* auto width */
|
||||
height: 1em;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
font-size: 50%;
|
||||
width: 2em;
|
||||
/* auto height */
|
||||
}
|
||||
|
||||
.bastart { -webkit-box-align: start; }
|
||||
.bacenter { -webkit-box-align: center; }
|
||||
.baend { -webkit-box-align: end; }
|
||||
.babaseline { -webkit-box-align: baseline; }
|
||||
.bastretch { -webkit-box-align: stretch; }
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-align -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: -webkit-box-align: start -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bastart">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bastart" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bastart" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bastart" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: -webkit-box-align: center -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bacenter">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bacenter" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bacenter" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bacenter" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: -webkit-box-align: end -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box baend">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box baend" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box baend" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box baend" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FIFTH ROW: -webkit-box-align: baseline -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box babaseline">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box babaseline" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box babaseline" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box babaseline" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
<!-- SIXTH ROW: -webkit-box-align: stretch -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bastretch">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bastretch" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bastretch" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bastretch" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,82 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Reference
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: flex;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
}
|
||||
|
||||
.rtl { direction: rtl; }
|
||||
|
||||
.horizNormal {
|
||||
flex-direction: row;
|
||||
}
|
||||
.horizReverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
.vertNormal {
|
||||
flex-direction: column;
|
||||
}
|
||||
.vertReverse {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: '-webkit-box-orient: horizontal', default 'direction' -->
|
||||
<div class="box horizNormal">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<div class="box horizReverse">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: '-webkit-box-orient: horizontal', 'direction: rtl' -->
|
||||
<div class="box horizNormal rtl">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<div class="box horizReverse rtl">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: '-webkit-box-orient: vertical', default 'direction' -->
|
||||
<div class="box vertNormal">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<div class="box vertReverse">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: '-webkit-box-orient: vertical', 'direction: rtl' -->
|
||||
<div class="box vertNormal rtl">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<div class="box vertReverse rtl">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,87 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Test: "-webkit-box-direction" property
|
||||
in a -webkit-box with default writing-mode
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: -webkit-box;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
}
|
||||
|
||||
.rtl { direction: rtl; }
|
||||
|
||||
.horizNormal {
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: normal;
|
||||
}
|
||||
.horizReverse {
|
||||
-webkit-box-orient: horizontal;
|
||||
-webkit-box-direction: reverse;
|
||||
}
|
||||
.vertNormal {
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
}
|
||||
.vertReverse {
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: reverse;
|
||||
}
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: '-webkit-box-orient: horizontal', default 'direction' -->
|
||||
<div class="box horizNormal">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<div class="box horizReverse">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: '-webkit-box-orient: horizontal', 'direction: rtl' -->
|
||||
<div class="box horizNormal rtl">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<div class="box horizReverse rtl">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: '-webkit-box-orient: vertical', default 'direction' -->
|
||||
<div class="box vertNormal">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<div class="box vertReverse">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: '-webkit-box-orient: vertical', 'direction: rtl' -->
|
||||
<div class="box vertNormal rtl">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<div class="box vertReverse rtl">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,101 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Reference
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: flex;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
width: 100px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > * {
|
||||
/* Modern flexbox (used in this reference case) allows everything to
|
||||
shrink by default, but -webkit-box does not, so we have to turn that
|
||||
feature off to make an accurate reference case. */
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.box > *:nth-child(1) { background: turquoise; }
|
||||
.box > *:nth-child(2) { background: salmon; }
|
||||
.box > *:nth-child(3) { background: yellow; }
|
||||
|
||||
.huge { width: 120px }
|
||||
.bf1 { flex: 1 1 auto }
|
||||
.bf3 { flex: 3 3 auto }
|
||||
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-flex -->
|
||||
<div class="box">
|
||||
<div>a</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="huge">a</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: One item has nonzero -webkit-box-flex -->
|
||||
<div class="box">
|
||||
<div class="bf1">a</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div>a</div><div class="bf1">b</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="huge bf1">a</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: Two items have nonzero (equal) -webkit-box-flex -->
|
||||
<div class="box">
|
||||
<div class="bf1">a</div><div class="bf1">b</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="bf1">a</div><div>b</div><div class="bf1">c</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="huge bf1">a</div>
|
||||
<div>b</div>
|
||||
<div class="huge bf1">c</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: Non-equal nonzero -webkit-box-flex values -->
|
||||
<div class="box">
|
||||
<div class="bf1">a</div><div class="bf3">b</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="bf3">a</div><div class="bf1">b</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="huge bf1">a</div>
|
||||
<div class="huge bf3">b</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Test: "-webkit-box-flex" in a "display: -webkit-box" container
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: -webkit-box;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
width: 100px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) { background: turquoise; }
|
||||
.box > *:nth-child(2) { background: salmon; }
|
||||
.box > *:nth-child(3) { background: yellow; }
|
||||
|
||||
.huge { width: 120px }
|
||||
.bf1 { -webkit-box-flex: 1 }
|
||||
.bf3 { -webkit-box-flex: 3 }
|
||||
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-flex -->
|
||||
<div class="box">
|
||||
<div>a</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="huge">a</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: One item has nonzero -webkit-box-flex -->
|
||||
<div class="box">
|
||||
<div class="bf1">a</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div>a</div><div class="bf1">b</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="huge bf1">a</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: Two items have nonzero (equal) -webkit-box-flex -->
|
||||
<div class="box">
|
||||
<div class="bf1">a</div><div class="bf1">b</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="bf1">a</div><div>b</div><div class="bf1">c</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="huge bf1">a</div>
|
||||
<div>b</div>
|
||||
<div class="huge bf1">c</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: Non-equal nonzero -webkit-box-flex values -->
|
||||
<div class="box">
|
||||
<div class="bf1">a</div><div class="bf3">b</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="bf3">a</div><div class="bf1">b</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="huge bf1">a</div>
|
||||
<div class="huge bf3">b</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,84 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Reference
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: flex;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
}
|
||||
br { clear: both; }
|
||||
|
||||
.box > * {
|
||||
border: 1px dotted purple;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- First row: initial value mixed with single specified values -->
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div class="bogOne">1a</div>
|
||||
<div>*</div>
|
||||
<div class="bogOne">1b</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div>*</div>
|
||||
<div>*</div>
|
||||
<div class="bogTwo">2a</div>
|
||||
<div class="bogTwo">2b</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div>*</div>
|
||||
<div>*</div>
|
||||
<div class="bogNine">9a</div>
|
||||
<div class="bogNine">9b</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- Second row: various mixes of specified values -->
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div class="bogOne">1</div>
|
||||
<div class="bogTwo">2</div>
|
||||
<div class="bogNine">9</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="bogOne">1</div>
|
||||
<div>*</div>
|
||||
<div class="bogTwo">2</div>
|
||||
<div class="bogNine">9</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="bogOne">1</div>
|
||||
<div>*</div>
|
||||
<div class="bogTwo">2a</div>
|
||||
<div class="bogTwo">2b</div>
|
||||
<div class="bogNine">9</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="bogOne">1</div>
|
||||
<div class="bogTwo">2a</div>
|
||||
<div class="bogTwo">2b</div>
|
||||
<div class="bogNine">9a</div>
|
||||
<div class="bogNine">9b</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,88 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Test: -webkit-box-ordinal-group inside a -webkit-box
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: -webkit-box;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
}
|
||||
br { clear: both; }
|
||||
|
||||
.box > * {
|
||||
border: 1px dotted purple;
|
||||
}
|
||||
|
||||
.bogOne { -webkit-box-ordinal-group: 1; }
|
||||
.bogTwo { -webkit-box-ordinal-group: 2; }
|
||||
.bogNine { -webkit-box-ordinal-group: 9; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- First row: initial value mixed with single specified values -->
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div class="bogOne">1a</div>
|
||||
<div>*</div>
|
||||
<div class="bogOne">1b</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div class="bogTwo">2a</div>
|
||||
<div>*</div>
|
||||
<div class="bogTwo">2b</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div class="bogNine">9a</div>
|
||||
<div>*</div>
|
||||
<div class="bogNine">9b</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- Second row: various mixes of specified values -->
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div class="bogOne">1</div>
|
||||
<div class="bogTwo">2</div>
|
||||
<div class="bogNine">9</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="bogNine">9</div>
|
||||
<div class="bogTwo">2</div>
|
||||
<div class="bogOne">1</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="bogTwo">2a</div>
|
||||
<div class="bogNine">9</div>
|
||||
<div class="bogTwo">2b</div>
|
||||
<div class="bogOne">1</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<div class="bogTwo">2a</div>
|
||||
<div class="bogNine">9a</div>
|
||||
<div class="bogNine">9b</div>
|
||||
<div class="bogTwo">2b</div>
|
||||
<div class="bogOne">1</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Reference
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: flex;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
}
|
||||
|
||||
.box > * {
|
||||
border: 1px dotted purple;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box">
|
||||
<div>1</div>
|
||||
<div>0</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Test: -webkit-box-ordinal-group:0 inside a -webkit-box
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: -webkit-box;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
}
|
||||
|
||||
.box > * {
|
||||
border: 1px dotted purple;
|
||||
}
|
||||
|
||||
.bogZero { -webkit-box-ordinal-group: 0; }
|
||||
.bogOne { -webkit-box-ordinal-group: 1; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- -webkit-box-ordinal-group is strictly positive in Blink & WebKit. 0 is
|
||||
rejected as an invalid value. So, the bogZero element below should
|
||||
end up with the initial value (1) and should *not* be sorted out of its
|
||||
DOM position in the final rendering. -->
|
||||
<div class="box">
|
||||
<div class="bogOne">1</div>
|
||||
<div class="bogZero">0</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Reference
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: flex;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
}
|
||||
br { clear: both; }
|
||||
|
||||
.box > * {
|
||||
border: 1px dotted purple;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div>10</div>
|
||||
<div>A</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div>10</div>
|
||||
<div>B</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div>10</div>
|
||||
<div>C</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div>10</div>
|
||||
<div>D</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div>10</div>
|
||||
<div>E</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div>*</div>
|
||||
<div>10</div>
|
||||
<div>F</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="box">
|
||||
<div>A</div>
|
||||
<div>B</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div>A</div>
|
||||
<div>C</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div>A</div>
|
||||
<div>D</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div>A</div>
|
||||
<div>E</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div>A</div>
|
||||
<div>F</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,103 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Test: -webkit-box-ordinal-group with huge values inside a -webkit-box
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: -webkit-box;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
}
|
||||
br { clear: both; }
|
||||
|
||||
.box > * {
|
||||
border: 1px dotted purple;
|
||||
}
|
||||
|
||||
.bogTen { -webkit-box-ordinal-group: 10; }
|
||||
.bogHugeA { -webkit-box-ordinal-group: 2147483646; /* 2^31 - 2 */ }
|
||||
.bogHugeB {
|
||||
/* NOTE: This is INT32_MAX, so we may not be able to distinguish this
|
||||
from anything larger than it (if we represent it internally in a
|
||||
32-bit signed integer). However, it's still worth testing larger
|
||||
values against e.g. 10 to be sure they don't overflow into
|
||||
negative territory. */
|
||||
-webkit-box-ordinal-group: 2147483647; /* 2^31 - 1 */ }
|
||||
|
||||
.bogHugeC { -webkit-box-ordinal-group: 4294967294; /* 2^32 - 2 */ }
|
||||
.bogHugeD { -webkit-box-ordinal-group: 4294967295; /* 2^32 - 1 */ }
|
||||
.bogHugeE { -webkit-box-ordinal-group: 4294967296; /* 2^32 */ }
|
||||
.bogHugeF { -webkit-box-ordinal-group: 8589934592; /* 2^33 */ }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Test each huge value to see if it sorts after smaller values.
|
||||
(The divs with huge values should sort to the right.) -->
|
||||
<div class="box">
|
||||
<div class="bogHugeA">A</div>
|
||||
<div class="bogTen">10</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="bogHugeB">B</div>
|
||||
<div class="bogTen">10</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="bogHugeC">C</div>
|
||||
<div class="bogTen">10</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="box">
|
||||
<div class="bogHugeD">D</div>
|
||||
<div class="bogTen">10</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="bogHugeE">E</div>
|
||||
<div class="bogTen">10</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="bogHugeE">F</div>
|
||||
<div class="bogTen">10</div>
|
||||
<div>*</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<!-- Test that 'bogHugeA' sorts to the left of larger huge values. It's
|
||||
less than INT32_MAX, so it's reasonable to expect that it can be
|
||||
compared correctly against (possibly-clamped) larger values) -->
|
||||
<div class="box">
|
||||
<div class="bogHugeB">B</div>
|
||||
<div class="bogHugeA">A</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="bogHugeC">C</div>
|
||||
<div class="bogHugeA">A</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="bogHugeD">D</div>
|
||||
<div class="bogHugeA">A</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="bogHugeE">E</div>
|
||||
<div class="bogHugeA">A</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="bogHugeF">F</div>
|
||||
<div class="bogHugeA">A</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,150 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Reference
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: flex;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
/* auto width */
|
||||
height: 1em;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
font-size: 50%;
|
||||
width: 2em;
|
||||
/* auto height */
|
||||
}
|
||||
|
||||
.bpstart { justify-content: flex-start; }
|
||||
.bpcenter { justify-content: center; }
|
||||
.bpend { justify-content: flex-end; }
|
||||
.bpjustify { justify-content: space-between; }
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-pack -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: -webkit-box-pack: start -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpstart">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpstart" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpstart" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpstart" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: -webkit-box-pack: center -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpcenter">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpcenter" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpcenter" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpcenter" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: -webkit-box-pack: end -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpend">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpend" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpend" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpend" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FIFTH ROW: -webkit-box-pack: justify -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpjustify">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpjustify" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpjustify" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpjustify" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,151 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Test: horizontally-oriented "display: -webkit-box" container,
|
||||
with all the various -webkit-box-pack values.
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: -webkit-box;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
/* auto width */
|
||||
height: 1em;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
font-size: 50%;
|
||||
width: 2em;
|
||||
/* auto height */
|
||||
}
|
||||
|
||||
.bpstart { -webkit-box-pack: start; }
|
||||
.bpcenter { -webkit-box-pack: center; }
|
||||
.bpend { -webkit-box-pack: end; }
|
||||
.bpjustify { -webkit-box-pack: justify; }
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-pack -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: -webkit-box-pack: start -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpstart">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpstart" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpstart" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpstart" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: -webkit-box-pack: center -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpcenter">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpcenter" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpcenter" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpcenter" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: -webkit-box-pack: end -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpend">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpend" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpend" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpend" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FIFTH ROW: -webkit-box-pack: justify -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpjustify">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpjustify" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpjustify" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpjustify" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,152 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Test: horizontally-oriented "display: -webkit-box" container,
|
||||
with all the various -webkit-box-pack values.
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: horizontal;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
/* auto width */
|
||||
height: 1em;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
font-size: 50%;
|
||||
width: 2em;
|
||||
/* auto height */
|
||||
}
|
||||
|
||||
.bpstart { -webkit-box-pack: start; }
|
||||
.bpcenter { -webkit-box-pack: center; }
|
||||
.bpend { -webkit-box-pack: end; }
|
||||
.bpjustify { -webkit-box-pack: justify; }
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-pack -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: -webkit-box-pack: start -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpstart">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpstart" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpstart" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpstart" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: -webkit-box-pack: center -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpcenter">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpcenter" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpcenter" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpcenter" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: -webkit-box-pack: end -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpend">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpend" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpend" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpend" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FIFTH ROW: -webkit-box-pack: justify -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpjustify">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpjustify" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpjustify" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpjustify" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,151 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Reference
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
/* auto width */
|
||||
height: 1em;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
font-size: 50%;
|
||||
width: 2em;
|
||||
/* auto height */
|
||||
}
|
||||
|
||||
.bpstart { justify-content: flex-start; }
|
||||
.bpcenter { justify-content: center; }
|
||||
.bpend { justify-content: flex-end; }
|
||||
.bpjustify { justify-content: space-between; }
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-pack -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: -webkit-box-pack: start -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpstart">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpstart" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpstart" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpstart" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: -webkit-box-pack: center -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpcenter">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpcenter" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpcenter" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpcenter" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: -webkit-box-pack: end -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpend">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpend" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpend" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpend" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FIFTH ROW: -webkit-box-pack: justify -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpjustify">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpjustify" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpjustify" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpjustify" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,152 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
CSS Test: vertically-oriented "display: -webkit-box" container,
|
||||
with all the various -webkit-box-pack values.
|
||||
</title>
|
||||
<style>
|
||||
.box {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
border: 1px solid black;
|
||||
margin: 5px 20px;
|
||||
float: left; /* For testing in "rows" */
|
||||
font: 10px serif;
|
||||
}
|
||||
.box > *:nth-child(1) {
|
||||
background: turquoise;
|
||||
/* auto width */
|
||||
height: 1em;
|
||||
}
|
||||
.box > *:nth-child(2) {
|
||||
background: salmon;
|
||||
font-size: 50%;
|
||||
width: 2em;
|
||||
/* auto height */
|
||||
}
|
||||
|
||||
.bpstart { -webkit-box-pack: start; }
|
||||
.bpcenter { -webkit-box-pack: center; }
|
||||
.bpend { -webkit-box-pack: end; }
|
||||
.bpjustify { -webkit-box-pack: justify; }
|
||||
br { clear: both; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- FIRST ROW: Default -webkit-box-pack -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- SECOND ROW: -webkit-box-pack: start -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpstart">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpstart" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpstart" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpstart" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- THIRD ROW: -webkit-box-pack: center -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpcenter">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpcenter" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpcenter" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpcenter" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FOURTH ROW: -webkit-box-pack: end -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpend">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpend" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpend" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpend" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<!-- FIFTH ROW: -webkit-box-pack: justify -->
|
||||
<!-- intrinsically sized -->
|
||||
<div class="box bpjustify">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra width -->
|
||||
<div class="box bpjustify" style="width: 36px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height -->
|
||||
<div class="box bpjustify" style="height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
|
||||
<!-- explicit size, extra height and width -->
|
||||
<div class="box bpjustify" style="width: 36px; height: 40px">
|
||||
<div>a</div><div>b</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+45
-100
@@ -14,7 +14,6 @@
|
||||
#include "CSSVariableImageTable.h"
|
||||
#include "mozilla/css/Declaration.h"
|
||||
#include "mozilla/css/ImageLoader.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/WritingModes.h"
|
||||
#include "nsIDocument.h"
|
||||
@@ -41,50 +40,6 @@ MoveValue(nsCSSValue* aSource, nsCSSValue* aDest)
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function maps "-webkit-box-orient" values to "flex-direction" values,
|
||||
* for a given writing-mode (taken from aRuleData).
|
||||
*
|
||||
* Specifically:
|
||||
* - If aBoxOrientVal is an enumerated value (representing a physical axis),
|
||||
* then we'll map it to the appropriate logical "flex-direction" value, using
|
||||
* the writing mode. The converted value will be emplace()'d into in the
|
||||
* outparam aConvertedValStorage, and we'll return a pointer to that value.
|
||||
* - Otherwise (e.g. if we have "inherit" or "initial"), we won't do any
|
||||
* mapping, and we'll directly return the passed-in aBoxOrientVal.
|
||||
*
|
||||
* Either way, the idea is that our caller can treat the returned value as if
|
||||
* it were a value for "flex-direction".
|
||||
*/
|
||||
static const nsCSSValue*
|
||||
ConvertBoxOrientToFlexDirection(const nsCSSValue* aBoxOrientVal,
|
||||
const nsRuleData* aRuleData,
|
||||
Maybe<nsCSSValue>& aConvertedValStorage)
|
||||
{
|
||||
MOZ_ASSERT(aBoxOrientVal, "expecting a non-null value to convert");
|
||||
MOZ_ASSERT(aConvertedValStorage.isNothing(),
|
||||
"expecting outparam for converted-value to be initially empty");
|
||||
|
||||
if (aBoxOrientVal->GetUnit() != eCSSUnit_Enumerated) {
|
||||
// We probably have "inherit" or "initial" -- just return that & have the
|
||||
// caller directly use it as a "flex-direction" value.
|
||||
return aBoxOrientVal;
|
||||
}
|
||||
|
||||
// OK, we have an enumerated value -- "horizontal" or "vertical".
|
||||
|
||||
WritingMode wm(aRuleData->mStyleContext);
|
||||
// In a horizontal writing-mode, "horizontal" maps to "row".
|
||||
// In a vertical writing-mode, "horizontal" maps to "column".
|
||||
bool isRow = wm.IsVertical() !=
|
||||
(aBoxOrientVal->GetIntValue() == NS_STYLE_BOX_ORIENT_HORIZONTAL);
|
||||
|
||||
aConvertedValStorage.emplace(isRow ? NS_STYLE_FLEX_DIRECTION_ROW :
|
||||
NS_STYLE_FLEX_DIRECTION_COLUMN,
|
||||
eCSSUnit_Enumerated);
|
||||
return aConvertedValStorage.ptr();
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldIgnoreColors(nsRuleData *aRuleData)
|
||||
{
|
||||
@@ -170,32 +125,15 @@ ShouldStartImageLoads(nsRuleData *aRuleData, nsCSSProperty aProperty)
|
||||
}
|
||||
|
||||
static void
|
||||
MapSinglePropertyInto(nsCSSProperty aSrcProp,
|
||||
MapSinglePropertyInto(nsCSSProperty aTargetProp,
|
||||
const nsCSSValue* aSrcValue,
|
||||
nsCSSProperty aTargetProp,
|
||||
nsCSSValue* aTargetValue,
|
||||
nsRuleData* aRuleData)
|
||||
{
|
||||
MOZ_ASSERT(!nsCSSProps::PropHasFlags(aTargetProp, CSS_PROPERTY_LOGICAL),
|
||||
"Can't map into a logical property");
|
||||
MOZ_ASSERT(aSrcProp == aTargetProp ||
|
||||
nsCSSProps::PropHasFlags(aSrcProp, CSS_PROPERTY_LOGICAL),
|
||||
"Source & target property must be the same, except when we're "
|
||||
"doing a logical-to-physical property mapping");
|
||||
MOZ_ASSERT(aSrcValue->GetUnit() != eCSSUnit_Null, "oops");
|
||||
|
||||
// Handle logical properties that have custom value-mapping behavior:
|
||||
Maybe<nsCSSValue> convertedVal; // storage for converted value, if needed
|
||||
bool hasCustomValMapping =
|
||||
nsCSSProps::PropHasFlags(aSrcProp,
|
||||
CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING);
|
||||
if (hasCustomValMapping) {
|
||||
if (aSrcProp == eCSSProperty_webkit_box_orient) {
|
||||
aSrcValue = ConvertBoxOrientToFlexDirection(aSrcValue, aRuleData,
|
||||
convertedVal);
|
||||
}
|
||||
}
|
||||
|
||||
// Although aTargetValue is the nsCSSValue we are going to write into,
|
||||
// we also look at its value before writing into it. This is done
|
||||
// when aTargetValue is a token stream value, which is the case when we
|
||||
@@ -234,20 +172,13 @@ MapSinglePropertyInto(nsCSSProperty aSrcProp,
|
||||
}
|
||||
|
||||
/**
|
||||
* If aProperty is a logical property, returns the equivalent physical
|
||||
* If aProperty is a logical property, converts it to the equivalent physical
|
||||
* property based on writing mode information obtained from aRuleData's
|
||||
* style context.
|
||||
*/
|
||||
static inline nsCSSProperty
|
||||
EnsurePhysicalProperty(nsCSSProperty aProperty, nsRuleData* aRuleData)
|
||||
static inline void
|
||||
EnsurePhysicalProperty(nsCSSProperty& aProperty, nsRuleData* aRuleData)
|
||||
{
|
||||
if (!nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL)) {
|
||||
return aProperty;
|
||||
}
|
||||
|
||||
bool isSingleProperty =
|
||||
nsCSSProps::PropHasFlags(aProperty,
|
||||
CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING);
|
||||
bool isAxisProperty =
|
||||
nsCSSProps::PropHasFlags(aProperty, CSS_PROPERTY_LOGICAL_AXIS);
|
||||
bool isBlock =
|
||||
@@ -255,9 +186,7 @@ EnsurePhysicalProperty(nsCSSProperty aProperty, nsRuleData* aRuleData)
|
||||
|
||||
int index;
|
||||
|
||||
if (isSingleProperty) {
|
||||
index = 0; // We always map to the same physical property.
|
||||
} else if (isAxisProperty) {
|
||||
if (isAxisProperty) {
|
||||
LogicalAxis logicalAxis = isBlock ? eLogicalAxisBlock : eLogicalAxisInline;
|
||||
uint8_t wm = aRuleData->mStyleContext->StyleVisibility()->mWritingMode;
|
||||
PhysicalAxis axis =
|
||||
@@ -295,19 +224,43 @@ EnsurePhysicalProperty(nsCSSProperty aProperty, nsRuleData* aRuleData)
|
||||
}
|
||||
|
||||
const nsCSSProperty* props = nsCSSProps::LogicalGroup(aProperty);
|
||||
size_t len = isAxisProperty ? 2 : 4;
|
||||
#ifdef DEBUG
|
||||
{
|
||||
// Table-length is 1 for single prop, 2 for axis prop, 4 for block prop.
|
||||
size_t len = isSingleProperty ? 1 : (isAxisProperty ? 2 : 4);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
MOZ_ASSERT(props[i] != eCSSProperty_UNKNOWN,
|
||||
"unexpected logical group length");
|
||||
}
|
||||
MOZ_ASSERT(props[len] == eCSSProperty_UNKNOWN,
|
||||
MOZ_ASSERT(props[i] != eCSSProperty_UNKNOWN,
|
||||
"unexpected logical group length");
|
||||
}
|
||||
MOZ_ASSERT(props[len] == eCSSProperty_UNKNOWN,
|
||||
"unexpected logical group length");
|
||||
#endif
|
||||
return props[index];
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (aRuleData->ValueFor(props[i])->GetUnit() == eCSSUnit_Null) {
|
||||
// A declaration of one of the logical properties in this logical
|
||||
// group (but maybe not aProperty) would be the winning
|
||||
// declaration in the cascade. This means that it's reasonably
|
||||
// likely that this logical property could be the winning
|
||||
// declaration in the cascade for some values of writing-mode,
|
||||
// direction, and text-orientation. (It doesn't mean that for
|
||||
// sure, though. For example, if this is a block-start logical
|
||||
// property, and all but the bottom physical property were set.
|
||||
// But the common case we want to hit here is logical declarations
|
||||
// that are completely overridden by a shorthand.)
|
||||
//
|
||||
// If this logical property could be the winning declaration in
|
||||
// the cascade for some values of writing-mode, direction, and
|
||||
// text-orientation, then we have to fault the resulting style
|
||||
// struct out of the rule tree. We can't cache anything on the
|
||||
// rule tree if it depends on data from the style context, since
|
||||
// data cached in the rule tree could be used with a style context
|
||||
// with a different value of the depended-upon data.
|
||||
uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits();
|
||||
aRuleData->mConditions.SetWritingModeDependency(wm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aProperty = props[index];
|
||||
}
|
||||
|
||||
void
|
||||
@@ -327,16 +280,10 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
|
||||
nsCSSProperty iProp = PropertyAtIndex(i);
|
||||
if (nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]) &
|
||||
aRuleData->mSIDs) {
|
||||
nsCSSProperty physicalProp = EnsurePhysicalProperty(iProp,
|
||||
aRuleData);
|
||||
if (physicalProp != iProp) {
|
||||
// We can't cache anything on the rule tree if we use any data from
|
||||
// the style context, since data cached in the rule tree could be
|
||||
// used with a style context with a different value.
|
||||
uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits();
|
||||
aRuleData->mConditions.SetWritingModeDependency(wm);
|
||||
if (nsCSSProps::PropHasFlags(iProp, CSS_PROPERTY_LOGICAL)) {
|
||||
EnsurePhysicalProperty(iProp, aRuleData);
|
||||
}
|
||||
nsCSSValue* target = aRuleData->ValueFor(physicalProp);
|
||||
nsCSSValue* target = aRuleData->ValueFor(iProp);
|
||||
if (target->GetUnit() == eCSSUnit_Null) {
|
||||
const nsCSSValue *val = ValueAtIndex(i);
|
||||
// In order for variable resolution to have the right information
|
||||
@@ -348,8 +295,7 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
|
||||
if (val->GetUnit() == eCSSUnit_TokenStream) {
|
||||
val->GetTokenStreamValue()->mLevel = aRuleData->mLevel;
|
||||
}
|
||||
MapSinglePropertyInto(iProp, val, physicalProp, target,
|
||||
aRuleData);
|
||||
MapSinglePropertyInto(iProp, val, target, aRuleData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -791,10 +737,9 @@ nsCSSExpandedDataBlock::MapRuleInfoInto(nsCSSProperty aPropID,
|
||||
const nsCSSValue* src = PropertyAt(aPropID);
|
||||
MOZ_ASSERT(src->GetUnit() != eCSSUnit_Null);
|
||||
|
||||
nsCSSProperty physicalProp = EnsurePhysicalProperty(aPropID, aRuleData);
|
||||
if (physicalProp != aPropID) {
|
||||
uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits();
|
||||
aRuleData->mConditions.SetWritingModeDependency(wm);
|
||||
nsCSSProperty physicalProp = aPropID;
|
||||
if (nsCSSProps::PropHasFlags(aPropID, CSS_PROPERTY_LOGICAL)) {
|
||||
EnsurePhysicalProperty(physicalProp, aRuleData);
|
||||
}
|
||||
|
||||
nsCSSValue* dest = aRuleData->ValueFor(physicalProp);
|
||||
@@ -802,7 +747,7 @@ nsCSSExpandedDataBlock::MapRuleInfoInto(nsCSSProperty aPropID,
|
||||
dest->GetTokenStreamValue()->mPropertyID == aPropID);
|
||||
|
||||
CSSVariableImageTable::ReplaceAll(aRuleData->mStyleContext, aPropID, [=] {
|
||||
MapSinglePropertyInto(aPropID, src, physicalProp, dest, aRuleData);
|
||||
MapSinglePropertyInto(physicalProp, src, dest, aRuleData);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -296,10 +296,6 @@ CSS_PROP_ALIAS(-webkit-border-bottom-right-radius,
|
||||
WebkitBorderBottomRightRadius, // really no dom property
|
||||
WEBKIT_PREFIX_PREF)
|
||||
|
||||
CSS_PROP_ALIAS(-webkit-appearance,
|
||||
appearance,
|
||||
WebkitAppearance,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-background-clip,
|
||||
background_clip,
|
||||
WebkitBackgroundClip,
|
||||
@@ -327,21 +323,33 @@ CSS_PROP_ALIAS(-webkit-box-sizing,
|
||||
WebkitBoxSizing,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
|
||||
// Alias old flexbox properties to modern flexbox pseudo-equivalents:
|
||||
// Alias -webkit-box properties to their -moz-box equivalents.
|
||||
// (NOTE: Even though they're aliases, in practice these -webkit properties
|
||||
// will behave a bit differently from their -moz versions, if they're
|
||||
// accompanied by "display:-webkit-box", because we generate a different frame
|
||||
// for those two display values.)
|
||||
CSS_PROP_ALIAS(-webkit-box-flex,
|
||||
flex_grow,
|
||||
box_flex,
|
||||
WebkitBoxFlex,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-box-ordinal-group,
|
||||
order,
|
||||
box_ordinal_group,
|
||||
WebkitBoxOrdinalGroup,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-box-orient,
|
||||
box_orient,
|
||||
WebkitBoxOrient,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-box-direction,
|
||||
box_direction,
|
||||
WebkitBoxDirection,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-box-align,
|
||||
align_items,
|
||||
box_align,
|
||||
WebkitBoxAlign,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
CSS_PROP_ALIAS(-webkit-box-pack,
|
||||
justify_content,
|
||||
box_pack,
|
||||
WebkitBoxPack,
|
||||
WEBKIT_PREFIX_PREF)
|
||||
|
||||
|
||||
@@ -1330,22 +1330,6 @@ CSS_PROP_XUL(
|
||||
kBoxOrientKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None) // XXX bug 3935
|
||||
/* We treat -webkit-box-orient as a writing-mode-aware logical alias
|
||||
* for "flex-direction": */
|
||||
CSS_PROP_LOGICAL(
|
||||
-webkit-box-orient,
|
||||
webkit_box_orient,
|
||||
WebkitBoxOrient,
|
||||
CSS_PROPERTY_PARSE_VALUE |
|
||||
CSS_PROPERTY_LOGICAL |
|
||||
CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING,
|
||||
"layout.css.prefixes.webkit",
|
||||
VARIANT_HK,
|
||||
kBoxOrientKTable,
|
||||
WebkitBoxOrient,
|
||||
Position,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_XUL(
|
||||
-moz-box-pack,
|
||||
box_pack,
|
||||
|
||||
@@ -44,17 +44,6 @@
|
||||
// defined in nCSSProps.cpp named g<name_>LogicalGroupTable
|
||||
// containing the two physical properties in vertical/horizontal
|
||||
// order, followed by an nsCSSProperty_UNKNOWN entry.
|
||||
//
|
||||
// CSS_PROP_LOGICAL_GROUP_SINGLE(name_)
|
||||
// Defines a logical property group in which the logical property always
|
||||
// maps to the same physical property. For such properties, the
|
||||
// "logicalness" is in the value-mapping, not in the property-mapping. For
|
||||
// example, the logical property "-webkit-box-orient" is always mapped to
|
||||
// "flex-direction", but its values ("horizontal", "vertical") map to
|
||||
// different flex-direction values ("row", "column") depending on the
|
||||
// writing-mode. A table must be defined in nsCSSProps.cpp named
|
||||
// g<name_>LogicalGroupTable containing the one physical property,
|
||||
// followed by an nsCSSProperty_UNKNOWN entry.
|
||||
|
||||
CSS_PROP_LOGICAL_GROUP_SHORTHAND(BorderColor)
|
||||
CSS_PROP_LOGICAL_GROUP_SHORTHAND(BorderStyle)
|
||||
@@ -65,4 +54,3 @@ CSS_PROP_LOGICAL_GROUP_BOX(Offset)
|
||||
CSS_PROP_LOGICAL_GROUP_SHORTHAND(Padding)
|
||||
CSS_PROP_LOGICAL_GROUP_AXIS(MinSize)
|
||||
CSS_PROP_LOGICAL_GROUP_AXIS(Size)
|
||||
CSS_PROP_LOGICAL_GROUP_SINGLE(WebkitBoxOrient)
|
||||
|
||||
@@ -103,13 +103,10 @@ enum nsCSSPropertyLogicalGroup {
|
||||
eCSSPropertyLogicalGroup_##name_,
|
||||
#define CSS_PROP_LOGICAL_GROUP_BOX(name_) \
|
||||
eCSSPropertyLogicalGroup_##name_,
|
||||
#define CSS_PROP_LOGICAL_GROUP_SINGLE(name_) \
|
||||
eCSSPropertyLogicalGroup_##name_,
|
||||
#define CSS_PROP_LOGICAL_GROUP_SHORTHAND(name_) \
|
||||
eCSSPropertyLogicalGroup_##name_,
|
||||
#include "nsCSSPropLogicalGroupList.h"
|
||||
#undef CSS_PROP_LOGICAL_GROUP_SHORTHAND
|
||||
#undef CSS_PROP_LOGICAL_GROUP_SINGLE
|
||||
#undef CSS_PROP_LOGICAL_GROUP_BOX
|
||||
#undef CSS_PROP_LOGICAL_GROUP_AXIS
|
||||
eCSSPropertyLogicalGroup_COUNT
|
||||
|
||||
@@ -3026,19 +3026,12 @@ static const nsCSSProperty gSizeLogicalGroupTable[] = {
|
||||
eCSSProperty_UNKNOWN
|
||||
};
|
||||
|
||||
static const nsCSSProperty gWebkitBoxOrientLogicalGroupTable[] = {
|
||||
eCSSProperty_flex_direction,
|
||||
eCSSProperty_UNKNOWN
|
||||
};
|
||||
|
||||
const nsCSSProperty* const
|
||||
nsCSSProps::kLogicalGroupTable[eCSSPropertyLogicalGroup_COUNT] = {
|
||||
#define CSS_PROP_LOGICAL_GROUP_SHORTHAND(id_) g##id_##SubpropTable,
|
||||
#define CSS_PROP_LOGICAL_GROUP_AXIS(name_) g##name_##LogicalGroupTable,
|
||||
#define CSS_PROP_LOGICAL_GROUP_BOX(name_) g##name_##LogicalGroupTable,
|
||||
#define CSS_PROP_LOGICAL_GROUP_SINGLE(name_) g##name_##LogicalGroupTable,
|
||||
#include "nsCSSPropLogicalGroupList.h"
|
||||
#undef CSS_PROP_LOGICAL_GROUP_SINGLE
|
||||
#undef CSS_PROP_LOGICAL_GROUP_BOX
|
||||
#undef CSS_PROP_LOGICAL_GROUP_AXIS
|
||||
#undef CSS_PROP_LOGICAL_GROUP_SHORTHAND
|
||||
@@ -3339,10 +3332,7 @@ nsCSSProps::gPropertyUseCounter[eCSSProperty_COUNT_no_shorthands] = {
|
||||
"the CSS_PROPERTY_LOGICAL_BLOCK_AXIS flag"); \
|
||||
static_assert(!((flags_) & CSS_PROPERTY_LOGICAL_END_EDGE), \
|
||||
"only properties defined with CSS_PROP_LOGICAL can use " \
|
||||
"the CSS_PROPERTY_LOGICAL_END_EDGE flag"); \
|
||||
static_assert(!((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING),\
|
||||
"only properties defined with CSS_PROP_LOGICAL can use " \
|
||||
"the CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING flag");
|
||||
"the CSS_PROPERTY_LOGICAL_END_EDGE flag");
|
||||
#define CSS_PROP_LOGICAL(name_, id_, method_, flags_, pref_, parsevariant_, \
|
||||
kwtable_, group_, stylestruct_, \
|
||||
stylestructoffset_, animtype_) \
|
||||
@@ -3355,21 +3345,7 @@ nsCSSProps::gPropertyUseCounter[eCSSProperty_COUNT_no_shorthands] = {
|
||||
static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_AXIS) && \
|
||||
((flags_) & CSS_PROPERTY_LOGICAL_END_EDGE)), \
|
||||
"CSS_PROPERTY_LOGICAL_END_EDGE makes no sense when used " \
|
||||
"with CSS_PROPERTY_LOGICAL_AXIS"); \
|
||||
/* Make sure CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING isn't used */ \
|
||||
/* with other mutually-exclusive flags: */ \
|
||||
static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_AXIS) && \
|
||||
((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING)),\
|
||||
"CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING makes no " \
|
||||
"sense when used with CSS_PROPERTY_LOGICAL_AXIS"); \
|
||||
static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_BLOCK_AXIS) && \
|
||||
((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING)),\
|
||||
"CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING makes no " \
|
||||
"sense when used with CSS_PROPERTY_LOGICAL_BLOCK_AXIS"); \
|
||||
static_assert(!(((flags_) & CSS_PROPERTY_LOGICAL_END_EDGE) && \
|
||||
((flags_) & CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING)),\
|
||||
"CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING makes no " \
|
||||
"sense when used with CSS_PROPERTY_LOGICAL_END_EDGE");
|
||||
"with CSS_PROPERTY_LOGICAL_AXIS");
|
||||
#include "nsCSSPropList.h"
|
||||
#undef CSS_PROP_LOGICAL
|
||||
#undef CSS_PROP
|
||||
|
||||
+10
-18
@@ -226,6 +226,10 @@ static_assert((CSS_PROPERTY_PARSE_PROPERTY_MASK &
|
||||
// wrapped in "#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL".
|
||||
// Note that, these flags have no effect on the use of aliases of this
|
||||
// property.
|
||||
// Furthermore, for the purposes of animation (including triggering
|
||||
// transitions) these flags are ignored. That is, if the property is disabled
|
||||
// by a pref, we will *not* run animations or transitions on it even in
|
||||
// UA sheets or chrome.
|
||||
#define CSS_PROPERTY_ENABLED_MASK (3<<22)
|
||||
#define CSS_PROPERTY_ENABLED_IN_UA_SHEETS (1<<22)
|
||||
#define CSS_PROPERTY_ENABLED_IN_CHROME (1<<23)
|
||||
@@ -250,26 +254,20 @@ static_assert((CSS_PROPERTY_PARSE_PROPERTY_MASK &
|
||||
// margin-block-start or margin-inline-start).
|
||||
#define CSS_PROPERTY_LOGICAL_END_EDGE (1<<26)
|
||||
|
||||
// This property is a logical property which always maps to the same physical
|
||||
// property, and its values have some custom processing when being mapped to
|
||||
// the physical property's values. Must not be used in conjunction with
|
||||
// CSS_PROPERTY_LOGICAL_{AXIS,BLOCK_AXIS,END_EDGE}.
|
||||
#define CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING (1<<27)
|
||||
|
||||
// This property can be animated on the compositor.
|
||||
#define CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR (1<<28)
|
||||
#define CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR (1<<27)
|
||||
|
||||
// This property is an internal property that is not represented
|
||||
// in the DOM. Properties with this flag must be defined in an #ifndef
|
||||
// CSS_PROP_LIST_EXCLUDE_INTERNAL section of nsCSSPropList.h.
|
||||
#define CSS_PROPERTY_INTERNAL (1<<29)
|
||||
#define CSS_PROPERTY_INTERNAL (1<<28)
|
||||
|
||||
// This property has values that can establish a containing block for
|
||||
// fixed positioned and absolutely positioned elements.
|
||||
// This should be set for any properties that can cause an element to be
|
||||
// such a containing block, as implemented in
|
||||
// nsStyleDisplay::IsFixedPosContainingBlock.
|
||||
#define CSS_PROPERTY_FIXPOS_CB (1<<30)
|
||||
#define CSS_PROPERTY_FIXPOS_CB (1<<29)
|
||||
|
||||
// This property has values that can establish a containing block for
|
||||
// absolutely positioned elements.
|
||||
@@ -278,10 +276,7 @@ static_assert((CSS_PROPERTY_PARSE_PROPERTY_MASK &
|
||||
// nsStyleDisplay::IsAbsPosContainingBlock.
|
||||
// It does not need to be set for properties that also have
|
||||
// CSS_PROPERTY_FIXPOS_CB set.
|
||||
#define CSS_PROPERTY_ABSPOS_CB (1u<<31)
|
||||
|
||||
// NOTE: Before adding any new CSS_PROPERTY_* flags here, we'll need to
|
||||
// upgrade kFlagsTable to 64-bits -- see bug 1231384.
|
||||
#define CSS_PROPERTY_ABSPOS_CB (1<<30)
|
||||
|
||||
/**
|
||||
* Types of animatable values.
|
||||
@@ -555,11 +550,8 @@ public:
|
||||
* by the sentinel.
|
||||
*
|
||||
* When called with a property that has the CSS_PROPERTY_LOGICAL_AXIS
|
||||
* flag, the returned array will have two values preceding the sentinel.
|
||||
* When called with a property that has the
|
||||
* CSS_PROPERTY_LOGICAL_SINGLE_CUSTOM_VALMAPPING flag, the returned array
|
||||
* will have one value preceding the sentinel.
|
||||
* Otherwise it will have four values preceding the sentinel.
|
||||
* flag, the returned array will have two values preceding the sentinel;
|
||||
* otherwise it will have four.
|
||||
*
|
||||
* (Note that the running time of this function is proportional to the
|
||||
* number of logical longhand properties that exist. If we start
|
||||
|
||||
@@ -3209,7 +3209,7 @@ nsCSSRuleProcessor::ClearRuleCascades()
|
||||
|
||||
// We rely on our caller (perhaps indirectly) to do something that
|
||||
// will rebuild style data and the user font set (either
|
||||
// nsIPresShell::ReconstructStyleData or
|
||||
// nsIPresShell::RestyleForCSSRuleChanges or
|
||||
// nsPresContext::RebuildAllStyleData).
|
||||
RuleCascadeData *data = mRuleCascades;
|
||||
mRuleCascades = nullptr;
|
||||
|
||||
+10
-10
@@ -5303,7 +5303,7 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
|
||||
display, parentDisplay, aRuleData,
|
||||
conditions);
|
||||
|
||||
display->mTransitions.SetLength(numTransitions);
|
||||
display->mTransitions.SetLengthNonZero(numTransitions);
|
||||
|
||||
FOR_ALL_TRANSITION_PROPS(p) {
|
||||
const TransitionPropInfo& i = transitionPropInfo[p];
|
||||
@@ -5460,7 +5460,7 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
|
||||
display, parentDisplay, aRuleData,
|
||||
conditions);
|
||||
|
||||
display->mAnimations.SetLength(numAnimations);
|
||||
display->mAnimations.SetLengthNonZero(numAnimations);
|
||||
|
||||
FOR_ALL_ANIMATION_PROPS(p) {
|
||||
const TransitionPropInfo& i = animationPropInfo[p];
|
||||
@@ -6779,8 +6779,8 @@ template <class ComputedValueItem>
|
||||
static void
|
||||
SetImageLayerList(nsStyleContext* aStyleContext,
|
||||
const nsCSSValue& aValue,
|
||||
AutoTArray< nsStyleImageLayers::Layer, 1> &aLayers,
|
||||
const AutoTArray<nsStyleImageLayers::Layer, 1> &aParentLayers,
|
||||
nsStyleAutoArray<nsStyleImageLayers::Layer>& aLayers,
|
||||
const nsStyleAutoArray<nsStyleImageLayers::Layer>& aParentLayers,
|
||||
ComputedValueItem nsStyleImageLayers::Layer::* aResultLocation,
|
||||
ComputedValueItem aInitialValue,
|
||||
uint32_t aParentItemCount,
|
||||
@@ -6844,9 +6844,8 @@ template <class ComputedValueItem>
|
||||
static void
|
||||
SetImageLayerPairList(nsStyleContext* aStyleContext,
|
||||
const nsCSSValue& aValue,
|
||||
AutoTArray< nsStyleImageLayers::Layer, 1> &aLayers,
|
||||
const AutoTArray<nsStyleImageLayers::Layer, 1>
|
||||
&aParentLayers,
|
||||
nsStyleAutoArray<nsStyleImageLayers::Layer>& aLayers,
|
||||
const nsStyleAutoArray<nsStyleImageLayers::Layer>& aParentLayers,
|
||||
ComputedValueItem nsStyleImageLayers::Layer::*
|
||||
aResultLocation,
|
||||
ComputedValueItem aInitialValue,
|
||||
@@ -6911,7 +6910,8 @@ SetImageLayerPairList(nsStyleContext* aStyleContext,
|
||||
|
||||
template <class ComputedValueItem>
|
||||
static void
|
||||
FillBackgroundList(AutoTArray< nsStyleImageLayers::Layer, 1> &aLayers,
|
||||
FillBackgroundList(
|
||||
nsStyleAutoArray<nsStyleImageLayers::Layer>& aLayers,
|
||||
ComputedValueItem nsStyleImageLayers::Layer::* aResultLocation,
|
||||
uint32_t aItemCount, uint32_t aFillCount)
|
||||
{
|
||||
@@ -7033,7 +7033,7 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct,
|
||||
if (rebuild) {
|
||||
// Delete any extra items. We need to keep layers in which any
|
||||
// property was specified.
|
||||
bg->mImage.mLayers.TruncateLength(maxItemCount);
|
||||
bg->mImage.mLayers.TruncateLengthNonZero(maxItemCount);
|
||||
|
||||
uint32_t fillCount = bg->mImage.mImageCount;
|
||||
FillBackgroundList(bg->mImage.mLayers,
|
||||
@@ -9852,7 +9852,7 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct,
|
||||
if (rebuild) {
|
||||
// Delete any extra items. We need to keep layers in which any
|
||||
// property was specified.
|
||||
svgReset->mMask.mLayers.TruncateLength(maxItemCount);
|
||||
svgReset->mMask.mLayers.TruncateLengthNonZero(maxItemCount);
|
||||
|
||||
uint32_t fillCount = svgReset->mMask.mImageCount;
|
||||
|
||||
|
||||
@@ -2317,10 +2317,9 @@ nsStyleImageLayers::nsStyleImageLayers()
|
||||
, mMaskModeCount(1)
|
||||
, mBlendModeCount(1)
|
||||
, mCompositeCount(1)
|
||||
, mLayers(nsStyleAutoArray<Layer>::WITH_SINGLE_INITIAL_ELEMENT)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsStyleImageLayers);
|
||||
mLayers.AppendElement();
|
||||
NS_ASSERTION(mLayers.Length() == 1, "auto array must have room for 1 element");
|
||||
}
|
||||
|
||||
nsStyleImageLayers::nsStyleImageLayers(const nsStyleImageLayers &aSource)
|
||||
@@ -2388,7 +2387,8 @@ nsStyleImageLayers::CalcDifference(const nsStyleImageLayers& aOther) const
|
||||
return hint;
|
||||
}
|
||||
|
||||
if (mBlendModeCount != aOther.mBlendModeCount ||
|
||||
if (mAttachmentCount != aOther.mAttachmentCount ||
|
||||
mBlendModeCount != aOther.mBlendModeCount ||
|
||||
mClipCount != aOther.mClipCount ||
|
||||
mCompositeCount != aOther.mCompositeCount ||
|
||||
mMaskModeCount != aOther.mMaskModeCount ||
|
||||
@@ -2406,7 +2406,12 @@ bool
|
||||
nsStyleImageLayers::HasLayerWithImage() const
|
||||
{
|
||||
for (uint32_t i = 0; i < mImageCount; i++) {
|
||||
if (mLayers[i].mSourceURI) {
|
||||
// mLayers[i].mSourceURI can be nullptr if mask-image prop value is
|
||||
// <element-reference> or <gradient>
|
||||
// mLayers[i].mImage can be empty if mask-image prop value is a reference
|
||||
// to SVG mask element.
|
||||
// So we need to test both mSourceURI and mImage.
|
||||
if (mLayers[i].mSourceURI || !mLayers[i].mImage.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2832,6 +2837,8 @@ mozilla::StyleAnimation::operator==(const mozilla::StyleAnimation& aOther) const
|
||||
|
||||
nsStyleDisplay::nsStyleDisplay(StyleStructContext aContext)
|
||||
: mWillChangeBitField(0)
|
||||
, mTransitions(nsStyleAutoArray<StyleTransition>::WITH_SINGLE_INITIAL_ELEMENT)
|
||||
, mAnimations(nsStyleAutoArray<StyleAnimation>::WITH_SINGLE_INITIAL_ELEMENT)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsStyleDisplay);
|
||||
mAppearance = NS_THEME_NONE;
|
||||
@@ -2872,18 +2879,12 @@ nsStyleDisplay::nsStyleDisplay(StyleStructContext aContext)
|
||||
// Initial value for mScrollSnapDestination is "0px 0px"
|
||||
mScrollSnapDestination.SetInitialZeroValues();
|
||||
|
||||
mTransitions.AppendElement();
|
||||
MOZ_ASSERT(mTransitions.Length() == 1,
|
||||
"appending within auto buffer should never fail");
|
||||
mTransitions[0].SetInitialValues();
|
||||
mTransitionTimingFunctionCount = 1;
|
||||
mTransitionDurationCount = 1;
|
||||
mTransitionDelayCount = 1;
|
||||
mTransitionPropertyCount = 1;
|
||||
|
||||
mAnimations.AppendElement();
|
||||
MOZ_ASSERT(mAnimations.Length() == 1,
|
||||
"appending within auto buffer should never fail");
|
||||
mAnimations[0].SetInitialValues();
|
||||
mAnimationTimingFunctionCount = 1;
|
||||
mAnimationDurationCount = 1;
|
||||
|
||||
@@ -152,7 +152,7 @@ static_assert(offsetof(nsRect_Simple, width) == offsetof(nsRect, width), "Wrong
|
||||
static_assert(offsetof(nsRect_Simple, height) == offsetof(nsRect, height), "Wrong nsRect_Simple member alignment");
|
||||
|
||||
// The lifetime of these objects is managed by the presshell's arena.
|
||||
struct nsStyleFont
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont
|
||||
{
|
||||
nsStyleFont(const nsFont& aFont, StyleStructContext aContext);
|
||||
nsStyleFont(const nsStyleFont& aStyleFont);
|
||||
@@ -421,7 +421,7 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
struct nsStyleColor
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColor
|
||||
{
|
||||
explicit nsStyleColor(StyleStructContext aContext);
|
||||
nsStyleColor(const nsStyleColor& aOther);
|
||||
@@ -455,6 +455,65 @@ struct nsStyleColor
|
||||
nscolor mColor; // [inherited]
|
||||
};
|
||||
|
||||
/**
|
||||
* An array of objects, similar to AutoTArray<T,1> but which is memmovable. It
|
||||
* always has length >= 1.
|
||||
*/
|
||||
template<typename T>
|
||||
class nsStyleAutoArray
|
||||
{
|
||||
public:
|
||||
// This constructor places a single element in mFirstElement.
|
||||
enum WithSingleInitialElement { WITH_SINGLE_INITIAL_ELEMENT };
|
||||
explicit nsStyleAutoArray(WithSingleInitialElement) {}
|
||||
nsStyleAutoArray(const nsStyleAutoArray& aOther) { *this = aOther; }
|
||||
nsStyleAutoArray& operator=(const nsStyleAutoArray& aOther) {
|
||||
mFirstElement = aOther.mFirstElement;
|
||||
mOtherElements = aOther.mOtherElements;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const nsStyleAutoArray& aOther) const {
|
||||
return Length() == aOther.Length() &&
|
||||
mFirstElement == aOther.mFirstElement &&
|
||||
mOtherElements == aOther.mOtherElements;
|
||||
}
|
||||
bool operator!=(const nsStyleAutoArray& aOther) const {
|
||||
return !(*this == aOther);
|
||||
}
|
||||
|
||||
size_t Length() const {
|
||||
return mOtherElements.Length() + 1;
|
||||
}
|
||||
const T& operator[](size_t aIndex) const {
|
||||
return aIndex == 0 ? mFirstElement : mOtherElements[aIndex - 1];
|
||||
}
|
||||
T& operator[](size_t aIndex) {
|
||||
return aIndex == 0 ? mFirstElement : mOtherElements[aIndex - 1];
|
||||
}
|
||||
|
||||
void EnsureLengthAtLeast(size_t aMinLen) {
|
||||
if (aMinLen > 0) {
|
||||
mOtherElements.EnsureLengthAtLeast(aMinLen - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void SetLengthNonZero(size_t aNewLen) {
|
||||
MOZ_ASSERT(aNewLen > 0);
|
||||
mOtherElements.SetLength(aNewLen - 1);
|
||||
}
|
||||
|
||||
void TruncateLengthNonZero(size_t aNewLen) {
|
||||
MOZ_ASSERT(aNewLen > 0);
|
||||
MOZ_ASSERT(aNewLen <= Length());
|
||||
mOtherElements.TruncateLength(aNewLen - 1);
|
||||
}
|
||||
|
||||
private:
|
||||
T mFirstElement;
|
||||
nsTArray<T> mOtherElements;
|
||||
};
|
||||
|
||||
struct nsStyleImageLayers {
|
||||
nsStyleImageLayers();
|
||||
nsStyleImageLayers(const nsStyleImageLayers &aSource);
|
||||
@@ -695,7 +754,7 @@ struct nsStyleImageLayers {
|
||||
// layer. In layers below the bottom layer, properties will be
|
||||
// uninitialized unless their count, above, indicates that they are
|
||||
// present.
|
||||
AutoTArray<Layer, 1> mLayers;
|
||||
nsStyleAutoArray<Layer> mLayers;
|
||||
|
||||
const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
|
||||
|
||||
@@ -724,7 +783,7 @@ struct nsStyleImageLayers {
|
||||
for (uint32_t var_ = (start_) + 1; var_-- != (uint32_t)((start_) + 1 - (count_)); )
|
||||
};
|
||||
|
||||
struct nsStyleBackground {
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBackground {
|
||||
explicit nsStyleBackground(StyleStructContext aContext);
|
||||
nsStyleBackground(const nsStyleBackground& aOther);
|
||||
~nsStyleBackground();
|
||||
@@ -777,7 +836,7 @@ struct nsStyleBackground {
|
||||
#define NS_SPACING_BORDER 2
|
||||
|
||||
|
||||
struct nsStyleMargin
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin
|
||||
{
|
||||
explicit nsStyleMargin(StyleStructContext aContext);
|
||||
nsStyleMargin(const nsStyleMargin& aMargin);
|
||||
@@ -823,7 +882,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
struct nsStylePadding
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding
|
||||
{
|
||||
explicit nsStylePadding(StyleStructContext aContext);
|
||||
nsStylePadding(const nsStylePadding& aPadding);
|
||||
@@ -1026,7 +1085,7 @@ static bool IsVisibleBorderStyle(uint8_t aStyle)
|
||||
aStyle != NS_STYLE_BORDER_STYLE_HIDDEN);
|
||||
}
|
||||
|
||||
struct nsStyleBorder
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder
|
||||
{
|
||||
explicit nsStyleBorder(StyleStructContext aContext);
|
||||
nsStyleBorder(const nsStyleBorder& aBorder);
|
||||
@@ -1253,7 +1312,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
struct nsStyleOutline
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline
|
||||
{
|
||||
explicit nsStyleOutline(StyleStructContext aContext);
|
||||
nsStyleOutline(const nsStyleOutline& aOutline);
|
||||
@@ -1364,7 +1423,7 @@ private:
|
||||
~nsStyleQuoteValues() {}
|
||||
};
|
||||
|
||||
struct nsStyleList
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList
|
||||
{
|
||||
explicit nsStyleList(StyleStructContext aContext);
|
||||
nsStyleList(const nsStyleList& aStyleList);
|
||||
@@ -1570,7 +1629,7 @@ struct nsStyleTextOverflow
|
||||
bool mLogicalDirections; // true when only one value was specified
|
||||
};
|
||||
|
||||
struct nsStyleTextReset
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset
|
||||
{
|
||||
explicit nsStyleTextReset(StyleStructContext aContext);
|
||||
nsStyleTextReset(const nsStyleTextReset& aOther);
|
||||
@@ -1655,7 +1714,7 @@ protected:
|
||||
nscolor mTextDecorationColor; // [reset] the colors to use for a decoration lines, not used at currentColor
|
||||
};
|
||||
|
||||
struct nsStyleText
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText
|
||||
{
|
||||
explicit nsStyleText(StyleStructContext aContext);
|
||||
nsStyleText(const nsStyleText& aOther);
|
||||
@@ -1872,7 +1931,7 @@ protected:
|
||||
uint8_t mOrientation;
|
||||
};
|
||||
|
||||
struct nsStyleVisibility
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVisibility
|
||||
{
|
||||
explicit nsStyleVisibility(StyleStructContext aContext);
|
||||
nsStyleVisibility(const nsStyleVisibility& aVisibility);
|
||||
@@ -2153,7 +2212,7 @@ private:
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
struct nsStyleDisplay
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
|
||||
{
|
||||
explicit nsStyleDisplay(StyleStructContext aContext);
|
||||
nsStyleDisplay(const nsStyleDisplay& aOther);
|
||||
@@ -2224,7 +2283,7 @@ struct nsStyleDisplay
|
||||
// match mWillChange. Also tracks if any of the
|
||||
// properties in the will-change list require
|
||||
// a stacking context.
|
||||
AutoTArray<nsString, 1> mWillChange;
|
||||
nsTArray<nsString> mWillChange;
|
||||
|
||||
uint8_t mTouchAction; // [reset] see nsStyleConsts.h
|
||||
uint8_t mScrollBehavior; // [reset] see nsStyleConsts.h NS_STYLE_SCROLL_BEHAVIOR_*
|
||||
@@ -2249,7 +2308,7 @@ struct nsStyleDisplay
|
||||
|
||||
nsStyleCoord mVerticalAlign; // [reset] coord, percent, calc, enum (see nsStyleConsts.h)
|
||||
|
||||
AutoTArray<mozilla::StyleTransition, 1> mTransitions; // [reset]
|
||||
nsStyleAutoArray<mozilla::StyleTransition> mTransitions; // [reset]
|
||||
// The number of elements in mTransitions that are not from repeating
|
||||
// a list due to another property being longer.
|
||||
uint32_t mTransitionTimingFunctionCount,
|
||||
@@ -2257,7 +2316,7 @@ struct nsStyleDisplay
|
||||
mTransitionDelayCount,
|
||||
mTransitionPropertyCount;
|
||||
|
||||
AutoTArray<mozilla::StyleAnimation, 1> mAnimations; // [reset]
|
||||
nsStyleAutoArray<mozilla::StyleAnimation> mAnimations; // [reset]
|
||||
// The number of elements in mAnimations that are not from repeating
|
||||
// a list due to another property being longer.
|
||||
uint32_t mAnimationTimingFunctionCount,
|
||||
@@ -2425,7 +2484,7 @@ struct nsStyleDisplay
|
||||
inline uint8_t PhysicalBreakType(mozilla::WritingMode aWM) const;
|
||||
};
|
||||
|
||||
struct nsStyleTable
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTable
|
||||
{
|
||||
explicit nsStyleTable(StyleStructContext aContext);
|
||||
nsStyleTable(const nsStyleTable& aOther);
|
||||
@@ -2536,7 +2595,7 @@ struct nsStyleGridTemplate
|
||||
}
|
||||
};
|
||||
|
||||
struct nsStylePosition
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition
|
||||
{
|
||||
explicit nsStylePosition(StyleStructContext aContext);
|
||||
nsStylePosition(const nsStylePosition& aOther);
|
||||
@@ -2730,7 +2789,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
struct nsStyleTableBorder
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTableBorder
|
||||
{
|
||||
explicit nsStyleTableBorder(StyleStructContext aContext);
|
||||
nsStyleTableBorder(const nsStyleTableBorder& aOther);
|
||||
@@ -2830,7 +2889,7 @@ struct nsStyleCounterData
|
||||
|
||||
#define DELETE_ARRAY_IF(array) if (array) { delete[] array; array = nullptr; }
|
||||
|
||||
struct nsStyleContent
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent
|
||||
{
|
||||
explicit nsStyleContent(StyleStructContext aContext);
|
||||
nsStyleContent(const nsStyleContent& aContent);
|
||||
@@ -2941,7 +3000,7 @@ protected:
|
||||
uint32_t mResetCount;
|
||||
};
|
||||
|
||||
struct nsStyleUIReset
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset
|
||||
{
|
||||
explicit nsStyleUIReset(StyleStructContext aContext);
|
||||
nsStyleUIReset(const nsStyleUIReset& aOther);
|
||||
@@ -3007,7 +3066,7 @@ private:
|
||||
nsCOMPtr<imgIRequest> mImage;
|
||||
};
|
||||
|
||||
struct nsStyleUserInterface
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUserInterface
|
||||
{
|
||||
explicit nsStyleUserInterface(StyleStructContext aContext);
|
||||
nsStyleUserInterface(const nsStyleUserInterface& aOther);
|
||||
@@ -3058,7 +3117,7 @@ struct nsStyleUserInterface
|
||||
inline uint8_t GetEffectivePointerEvents(nsIFrame* aFrame) const;
|
||||
};
|
||||
|
||||
struct nsStyleXUL
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleXUL
|
||||
{
|
||||
explicit nsStyleXUL(StyleStructContext aContext);
|
||||
nsStyleXUL(const nsStyleXUL& aSource);
|
||||
@@ -3096,7 +3155,7 @@ struct nsStyleXUL
|
||||
bool mStretchStack; // [reset] see nsStyleConsts.h
|
||||
};
|
||||
|
||||
struct nsStyleColumn
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColumn
|
||||
{
|
||||
explicit nsStyleColumn(StyleStructContext aContext);
|
||||
nsStyleColumn(const nsStyleColumn& aSource);
|
||||
@@ -3191,7 +3250,7 @@ struct nsStyleSVGPaint
|
||||
}
|
||||
};
|
||||
|
||||
struct nsStyleSVG
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG
|
||||
{
|
||||
explicit nsStyleSVG(StyleStructContext aContext);
|
||||
nsStyleSVG(const nsStyleSVG& aSource);
|
||||
@@ -3477,7 +3536,7 @@ struct nsTArray_CopyChooser<nsStyleFilter>
|
||||
typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type;
|
||||
};
|
||||
|
||||
struct nsStyleSVGReset
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset
|
||||
{
|
||||
explicit nsStyleSVGReset(StyleStructContext aContext);
|
||||
nsStyleSVGReset(const nsStyleSVGReset& aSource);
|
||||
@@ -3527,7 +3586,7 @@ struct nsStyleSVGReset
|
||||
uint8_t mMaskType; // [reset] see nsStyleConsts.h
|
||||
};
|
||||
|
||||
struct nsStyleVariables
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVariables
|
||||
{
|
||||
explicit nsStyleVariables(StyleStructContext aContext);
|
||||
nsStyleVariables(const nsStyleVariables& aSource);
|
||||
@@ -3557,7 +3616,7 @@ struct nsStyleVariables
|
||||
mozilla::CSSVariableValues mVariables;
|
||||
};
|
||||
|
||||
struct nsStyleEffects
|
||||
struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleEffects
|
||||
{
|
||||
explicit nsStyleEffects(StyleStructContext aContext);
|
||||
nsStyleEffects(const nsStyleEffects& aSource);
|
||||
|
||||
@@ -639,6 +639,7 @@ MatrixForTransformFunction(Matrix4x4& aMatrix,
|
||||
break;
|
||||
case eCSSKeyword_rotatez:
|
||||
*aContains3dTransform = true;
|
||||
MOZ_FALLTHROUGH;
|
||||
case eCSSKeyword_rotate:
|
||||
ProcessRotateZ(aMatrix, aData);
|
||||
break;
|
||||
|
||||
@@ -63,13 +63,11 @@ ElementPropertyTransition::CurrentValuePortion() const
|
||||
|
||||
MOZ_ASSERT(!computedTiming.mProgress.IsNull(),
|
||||
"Got a null progress for a fill mode of 'both'");
|
||||
MOZ_ASSERT(mProperties.Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
MOZ_ASSERT(mProperties[0].mSegments.Length() == 1,
|
||||
"Animation property should have one segment for a transition");
|
||||
return ComputedTimingFunction::GetPortion(
|
||||
mProperties[0].mSegments[0].mTimingFunction,
|
||||
computedTiming.mProgress.Value(), computedTiming.mBeforeFlag);
|
||||
MOZ_ASSERT(mFrames.Length() == 2,
|
||||
"Should have two animation frames for a transition");
|
||||
return ComputedTimingFunction::GetPortion(mFrames[0].mTimingFunction,
|
||||
computedTiming.mProgress.Value(),
|
||||
computedTiming.mBeforeFlag);
|
||||
}
|
||||
|
||||
////////////////////////// CSSTransition ////////////////////////////
|
||||
@@ -135,16 +133,6 @@ CSSTransition::QueueEvents()
|
||||
mOwningElement.GetElement(owningElement, owningPseudoType);
|
||||
MOZ_ASSERT(owningElement, "Owning element should be set");
|
||||
|
||||
// Do not queue any event for disabled properties. This could happen
|
||||
// if the property has a default value which derives value from other
|
||||
// property, e.g. color.
|
||||
nsCSSProperty property = TransitionProperty();
|
||||
if (!nsCSSProps::IsEnabled(property, nsCSSProps::eEnabledForAllContent) &&
|
||||
(!nsContentUtils::IsSystemPrincipal(owningElement->NodePrincipal()) ||
|
||||
!nsCSSProps::IsEnabled(property, nsCSSProps::eEnabledInChrome))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsPresContext* presContext = mOwningElement.GetRenderedPresContext();
|
||||
if (!presContext) {
|
||||
return;
|
||||
@@ -152,7 +140,7 @@ CSSTransition::QueueEvents()
|
||||
|
||||
nsTransitionManager* manager = presContext->TransitionManager();
|
||||
manager->QueueEvent(TransitionEventInfo(owningElement, owningPseudoType,
|
||||
property,
|
||||
TransitionProperty(),
|
||||
mEffect->GetComputedTiming()
|
||||
.mDuration,
|
||||
AnimationTimeToTimeStamp(EffectEnd()),
|
||||
@@ -178,6 +166,17 @@ CSSTransition::TransitionProperty() const
|
||||
return effect->AsTransition()->TransitionProperty();
|
||||
}
|
||||
|
||||
StyleAnimationValue
|
||||
CSSTransition::ToValue() const
|
||||
{
|
||||
// FIXME: Once we support replacing/removing the effect (bug 1049975)
|
||||
// the following assertion will no longer hold.
|
||||
dom::KeyframeEffectReadOnly* effect = GetEffect();
|
||||
MOZ_ASSERT(effect && effect->AsTransition(),
|
||||
"Transition should have a transition effect");
|
||||
return effect->AsTransition()->ToValue();
|
||||
}
|
||||
|
||||
bool
|
||||
CSSTransition::HasLowerCompositeOrderThan(const CSSTransition& aOther) const
|
||||
{
|
||||
@@ -335,131 +334,12 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
||||
|
||||
nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
|
||||
|
||||
// Per http://lists.w3.org/Archives/Public/www-style/2009Aug/0109.html
|
||||
// I'll consider only the transitions from the number of items in
|
||||
// 'transition-property' on down, and later ones will override earlier
|
||||
// ones (tracked using |whichStarted|).
|
||||
bool startedAny = false;
|
||||
nsCSSPropertySet whichStarted;
|
||||
for (uint32_t i = disp->mTransitionPropertyCount; i-- != 0; ) {
|
||||
const StyleTransition& t = disp->mTransitions[i];
|
||||
// Check the combined duration (combination of delay and duration)
|
||||
// first, since it defaults to zero, which means we can ignore the
|
||||
// transition.
|
||||
if (t.GetCombinedDuration() > 0.0f) {
|
||||
// We might have something to transition. See if any of the
|
||||
// properties in question changed and are animatable.
|
||||
// FIXME: Would be good to find a way to share code between this
|
||||
// interpretation of transition-property and the one below.
|
||||
nsCSSProperty property = t.GetProperty();
|
||||
if (property == eCSSPropertyExtra_no_properties ||
|
||||
property == eCSSPropertyExtra_variable ||
|
||||
property == eCSSProperty_UNKNOWN) {
|
||||
// Nothing to do, but need to exclude this from cases below.
|
||||
} else if (property == eCSSPropertyExtra_all_properties) {
|
||||
for (nsCSSProperty p = nsCSSProperty(0);
|
||||
p < eCSSProperty_COUNT_no_shorthands;
|
||||
p = nsCSSProperty(p + 1)) {
|
||||
ConsiderStartingTransition(p, t, aElement, collection,
|
||||
aOldStyleContext, afterChangeStyle,
|
||||
&startedAny, &whichStarted);
|
||||
}
|
||||
} else if (nsCSSProps::IsShorthand(property)) {
|
||||
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(
|
||||
subprop, property, nsCSSProps::eEnabledForAllContent) {
|
||||
ConsiderStartingTransition(*subprop, t, aElement, collection,
|
||||
aOldStyleContext, afterChangeStyle,
|
||||
&startedAny, &whichStarted);
|
||||
}
|
||||
} else {
|
||||
ConsiderStartingTransition(property, t, aElement, collection,
|
||||
aOldStyleContext, afterChangeStyle,
|
||||
&startedAny, &whichStarted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stop any transitions for properties that are no longer in
|
||||
// 'transition-property', including finished transitions.
|
||||
// Also stop any transitions (and remove any finished transitions)
|
||||
// for properties that just changed (and are still in the set of
|
||||
// properties to transition), but for which we didn't just start the
|
||||
// transition. This can happen delay and duration are both zero, or
|
||||
// because the new value is not interpolable.
|
||||
// Note that we also do the latter set of work in
|
||||
// nsTransitionManager::PruneCompletedTransitions.
|
||||
if (collection) {
|
||||
bool checkProperties =
|
||||
disp->mTransitions[0].GetProperty() != eCSSPropertyExtra_all_properties;
|
||||
nsCSSPropertySet allTransitionProperties;
|
||||
if (checkProperties) {
|
||||
for (uint32_t i = disp->mTransitionPropertyCount; i-- != 0; ) {
|
||||
const StyleTransition& t = disp->mTransitions[i];
|
||||
// FIXME: Would be good to find a way to share code between this
|
||||
// interpretation of transition-property and the one above.
|
||||
nsCSSProperty property = t.GetProperty();
|
||||
if (property == eCSSPropertyExtra_no_properties ||
|
||||
property == eCSSPropertyExtra_variable ||
|
||||
property == eCSSProperty_UNKNOWN) {
|
||||
// Nothing to do, but need to exclude this from cases below.
|
||||
} else if (property == eCSSPropertyExtra_all_properties) {
|
||||
for (nsCSSProperty p = nsCSSProperty(0);
|
||||
p < eCSSProperty_COUNT_no_shorthands;
|
||||
p = nsCSSProperty(p + 1)) {
|
||||
allTransitionProperties.AddProperty(p);
|
||||
}
|
||||
} else if (nsCSSProps::IsShorthand(property)) {
|
||||
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(
|
||||
subprop, property, nsCSSProps::eEnabledForAllContent) {
|
||||
allTransitionProperties.AddProperty(*subprop);
|
||||
}
|
||||
} else {
|
||||
allTransitionProperties.AddProperty(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OwningCSSTransitionPtrArray& animations = collection->mAnimations;
|
||||
size_t i = animations.Length();
|
||||
MOZ_ASSERT(i != 0, "empty transitions list?");
|
||||
StyleAnimationValue currentValue;
|
||||
do {
|
||||
--i;
|
||||
CSSTransition* anim = animations[i];
|
||||
dom::KeyframeEffectReadOnly* effect = anim->GetEffect();
|
||||
MOZ_ASSERT(effect && effect->Properties().Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
MOZ_ASSERT(effect && effect->Properties()[0].mSegments.Length() == 1,
|
||||
"Animation property should have one segment for a transition");
|
||||
const AnimationProperty& prop = effect->Properties()[0];
|
||||
const AnimationPropertySegment& segment = prop.mSegments[0];
|
||||
// properties no longer in 'transition-property'
|
||||
if ((checkProperties &&
|
||||
!allTransitionProperties.HasProperty(prop.mProperty)) ||
|
||||
// properties whose computed values changed but for which we
|
||||
// did not start a new transition (because delay and
|
||||
// duration are both zero, or because the new value is not
|
||||
// interpolable); a new transition would have segment.mToValue
|
||||
// matching currentValue
|
||||
!ExtractComputedValueForTransition(prop.mProperty, afterChangeStyle,
|
||||
currentValue) ||
|
||||
currentValue != segment.mToValue) {
|
||||
// stop the transition
|
||||
if (anim->HasCurrentEffect()) {
|
||||
EffectSet* effectSet = EffectSet::GetEffectSet(aElement, pseudoType);
|
||||
if (effectSet) {
|
||||
effectSet->UpdateAnimationGeneration(mPresContext);
|
||||
}
|
||||
}
|
||||
anim->CancelFromStyle();
|
||||
animations.RemoveElementAt(i);
|
||||
}
|
||||
} while (i != 0);
|
||||
|
||||
if (animations.IsEmpty()) {
|
||||
collection->Destroy();
|
||||
collection = nullptr;
|
||||
}
|
||||
DebugOnly<bool> startedAny = false;
|
||||
// We don't have to update transitions if display:none, although we will
|
||||
// cancel them after restyling.
|
||||
if (!afterChangeStyle->IsInDisplayNoneSubtree()) {
|
||||
startedAny = UpdateTransitions(disp, aElement, collection,
|
||||
aOldStyleContext, afterChangeStyle);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!startedAny || collection,
|
||||
@@ -491,6 +371,145 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsTransitionManager::UpdateTransitions(
|
||||
const nsStyleDisplay* aDisp,
|
||||
dom::Element* aElement,
|
||||
CSSTransitionCollection*& aElementTransitions,
|
||||
nsStyleContext* aOldStyleContext,
|
||||
nsStyleContext* aNewStyleContext)
|
||||
{
|
||||
MOZ_ASSERT(aDisp, "Null nsStyleDisplay");
|
||||
MOZ_ASSERT(!aElementTransitions ||
|
||||
aElementTransitions->mElement == aElement, "Element mismatch");
|
||||
|
||||
// Per http://lists.w3.org/Archives/Public/www-style/2009Aug/0109.html
|
||||
// I'll consider only the transitions from the number of items in
|
||||
// 'transition-property' on down, and later ones will override earlier
|
||||
// ones (tracked using |whichStarted|).
|
||||
bool startedAny = false;
|
||||
nsCSSPropertySet whichStarted;
|
||||
for (uint32_t i = aDisp->mTransitionPropertyCount; i-- != 0; ) {
|
||||
const StyleTransition& t = aDisp->mTransitions[i];
|
||||
// Check the combined duration (combination of delay and duration)
|
||||
// first, since it defaults to zero, which means we can ignore the
|
||||
// transition.
|
||||
if (t.GetCombinedDuration() > 0.0f) {
|
||||
// We might have something to transition. See if any of the
|
||||
// properties in question changed and are animatable.
|
||||
// FIXME: Would be good to find a way to share code between this
|
||||
// interpretation of transition-property and the one below.
|
||||
nsCSSProperty property = t.GetProperty();
|
||||
if (property == eCSSPropertyExtra_no_properties ||
|
||||
property == eCSSPropertyExtra_variable ||
|
||||
property == eCSSProperty_UNKNOWN) {
|
||||
// Nothing to do, but need to exclude this from cases below.
|
||||
} else if (property == eCSSPropertyExtra_all_properties) {
|
||||
for (nsCSSProperty p = nsCSSProperty(0);
|
||||
p < eCSSProperty_COUNT_no_shorthands;
|
||||
p = nsCSSProperty(p + 1)) {
|
||||
ConsiderStartingTransition(p, t, aElement, aElementTransitions,
|
||||
aOldStyleContext, aNewStyleContext,
|
||||
&startedAny, &whichStarted);
|
||||
}
|
||||
} else if (nsCSSProps::IsShorthand(property)) {
|
||||
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(subprop, property,
|
||||
nsCSSProps::eEnabledForAllContent)
|
||||
{
|
||||
ConsiderStartingTransition(*subprop, t, aElement, aElementTransitions,
|
||||
aOldStyleContext, aNewStyleContext,
|
||||
&startedAny, &whichStarted);
|
||||
}
|
||||
} else {
|
||||
ConsiderStartingTransition(property, t, aElement, aElementTransitions,
|
||||
aOldStyleContext, aNewStyleContext,
|
||||
&startedAny, &whichStarted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stop any transitions for properties that are no longer in
|
||||
// 'transition-property', including finished transitions.
|
||||
// Also stop any transitions (and remove any finished transitions)
|
||||
// for properties that just changed (and are still in the set of
|
||||
// properties to transition), but for which we didn't just start the
|
||||
// transition. This can happen delay and duration are both zero, or
|
||||
// because the new value is not interpolable.
|
||||
// Note that we also do the latter set of work in
|
||||
// nsTransitionManager::PruneCompletedTransitions.
|
||||
if (aElementTransitions) {
|
||||
bool checkProperties =
|
||||
aDisp->mTransitions[0].GetProperty() != eCSSPropertyExtra_all_properties;
|
||||
nsCSSPropertySet allTransitionProperties;
|
||||
if (checkProperties) {
|
||||
for (uint32_t i = aDisp->mTransitionPropertyCount; i-- != 0; ) {
|
||||
const StyleTransition& t = aDisp->mTransitions[i];
|
||||
// FIXME: Would be good to find a way to share code between this
|
||||
// interpretation of transition-property and the one above.
|
||||
nsCSSProperty property = t.GetProperty();
|
||||
if (property == eCSSPropertyExtra_no_properties ||
|
||||
property == eCSSPropertyExtra_variable ||
|
||||
property == eCSSProperty_UNKNOWN) {
|
||||
// Nothing to do, but need to exclude this from cases below.
|
||||
} else if (property == eCSSPropertyExtra_all_properties) {
|
||||
for (nsCSSProperty p = nsCSSProperty(0);
|
||||
p < eCSSProperty_COUNT_no_shorthands;
|
||||
p = nsCSSProperty(p + 1)) {
|
||||
allTransitionProperties.AddProperty(p);
|
||||
}
|
||||
} else if (nsCSSProps::IsShorthand(property)) {
|
||||
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(
|
||||
subprop, property, nsCSSProps::eEnabledForAllContent) {
|
||||
allTransitionProperties.AddProperty(*subprop);
|
||||
}
|
||||
} else {
|
||||
allTransitionProperties.AddProperty(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OwningCSSTransitionPtrArray& animations = aElementTransitions->mAnimations;
|
||||
size_t i = animations.Length();
|
||||
MOZ_ASSERT(i != 0, "empty transitions list?");
|
||||
StyleAnimationValue currentValue;
|
||||
do {
|
||||
--i;
|
||||
CSSTransition* anim = animations[i];
|
||||
// properties no longer in 'transition-property'
|
||||
if ((checkProperties &&
|
||||
!allTransitionProperties.HasProperty(anim->TransitionProperty())) ||
|
||||
// properties whose computed values changed but for which we
|
||||
// did not start a new transition (because delay and
|
||||
// duration are both zero, or because the new value is not
|
||||
// interpolable); a new transition would have anim->ToValue()
|
||||
// matching currentValue
|
||||
!ExtractComputedValueForTransition(anim->TransitionProperty(),
|
||||
aNewStyleContext,
|
||||
currentValue) ||
|
||||
currentValue != anim->ToValue()) {
|
||||
// stop the transition
|
||||
if (anim->HasCurrentEffect()) {
|
||||
EffectSet* effectSet =
|
||||
EffectSet::GetEffectSet(aElement,
|
||||
aNewStyleContext->GetPseudoType());
|
||||
if (effectSet) {
|
||||
effectSet->UpdateAnimationGeneration(mPresContext);
|
||||
}
|
||||
}
|
||||
anim->CancelFromStyle();
|
||||
animations.RemoveElementAt(i);
|
||||
}
|
||||
} while (i != 0);
|
||||
|
||||
if (animations.IsEmpty()) {
|
||||
aElementTransitions->Destroy();
|
||||
aElementTransitions = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return startedAny;
|
||||
}
|
||||
|
||||
void
|
||||
nsTransitionManager::ConsiderStartingTransition(
|
||||
nsCSSProperty aProperty,
|
||||
@@ -508,6 +527,13 @@ nsTransitionManager::ConsiderStartingTransition(
|
||||
NS_ASSERTION(!aElementTransitions ||
|
||||
aElementTransitions->mElement == aElement, "Element mismatch");
|
||||
|
||||
// Ignore disabled properties. We can arrive here if the transition-property
|
||||
// is 'all' and the disabled property has a default value which derives value
|
||||
// from another property, e.g. color.
|
||||
if (!nsCSSProps::IsEnabled(aProperty, nsCSSProps::eEnabledForAllContent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aWhichStarted->HasProperty(aProperty)) {
|
||||
// A later item in transition-property already started a
|
||||
// transition for this property, so we ignore this one.
|
||||
@@ -667,19 +693,9 @@ nsTransitionManager::ConsiderStartingTransition(
|
||||
aNewStyleContext->GetPseudoType(), timing,
|
||||
startForReversingTest, reversePortion);
|
||||
|
||||
AnimationProperty& prop = *pt->Properties().AppendElement();
|
||||
prop.mProperty = aProperty;
|
||||
|
||||
AnimationPropertySegment& segment = *prop.mSegments.AppendElement();
|
||||
segment.mFromValue = startValue;
|
||||
segment.mToValue = endValue;
|
||||
segment.mFromKey = 0;
|
||||
segment.mToKey = 1;
|
||||
if (tf.mType != nsTimingFunction::Type::Linear) {
|
||||
ComputedTimingFunction computedTimingFunction;
|
||||
computedTimingFunction.Init(tf);
|
||||
segment.mTimingFunction = Some(computedTimingFunction);
|
||||
}
|
||||
pt->SetFrames(GetTransitionKeyframes(aNewStyleContext, aProperty,
|
||||
Move(startValue), Move(endValue), tf),
|
||||
aNewStyleContext);
|
||||
|
||||
MOZ_ASSERT(mPresContext->RestyleManager()->IsGecko(),
|
||||
"ServoRestyleManager should not use nsTransitionManager "
|
||||
@@ -747,6 +763,43 @@ nsTransitionManager::ConsiderStartingTransition(
|
||||
aWhichStarted->AddProperty(aProperty);
|
||||
}
|
||||
|
||||
static Keyframe&
|
||||
AppendKeyframe(double aOffset, nsCSSProperty aProperty,
|
||||
StyleAnimationValue&& aValue, nsTArray<Keyframe>& aKeyframes)
|
||||
{
|
||||
Keyframe& frame = *aKeyframes.AppendElement();
|
||||
frame.mOffset.emplace(aOffset);
|
||||
PropertyValuePair& pv = *frame.mPropertyValues.AppendElement();
|
||||
pv.mProperty = aProperty;
|
||||
DebugOnly<bool> uncomputeResult =
|
||||
StyleAnimationValue::UncomputeValue(aProperty, Move(aValue), pv.mValue);
|
||||
MOZ_ASSERT(uncomputeResult,
|
||||
"Unable to get specified value from computed value");
|
||||
return frame;
|
||||
}
|
||||
|
||||
nsTArray<Keyframe>
|
||||
nsTransitionManager::GetTransitionKeyframes(
|
||||
nsStyleContext* aStyleContext,
|
||||
nsCSSProperty aProperty,
|
||||
StyleAnimationValue&& aStartValue,
|
||||
StyleAnimationValue&& aEndValue,
|
||||
const nsTimingFunction& aTimingFunction)
|
||||
{
|
||||
nsTArray<Keyframe> keyframes(2);
|
||||
|
||||
Keyframe& fromFrame = AppendKeyframe(0.0, aProperty, Move(aStartValue),
|
||||
keyframes);
|
||||
if (aTimingFunction.mType != nsTimingFunction::Type::Linear) {
|
||||
fromFrame.mTimingFunction.emplace();
|
||||
fromFrame.mTimingFunction->Init(aTimingFunction);
|
||||
}
|
||||
|
||||
AppendKeyframe(1.0, aProperty, Move(aEndValue), keyframes);
|
||||
|
||||
return keyframes;
|
||||
}
|
||||
|
||||
void
|
||||
nsTransitionManager::PruneCompletedTransitions(mozilla::dom::Element* aElement,
|
||||
CSSPseudoElementType aPseudoType,
|
||||
@@ -775,20 +828,13 @@ nsTransitionManager::PruneCompletedTransitions(mozilla::dom::Element* aElement,
|
||||
continue;
|
||||
}
|
||||
|
||||
dom::KeyframeEffectReadOnly* effect = anim->GetEffect();
|
||||
MOZ_ASSERT(effect->Properties().Length() == 1,
|
||||
"Should have one animation property for a transition");
|
||||
MOZ_ASSERT(effect->Properties()[0].mSegments.Length() == 1,
|
||||
"Animation property should have one segment for a transition");
|
||||
const AnimationProperty& prop = effect->Properties()[0];
|
||||
const AnimationPropertySegment& segment = prop.mSegments[0];
|
||||
|
||||
// Since effect is a finished transition, we know it didn't
|
||||
// influence style.
|
||||
StyleAnimationValue currentValue;
|
||||
if (!ExtractComputedValueForTransition(prop.mProperty, aNewStyleContext,
|
||||
if (!ExtractComputedValueForTransition(anim->TransitionProperty(),
|
||||
aNewStyleContext,
|
||||
currentValue) ||
|
||||
currentValue != segment.mToValue) {
|
||||
currentValue != anim->ToValue()) {
|
||||
anim->CancelFromStyle();
|
||||
animations.RemoveElementAt(i);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ class nsCSSPropertySet;
|
||||
|
||||
namespace mozilla {
|
||||
enum class CSSPseudoElementType : uint8_t;
|
||||
struct Keyframe;
|
||||
struct StyleTransition;
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -52,19 +53,28 @@ struct ElementPropertyTransition : public dom::KeyframeEffectReadOnly
|
||||
}
|
||||
|
||||
nsCSSProperty TransitionProperty() const {
|
||||
MOZ_ASSERT(mProperties.Length() == 1,
|
||||
"Transitions should have exactly one animation property. "
|
||||
MOZ_ASSERT(mFrames.Length() == 2,
|
||||
"Transitions should have exactly two animation frames. "
|
||||
"Perhaps we are using an un-initialized transition?");
|
||||
return mProperties[0].mProperty;
|
||||
MOZ_ASSERT(mFrames[0].mPropertyValues.Length() == 1,
|
||||
"Transitions should have exactly one property in their first "
|
||||
"frame");
|
||||
return mFrames[0].mPropertyValues[0].mProperty;
|
||||
}
|
||||
|
||||
StyleAnimationValue ToValue() const {
|
||||
MOZ_ASSERT(mProperties.Length() == 1,
|
||||
"Transitions should have exactly one animation property");
|
||||
MOZ_ASSERT(mProperties[0].mSegments.Length() == 1,
|
||||
"Transitions should have one animation property segment ");
|
||||
// If we failed to generate properties from the transition frames,
|
||||
// return a null value but also show a warning since we should be
|
||||
// detecting that kind of situation in advance and not generating a
|
||||
// transition in the first place.
|
||||
if (mProperties.Length() < 1 ||
|
||||
mProperties[0].mSegments.Length() < 1) {
|
||||
NS_WARNING("Failed to generate transition property values");
|
||||
return StyleAnimationValue();
|
||||
}
|
||||
return mProperties[0].mSegments[0].mToValue;
|
||||
}
|
||||
|
||||
// This is the start value to be used for a check for whether a
|
||||
// transition is being reversed. Normally the same as
|
||||
// mProperties[0].mSegments[0].mFromValue, except when this transition
|
||||
@@ -147,6 +157,7 @@ public:
|
||||
void Tick() override;
|
||||
|
||||
nsCSSProperty TransitionProperty() const;
|
||||
StyleAnimationValue ToValue() const;
|
||||
|
||||
bool HasLowerCompositeOrderThan(const CSSTransition& aOther) const;
|
||||
EffectCompositor::CascadeLevel CascadeLevel() const override
|
||||
@@ -250,10 +261,10 @@ struct TransitionEventInfo {
|
||||
, mTimeStamp(aTimeStamp)
|
||||
{
|
||||
// XXX Looks like nobody initialize WidgetEvent::time
|
||||
mEvent.propertyName =
|
||||
mEvent.mPropertyName =
|
||||
NS_ConvertUTF8toUTF16(nsCSSProps::GetStringValue(aProperty));
|
||||
mEvent.elapsedTime = aDuration.ToSeconds();
|
||||
mEvent.pseudoElement =
|
||||
mEvent.mElapsedTime = aDuration.ToSeconds();
|
||||
mEvent.mPseudoElement =
|
||||
AnimationCollection<dom::CSSTransition>::PseudoTypeAsString(aPseudoType);
|
||||
}
|
||||
|
||||
@@ -351,6 +362,17 @@ protected:
|
||||
typedef nsTArray<RefPtr<mozilla::dom::CSSTransition>>
|
||||
OwningCSSTransitionPtrArray;
|
||||
|
||||
// Update the transitions. It'd start new, replace, or stop current
|
||||
// transitions if need. aDisp and aElement shouldn't be nullptr.
|
||||
// aElementTransitions is the collection of current transitions, and it
|
||||
// could be a nullptr if we don't have any transitions.
|
||||
bool
|
||||
UpdateTransitions(const nsStyleDisplay* aDisp,
|
||||
mozilla::dom::Element* aElement,
|
||||
CSSTransitionCollection*& aElementTransitions,
|
||||
nsStyleContext* aOldStyleContext,
|
||||
nsStyleContext* aNewStyleContext);
|
||||
|
||||
void
|
||||
ConsiderStartingTransition(nsCSSProperty aProperty,
|
||||
const mozilla::StyleTransition& aTransition,
|
||||
@@ -361,6 +383,13 @@ protected:
|
||||
bool* aStartedAny,
|
||||
nsCSSPropertySet* aWhichStarted);
|
||||
|
||||
nsTArray<mozilla::Keyframe> GetTransitionKeyframes(
|
||||
nsStyleContext* aStyleContext,
|
||||
nsCSSProperty aProperty,
|
||||
mozilla::StyleAnimationValue&& aStartValue,
|
||||
mozilla::StyleAnimationValue&& aEndValue,
|
||||
const nsTimingFunction& aTimingFunction);
|
||||
|
||||
bool mInAnimationOnlyStyleUpdate;
|
||||
|
||||
mozilla::DelayedEventDispatcher<mozilla::TransitionEventInfo>
|
||||
|
||||
@@ -264,6 +264,8 @@ skip-if = (android_version == '18' && debug) # bug 1159532
|
||||
[test_transitions_per_property.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 775227 # b2g(times out, needs more time + various failures) b2g-debug(times out, needs more time + various failures) b2g-desktop(times out, needs more time + various failures)
|
||||
[test_transitions_step_functions.html]
|
||||
[test_transitions_with_displaynone.html]
|
||||
[test_transitions_with_disabled_properties.html]
|
||||
[test_unclosed_parentheses.html]
|
||||
[test_unicode_range_loading.html]
|
||||
support-files = ../../reftests/fonts/markA.woff ../../reftests/fonts/markB.woff ../../reftests/fonts/markC.woff ../../reftests/fonts/markD.woff
|
||||
@@ -298,6 +300,5 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262,
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support)
|
||||
[test_visited_reftests.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support)
|
||||
[test_webkit_box_orient.html]
|
||||
[test_webkit_device_pixel_ratio.html]
|
||||
[test_asyncopen2.html]
|
||||
|
||||
@@ -665,7 +665,7 @@ if (IsCSSPropertyPrefEnabled("layout.css.prefixes.webkit")) {
|
||||
"-webkit-gradient(linear, 1 2, 3 4, color-stop(0, rgb(1,2,3)))",
|
||||
"-webkit-gradient(linear, 1 2, 3 4, color-stop(0, #00ff00))",
|
||||
"-webkit-gradient(linear, 1 2, 3 4, color-stop(0, #00f))",
|
||||
"-webkit-gradient(linear, 1 2, 3 4, color-stop(0, hsla(240, 30%, 50%, 0.9)))",
|
||||
"-webkit-gradient(linear, 1 2, 3 4, color-stop(0, hsla(240, 30%, 50%, 0.8)))",
|
||||
"-webkit-gradient(linear, 1 2, 3 4, color-stop(0, rgba(255, 230, 10, 0.5)))",
|
||||
|
||||
// linear w/ multiple color stops:
|
||||
@@ -4331,7 +4331,7 @@ var gCSSProperties = {
|
||||
initial_values: [ "auto", "normal" ],
|
||||
other_values: [ "start", "end", "flex-start", "flex-end", "self-start",
|
||||
"self-end", "center", "left", "right", "baseline",
|
||||
"last-baseline", "stretch", "left true", "true right",
|
||||
"last-baseline", "stretch", "left unsafe", "unsafe right",
|
||||
"safe right", "center safe" ],
|
||||
invalid_values: [ "space-between", "abc", "30px", "none",
|
||||
"legacy left", "right legacy" ]
|
||||
@@ -4875,25 +4875,6 @@ function logical_box_prop_get_computed(cs, property)
|
||||
return cs.getPropertyValue(property);
|
||||
}
|
||||
|
||||
// Helper to get computed style of "-webkit-box-orient" from "flex-direction"
|
||||
// and the "writing-mode".
|
||||
function webkit_orient_get_computed(cs, property)
|
||||
{
|
||||
var writingMode = cs.getPropertyValue("writing-mode") || "horizontal-tb";
|
||||
|
||||
var mapping; // map from flex-direction values to -webkit-box-orient values.
|
||||
if (writingMode == "horizontal-tb") {
|
||||
// Horizontal writing-mode
|
||||
mapping = { "row" : "horizontal", "column" : "vertical"};
|
||||
} else {
|
||||
// Vertical writing-mode
|
||||
mapping = { "row" : "vertical", "column" : "horizontal"};
|
||||
}
|
||||
|
||||
var flexDirection = cs.getPropertyValue("flex-direction");
|
||||
return mapping[flexDirection];
|
||||
}
|
||||
|
||||
// Get the computed value for a property. For shorthands, return the
|
||||
// computed values of all the subproperties, delimited by " ; ".
|
||||
function get_computed_value(cs, property)
|
||||
@@ -6590,17 +6571,6 @@ if (IsCSSPropertyPrefEnabled("layout.css.background-blend-mode.enabled")) {
|
||||
};
|
||||
}
|
||||
|
||||
if (SpecialPowers.getBoolPref("layout.css.will-change.enabled")) {
|
||||
gCSSProperties["will-change"] = {
|
||||
domProp: "willChange",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "auto" ],
|
||||
other_values: [ "scroll-position", "contents", "transform", "opacity", "scroll-position, transform", "transform, opacity", "contents, transform", "property-that-doesnt-exist-yet" ],
|
||||
invalid_values: [ "none", "all", "default", "auto, scroll-position", "scroll-position, auto", "transform scroll-position", ",", "trailing,", "will-change", "transform, will-change" ]
|
||||
};
|
||||
}
|
||||
|
||||
if (IsCSSPropertyPrefEnabled("layout.css.object-fit-and-position.enabled")) {
|
||||
gCSSProperties["object-fit"] = {
|
||||
domProp: "objectFit",
|
||||
@@ -7216,13 +7186,6 @@ if (IsCSSPropertyPrefEnabled("layout.css.prefixes.webkit")) {
|
||||
alias_for: "border-bottom-right-radius",
|
||||
subproperties: [ "border-bottom-right-radius" ],
|
||||
};
|
||||
gCSSProperties["-webkit-appearance"] = {
|
||||
domProp: "webkitAppearance",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "-moz-appearance",
|
||||
subproperties: [ "-moz-appearance" ],
|
||||
};
|
||||
gCSSProperties["-webkit-background-clip"] = {
|
||||
domProp: "webkitBackgroundClip",
|
||||
inherited: false,
|
||||
@@ -7269,44 +7232,43 @@ if (IsCSSPropertyPrefEnabled("layout.css.prefixes.webkit")) {
|
||||
domProp: "webkitBoxFlex",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "flex-grow",
|
||||
subproperties: [ "flex-grow" ],
|
||||
alias_for: "-moz-box-flex",
|
||||
subproperties: [ "-moz-box-flex" ],
|
||||
};
|
||||
gCSSProperties["-webkit-box-ordinal-group"] = {
|
||||
domProp: "webkitBoxOrdinalGroup",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "order",
|
||||
subproperties: [ "order" ],
|
||||
alias_for: "-moz-box-ordinal-group",
|
||||
subproperties: [ "-moz-box-ordinal-group" ],
|
||||
};
|
||||
/* This one is not an alias - it's implemented as a logical property: */
|
||||
gCSSProperties["-webkit-box-orient"] = {
|
||||
domProp: "webkitBoxOrient",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
logical: true,
|
||||
get_computed: webkit_orient_get_computed,
|
||||
initial_values: [ "horizontal" ],
|
||||
other_values: [ "vertical" ],
|
||||
invalid_values: [
|
||||
"0", "0px", "auto",
|
||||
/* Flex-direction values: */
|
||||
"row", "column", "row-reverse", "column-reverse",
|
||||
],
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "-moz-box-orient",
|
||||
subproperties: [ "-moz-box-orient" ],
|
||||
};
|
||||
gCSSProperties["-webkit-box-direction"] = {
|
||||
domProp: "webkitBoxDirection",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "-moz-box-direction",
|
||||
subproperties: [ "-moz-box-direction" ],
|
||||
};
|
||||
gCSSProperties["-webkit-box-align"] = {
|
||||
domProp: "webkitBoxAlign",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "align-items",
|
||||
subproperties: [ "align-items" ],
|
||||
alias_for: "-moz-box-align",
|
||||
subproperties: [ "-moz-box-align" ],
|
||||
};
|
||||
gCSSProperties["-webkit-box-pack"] = {
|
||||
domProp: "webkitBoxPack",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
|
||||
alias_for: "justify-content",
|
||||
subproperties: [ "justify-content" ],
|
||||
alias_for: "-moz-box-pack",
|
||||
subproperties: [ "-moz-box-pack" ],
|
||||
};
|
||||
gCSSProperties["-webkit-user-select"] = {
|
||||
domProp: "webkitUserSelect",
|
||||
|
||||
@@ -738,18 +738,15 @@ add_future_call(8, check_number_tests);
|
||||
|
||||
function check_display_tests(time)
|
||||
{
|
||||
var tf = timingFunctions["ease-in-out"];
|
||||
for (var i in display_tests) {
|
||||
var p = display_tests[i];
|
||||
|
||||
check_transition_value(tf, 0, 8, 0, 100,
|
||||
getComputedStyle(p, "").textIndent,
|
||||
"display test for test with " +
|
||||
p.childNodes[0].data,
|
||||
// TODO: Making transitions work on 'display:none' elements is
|
||||
// still not implemented.
|
||||
function(range) { return p != to_none_test &&
|
||||
range[1] < 100 });
|
||||
// There is no transition if the old or new style is display:none, so
|
||||
// the computed value is always the end value.
|
||||
var computedValue = getComputedStyle(p, "").textIndent;
|
||||
is(computedValue, "100px",
|
||||
"display test for test with " + p.childNodes[0].data +
|
||||
": computed value " + computedValue + " should be 100px.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1265611
|
||||
-->
|
||||
<head>
|
||||
<meta charset=utf-8>
|
||||
<title>Test for bug 1265611</title>
|
||||
<script type="application/javascript"
|
||||
src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
#display {
|
||||
transition: all 0.01s;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1265611">Mozilla Bug
|
||||
1265611</a>
|
||||
|
||||
<div id="display"></div>
|
||||
<pre id="test">
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/*
|
||||
* This tests for transitions generated on the -webkit-text-fill-color property.
|
||||
* This property has an initial value of 'currentcolor' so by triggering a
|
||||
* transition on the 'color' property we also--at least at the point when
|
||||
* this test was written--trigger a transition on the -webkit-text-fill-color
|
||||
* property (that behavior may change in bug 1260543).
|
||||
*
|
||||
* However, before beginning the test we disable -webkit-text-fill-color by
|
||||
* setting layout.css.prefixes.webkit to false. This code tests that we don't
|
||||
* end up triggering a transition on the (disabled) property in that case.
|
||||
*/
|
||||
SpecialPowers.pushPrefEnv({'set': [['layout.css.prefixes.webkit', false],
|
||||
['dom.animations-api.core.enabled', true]] },
|
||||
() => {
|
||||
var display = document.getElementById('display');
|
||||
display.style.color = 'green';
|
||||
|
||||
var transitionedProperties =
|
||||
display.getAnimations().map(transition => transition.transitionProperty);
|
||||
|
||||
ok(!transitionedProperties.includes('-webkit-text-fill-color'),
|
||||
'We should not fire transitions for properties disabled by prefs');
|
||||
SimpleTest.finish();
|
||||
}
|
||||
);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,71 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1182856
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1182856</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="animation_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
#display {
|
||||
background: blue;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1182856">Mozilla Bug 1182856</a>
|
||||
|
||||
<div id="display"></div>
|
||||
<pre id="test"></pre>
|
||||
|
||||
<script type="application/javascript">
|
||||
'use strict';
|
||||
|
||||
function TestDisplayNoneTurnOffTransitions(elem, cs, elemToDisplayNone, name) {
|
||||
var ended = false;
|
||||
var markEnded = function () {
|
||||
ended = true;
|
||||
};
|
||||
elem.addEventListener('transitionend', markEnded, false);
|
||||
|
||||
cs.marginLeft; // flush
|
||||
elem.style.marginLeft = "100px"; // start transition
|
||||
is(cs.marginLeft, "0px", name + ": margin-left at 0s");
|
||||
|
||||
advance_clock(1000);
|
||||
is(cs.marginLeft, "10px", name + ": margin-left at 1s");
|
||||
|
||||
elemToDisplayNone.style.display = "none";
|
||||
is(cs.marginLeft, "100px", name + ": margin-left after display:none");
|
||||
|
||||
advance_clock(10000);
|
||||
ok(!ended, name + ": Should not get transitionend");
|
||||
}
|
||||
|
||||
advance_clock(0);
|
||||
|
||||
// Set display:none on the target.
|
||||
var [div, cs] = new_div("margin-left: 0px; transition: margin-left 10s linear");
|
||||
TestDisplayNoneTurnOffTransitions(div, cs, div, "Set display:none on target");
|
||||
done_div();
|
||||
|
||||
// Set display:none on the ancestor of the target.
|
||||
var [div, cs] = new_div("margin-left: 0px; transition: margin-left 10s linear");
|
||||
var ancestor = document.createElement("div");
|
||||
div.parentNode.insertBefore(ancestor, div);
|
||||
ancestor.appendChild(div);
|
||||
TestDisplayNoneTurnOffTransitions(div, cs, ancestor,
|
||||
"Set display:none on ancestor");
|
||||
ancestor.parentNode.insertBefore(div, ancestor);
|
||||
ancestor.remove();
|
||||
done_div();
|
||||
|
||||
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user