2016-02-24 10:01:10 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "mozilla/ServoStyleSet.h"
|
2018-03-29 14:15:46 +03:00
|
|
|
#include "mozilla/ServoStyleSetInlines.h"
|
2016-02-24 10:01:10 +03:00
|
|
|
|
2017-04-08 01:49:44 +03:00
|
|
|
#include "gfxPlatformFontList.h"
|
2017-06-28 22:03:18 +03:00
|
|
|
#include "mozilla/AutoRestyleTimelineMarker.h"
|
2016-12-01 11:19:50 +03:00
|
|
|
#include "mozilla/DocumentStyleRootIterator.h"
|
2018-11-13 01:20:52 +03:00
|
|
|
#include "mozilla/EffectCompositor.h"
|
2018-02-25 20:01:42 +03:00
|
|
|
#include "mozilla/IntegerRange.h"
|
2017-08-03 23:16:31 +03:00
|
|
|
#include "mozilla/LookAndFeel.h"
|
2019-03-29 18:12:47 +03:00
|
|
|
#include "mozilla/PresShell.h"
|
2017-06-14 02:38:16 +03:00
|
|
|
#include "mozilla/ServoBindings.h"
|
2018-04-05 22:12:37 +03:00
|
|
|
#include "mozilla/RestyleManager.h"
|
2017-06-19 08:45:43 +03:00
|
|
|
#include "mozilla/ServoStyleRuleMap.h"
|
Bug 1400078 - Measure the UA cache. r=njn.
ServoStyleSetSizes now has two uses, one for the Stylist, and one for the UA
cache, and so the patch removes 'Stylist' from the field names.
Example output from about:memory:
> +----1,359,608 B (00.55%) -- layout
> | +----756,488 B (00.31%) -- style-sheet-cache [2]
> | +----393,968 B (00.16%) -- servo-ua-cache
> | | +--234,496 B (00.10%) -- element-and-pseudos-maps
> | | +---59,648 B (00.02%) -- revalidation-selectors
> | | +---58,320 B (00.02%) -- invalidation-map
> | | +---30,752 B (00.01%) -- other
> | | +---10,752 B (00.00%) -- precomputed-pseudos
MozReview-Commit-ID: 8oxuJO0ojp
--HG--
extra : rebase_source : 7d86216967259b71df7280261d025cc65bf00ba4
2017-09-19 02:25:00 +03:00
|
|
|
#include "mozilla/ServoTypes.h"
|
2018-12-28 14:47:58 +03:00
|
|
|
#include "mozilla/SMILAnimationController.h"
|
2018-03-16 00:35:56 +03:00
|
|
|
#include "mozilla/StyleAnimationValue.h"
|
2017-06-19 08:45:43 +03:00
|
|
|
#include "mozilla/css/Loader.h"
|
2017-03-18 09:15:09 +03:00
|
|
|
#include "mozilla/dom/AnonymousContent.h"
|
2016-08-12 00:12:49 +03:00
|
|
|
#include "mozilla/dom/ChildIterator.h"
|
2017-07-08 13:00:24 +03:00
|
|
|
#include "mozilla/dom/FontFaceSet.h"
|
2017-01-01 03:10:45 +03:00
|
|
|
#include "mozilla/dom/Element.h"
|
|
|
|
#include "mozilla/dom/ElementInlines.h"
|
2016-02-24 10:01:10 +03:00
|
|
|
#include "nsCSSAnonBoxes.h"
|
2017-06-18 12:57:55 +03:00
|
|
|
#include "nsCSSFrameConstructor.h"
|
2016-03-18 23:14:07 +03:00
|
|
|
#include "nsCSSPseudoElements.h"
|
2017-04-08 01:49:44 +03:00
|
|
|
#include "nsDeviceContext.h"
|
2017-01-20 02:56:53 +03:00
|
|
|
#include "nsHTMLStyleSheet.h"
|
2017-06-18 12:57:55 +03:00
|
|
|
#include "nsIAnonymousContentCreator.h"
|
2019-01-02 16:05:23 +03:00
|
|
|
#include "mozilla/dom/DocumentInlines.h"
|
2017-11-17 10:35:26 +03:00
|
|
|
#include "nsMediaFeatures.h"
|
2016-07-28 06:03:49 +03:00
|
|
|
#include "nsPrintfCString.h"
|
2017-05-26 17:29:10 +03:00
|
|
|
#include "gfxUserFontSet.h"
|
2018-02-01 07:04:04 +03:00
|
|
|
#include "nsBindingManager.h"
|
2018-03-28 02:44:49 +03:00
|
|
|
#include "nsWindowSizes.h"
|
2018-05-23 12:35:03 +03:00
|
|
|
#include "GeckoProfiler.h"
|
2016-02-24 10:01:10 +03:00
|
|
|
|
|
|
|
using namespace mozilla;
|
|
|
|
using namespace mozilla::dom;
|
|
|
|
|
2017-09-19 04:26:29 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
bool ServoStyleSet::IsCurrentThreadInServoTraversal() {
|
|
|
|
return sInServoTraversal && (NS_IsMainThread() || Servo_IsWorkerThread());
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-08-10 20:58:40 +03:00
|
|
|
namespace mozilla {
|
2019-04-19 07:32:12 +03:00
|
|
|
|
|
|
|
constexpr const StyleOrigin ServoStyleSet::kOrigins[];
|
|
|
|
|
2018-01-30 23:05:43 +03:00
|
|
|
ServoStyleSet* sInServoTraversal = nullptr;
|
|
|
|
|
2017-08-10 20:58:40 +03:00
|
|
|
// On construction, sets sInServoTraversal to the given ServoStyleSet.
|
|
|
|
// On destruction, clears sInServoTraversal and calls RunPostTraversalTasks.
|
|
|
|
class MOZ_RAII AutoSetInServoTraversal {
|
|
|
|
public:
|
|
|
|
explicit AutoSetInServoTraversal(ServoStyleSet* aSet) : mSet(aSet) {
|
2018-01-30 23:05:43 +03:00
|
|
|
MOZ_ASSERT(!sInServoTraversal);
|
2017-08-10 20:58:40 +03:00
|
|
|
MOZ_ASSERT(aSet);
|
2018-01-30 23:05:43 +03:00
|
|
|
sInServoTraversal = aSet;
|
2017-08-10 20:58:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
~AutoSetInServoTraversal() {
|
2018-01-30 23:05:43 +03:00
|
|
|
MOZ_ASSERT(sInServoTraversal);
|
|
|
|
sInServoTraversal = nullptr;
|
2017-08-10 20:58:40 +03:00
|
|
|
mSet->RunPostTraversalTasks();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
ServoStyleSet* mSet;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Sets up for one or more calls to Servo_TraverseSubtree.
|
|
|
|
class MOZ_RAII AutoPrepareTraversal {
|
|
|
|
public:
|
|
|
|
explicit AutoPrepareTraversal(ServoStyleSet* aSet)
|
|
|
|
// For markers for animations, we have already set the markers in
|
2018-04-05 22:12:37 +03:00
|
|
|
// RestyleManager::PostRestyleEventForAnimations so that we don't need
|
2017-08-10 20:58:40 +03:00
|
|
|
// to care about animation restyles here.
|
2018-01-05 15:51:08 +03:00
|
|
|
: mTimelineMarker(aSet->mDocument->GetDocShell(), false),
|
2017-08-10 20:58:40 +03:00
|
|
|
mSetInServoTraversal(aSet) {
|
|
|
|
MOZ_ASSERT(!aSet->StylistNeedsUpdate());
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
AutoRestyleTimelineMarker mTimelineMarker;
|
|
|
|
AutoSetInServoTraversal mSetInServoTraversal;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace mozilla
|
|
|
|
|
2019-04-19 07:20:31 +03:00
|
|
|
ServoStyleSet::ServoStyleSet(Document& aDocument) : mDocument(&aDocument) {
|
2019-04-03 10:02:00 +03:00
|
|
|
PreferenceSheet::EnsureInitialized();
|
|
|
|
mRawSet.reset(Servo_StyleSet_Init(&aDocument));
|
|
|
|
}
|
2016-02-24 10:01:12 +03:00
|
|
|
|
2017-03-08 08:18:39 +03:00
|
|
|
ServoStyleSet::~ServoStyleSet() {
|
2019-04-27 18:37:58 +03:00
|
|
|
MOZ_ASSERT(!IsInServoTraversal());
|
2019-04-19 07:20:31 +03:00
|
|
|
EnumerateStyleSheets([&](StyleSheet& aSheet) { aSheet.DropStyleSet(this); });
|
2017-03-08 08:18:39 +03:00
|
|
|
}
|
|
|
|
|
2018-01-05 15:51:08 +03:00
|
|
|
nsPresContext* ServoStyleSet::GetPresContext() {
|
2018-02-21 01:00:10 +03:00
|
|
|
return mDocument->GetPresContext();
|
2018-01-05 15:51:08 +03:00
|
|
|
}
|
|
|
|
|
2018-02-25 20:01:42 +03:00
|
|
|
template <typename Functor>
|
2019-01-02 16:05:23 +03:00
|
|
|
void EnumerateShadowRoots(const Document& aDoc, const Functor& aCb) {
|
|
|
|
const Document::ShadowRootSet& shadowRoots = aDoc.ComposedShadowRoots();
|
2018-03-29 19:49:10 +03:00
|
|
|
for (auto iter = shadowRoots.ConstIter(); !iter.Done(); iter.Next()) {
|
|
|
|
ShadowRoot* root = iter.Get()->GetKey();
|
|
|
|
MOZ_ASSERT(root);
|
2018-08-20 14:56:27 +03:00
|
|
|
MOZ_DIAGNOSTIC_ASSERT(root->IsInComposedDoc());
|
2018-03-29 19:49:10 +03:00
|
|
|
aCb(*root);
|
|
|
|
}
|
2018-02-25 20:01:42 +03:00
|
|
|
}
|
|
|
|
|
2019-04-03 10:02:00 +03:00
|
|
|
void ServoStyleSet::ShellDetachedFromDocument() {
|
2018-03-22 21:20:41 +03:00
|
|
|
ClearNonInheritingComputedStyles();
|
2017-11-28 03:50:45 +03:00
|
|
|
mStyleRuleMap = nullptr;
|
2019-04-19 07:32:12 +03:00
|
|
|
|
|
|
|
// Remove all our stylesheets...
|
|
|
|
for (const Origin origin : kOrigins) {
|
|
|
|
for (size_t count = SheetCount(origin); count--;) {
|
|
|
|
RemoveStyleSheet(origin, SheetAt(origin, count));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// And remove all the CascadeDatas from memory.
|
2019-04-22 22:45:06 +03:00
|
|
|
UpdateStylistIfNeeded();
|
2019-04-19 07:32:12 +03:00
|
|
|
|
|
|
|
// Also GC the ruletree if it got big now that the DOM no longer has
|
|
|
|
// references to styles around anymore.
|
|
|
|
MaybeGCRuleTree();
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2018-02-18 16:35:57 +03:00
|
|
|
void ServoStyleSet::RecordShadowStyleChange(ShadowRoot& aShadowRoot) {
|
|
|
|
// TODO(emilio): We could keep track of the actual shadow roots that need
|
|
|
|
// their styles recomputed.
|
2019-04-23 19:43:15 +03:00
|
|
|
SetStylistShadowDOMStyleSheetsDirty();
|
2018-02-18 16:35:57 +03:00
|
|
|
|
|
|
|
// FIXME(emilio): This should be done using stylesheet invalidation instead.
|
|
|
|
if (nsPresContext* pc = GetPresContext()) {
|
2019-03-14 14:47:50 +03:00
|
|
|
pc->RestyleManager()->PostRestyleEvent(
|
|
|
|
aShadowRoot.Host(), RestyleHint::RestyleSubtree(), nsChangeHint(0));
|
2018-02-18 16:35:57 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-16 17:14:39 +03:00
|
|
|
void ServoStyleSet::InvalidateStyleForDocumentStateChanges(
|
|
|
|
EventStates aStatesChanged) {
|
|
|
|
MOZ_ASSERT(mDocument);
|
|
|
|
MOZ_ASSERT(!aStatesChanged.IsEmpty());
|
|
|
|
|
|
|
|
nsPresContext* pc = GetPresContext();
|
|
|
|
if (!pc) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Element* root = mDocument->GetRootElement();
|
|
|
|
if (!root) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO(emilio): It may be nicer to just invalidate stuff in a given subtree
|
2019-04-23 19:43:15 +03:00
|
|
|
// for Shadow DOM. Consider just enumerating shadow roots instead and run
|
|
|
|
// invalidation individually, passing mRawSet for the UA / User sheets.
|
2019-03-21 20:00:27 +03:00
|
|
|
AutoTArray<const RawServoAuthorStyles*, 20> nonDocumentStyles;
|
2018-02-25 20:01:42 +03:00
|
|
|
|
|
|
|
EnumerateShadowRoots(*mDocument, [&](ShadowRoot& aShadowRoot) {
|
2018-08-30 15:00:00 +03:00
|
|
|
if (auto* authorStyles = aShadowRoot.GetServoStyles()) {
|
|
|
|
nonDocumentStyles.AppendElement(authorStyles);
|
|
|
|
}
|
2018-02-25 20:01:42 +03:00
|
|
|
});
|
|
|
|
|
2018-01-16 17:14:39 +03:00
|
|
|
Servo_InvalidateStyleForDocStateChanges(
|
2018-02-25 20:01:42 +03:00
|
|
|
root, mRawSet.get(), &nonDocumentStyles, aStatesChanged.ServoValue());
|
2018-01-16 17:14:39 +03:00
|
|
|
}
|
|
|
|
|
2018-02-06 17:17:10 +03:00
|
|
|
static const MediaFeatureChangeReason kMediaFeaturesAffectingDefaultStyle =
|
|
|
|
// Zoom changes change the meaning of em units.
|
|
|
|
MediaFeatureChangeReason::ZoomChange |
|
|
|
|
// A resolution change changes the app-units-per-dev-pixels ratio, which
|
|
|
|
// some structs (Border, Outline, Column) store for clamping. We should
|
|
|
|
// arguably not do that, maybe doing it on layout directly, to try to avoid
|
|
|
|
// relying on the pres context (bug 1418159).
|
|
|
|
MediaFeatureChangeReason::ResolutionChange;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2019-03-14 14:47:50 +03:00
|
|
|
RestyleHint ServoStyleSet::MediumFeaturesChanged(
|
2018-02-06 18:52:22 +03:00
|
|
|
MediaFeatureChangeReason aReason) {
|
2019-03-21 20:00:27 +03:00
|
|
|
AutoTArray<RawServoAuthorStyles*, 20> nonDocumentStyles;
|
2018-02-25 20:01:42 +03:00
|
|
|
|
|
|
|
EnumerateShadowRoots(*mDocument, [&](ShadowRoot& aShadowRoot) {
|
2018-08-30 15:00:00 +03:00
|
|
|
if (auto* authorStyles = aShadowRoot.GetServoStyles()) {
|
|
|
|
nonDocumentStyles.AppendElement(authorStyles);
|
|
|
|
}
|
2018-02-25 20:01:42 +03:00
|
|
|
});
|
|
|
|
|
2018-02-06 17:17:10 +03:00
|
|
|
bool mayAffectDefaultStyle =
|
|
|
|
bool(aReason & kMediaFeaturesAffectingDefaultStyle);
|
|
|
|
|
2018-02-06 18:52:22 +03:00
|
|
|
const MediumFeaturesChangedResult result =
|
2018-02-06 17:17:10 +03:00
|
|
|
Servo_StyleSet_MediumFeaturesChanged(mRawSet.get(), &nonDocumentStyles,
|
2018-02-12 15:57:26 +03:00
|
|
|
mayAffectDefaultStyle);
|
2018-02-06 18:52:22 +03:00
|
|
|
|
|
|
|
const bool rulesChanged =
|
|
|
|
result.mAffectsDocumentRules || result.mAffectsNonDocumentRules;
|
2017-09-02 10:25:45 +03:00
|
|
|
|
2018-02-06 18:52:22 +03:00
|
|
|
if (result.mAffectsDocumentRules) {
|
|
|
|
SetStylistStyleSheetsDirty();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result.mAffectsNonDocumentRules) {
|
2019-04-23 19:43:15 +03:00
|
|
|
SetStylistShadowDOMStyleSheetsDirty();
|
2018-02-06 18:52:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (rulesChanged) {
|
2019-04-04 02:52:19 +03:00
|
|
|
// TODO(emilio): This could be more granular.
|
2019-03-14 14:47:50 +03:00
|
|
|
return RestyleHint::RestyleSubtree();
|
2017-09-02 10:25:45 +03:00
|
|
|
}
|
|
|
|
|
2018-02-06 18:52:22 +03:00
|
|
|
const bool viewportChanged =
|
|
|
|
bool(aReason & MediaFeatureChangeReason::ViewportChange);
|
|
|
|
if (result.mUsesViewportUnits && viewportChanged) {
|
2019-03-14 14:47:50 +03:00
|
|
|
return RestyleHint::RecascadeSubtree();
|
2018-02-06 18:52:22 +03:00
|
|
|
}
|
|
|
|
|
2019-03-14 14:47:50 +03:00
|
|
|
return RestyleHint{0};
|
2017-09-02 10:25:45 +03:00
|
|
|
}
|
|
|
|
|
2017-08-30 11:21:26 +03:00
|
|
|
MOZ_DEFINE_MALLOC_SIZE_OF(ServoStyleSetMallocSizeOf)
|
Bug 1387958 - Measure the stylist during memory reporting. r=heycam.
Example output from the Obama Wikipedia page:
> ├──2,315,600 B (01.16%) -- stylist
> │ ├──1,916,928 B (00.96%) ── invalidation-map
> │ ├────228,800 B (00.11%) ── rule-tree
> │ ├────142,336 B (00.07%) ── element-and-pseudos-maps
> │ ├─────14,336 B (00.01%) ── revalidation-selectors
> │ ├──────9,648 B (00.00%) ── other
> │ └──────3,552 B (00.00%) ── precomputed-pseudos
This change requires new code to measure HashMaps, which uses the new
'malloc_enclosing_size_of' functions that can measure a heap block from an
interior pointer.
The patch changes MallocSizeOfFn to a newtype, and introduces
MallocEnclosingSizeOfFn alongside.
It also adds new traits: MallocSizeOfBox, MallocSizeOfVec, MallocSizeOfHash.
These each contain a single method that does shallow measurement of the
relevant type, which is often useful. (This is a different style to the
existing MallocSizeOf trait, which does deep measurement, but I'm moving away
from the always-deep-measurement style because it's less flexible.)
MozReview-Commit-ID: FgJCCmdw0ZF
--HG--
extra : rebase_source : c692c2073aa66020224489b97247c49de95a99a4
2017-09-05 04:38:45 +03:00
|
|
|
MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoStyleSetMallocEnclosingSizeOf)
|
2017-08-30 11:21:26 +03:00
|
|
|
|
|
|
|
void ServoStyleSet::AddSizeOfIncludingThis(nsWindowSizes& aSizes) const {
|
|
|
|
MallocSizeOf mallocSizeOf = aSizes.mState.mMallocSizeOf;
|
|
|
|
|
2018-03-28 02:44:49 +03:00
|
|
|
aSizes.mLayoutStyleSetsOther += mallocSizeOf(this);
|
2017-08-30 11:21:26 +03:00
|
|
|
|
|
|
|
if (mRawSet) {
|
2018-03-28 02:44:49 +03:00
|
|
|
aSizes.mLayoutStyleSetsOther += mallocSizeOf(mRawSet.get());
|
2017-08-30 11:21:26 +03:00
|
|
|
ServoStyleSetSizes sizes;
|
|
|
|
// Measure mRawSet. We use ServoStyleSetMallocSizeOf rather than
|
|
|
|
// aMallocSizeOf to distinguish in DMD's output the memory measured within
|
|
|
|
// Servo code.
|
Bug 1387958 - Measure the stylist during memory reporting. r=heycam.
Example output from the Obama Wikipedia page:
> ├──2,315,600 B (01.16%) -- stylist
> │ ├──1,916,928 B (00.96%) ── invalidation-map
> │ ├────228,800 B (00.11%) ── rule-tree
> │ ├────142,336 B (00.07%) ── element-and-pseudos-maps
> │ ├─────14,336 B (00.01%) ── revalidation-selectors
> │ ├──────9,648 B (00.00%) ── other
> │ └──────3,552 B (00.00%) ── precomputed-pseudos
This change requires new code to measure HashMaps, which uses the new
'malloc_enclosing_size_of' functions that can measure a heap block from an
interior pointer.
The patch changes MallocSizeOfFn to a newtype, and introduces
MallocEnclosingSizeOfFn alongside.
It also adds new traits: MallocSizeOfBox, MallocSizeOfVec, MallocSizeOfHash.
These each contain a single method that does shallow measurement of the
relevant type, which is often useful. (This is a different style to the
existing MallocSizeOf trait, which does deep measurement, but I'm moving away
from the always-deep-measurement style because it's less flexible.)
MozReview-Commit-ID: FgJCCmdw0ZF
--HG--
extra : rebase_source : c692c2073aa66020224489b97247c49de95a99a4
2017-09-05 04:38:45 +03:00
|
|
|
Servo_StyleSet_AddSizeOfExcludingThis(ServoStyleSetMallocSizeOf,
|
|
|
|
ServoStyleSetMallocEnclosingSizeOf,
|
|
|
|
&sizes, mRawSet.get());
|
Bug 1400078 - Measure the UA cache. r=njn.
ServoStyleSetSizes now has two uses, one for the Stylist, and one for the UA
cache, and so the patch removes 'Stylist' from the field names.
Example output from about:memory:
> +----1,359,608 B (00.55%) -- layout
> | +----756,488 B (00.31%) -- style-sheet-cache [2]
> | +----393,968 B (00.16%) -- servo-ua-cache
> | | +--234,496 B (00.10%) -- element-and-pseudos-maps
> | | +---59,648 B (00.02%) -- revalidation-selectors
> | | +---58,320 B (00.02%) -- invalidation-map
> | | +---30,752 B (00.01%) -- other
> | | +---10,752 B (00.00%) -- precomputed-pseudos
MozReview-Commit-ID: 8oxuJO0ojp
--HG--
extra : rebase_source : 7d86216967259b71df7280261d025cc65bf00ba4
2017-09-19 02:25:00 +03:00
|
|
|
|
|
|
|
// The StyleSet does not contain precomputed pseudos; they are in the UA
|
|
|
|
// cache.
|
|
|
|
MOZ_RELEASE_ASSERT(sizes.mPrecomputedPseudos == 0);
|
|
|
|
|
2018-03-28 02:44:49 +03:00
|
|
|
aSizes.mLayoutStyleSetsStylistRuleTree += sizes.mRuleTree;
|
|
|
|
aSizes.mLayoutStyleSetsStylistElementAndPseudosMaps +=
|
Bug 1400078 - Measure the UA cache. r=njn.
ServoStyleSetSizes now has two uses, one for the Stylist, and one for the UA
cache, and so the patch removes 'Stylist' from the field names.
Example output from about:memory:
> +----1,359,608 B (00.55%) -- layout
> | +----756,488 B (00.31%) -- style-sheet-cache [2]
> | +----393,968 B (00.16%) -- servo-ua-cache
> | | +--234,496 B (00.10%) -- element-and-pseudos-maps
> | | +---59,648 B (00.02%) -- revalidation-selectors
> | | +---58,320 B (00.02%) -- invalidation-map
> | | +---30,752 B (00.01%) -- other
> | | +---10,752 B (00.00%) -- precomputed-pseudos
MozReview-Commit-ID: 8oxuJO0ojp
--HG--
extra : rebase_source : 7d86216967259b71df7280261d025cc65bf00ba4
2017-09-19 02:25:00 +03:00
|
|
|
sizes.mElementAndPseudosMaps;
|
2018-03-28 02:44:49 +03:00
|
|
|
aSizes.mLayoutStyleSetsStylistInvalidationMap += sizes.mInvalidationMap;
|
|
|
|
aSizes.mLayoutStyleSetsStylistRevalidationSelectors +=
|
Bug 1400078 - Measure the UA cache. r=njn.
ServoStyleSetSizes now has two uses, one for the Stylist, and one for the UA
cache, and so the patch removes 'Stylist' from the field names.
Example output from about:memory:
> +----1,359,608 B (00.55%) -- layout
> | +----756,488 B (00.31%) -- style-sheet-cache [2]
> | +----393,968 B (00.16%) -- servo-ua-cache
> | | +--234,496 B (00.10%) -- element-and-pseudos-maps
> | | +---59,648 B (00.02%) -- revalidation-selectors
> | | +---58,320 B (00.02%) -- invalidation-map
> | | +---30,752 B (00.01%) -- other
> | | +---10,752 B (00.00%) -- precomputed-pseudos
MozReview-Commit-ID: 8oxuJO0ojp
--HG--
extra : rebase_source : 7d86216967259b71df7280261d025cc65bf00ba4
2017-09-19 02:25:00 +03:00
|
|
|
sizes.mRevalidationSelectors;
|
2018-03-28 02:44:49 +03:00
|
|
|
aSizes.mLayoutStyleSetsStylistOther += sizes.mOther;
|
2017-08-30 11:21:26 +03:00
|
|
|
}
|
2017-04-06 05:22:36 +03:00
|
|
|
|
2017-06-19 08:45:43 +03:00
|
|
|
if (mStyleRuleMap) {
|
2018-03-28 02:44:49 +03:00
|
|
|
aSizes.mLayoutStyleSetsOther +=
|
2017-08-30 11:21:26 +03:00
|
|
|
mStyleRuleMap->SizeOfIncludingThis(aSizes.mState.mMallocSizeOf);
|
2017-06-19 08:45:43 +03:00
|
|
|
}
|
|
|
|
|
2017-04-06 05:22:36 +03:00
|
|
|
// Measurement of the following members may be added later if DMD finds it is
|
|
|
|
// worthwhile:
|
|
|
|
// - mSheets
|
2018-03-22 21:20:41 +03:00
|
|
|
// - mNonInheritingComputedStyles
|
2017-04-06 05:22:36 +03:00
|
|
|
//
|
|
|
|
// The following members are not measured:
|
2018-01-05 15:51:08 +03:00
|
|
|
// - mDocument, because it a non-owning pointer
|
2017-04-06 05:22:36 +03:00
|
|
|
}
|
|
|
|
|
2016-02-24 10:01:10 +03:00
|
|
|
void ServoStyleSet::SetAuthorStyleDisabled(bool aStyleDisabled) {
|
2017-04-11 10:43:14 +03:00
|
|
|
if (mAuthorStyleDisabled == aStyleDisabled) {
|
2018-02-08 15:05:28 +03:00
|
|
|
return;
|
2017-04-11 10:43:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mAuthorStyleDisabled = aStyleDisabled;
|
2018-02-08 15:05:28 +03:00
|
|
|
if (Element* root = mDocument->GetRootElement()) {
|
|
|
|
if (nsPresContext* pc = GetPresContext()) {
|
2019-03-14 14:47:50 +03:00
|
|
|
pc->RestyleManager()->PostRestyleEvent(
|
|
|
|
root, RestyleHint::RestyleSubtree(), nsChangeHint(0));
|
2018-02-08 15:05:28 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Servo_StyleSet_SetAuthorStyleDisabled(mRawSet.get(), mAuthorStyleDisabled);
|
2019-05-01 05:27:53 +03:00
|
|
|
// XXX Workaround for bug 1437785.
|
2018-02-13 10:33:00 +03:00
|
|
|
SetStylistStyleSheetsDirty();
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2017-05-07 17:36:47 +03:00
|
|
|
const ServoElementSnapshotTable& ServoStyleSet::Snapshots() {
|
2018-01-05 15:51:08 +03:00
|
|
|
MOZ_ASSERT(GetPresContext(), "Styling a document without a shell?");
|
2018-04-05 21:55:51 +03:00
|
|
|
return GetPresContext()->RestyleManager()->Snapshots();
|
2017-05-07 17:36:47 +03:00
|
|
|
}
|
|
|
|
|
2017-01-20 02:56:53 +03:00
|
|
|
void ServoStyleSet::ResolveMappedAttrDeclarationBlocks() {
|
2018-01-05 15:51:08 +03:00
|
|
|
if (nsHTMLStyleSheet* sheet = mDocument->GetAttributeStyleSheet()) {
|
2018-01-05 15:47:04 +03:00
|
|
|
sheet->CalculateMappedServoDeclarations();
|
2017-01-20 02:56:53 +03:00
|
|
|
}
|
2017-02-23 04:19:04 +03:00
|
|
|
|
2018-01-05 15:51:08 +03:00
|
|
|
mDocument->ResolveScheduledSVGPresAttrs();
|
2017-01-20 02:56:53 +03:00
|
|
|
}
|
|
|
|
|
2017-03-17 00:10:22 +03:00
|
|
|
void ServoStyleSet::PreTraverseSync() {
|
2017-07-28 08:18:13 +03:00
|
|
|
// Get the Document's root element to ensure that the cache is valid before
|
|
|
|
// calling into the (potentially-parallel) Servo traversal, where a cache hit
|
|
|
|
// is necessary to avoid a data race when updating the cache.
|
2018-01-05 15:51:08 +03:00
|
|
|
mozilla::Unused << mDocument->GetRootElement();
|
2017-07-28 08:18:13 +03:00
|
|
|
|
2019-01-27 18:30:38 +03:00
|
|
|
// FIXME(emilio): This shouldn't be needed in theory, the call to the same
|
|
|
|
// function in PresShell should do the work, but as it turns out we
|
|
|
|
// ProcessPendingRestyles() twice, and runnables from frames just constructed
|
|
|
|
// can end up doing editing stuff, which adds stylesheets etc...
|
|
|
|
mDocument->FlushUserFontSet();
|
|
|
|
|
2017-01-20 02:56:53 +03:00
|
|
|
ResolveMappedAttrDeclarationBlocks();
|
2017-02-02 22:48:28 +03:00
|
|
|
|
2017-11-17 10:35:26 +03:00
|
|
|
nsMediaFeatures::InitSystemMetrics();
|
2017-04-14 04:28:25 +03:00
|
|
|
|
2017-08-03 23:16:31 +03:00
|
|
|
LookAndFeel::NativeInit();
|
|
|
|
|
2019-01-18 16:43:06 +03:00
|
|
|
mDocument->CacheAllKnownLangPrefs();
|
|
|
|
|
2018-01-05 15:51:08 +03:00
|
|
|
if (gfxUserFontSet* userFontSet = mDocument->GetUserFontSet()) {
|
2019-01-18 16:43:06 +03:00
|
|
|
nsPresContext* presContext = GetPresContext();
|
|
|
|
MOZ_ASSERT(presContext,
|
|
|
|
"For now, we don't call into here without a pres context");
|
|
|
|
|
2017-07-07 08:35:28 +03:00
|
|
|
// Ensure that the @font-face data is not stale
|
2017-05-26 17:29:10 +03:00
|
|
|
uint64_t generation = userFontSet->GetGeneration();
|
|
|
|
if (generation != mUserFontSetUpdateGeneration) {
|
2018-03-23 18:06:56 +03:00
|
|
|
mDocument->GetFonts()->CacheFontLoadability();
|
2018-01-05 15:51:08 +03:00
|
|
|
presContext->DeviceContext()->UpdateFontCacheUserFonts(userFontSet);
|
2017-05-26 17:29:10 +03:00
|
|
|
mUserFontSetUpdateGeneration = generation;
|
|
|
|
}
|
|
|
|
}
|
2017-05-15 19:02:59 +03:00
|
|
|
|
2018-02-10 00:09:59 +03:00
|
|
|
MOZ_ASSERT(!StylistNeedsUpdate());
|
2017-03-17 00:10:22 +03:00
|
|
|
}
|
|
|
|
|
2017-08-11 22:54:35 +03:00
|
|
|
void ServoStyleSet::PreTraverse(ServoTraversalFlags aFlags, Element* aRoot) {
|
2017-03-17 00:10:22 +03:00
|
|
|
PreTraverseSync();
|
|
|
|
|
2017-03-08 23:20:17 +03:00
|
|
|
// Process animation stuff that we should avoid doing during the parallel
|
|
|
|
// traversal.
|
2018-12-28 14:47:58 +03:00
|
|
|
SMILAnimationController* smilController =
|
2018-01-05 15:51:08 +03:00
|
|
|
mDocument->HasAnimationController() ? mDocument->GetAnimationController()
|
2017-08-31 09:00:39 +03:00
|
|
|
: nullptr;
|
|
|
|
|
2018-01-05 15:51:08 +03:00
|
|
|
MOZ_ASSERT(GetPresContext());
|
2017-04-04 14:34:30 +03:00
|
|
|
if (aRoot) {
|
2018-01-05 15:51:08 +03:00
|
|
|
GetPresContext()->EffectCompositor()->PreTraverseInSubtree(aFlags, aRoot);
|
2017-04-26 07:00:11 +03:00
|
|
|
if (smilController) {
|
|
|
|
smilController->PreTraverseInSubtree(aRoot);
|
|
|
|
}
|
2017-04-04 14:34:30 +03:00
|
|
|
} else {
|
2018-01-05 15:51:08 +03:00
|
|
|
GetPresContext()->EffectCompositor()->PreTraverse(aFlags);
|
2017-04-26 07:00:11 +03:00
|
|
|
if (smilController) {
|
|
|
|
smilController->PreTraverse();
|
|
|
|
}
|
2017-04-04 14:34:30 +03:00
|
|
|
}
|
2017-03-08 23:20:17 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
static inline already_AddRefed<ComputedStyle>
|
2019-03-21 20:00:27 +03:00
|
|
|
ResolveStyleForTextOrFirstLetterContinuation(const RawServoStyleSet* aStyleSet,
|
2018-03-22 21:20:41 +03:00
|
|
|
ComputedStyle& aParent,
|
2019-02-19 16:44:33 +03:00
|
|
|
PseudoStyleType aType) {
|
|
|
|
MOZ_ASSERT(aType == PseudoStyleType::mozText ||
|
|
|
|
aType == PseudoStyleType::firstLetterContinuation);
|
|
|
|
auto inheritTarget = aType == PseudoStyleType::mozText
|
2017-08-05 00:34:18 +03:00
|
|
|
? InheritTarget::Text
|
|
|
|
: InheritTarget::FirstLetterContinuation;
|
|
|
|
|
2019-02-19 16:44:33 +03:00
|
|
|
RefPtr<ComputedStyle> style = aParent.GetCachedInheritingAnonBoxStyle(aType);
|
2017-08-05 00:34:18 +03:00
|
|
|
if (!style) {
|
2019-02-19 16:44:33 +03:00
|
|
|
style =
|
|
|
|
Servo_ComputedValues_Inherit(aStyleSet, aType, &aParent, inheritTarget)
|
|
|
|
.Consume();
|
2017-08-05 00:34:18 +03:00
|
|
|
MOZ_ASSERT(style);
|
2019-02-19 16:44:33 +03:00
|
|
|
aParent.SetCachedInheritedAnonBoxStyle(style);
|
2017-08-05 00:34:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return style.forget();
|
|
|
|
}
|
|
|
|
|
2016-04-29 07:01:44 +03:00
|
|
|
already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleForText(
|
2019-02-19 16:44:33 +03:00
|
|
|
nsIContent* aTextNode, ComputedStyle* aParentStyle) {
|
2018-04-13 01:41:00 +03:00
|
|
|
MOZ_ASSERT(aTextNode && aTextNode->IsText());
|
2016-08-12 21:30:29 +03:00
|
|
|
MOZ_ASSERT(aTextNode->GetParent());
|
2019-02-19 16:44:33 +03:00
|
|
|
MOZ_ASSERT(aParentStyle);
|
2016-10-26 02:27:08 +03:00
|
|
|
|
2017-08-05 00:34:18 +03:00
|
|
|
return ResolveStyleForTextOrFirstLetterContinuation(
|
2019-02-19 16:44:33 +03:00
|
|
|
mRawSet.get(), *aParentStyle, PseudoStyleType::mozText);
|
2016-04-29 07:01:44 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
already_AddRefed<ComputedStyle>
|
|
|
|
ServoStyleSet::ResolveStyleForFirstLetterContinuation(
|
2019-02-19 16:44:33 +03:00
|
|
|
ComputedStyle* aParentStyle) {
|
|
|
|
MOZ_ASSERT(aParentStyle);
|
2017-08-05 00:34:18 +03:00
|
|
|
|
|
|
|
return ResolveStyleForTextOrFirstLetterContinuation(
|
2019-02-19 16:44:33 +03:00
|
|
|
mRawSet.get(), *aParentStyle, PseudoStyleType::firstLetterContinuation);
|
2017-03-08 08:18:32 +03:00
|
|
|
}
|
|
|
|
|
2017-03-08 08:18:40 +03:00
|
|
|
already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleForPlaceholder() {
|
2018-03-22 21:20:41 +03:00
|
|
|
RefPtr<ComputedStyle>& cache = mNonInheritingComputedStyles
|
|
|
|
[nsCSSAnonBoxes::NonInheriting::oofPlaceholder];
|
2017-03-08 08:18:40 +03:00
|
|
|
if (cache) {
|
2018-03-22 21:20:41 +03:00
|
|
|
RefPtr<ComputedStyle> retval = cache;
|
2017-03-08 08:18:40 +03:00
|
|
|
return retval.forget();
|
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
RefPtr<ComputedStyle> computedValues =
|
2017-04-28 14:10:00 +03:00
|
|
|
Servo_ComputedValues_Inherit(mRawSet.get(),
|
2019-02-19 16:44:33 +03:00
|
|
|
PseudoStyleType::oofPlaceholder, nullptr,
|
2017-04-28 14:10:00 +03:00
|
|
|
InheritTarget::PlaceholderFrame)
|
|
|
|
.Consume();
|
2016-05-06 01:32:00 +03:00
|
|
|
MOZ_ASSERT(computedValues);
|
|
|
|
|
2017-07-17 21:42:24 +03:00
|
|
|
cache = computedValues;
|
|
|
|
return computedValues.forget();
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2019-02-19 16:44:33 +03:00
|
|
|
static inline bool LazyPseudoIsCacheable(PseudoStyleType aType,
|
2018-07-24 19:15:01 +03:00
|
|
|
const Element& aOriginatingElement,
|
2019-02-19 16:44:33 +03:00
|
|
|
ComputedStyle* aParentStyle) {
|
|
|
|
return aParentStyle &&
|
2017-09-20 07:43:31 +03:00
|
|
|
!nsCSSPseudoElements::IsEagerlyCascadedInServo(aType) &&
|
2018-07-24 19:15:01 +03:00
|
|
|
aOriginatingElement.HasServoData() &&
|
|
|
|
!Servo_Element_IsPrimaryStyleReusedViaRuleNode(&aOriginatingElement);
|
2017-09-20 07:43:31 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
already_AddRefed<ComputedStyle> ServoStyleSet::ResolvePseudoElementStyle(
|
2019-05-01 22:03:06 +03:00
|
|
|
Element* aOriginatingElement, PseudoStyleType aType,
|
|
|
|
ComputedStyle* aParentStyle, Element* aPseudoElement) {
|
2018-02-10 00:09:59 +03:00
|
|
|
// Runs from frame construction, this should have clean styles already, except
|
|
|
|
// with non-lazy FC...
|
2017-05-15 19:02:59 +03:00
|
|
|
UpdateStylistIfNeeded();
|
2019-02-19 16:44:33 +03:00
|
|
|
MOZ_ASSERT(PseudoStyle::IsPseudoElement(aType));
|
2016-04-29 03:56:37 +03:00
|
|
|
|
2019-05-01 22:03:06 +03:00
|
|
|
RefPtr<ComputedStyle> computedValues;
|
2017-07-17 21:42:00 +03:00
|
|
|
|
2019-05-01 22:03:06 +03:00
|
|
|
if (aPseudoElement) {
|
|
|
|
MOZ_ASSERT(aType == aPseudoElement->GetPseudoElementType());
|
|
|
|
computedValues =
|
|
|
|
Servo_ResolveStyle(aPseudoElement, mRawSet.get()).Consume();
|
|
|
|
} else {
|
|
|
|
bool cacheable =
|
|
|
|
LazyPseudoIsCacheable(aType, *aOriginatingElement, aParentStyle);
|
|
|
|
computedValues =
|
|
|
|
cacheable ? aParentStyle->GetCachedLazyPseudoStyle(aType) : nullptr;
|
|
|
|
|
|
|
|
if (!computedValues) {
|
|
|
|
computedValues = Servo_ResolvePseudoStyle(aOriginatingElement, aType,
|
|
|
|
/* is_probe = */ false,
|
|
|
|
aParentStyle, mRawSet.get())
|
|
|
|
.Consume();
|
|
|
|
if (cacheable) {
|
|
|
|
aParentStyle->SetCachedLazyPseudoStyle(computedValues);
|
|
|
|
}
|
2017-08-06 19:42:55 +03:00
|
|
|
}
|
2017-05-13 20:29:14 +03:00
|
|
|
}
|
|
|
|
|
2019-05-01 22:03:06 +03:00
|
|
|
MOZ_ASSERT(computedValues);
|
|
|
|
return computedValues.forget();
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
already_AddRefed<ComputedStyle>
|
2019-02-19 16:44:33 +03:00
|
|
|
ServoStyleSet::ResolveInheritingAnonymousBoxStyle(PseudoStyleType aType,
|
|
|
|
ComputedStyle* aParentStyle) {
|
|
|
|
MOZ_ASSERT(PseudoStyle::IsInheritingAnonBox(aType));
|
|
|
|
MOZ_ASSERT_IF(aParentStyle, !StylistNeedsUpdate());
|
2017-09-06 22:56:53 +03:00
|
|
|
|
|
|
|
UpdateStylistIfNeeded();
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
RefPtr<ComputedStyle> style = nullptr;
|
2017-08-05 00:34:18 +03:00
|
|
|
|
2019-02-19 16:44:33 +03:00
|
|
|
if (aParentStyle) {
|
|
|
|
style = aParentStyle->GetCachedInheritingAnonBoxStyle(aType);
|
2016-07-28 06:03:49 +03:00
|
|
|
}
|
2016-03-18 23:14:07 +03:00
|
|
|
|
2017-08-05 00:34:18 +03:00
|
|
|
if (!style) {
|
2019-02-19 16:44:33 +03:00
|
|
|
style = Servo_ComputedValues_GetForAnonymousBox(aParentStyle, aType,
|
2017-08-05 00:34:18 +03:00
|
|
|
mRawSet.get())
|
|
|
|
.Consume();
|
|
|
|
MOZ_ASSERT(style);
|
2019-02-19 16:44:33 +03:00
|
|
|
if (aParentStyle) {
|
|
|
|
aParentStyle->SetCachedInheritedAnonBoxStyle(style);
|
2017-08-05 00:34:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return style.forget();
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
already_AddRefed<ComputedStyle>
|
2019-02-19 16:44:33 +03:00
|
|
|
ServoStyleSet::ResolveNonInheritingAnonymousBoxStyle(PseudoStyleType aType) {
|
|
|
|
MOZ_ASSERT(PseudoStyle::IsNonInheritingAnonBox(aType));
|
|
|
|
MOZ_ASSERT(aType != PseudoStyleType::pageContent,
|
|
|
|
"If pageContent ends up non-inheriting, check "
|
2017-03-09 07:41:04 +03:00
|
|
|
"whether we need to do anything to move the "
|
2017-03-09 07:50:28 +03:00
|
|
|
"@page handling from ResolveInheritingAnonymousBoxStyle to "
|
2017-03-09 07:41:04 +03:00
|
|
|
"ResolveNonInheritingAnonymousBoxStyle");
|
|
|
|
|
|
|
|
nsCSSAnonBoxes::NonInheriting type =
|
2019-02-19 16:44:33 +03:00
|
|
|
nsCSSAnonBoxes::NonInheritingTypeForPseudoType(aType);
|
2018-03-22 21:20:41 +03:00
|
|
|
RefPtr<ComputedStyle>& cache = mNonInheritingComputedStyles[type];
|
2017-03-09 07:41:04 +03:00
|
|
|
if (cache) {
|
2018-03-22 21:20:41 +03:00
|
|
|
RefPtr<ComputedStyle> retval = cache;
|
2017-03-09 07:41:04 +03:00
|
|
|
return retval.forget();
|
|
|
|
}
|
|
|
|
|
2017-05-15 19:02:59 +03:00
|
|
|
UpdateStylistIfNeeded();
|
2017-05-10 20:13:39 +03:00
|
|
|
|
2017-03-13 19:53:45 +03:00
|
|
|
// We always want to skip parent-based display fixup here. It never makes
|
2017-04-24 11:25:37 +03:00
|
|
|
// sense for non-inheriting anonymous boxes. (Static assertions in
|
|
|
|
// nsCSSAnonBoxes.cpp ensure that all non-inheriting non-anonymous boxes
|
|
|
|
// are indeed annotated as skipping this fixup.)
|
2019-02-19 16:44:33 +03:00
|
|
|
MOZ_ASSERT(!PseudoStyle::IsNonInheritingAnonBox(PseudoStyleType::viewport),
|
|
|
|
"viewport needs fixup to handle blockifying it");
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
RefPtr<ComputedStyle> computedValues =
|
2019-02-19 16:44:33 +03:00
|
|
|
Servo_ComputedValues_GetForAnonymousBox(nullptr, aType, mRawSet.get())
|
2017-03-09 07:41:04 +03:00
|
|
|
.Consume();
|
2019-02-19 16:44:33 +03:00
|
|
|
MOZ_ASSERT(computedValues);
|
2017-03-09 07:41:04 +03:00
|
|
|
|
2017-07-17 21:42:24 +03:00
|
|
|
cache = computedValues;
|
|
|
|
return computedValues.forget();
|
2017-03-09 07:41:04 +03:00
|
|
|
}
|
|
|
|
|
2017-10-20 13:31:13 +03:00
|
|
|
#ifdef MOZ_XUL
|
|
|
|
already_AddRefed<ComputedStyle> ServoStyleSet::ResolveXULTreePseudoStyle(
|
2018-10-10 08:49:13 +03:00
|
|
|
dom::Element* aParentElement, nsCSSAnonBoxPseudoStaticAtom* aPseudoTag,
|
2019-02-19 16:44:33 +03:00
|
|
|
ComputedStyle* aParentStyle, const AtomArray& aInputWord) {
|
2017-10-20 13:31:13 +03:00
|
|
|
MOZ_ASSERT(nsCSSAnonBoxes::IsTreePseudoElement(aPseudoTag));
|
2019-02-19 16:44:33 +03:00
|
|
|
MOZ_ASSERT(aParentStyle);
|
2017-10-20 13:31:13 +03:00
|
|
|
MOZ_ASSERT(!StylistNeedsUpdate());
|
|
|
|
|
|
|
|
return Servo_ComputedValues_ResolveXULTreePseudoStyle(
|
2019-02-19 16:44:33 +03:00
|
|
|
aParentElement, aPseudoTag, aParentStyle, &aInputWord,
|
2017-10-20 13:31:13 +03:00
|
|
|
mRawSet.get())
|
|
|
|
.Consume();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-02-24 10:01:10 +03:00
|
|
|
// manage the set of style sheets in the style set
|
2019-04-19 07:20:31 +03:00
|
|
|
void ServoStyleSet::AppendStyleSheet(StyleOrigin aOrigin, StyleSheet* aSheet) {
|
2016-02-26 04:51:02 +03:00
|
|
|
MOZ_ASSERT(aSheet);
|
|
|
|
MOZ_ASSERT(aSheet->IsApplicable());
|
2017-06-29 04:07:06 +03:00
|
|
|
MOZ_ASSERT(aSheet->RawContents(),
|
|
|
|
"Raw sheet should be in place before insertion.");
|
2017-05-02 02:46:41 +03:00
|
|
|
|
2019-04-19 07:20:31 +03:00
|
|
|
aSheet->AddStyleSet(this);
|
2016-02-26 04:51:02 +03:00
|
|
|
|
2019-04-03 10:02:00 +03:00
|
|
|
// Maintain a mirrored list of sheets on the servo side.
|
|
|
|
// Servo will remove aSheet from its original position as part of the call
|
|
|
|
// to Servo_StyleSet_AppendStyleSheet.
|
|
|
|
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), aSheet);
|
|
|
|
SetStylistStyleSheetsDirty();
|
2016-02-26 05:57:42 +03:00
|
|
|
|
2017-11-28 03:50:45 +03:00
|
|
|
if (mStyleRuleMap) {
|
|
|
|
mStyleRuleMap->SheetAdded(*aSheet);
|
|
|
|
}
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2019-04-19 07:20:31 +03:00
|
|
|
void ServoStyleSet::RemoveStyleSheet(StyleOrigin aOrigin, StyleSheet* aSheet) {
|
2016-02-26 05:57:42 +03:00
|
|
|
MOZ_ASSERT(aSheet);
|
|
|
|
|
2019-04-19 07:20:31 +03:00
|
|
|
aSheet->DropStyleSet(this);
|
2019-04-03 10:02:00 +03:00
|
|
|
|
|
|
|
// Maintain a mirrored list of sheets on the servo side.
|
|
|
|
Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), aSheet);
|
|
|
|
SetStylistStyleSheetsDirty();
|
2016-02-26 05:57:42 +03:00
|
|
|
|
2017-11-28 03:50:45 +03:00
|
|
|
if (mStyleRuleMap) {
|
|
|
|
mStyleRuleMap->SheetRemoved(*aSheet);
|
|
|
|
}
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2019-04-19 07:20:31 +03:00
|
|
|
void ServoStyleSet::InsertStyleSheetBefore(Origin aOrigin,
|
|
|
|
StyleSheet* aNewSheet,
|
|
|
|
StyleSheet* aReferenceSheet) {
|
2016-04-29 07:01:44 +03:00
|
|
|
MOZ_ASSERT(aNewSheet);
|
|
|
|
MOZ_ASSERT(aReferenceSheet);
|
|
|
|
MOZ_ASSERT(aNewSheet->IsApplicable());
|
2017-04-18 21:29:13 +03:00
|
|
|
MOZ_ASSERT(aNewSheet != aReferenceSheet, "Can't place sheet before itself.");
|
2017-06-29 04:07:06 +03:00
|
|
|
MOZ_ASSERT(aNewSheet->RawContents(),
|
|
|
|
"Raw sheet should be in place before insertion.");
|
|
|
|
MOZ_ASSERT(aReferenceSheet->RawContents(),
|
|
|
|
"Reference sheet should have a raw sheet.");
|
2016-04-29 07:01:44 +03:00
|
|
|
|
2017-05-12 22:04:55 +03:00
|
|
|
// Servo will remove aNewSheet from its original position as part of the
|
|
|
|
// call to Servo_StyleSet_InsertStyleSheetBefore.
|
2019-04-19 07:20:31 +03:00
|
|
|
aNewSheet->AddStyleSet(this);
|
2016-04-29 07:01:44 +03:00
|
|
|
|
2019-04-03 10:02:00 +03:00
|
|
|
// Maintain a mirrored list of sheets on the servo side.
|
|
|
|
Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(), aNewSheet,
|
|
|
|
aReferenceSheet);
|
|
|
|
SetStylistStyleSheetsDirty();
|
2016-04-29 07:01:44 +03:00
|
|
|
|
2017-11-28 03:50:45 +03:00
|
|
|
if (mStyleRuleMap) {
|
|
|
|
mStyleRuleMap->SheetAdded(*aNewSheet);
|
|
|
|
}
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2019-04-19 07:20:31 +03:00
|
|
|
size_t ServoStyleSet::SheetCount(Origin aOrigin) const {
|
|
|
|
return Servo_StyleSet_GetSheetCount(mRawSet.get(), aOrigin);
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2019-04-19 07:20:31 +03:00
|
|
|
StyleSheet* ServoStyleSet::SheetAt(Origin aOrigin, size_t aIndex) const {
|
|
|
|
return const_cast<StyleSheet*>(
|
|
|
|
Servo_StyleSet_GetSheetAt(mRawSet.get(), aOrigin, aIndex));
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2018-04-16 20:10:57 +03:00
|
|
|
void ServoStyleSet::AppendAllNonDocumentAuthorSheets(
|
|
|
|
nsTArray<StyleSheet*>& aArray) const {
|
2019-04-23 19:43:15 +03:00
|
|
|
EnumerateShadowRoots(*mDocument, [&](ShadowRoot& aShadowRoot) {
|
|
|
|
for (auto index : IntegerRange(aShadowRoot.SheetCount())) {
|
|
|
|
aArray.AppendElement(aShadowRoot.SheetAt(index));
|
|
|
|
}
|
|
|
|
});
|
2017-06-30 02:09:22 +03:00
|
|
|
}
|
|
|
|
|
2019-04-19 07:20:31 +03:00
|
|
|
void ServoStyleSet::AddDocStyleSheet(StyleSheet* aSheet) {
|
2017-01-09 12:42:52 +03:00
|
|
|
MOZ_ASSERT(aSheet->IsApplicable());
|
2017-06-29 04:07:06 +03:00
|
|
|
MOZ_ASSERT(aSheet->RawContents(),
|
|
|
|
"Raw sheet should be in place by this point.");
|
2017-01-09 12:42:52 +03:00
|
|
|
|
2016-09-26 15:03:25 +03:00
|
|
|
RefPtr<StyleSheet> strong(aSheet);
|
2016-04-29 07:01:44 +03:00
|
|
|
|
2019-04-19 07:20:31 +03:00
|
|
|
size_t index = mDocument->FindDocStyleSheetInsertionPoint(*aSheet);
|
|
|
|
aSheet->AddStyleSet(this);
|
2017-05-02 02:46:41 +03:00
|
|
|
|
2019-04-19 07:20:31 +03:00
|
|
|
if (index < SheetCount(Origin::Author)) {
|
2017-05-02 02:46:41 +03:00
|
|
|
// This case is insert before.
|
2019-04-19 07:20:31 +03:00
|
|
|
StyleSheet* beforeSheet = SheetAt(Origin::Author, index);
|
2017-05-02 02:46:41 +03:00
|
|
|
|
2019-04-03 10:02:00 +03:00
|
|
|
// Maintain a mirrored list of sheets on the servo side.
|
|
|
|
Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(), aSheet, beforeSheet);
|
|
|
|
SetStylistStyleSheetsDirty();
|
2017-05-02 02:46:41 +03:00
|
|
|
} else {
|
2019-04-03 10:02:00 +03:00
|
|
|
// Maintain a mirrored list of sheets on the servo side.
|
|
|
|
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), aSheet);
|
|
|
|
SetStylistStyleSheetsDirty();
|
2016-04-29 07:01:44 +03:00
|
|
|
}
|
|
|
|
|
2017-11-28 03:50:45 +03:00
|
|
|
if (mStyleRuleMap) {
|
|
|
|
mStyleRuleMap->SheetAdded(*aSheet);
|
|
|
|
}
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2019-05-01 22:03:06 +03:00
|
|
|
already_AddRefed<ComputedStyle> ServoStyleSet::ProbePseudoElementStyle(
|
|
|
|
const Element& aOriginatingElement, PseudoStyleType aType,
|
|
|
|
ComputedStyle* aParentStyle) {
|
|
|
|
// Runs from frame construction, this should have clean styles already, except
|
|
|
|
// with non-lazy FC...
|
|
|
|
UpdateStylistIfNeeded();
|
|
|
|
|
|
|
|
// NB: We ignore aParentStyle, because in some cases
|
|
|
|
// (first-line/first-letter on anonymous box blocks) Gecko passes something
|
|
|
|
// nonsensical there. In all other cases we want to inherit directly from
|
|
|
|
// aOriginatingElement's styles anyway.
|
|
|
|
MOZ_ASSERT(PseudoStyle::IsPseudoElement(aType));
|
|
|
|
|
|
|
|
bool cacheable =
|
|
|
|
LazyPseudoIsCacheable(aType, aOriginatingElement, aParentStyle);
|
2017-08-06 19:42:55 +03:00
|
|
|
|
2019-05-01 22:03:06 +03:00
|
|
|
RefPtr<ComputedStyle> computedValues =
|
|
|
|
cacheable ? aParentStyle->GetCachedLazyPseudoStyle(aType) : nullptr;
|
|
|
|
if (!computedValues) {
|
|
|
|
computedValues =
|
|
|
|
Servo_ResolvePseudoStyle(&aOriginatingElement, aType,
|
|
|
|
/* is_probe = */ true, nullptr, mRawSet.get())
|
|
|
|
.Consume();
|
|
|
|
if (!computedValues) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cacheable) {
|
|
|
|
// NB: We don't need to worry about the before/after handling below
|
|
|
|
// because those are eager and thus not |cacheable| anyway.
|
|
|
|
aParentStyle->SetCachedLazyPseudoStyle(computedValues);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aType == PseudoStyleType::marker) {
|
2019-03-25 01:13:53 +03:00
|
|
|
// ::marker only exist for list items (for now).
|
2019-05-01 22:03:06 +03:00
|
|
|
if (aParentStyle->StyleDisplay()->mDisplay != StyleDisplay::ListItem) {
|
|
|
|
return nullptr;
|
2019-03-25 01:13:53 +03:00
|
|
|
}
|
|
|
|
// display:none is equivalent to not having the pseudo-element at all.
|
2019-05-01 22:03:06 +03:00
|
|
|
if (computedValues->StyleDisplay()->mDisplay == StyleDisplay::None) {
|
|
|
|
return nullptr;
|
2019-03-25 01:13:53 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-29 03:56:37 +03:00
|
|
|
// For :before and :after pseudo-elements, having display: none or no
|
|
|
|
// 'content' property is equivalent to not having the pseudo-element
|
|
|
|
// at all.
|
2019-05-01 22:03:06 +03:00
|
|
|
bool isBeforeOrAfter =
|
|
|
|
aType == PseudoStyleType::before || aType == PseudoStyleType::after;
|
|
|
|
if (isBeforeOrAfter) {
|
|
|
|
const nsStyleDisplay* display = computedValues->StyleDisplay();
|
|
|
|
const nsStyleContent* content = computedValues->StyleContent();
|
|
|
|
if (display->mDisplay == StyleDisplay::None ||
|
|
|
|
content->ContentCount() == 0) {
|
|
|
|
return nullptr;
|
2016-04-29 03:56:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-01 22:03:06 +03:00
|
|
|
return computedValues.forget();
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2017-09-01 20:28:57 +03:00
|
|
|
bool ServoStyleSet::StyleDocument(ServoTraversalFlags aFlags) {
|
2019-02-16 20:38:35 +03:00
|
|
|
AUTO_PROFILER_LABEL_CATEGORY_PAIR(LAYOUT_StyleComputation);
|
2018-01-05 15:51:08 +03:00
|
|
|
MOZ_ASSERT(GetPresContext(), "Styling a document without a shell?");
|
|
|
|
|
|
|
|
if (!mDocument->GetServoRestyleRoot()) {
|
2017-08-23 04:13:57 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-09-01 20:28:57 +03:00
|
|
|
PreTraverse(aFlags);
|
2017-07-19 04:38:47 +03:00
|
|
|
AutoPrepareTraversal guard(this);
|
|
|
|
const SnapshotTable& snapshots = Snapshots();
|
2017-03-08 23:20:17 +03:00
|
|
|
|
2016-12-01 11:19:50 +03:00
|
|
|
// Restyle the document from the root element and each of the document level
|
|
|
|
// NAC subtree roots.
|
2017-02-10 05:42:30 +03:00
|
|
|
bool postTraversalRequired = false;
|
2017-07-19 04:38:47 +03:00
|
|
|
|
2018-01-05 15:51:08 +03:00
|
|
|
Element* rootElement = mDocument->GetRootElement();
|
2017-09-01 20:31:45 +03:00
|
|
|
MOZ_ASSERT_IF(rootElement, rootElement->HasServoData());
|
2017-07-19 04:38:47 +03:00
|
|
|
|
2017-09-01 20:28:57 +03:00
|
|
|
if (ShouldTraverseInParallel()) {
|
|
|
|
aFlags |= ServoTraversalFlags::ParallelTraversal;
|
|
|
|
}
|
|
|
|
|
2017-07-19 04:38:47 +03:00
|
|
|
// Do the first traversal.
|
2018-01-05 15:51:08 +03:00
|
|
|
DocumentStyleRootIterator iter(mDocument->GetServoRestyleRoot());
|
2016-12-01 11:19:50 +03:00
|
|
|
while (Element* root = iter.GetNextStyleRoot()) {
|
2017-09-26 08:25:06 +03:00
|
|
|
MOZ_ASSERT(MayTraverseFrom(root));
|
|
|
|
|
|
|
|
Element* parent = root->GetFlattenedTreeParentElementForStyle();
|
|
|
|
MOZ_ASSERT_IF(parent,
|
|
|
|
!parent->HasAnyOfFlags(Element::kAllServoDescendantBits));
|
|
|
|
|
|
|
|
postTraversalRequired |=
|
|
|
|
Servo_TraverseSubtree(root, mRawSet.get(), &snapshots, aFlags);
|
|
|
|
postTraversalRequired |= root->HasAnyOfFlags(
|
|
|
|
Element::kAllServoDescendantBits | NODE_NEEDS_FRAME);
|
|
|
|
|
|
|
|
if (parent) {
|
2018-01-05 15:51:08 +03:00
|
|
|
MOZ_ASSERT(root == mDocument->GetServoRestyleRoot());
|
2017-09-26 08:25:06 +03:00
|
|
|
if (parent->HasDirtyDescendantsForServo()) {
|
|
|
|
// If any style invalidation was triggered in our siblings, then we may
|
|
|
|
// need to post-traverse them, even if the root wasn't restyled after
|
|
|
|
// all.
|
2018-01-05 15:51:08 +03:00
|
|
|
uint32_t existingBits = mDocument->GetServoRestyleRootDirtyBits();
|
2017-10-10 04:05:54 +03:00
|
|
|
// We need to propagate the existing bits to the parent.
|
|
|
|
parent->SetFlags(existingBits);
|
2018-01-05 15:51:08 +03:00
|
|
|
mDocument->SetServoRestyleRoot(
|
2017-10-10 04:05:54 +03:00
|
|
|
parent, existingBits | ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
|
2017-09-26 08:25:06 +03:00
|
|
|
postTraversalRequired = true;
|
|
|
|
}
|
|
|
|
}
|
2017-07-19 04:38:47 +03:00
|
|
|
}
|
2017-08-11 03:10:37 +03:00
|
|
|
|
2017-07-19 04:38:47 +03:00
|
|
|
// If there are still animation restyles needed, trigger a second traversal to
|
|
|
|
// update CSS animations or transitions' styles.
|
|
|
|
//
|
|
|
|
// Note that we need to check the style root again, because doing another
|
|
|
|
// PreTraverse on the EffectCompositor might alter the style root. But we
|
|
|
|
// don't need to worry about NAC, since document-level NAC shouldn't have
|
|
|
|
// animations.
|
|
|
|
//
|
|
|
|
// We don't need to do this for SMIL since SMIL only updates its animation
|
|
|
|
// values once at the begin of a tick. As a result, even if the previous
|
|
|
|
// traversal caused, for example, the font-size to change, the SMIL style
|
|
|
|
// won't be updated until the next tick anyway.
|
2018-01-05 15:51:08 +03:00
|
|
|
if (GetPresContext()->EffectCompositor()->PreTraverse(aFlags)) {
|
|
|
|
nsINode* styleRoot = mDocument->GetServoRestyleRoot();
|
2017-07-19 04:38:47 +03:00
|
|
|
Element* root =
|
|
|
|
styleRoot->IsElement() ? styleRoot->AsElement() : rootElement;
|
2017-09-01 20:31:45 +03:00
|
|
|
|
2017-09-26 08:25:06 +03:00
|
|
|
postTraversalRequired |=
|
|
|
|
Servo_TraverseSubtree(root, mRawSet.get(), &snapshots, aFlags);
|
|
|
|
postTraversalRequired |= root->HasAnyOfFlags(
|
|
|
|
Element::kAllServoDescendantBits | NODE_NEEDS_FRAME);
|
2016-12-01 11:19:50 +03:00
|
|
|
}
|
2017-08-11 03:10:37 +03:00
|
|
|
|
2017-02-10 05:42:30 +03:00
|
|
|
return postTraversalRequired;
|
2016-08-12 00:12:49 +03:00
|
|
|
}
|
|
|
|
|
2016-12-11 09:11:36 +03:00
|
|
|
void ServoStyleSet::StyleNewSubtree(Element* aRoot) {
|
2018-01-05 15:51:08 +03:00
|
|
|
MOZ_ASSERT(GetPresContext());
|
2017-11-17 23:13:48 +03:00
|
|
|
MOZ_ASSERT(!aRoot->HasServoData());
|
2018-04-17 22:17:44 +03:00
|
|
|
MOZ_ASSERT(aRoot->GetFlattenedTreeParentNodeForStyle(),
|
|
|
|
"Not in the flat tree? Fishy!");
|
2017-07-28 08:07:58 +03:00
|
|
|
PreTraverseSync();
|
2017-07-26 23:13:00 +03:00
|
|
|
AutoPrepareTraversal guard(this);
|
2017-03-08 23:20:17 +03:00
|
|
|
|
2017-07-26 23:13:00 +03:00
|
|
|
// Do the traversal. The snapshots will not be used.
|
|
|
|
const SnapshotTable& snapshots = Snapshots();
|
2017-08-11 22:54:35 +03:00
|
|
|
auto flags = ServoTraversalFlags::Empty;
|
2017-09-01 20:28:57 +03:00
|
|
|
if (ShouldTraverseInParallel()) {
|
|
|
|
flags |= ServoTraversalFlags::ParallelTraversal;
|
|
|
|
}
|
|
|
|
|
2017-02-10 05:42:30 +03:00
|
|
|
DebugOnly<bool> postTraversalRequired =
|
2017-08-11 22:54:35 +03:00
|
|
|
Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, flags);
|
2017-02-10 05:42:30 +03:00
|
|
|
MOZ_ASSERT(!postTraversalRequired);
|
2017-07-26 23:13:00 +03:00
|
|
|
|
|
|
|
// Annoyingly, the newly-styled content may have animations that need
|
|
|
|
// starting, which requires traversing them again. Mark the elements
|
|
|
|
// that need animation processing, then do a forgetful traversal to
|
|
|
|
// update the styles and clear the animation bits.
|
2018-01-05 15:51:08 +03:00
|
|
|
if (GetPresContext()->EffectCompositor()->PreTraverseInSubtree(flags,
|
|
|
|
aRoot)) {
|
2019-04-09 21:05:08 +03:00
|
|
|
postTraversalRequired =
|
|
|
|
Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots,
|
|
|
|
ServoTraversalFlags::AnimationOnly |
|
|
|
|
ServoTraversalFlags::FinalAnimationTraversal);
|
2017-07-26 23:13:00 +03:00
|
|
|
MOZ_ASSERT(!postTraversalRequired);
|
|
|
|
}
|
2016-08-12 00:12:49 +03:00
|
|
|
}
|
|
|
|
|
2017-08-12 13:49:01 +03:00
|
|
|
void ServoStyleSet::MarkOriginsDirty(OriginFlags aChangedOrigins) {
|
2017-05-15 19:02:59 +03:00
|
|
|
SetStylistStyleSheetsDirty();
|
2018-02-08 15:05:28 +03:00
|
|
|
Servo_StyleSet_NoteStyleSheetsChanged(mRawSet.get(), aChangedOrigins);
|
2016-12-19 09:30:14 +03:00
|
|
|
}
|
|
|
|
|
Bug 1418433 - move the implementation of SetStylistStyleSheetsDirty to .cpp file. r=heycam
This is a pre-patch for the real fix of Bug 1418433.
In the real fix, we'll add a IncrementUndisplayedRestyleGeneration() call into
SetStylistStyleSheetsDirty(). However, the IncrementUndisplayedRestyleGeneration()
call needs get through some deep structures in nsPresContext, RestyleManager,...
etc., and doing so means we need to move bunches of related include files, forward
declarations, from .cpp file to .h file, which doesn't make sense.
Instead, we move the implementation parts of SetStylistStyleSheetsDirty() to .cpp
file (since it is now a bit more complicated than it was), so we can use the existing
include files in the .cpp file to add IncrementUndisplayedRestyleGeneration() call
(this is in a following patch).
MozReview-Commit-ID: 3Vp9qyCf8NA
--HG--
extra : rebase_source : 16386256e16a2ca98bf988d66d861cbea58490a3
2017-11-29 13:56:15 +03:00
|
|
|
void ServoStyleSet::SetStylistStyleSheetsDirty() {
|
|
|
|
mStylistState |= StylistState::StyleSheetsDirty;
|
2017-11-26 18:24:12 +03:00
|
|
|
|
|
|
|
// We need to invalidate cached style in getComputedStyle for undisplayed
|
2019-04-04 02:52:19 +03:00
|
|
|
// elements, since we don't know if any of the style sheet change that we do
|
|
|
|
// would affect undisplayed elements.
|
|
|
|
//
|
|
|
|
// We don't allow to call getComputedStyle in elements without a pres shell
|
|
|
|
// yet, so it is fine if there's no pres context here.
|
2018-01-05 15:51:08 +03:00
|
|
|
if (nsPresContext* presContext = GetPresContext()) {
|
2018-04-05 21:55:51 +03:00
|
|
|
presContext->RestyleManager()->IncrementUndisplayedRestyleGeneration();
|
2017-11-26 18:24:12 +03:00
|
|
|
}
|
Bug 1418433 - move the implementation of SetStylistStyleSheetsDirty to .cpp file. r=heycam
This is a pre-patch for the real fix of Bug 1418433.
In the real fix, we'll add a IncrementUndisplayedRestyleGeneration() call into
SetStylistStyleSheetsDirty(). However, the IncrementUndisplayedRestyleGeneration()
call needs get through some deep structures in nsPresContext, RestyleManager,...
etc., and doing so means we need to move bunches of related include files, forward
declarations, from .cpp file to .h file, which doesn't make sense.
Instead, we move the implementation parts of SetStylistStyleSheetsDirty() to .cpp
file (since it is now a bit more complicated than it was), so we can use the existing
include files in the .cpp file to add IncrementUndisplayedRestyleGeneration() call
(this is in a following patch).
MozReview-Commit-ID: 3Vp9qyCf8NA
--HG--
extra : rebase_source : 16386256e16a2ca98bf988d66d861cbea58490a3
2017-11-29 13:56:15 +03:00
|
|
|
}
|
|
|
|
|
2019-04-23 19:43:15 +03:00
|
|
|
void ServoStyleSet::SetStylistShadowDOMStyleSheetsDirty() {
|
|
|
|
mStylistState |= StylistState::ShadowDOMStyleSheetsDirty;
|
2019-04-04 02:52:19 +03:00
|
|
|
if (nsPresContext* presContext = GetPresContext()) {
|
|
|
|
presContext->RestyleManager()->IncrementUndisplayedRestyleGeneration();
|
|
|
|
}
|
Bug 1418433 - move the implementation of SetStylistStyleSheetsDirty to .cpp file. r=heycam
This is a pre-patch for the real fix of Bug 1418433.
In the real fix, we'll add a IncrementUndisplayedRestyleGeneration() call into
SetStylistStyleSheetsDirty(). However, the IncrementUndisplayedRestyleGeneration()
call needs get through some deep structures in nsPresContext, RestyleManager,...
etc., and doing so means we need to move bunches of related include files, forward
declarations, from .cpp file to .h file, which doesn't make sense.
Instead, we move the implementation parts of SetStylistStyleSheetsDirty() to .cpp
file (since it is now a bit more complicated than it was), so we can use the existing
include files in the .cpp file to add IncrementUndisplayedRestyleGeneration() call
(this is in a following patch).
MozReview-Commit-ID: 3Vp9qyCf8NA
--HG--
extra : rebase_source : 16386256e16a2ca98bf988d66d861cbea58490a3
2017-11-29 13:56:15 +03:00
|
|
|
}
|
|
|
|
|
2019-04-19 07:20:31 +03:00
|
|
|
static OriginFlags ToOriginFlags(StyleOrigin aOrigin) {
|
|
|
|
switch (aOrigin) {
|
|
|
|
case StyleOrigin::UserAgent:
|
|
|
|
return OriginFlags::UserAgent;
|
|
|
|
case StyleOrigin::User:
|
|
|
|
return OriginFlags::User;
|
|
|
|
default:
|
|
|
|
MOZ_FALLTHROUGH_ASSERT("Unknown origin?");
|
|
|
|
case StyleOrigin::Author:
|
|
|
|
return OriginFlags::Author;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-30 20:23:14 +03:00
|
|
|
void ServoStyleSet::RuleAdded(StyleSheet& aSheet, css::Rule& aRule) {
|
2017-11-28 03:50:45 +03:00
|
|
|
if (mStyleRuleMap) {
|
|
|
|
mStyleRuleMap->RuleAdded(aSheet, aRule);
|
2017-05-25 20:50:03 +03:00
|
|
|
}
|
2017-11-28 03:50:45 +03:00
|
|
|
|
|
|
|
// FIXME(emilio): Could be more granular based on aRule.
|
2019-04-19 07:20:31 +03:00
|
|
|
MarkOriginsDirty(ToOriginFlags(aSheet.GetOrigin()));
|
2017-11-28 03:50:45 +03:00
|
|
|
}
|
|
|
|
|
2018-04-30 20:23:14 +03:00
|
|
|
void ServoStyleSet::RuleRemoved(StyleSheet& aSheet, css::Rule& aRule) {
|
2017-11-28 03:50:45 +03:00
|
|
|
if (mStyleRuleMap) {
|
|
|
|
mStyleRuleMap->RuleRemoved(aSheet, aRule);
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME(emilio): Could be more granular based on aRule.
|
2019-04-19 07:20:31 +03:00
|
|
|
MarkOriginsDirty(ToOriginFlags(aSheet.GetOrigin()));
|
2017-11-28 03:50:45 +03:00
|
|
|
}
|
|
|
|
|
2018-04-30 20:23:14 +03:00
|
|
|
void ServoStyleSet::RuleChanged(StyleSheet& aSheet, css::Rule* aRule) {
|
2017-11-28 03:50:45 +03:00
|
|
|
// FIXME(emilio): Could be more granular based on aRule.
|
2019-04-19 07:20:31 +03:00
|
|
|
MarkOriginsDirty(ToOriginFlags(aSheet.GetOrigin()));
|
2017-05-25 20:50:03 +03:00
|
|
|
}
|
|
|
|
|
2019-05-22 09:01:51 +03:00
|
|
|
void ServoStyleSet::StyleSheetCloned(StyleSheet& aSheet) {
|
|
|
|
mNeedsRestyleAfterEnsureUniqueInner = true;
|
|
|
|
}
|
|
|
|
|
2016-11-02 09:11:24 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
void ServoStyleSet::AssertTreeIsClean() {
|
2018-01-05 15:51:08 +03:00
|
|
|
DocumentStyleRootIterator iter(mDocument);
|
2016-12-28 11:26:10 +03:00
|
|
|
while (Element* root = iter.GetNextStyleRoot()) {
|
2016-11-02 09:11:24 +03:00
|
|
|
Servo_AssertTreeIsClean(root);
|
|
|
|
}
|
2016-05-25 09:55:49 +03:00
|
|
|
}
|
2016-11-02 09:11:24 +03:00
|
|
|
#endif
|
2017-01-04 22:52:27 +03:00
|
|
|
|
2018-05-01 08:09:12 +03:00
|
|
|
bool ServoStyleSet::GetKeyframesForName(const Element& aElement,
|
2018-07-06 06:19:10 +03:00
|
|
|
const ComputedStyle& aStyle,
|
2018-05-01 08:09:12 +03:00
|
|
|
nsAtom* aName,
|
2017-05-13 10:34:38 +03:00
|
|
|
const nsTimingFunction& aTimingFunction,
|
|
|
|
nsTArray<Keyframe>& aKeyframes) {
|
2018-02-10 00:09:59 +03:00
|
|
|
MOZ_ASSERT(!StylistNeedsUpdate());
|
2017-05-13 10:34:38 +03:00
|
|
|
return Servo_StyleSet_GetKeyframesForName(
|
|
|
|
mRawSet.get(), &aElement, &aStyle, aName, &aTimingFunction, &aKeyframes);
|
2017-01-29 06:58:28 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-03-21 10:41:23 +03:00
|
|
|
nsTArray<ComputedKeyframeValues> ServoStyleSet::GetComputedKeyframeValuesFor(
|
|
|
|
const nsTArray<Keyframe>& aKeyframes, Element* aElement,
|
2018-03-22 21:20:41 +03:00
|
|
|
const mozilla::ComputedStyle* aStyle) {
|
2017-03-11 04:40:47 +03:00
|
|
|
nsTArray<ComputedKeyframeValues> result(aKeyframes.Length());
|
|
|
|
|
|
|
|
// Construct each nsTArray<PropertyStyleAnimationValuePair> here.
|
|
|
|
result.AppendElements(aKeyframes.Length());
|
|
|
|
|
|
|
|
Servo_GetComputedKeyframeValues(&aKeyframes, aElement, aStyle, mRawSet.get(),
|
|
|
|
&result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-06-09 00:19:37 +03:00
|
|
|
void ServoStyleSet::GetAnimationValues(
|
|
|
|
RawServoDeclarationBlock* aDeclarations, Element* aElement,
|
2018-03-22 21:20:41 +03:00
|
|
|
const ComputedStyle* aComputedStyle,
|
2017-06-09 00:19:37 +03:00
|
|
|
nsTArray<RefPtr<RawServoAnimationValue>>& aAnimationValues) {
|
2017-08-04 12:26:04 +03:00
|
|
|
// Servo_GetAnimationValues below won't handle ignoring existing element
|
|
|
|
// data for bfcached documents. (See comment in ResolveStyleLazily
|
|
|
|
// about these bfcache issues.)
|
2017-06-09 00:19:37 +03:00
|
|
|
Servo_GetAnimationValues(aDeclarations, aElement, aComputedStyle,
|
|
|
|
mRawSet.get(), &aAnimationValues);
|
|
|
|
}
|
|
|
|
|
2017-07-17 21:41:44 +03:00
|
|
|
already_AddRefed<ComputedStyle> ServoStyleSet::GetBaseContextForElement(
|
2018-03-22 21:20:41 +03:00
|
|
|
Element* aElement, const ComputedStyle* aStyle) {
|
2017-07-17 21:42:00 +03:00
|
|
|
return Servo_StyleSet_GetBaseComputedValuesForElement(mRawSet.get(), aElement,
|
2017-11-22 05:03:40 +03:00
|
|
|
aStyle, &Snapshots())
|
|
|
|
.Consume();
|
2017-04-06 04:34:50 +03:00
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
already_AddRefed<ComputedStyle>
|
2017-10-19 05:51:55 +03:00
|
|
|
ServoStyleSet::ResolveServoStyleByAddingAnimation(
|
2018-03-22 21:20:41 +03:00
|
|
|
Element* aElement, const ComputedStyle* aStyle,
|
2017-10-19 05:51:55 +03:00
|
|
|
RawServoAnimationValue* aAnimationValue) {
|
|
|
|
return Servo_StyleSet_GetComputedValuesByAddingAnimation(
|
|
|
|
mRawSet.get(), aElement, aStyle, &Snapshots(), aAnimationValue)
|
|
|
|
.Consume();
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-05-03 06:15:27 +03:00
|
|
|
already_AddRefed<RawServoAnimationValue> ServoStyleSet::ComputeAnimationValue(
|
|
|
|
Element* aElement, RawServoDeclarationBlock* aDeclarations,
|
2018-03-22 21:20:41 +03:00
|
|
|
const mozilla::ComputedStyle* aStyle) {
|
2017-06-02 03:38:22 +03:00
|
|
|
return Servo_AnimationValue_Compute(aElement, aDeclarations, aStyle,
|
2017-05-03 06:15:27 +03:00
|
|
|
mRawSet.get())
|
|
|
|
.Consume();
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-05-16 02:30:10 +03:00
|
|
|
bool ServoStyleSet::EnsureUniqueInnerOnCSSSheets() {
|
2019-04-23 19:43:15 +03:00
|
|
|
using SheetOwner = Variant<ServoStyleSet*, ShadowRoot*>;
|
2018-02-16 13:34:12 +03:00
|
|
|
|
|
|
|
AutoTArray<Pair<StyleSheet*, SheetOwner>, 32> queue;
|
2019-04-19 07:20:31 +03:00
|
|
|
EnumerateStyleSheets([&](StyleSheet& aSheet) {
|
|
|
|
queue.AppendElement(MakePair(&aSheet, SheetOwner{this}));
|
|
|
|
});
|
2017-05-16 03:11:08 +03:00
|
|
|
|
2018-02-25 20:01:42 +03:00
|
|
|
EnumerateShadowRoots(*mDocument, [&](ShadowRoot& aShadowRoot) {
|
|
|
|
for (auto index : IntegerRange(aShadowRoot.SheetCount())) {
|
|
|
|
queue.AppendElement(
|
|
|
|
MakePair(aShadowRoot.SheetAt(index), SheetOwner{&aShadowRoot}));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-05-16 03:11:08 +03:00
|
|
|
while (!queue.IsEmpty()) {
|
|
|
|
uint32_t idx = queue.Length() - 1;
|
2018-02-16 13:34:12 +03:00
|
|
|
auto* sheet = queue[idx].first();
|
|
|
|
SheetOwner owner = queue[idx].second();
|
2017-05-16 03:11:08 +03:00
|
|
|
queue.RemoveElementAt(idx);
|
|
|
|
|
2017-10-03 21:15:26 +03:00
|
|
|
// Only call EnsureUniqueInner for complete sheets. If we do call it on
|
|
|
|
// incomplete sheets, we'll cause problems when the sheet is actually
|
|
|
|
// loaded. We don't care about incomplete sheets here anyway, because this
|
|
|
|
// method is only invoked by nsPresContext::EnsureSafeToHandOutCSSRules.
|
|
|
|
// The CSSRule objects we are handing out won't contain any rules derived
|
|
|
|
// from incomplete sheets (because they aren't yet applied in styling).
|
|
|
|
if (sheet->IsComplete()) {
|
|
|
|
sheet->EnsureUniqueInner();
|
|
|
|
}
|
2017-05-16 03:11:08 +03:00
|
|
|
|
|
|
|
// Enqueue all the sheet's children.
|
2018-02-16 13:34:12 +03:00
|
|
|
AutoTArray<StyleSheet*, 3> children;
|
|
|
|
sheet->AppendAllChildSheets(children);
|
|
|
|
for (auto* sheet : children) {
|
|
|
|
queue.AppendElement(MakePair(sheet, owner));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-22 21:36:14 +03:00
|
|
|
if (mNeedsRestyleAfterEnsureUniqueInner) {
|
|
|
|
// TODO(emilio): We could make this faster if needed tracking the specific
|
2019-05-22 09:01:51 +03:00
|
|
|
// origins and sheets that have been cloned. But the only caller of this
|
|
|
|
// doesn't seem to really care about perf.
|
2017-08-22 21:36:14 +03:00
|
|
|
MarkOriginsDirty(OriginFlags::All);
|
2019-05-22 09:01:51 +03:00
|
|
|
ForceDirtyAllShadowStyles();
|
2017-08-22 21:36:14 +03:00
|
|
|
}
|
2017-05-16 02:30:10 +03:00
|
|
|
bool res = mNeedsRestyleAfterEnsureUniqueInner;
|
|
|
|
mNeedsRestyleAfterEnsureUniqueInner = false;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2017-08-02 15:39:32 +03:00
|
|
|
void ServoStyleSet::ClearCachedStyleData() {
|
2018-03-22 21:20:41 +03:00
|
|
|
ClearNonInheritingComputedStyles();
|
2017-08-02 15:39:32 +03:00
|
|
|
Servo_StyleSet_RebuildCachedData(mRawSet.get());
|
2017-01-04 22:52:27 +03:00
|
|
|
}
|
2017-01-04 22:52:27 +03:00
|
|
|
|
2019-05-22 09:01:51 +03:00
|
|
|
void ServoStyleSet::ForceDirtyAllShadowStyles() {
|
2019-04-04 02:52:19 +03:00
|
|
|
bool anyShadow = false;
|
|
|
|
EnumerateShadowRoots(*mDocument, [&](ShadowRoot& aShadowRoot) {
|
|
|
|
if (auto* authorStyles = aShadowRoot.GetServoStyles()) {
|
|
|
|
anyShadow = true;
|
|
|
|
Servo_AuthorStyles_ForceDirty(authorStyles);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if (anyShadow) {
|
2019-04-23 19:43:15 +03:00
|
|
|
SetStylistShadowDOMStyleSheetsDirty();
|
2019-04-04 02:52:19 +03:00
|
|
|
}
|
2017-06-10 17:22:23 +03:00
|
|
|
}
|
|
|
|
|
2019-05-22 09:01:51 +03:00
|
|
|
void ServoStyleSet::CompatibilityModeChanged() {
|
|
|
|
Servo_StyleSet_CompatModeChanged(mRawSet.get());
|
|
|
|
SetStylistStyleSheetsDirty();
|
|
|
|
ForceDirtyAllShadowStyles();
|
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
void ServoStyleSet::ClearNonInheritingComputedStyles() {
|
|
|
|
for (RefPtr<ComputedStyle>& ptr : mNonInheritingComputedStyles) {
|
2017-03-08 08:18:39 +03:00
|
|
|
ptr = nullptr;
|
2017-03-11 04:40:47 +03:00
|
|
|
}
|
2017-03-08 08:18:39 +03:00
|
|
|
}
|
|
|
|
|
2019-04-09 21:05:04 +03:00
|
|
|
already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStyleLazily(
|
|
|
|
Element& aElement, PseudoStyleType aPseudoType,
|
2017-11-09 20:29:36 +03:00
|
|
|
StyleRuleInclusion aRuleInclusion) {
|
2019-04-09 21:05:04 +03:00
|
|
|
PreTraverseSync();
|
2018-01-05 15:51:08 +03:00
|
|
|
MOZ_ASSERT(GetPresContext(),
|
|
|
|
"For now, no style resolution without a pres context");
|
2017-05-15 19:02:59 +03:00
|
|
|
MOZ_ASSERT(!StylistNeedsUpdate());
|
2017-04-30 09:41:11 +03:00
|
|
|
|
|
|
|
AutoSetInServoTraversal guard(this);
|
2017-04-26 15:01:25 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* NB: This is needed because we process animations and transitions on the
|
|
|
|
* pseudo-elements themselves, not on the parent's EagerPseudoStyles.
|
|
|
|
*
|
|
|
|
* That means that that style doesn't account for animations, and we can't do
|
|
|
|
* that easily from the traversal without doing wasted work.
|
|
|
|
*
|
|
|
|
* As such, we just lie here a bit, which is the entrypoint of
|
|
|
|
* getComputedStyle, the only API where this can be observed, to look at the
|
|
|
|
* style of the pseudo-element if it exists instead.
|
|
|
|
*/
|
2019-04-09 21:05:04 +03:00
|
|
|
Element* elementForStyleResolution = &aElement;
|
2019-02-19 16:44:33 +03:00
|
|
|
PseudoStyleType pseudoTypeForStyleResolution = aPseudoType;
|
|
|
|
if (aPseudoType == PseudoStyleType::before) {
|
2019-04-09 21:05:04 +03:00
|
|
|
if (Element* pseudo = nsLayoutUtils::GetBeforePseudo(&aElement)) {
|
2017-04-26 15:01:25 +03:00
|
|
|
elementForStyleResolution = pseudo;
|
2019-02-19 16:44:33 +03:00
|
|
|
pseudoTypeForStyleResolution = PseudoStyleType::NotPseudo;
|
2017-04-26 15:01:25 +03:00
|
|
|
}
|
2019-02-19 16:44:33 +03:00
|
|
|
} else if (aPseudoType == PseudoStyleType::after) {
|
2019-04-09 21:05:04 +03:00
|
|
|
if (Element* pseudo = nsLayoutUtils::GetAfterPseudo(&aElement)) {
|
2017-04-26 15:01:25 +03:00
|
|
|
elementForStyleResolution = pseudo;
|
2019-02-19 16:44:33 +03:00
|
|
|
pseudoTypeForStyleResolution = PseudoStyleType::NotPseudo;
|
2017-04-26 15:01:25 +03:00
|
|
|
}
|
2019-03-26 07:48:26 +03:00
|
|
|
} else if (aPseudoType == PseudoStyleType::marker) {
|
2019-04-09 21:05:04 +03:00
|
|
|
if (Element* pseudo = nsLayoutUtils::GetMarkerPseudo(&aElement)) {
|
2019-03-26 07:48:26 +03:00
|
|
|
elementForStyleResolution = pseudo;
|
|
|
|
pseudoTypeForStyleResolution = PseudoStyleType::NotPseudo;
|
|
|
|
}
|
2017-04-26 15:01:25 +03:00
|
|
|
}
|
|
|
|
|
2019-04-09 21:05:08 +03:00
|
|
|
return Servo_ResolveStyleLazily(elementForStyleResolution,
|
|
|
|
pseudoTypeForStyleResolution, aRuleInclusion,
|
|
|
|
&Snapshots(), mRawSet.get())
|
|
|
|
.Consume();
|
2017-03-08 23:20:17 +03:00
|
|
|
}
|
|
|
|
|
2019-04-05 00:40:55 +03:00
|
|
|
void ServoStyleSet::AppendFontFaceRules(
|
2017-03-27 09:53:27 +03:00
|
|
|
nsTArray<nsFontFaceRuleContainer>& aArray) {
|
2018-08-27 21:44:20 +03:00
|
|
|
// TODO(emilio): Can we make this so this asserts instead?
|
2017-05-15 19:02:59 +03:00
|
|
|
UpdateStylistIfNeeded();
|
2017-03-27 09:53:27 +03:00
|
|
|
Servo_StyleSet_GetFontFaceRules(mRawSet.get(), &aArray);
|
|
|
|
}
|
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
const RawServoCounterStyleRule* ServoStyleSet::CounterStyleRuleForName(
|
|
|
|
nsAtom* aName) {
|
2018-02-10 00:09:59 +03:00
|
|
|
MOZ_ASSERT(!StylistNeedsUpdate());
|
2017-05-11 07:47:24 +03:00
|
|
|
return Servo_StyleSet_GetCounterStyleRule(mRawSet.get(), aName);
|
|
|
|
}
|
|
|
|
|
2017-08-24 04:05:53 +03:00
|
|
|
already_AddRefed<gfxFontFeatureValueSet>
|
|
|
|
ServoStyleSet::BuildFontFeatureValueSet() {
|
2018-08-27 21:44:20 +03:00
|
|
|
MOZ_ASSERT(!StylistNeedsUpdate());
|
2017-08-31 03:08:50 +03:00
|
|
|
RefPtr<gfxFontFeatureValueSet> set =
|
|
|
|
Servo_StyleSet_BuildFontFeatureValueSet(mRawSet.get());
|
2017-08-24 04:05:53 +03:00
|
|
|
return set.forget();
|
|
|
|
}
|
|
|
|
|
2017-04-15 01:37:35 +03:00
|
|
|
already_AddRefed<ComputedStyle> ServoStyleSet::ResolveForDeclarations(
|
2018-03-22 21:20:41 +03:00
|
|
|
const ComputedStyle* aParentOrNull,
|
2019-03-21 20:00:27 +03:00
|
|
|
const RawServoDeclarationBlock* aDeclarations) {
|
2018-02-10 00:09:59 +03:00
|
|
|
// No need to update the stylist, we're only cascading aDeclarations.
|
2017-04-15 01:37:35 +03:00
|
|
|
return Servo_StyleSet_ResolveForDeclarations(mRawSet.get(), aParentOrNull,
|
2017-07-07 00:56:06 +03:00
|
|
|
aDeclarations)
|
|
|
|
.Consume();
|
2017-04-15 01:37:35 +03:00
|
|
|
}
|
|
|
|
|
2017-05-15 19:02:59 +03:00
|
|
|
void ServoStyleSet::UpdateStylist() {
|
|
|
|
MOZ_ASSERT(StylistNeedsUpdate());
|
2017-08-31 23:59:11 +03:00
|
|
|
|
2017-09-02 10:25:45 +03:00
|
|
|
if (mStylistState & StylistState::StyleSheetsDirty) {
|
2018-02-16 13:49:18 +03:00
|
|
|
Element* root = mDocument->GetRootElement();
|
2018-01-25 04:53:49 +03:00
|
|
|
const ServoElementSnapshotTable* snapshots = nullptr;
|
|
|
|
if (nsPresContext* pc = GetPresContext()) {
|
2018-04-05 21:55:51 +03:00
|
|
|
snapshots = &pc->RestyleManager()->Snapshots();
|
2018-01-25 04:53:49 +03:00
|
|
|
}
|
|
|
|
Servo_StyleSet_FlushStyleSheets(mRawSet.get(), root, snapshots);
|
2017-09-02 10:25:45 +03:00
|
|
|
}
|
|
|
|
|
2019-04-23 19:43:15 +03:00
|
|
|
if (MOZ_UNLIKELY(mStylistState & StylistState::ShadowDOMStyleSheetsDirty)) {
|
2018-02-25 20:01:42 +03:00
|
|
|
EnumerateShadowRoots(*mDocument, [&](ShadowRoot& aShadowRoot) {
|
2018-08-30 15:00:00 +03:00
|
|
|
if (auto* authorStyles = aShadowRoot.GetServoStyles()) {
|
|
|
|
Servo_AuthorStyles_Flush(authorStyles, mRawSet.get());
|
|
|
|
}
|
2018-02-25 20:01:42 +03:00
|
|
|
});
|
2017-09-02 10:25:45 +03:00
|
|
|
}
|
2017-08-31 23:59:11 +03:00
|
|
|
|
2017-05-15 19:02:59 +03:00
|
|
|
mStylistState = StylistState::NotDirty;
|
2017-05-10 20:13:39 +03:00
|
|
|
}
|
|
|
|
|
2017-06-16 20:20:25 +03:00
|
|
|
void ServoStyleSet::MaybeGCRuleTree() {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
Servo_MaybeGCRuleTree(mRawSet.get());
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:09:24 +03:00
|
|
|
/* static */
|
|
|
|
bool ServoStyleSet::MayTraverseFrom(const Element* aElement) {
|
2017-07-26 20:43:48 +03:00
|
|
|
MOZ_ASSERT(aElement->IsInComposedDoc());
|
2017-11-22 16:15:34 +03:00
|
|
|
nsINode* parent = aElement->GetFlattenedTreeParentNodeForStyle();
|
2017-07-26 20:43:48 +03:00
|
|
|
if (!parent) {
|
2017-11-22 16:15:34 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!parent->IsElement()) {
|
2018-04-15 12:43:15 +03:00
|
|
|
MOZ_ASSERT(parent->IsDocument());
|
2017-07-26 20:43:48 +03:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-11-22 16:15:34 +03:00
|
|
|
if (!parent->AsElement()->HasServoData()) {
|
2017-07-26 20:43:48 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-11-22 16:15:34 +03:00
|
|
|
return !Servo_Element_IsDisplayNone(parent->AsElement());
|
2017-07-26 20:43:48 +03:00
|
|
|
}
|
|
|
|
|
2017-09-01 20:28:57 +03:00
|
|
|
bool ServoStyleSet::ShouldTraverseInParallel() const {
|
2019-03-29 18:12:47 +03:00
|
|
|
MOZ_ASSERT(mDocument->GetPresShell(), "Styling a document without a shell?");
|
|
|
|
if (!mDocument->GetPresShell()->IsActive()) {
|
2018-05-23 12:35:03 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#ifdef MOZ_GECKO_PROFILER
|
|
|
|
if (profiler_feature_active(ProfilerFeature::SequentialStyle)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return true;
|
2017-09-01 20:28:57 +03:00
|
|
|
}
|
|
|
|
|
2017-04-30 09:45:32 +03:00
|
|
|
void ServoStyleSet::RunPostTraversalTasks() {
|
|
|
|
MOZ_ASSERT(!IsInServoTraversal());
|
|
|
|
|
|
|
|
if (mPostTraversalTasks.IsEmpty()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsTArray<PostTraversalTask> tasks;
|
|
|
|
tasks.SwapElements(mPostTraversalTasks);
|
|
|
|
|
|
|
|
for (auto& task : tasks) {
|
|
|
|
task.Run();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-19 08:45:43 +03:00
|
|
|
ServoStyleRuleMap* ServoStyleSet::StyleRuleMap() {
|
|
|
|
if (!mStyleRuleMap) {
|
2018-02-12 15:57:26 +03:00
|
|
|
mStyleRuleMap = MakeUnique<ServoStyleRuleMap>();
|
2017-06-19 08:45:43 +03:00
|
|
|
}
|
2018-02-12 15:57:26 +03:00
|
|
|
mStyleRuleMap->EnsureTable(*this);
|
2017-11-28 03:50:45 +03:00
|
|
|
return mStyleRuleMap.get();
|
2017-06-19 08:45:43 +03:00
|
|
|
}
|
|
|
|
|
2017-06-28 08:18:02 +03:00
|
|
|
bool ServoStyleSet::MightHaveAttributeDependency(const Element& aElement,
|
2017-10-03 01:05:19 +03:00
|
|
|
nsAtom* aAttribute) const {
|
2017-06-28 08:18:02 +03:00
|
|
|
return Servo_StyleSet_MightHaveAttributeDependency(mRawSet.get(), &aElement,
|
|
|
|
aAttribute);
|
2017-05-08 11:04:31 +03:00
|
|
|
}
|
|
|
|
|
2017-07-04 20:16:04 +03:00
|
|
|
bool ServoStyleSet::HasStateDependency(const Element& aElement,
|
|
|
|
EventStates aState) const {
|
2017-06-28 08:18:02 +03:00
|
|
|
return Servo_StyleSet_HasStateDependency(mRawSet.get(), &aElement,
|
|
|
|
aState.ServoValue());
|
2017-05-09 13:13:45 +03:00
|
|
|
}
|
|
|
|
|
2017-11-01 13:20:39 +03:00
|
|
|
bool ServoStyleSet::HasDocumentStateDependency(EventStates aState) const {
|
|
|
|
return Servo_StyleSet_HasDocumentStateDependency(mRawSet.get(),
|
|
|
|
aState.ServoValue());
|
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
already_AddRefed<ComputedStyle> ServoStyleSet::ReparentComputedStyle(
|
|
|
|
ComputedStyle* aComputedStyle, ComputedStyle* aNewParent,
|
|
|
|
ComputedStyle* aNewParentIgnoringFirstLine, ComputedStyle* aNewLayoutParent,
|
|
|
|
Element* aElement) {
|
|
|
|
return Servo_ReparentStyle(aComputedStyle, aNewParent,
|
2017-07-29 04:20:41 +03:00
|
|
|
aNewParentIgnoringFirstLine, aNewLayoutParent,
|
|
|
|
aElement, mRawSet.get())
|
|
|
|
.Consume();
|
2017-07-29 04:11:18 +03:00
|
|
|
}
|
Bug 1400078 - Measure the UA cache. r=njn.
ServoStyleSetSizes now has two uses, one for the Stylist, and one for the UA
cache, and so the patch removes 'Stylist' from the field names.
Example output from about:memory:
> +----1,359,608 B (00.55%) -- layout
> | +----756,488 B (00.31%) -- style-sheet-cache [2]
> | +----393,968 B (00.16%) -- servo-ua-cache
> | | +--234,496 B (00.10%) -- element-and-pseudos-maps
> | | +---59,648 B (00.02%) -- revalidation-selectors
> | | +---58,320 B (00.02%) -- invalidation-map
> | | +---30,752 B (00.01%) -- other
> | | +---10,752 B (00.00%) -- precomputed-pseudos
MozReview-Commit-ID: 8oxuJO0ojp
--HG--
extra : rebase_source : 7d86216967259b71df7280261d025cc65bf00ba4
2017-09-19 02:25:00 +03:00
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS(UACacheReporter, nsIMemoryReporter)
|
|
|
|
|
|
|
|
MOZ_DEFINE_MALLOC_SIZE_OF(ServoUACacheMallocSizeOf)
|
|
|
|
MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoUACacheMallocEnclosingSizeOf)
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
UACacheReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
|
|
|
|
nsISupports* aData, bool aAnonymize) {
|
|
|
|
ServoStyleSetSizes sizes;
|
|
|
|
Servo_UACache_AddSizeOf(ServoUACacheMallocSizeOf,
|
|
|
|
ServoUACacheMallocEnclosingSizeOf, &sizes);
|
|
|
|
|
|
|
|
#define REPORT(_path, _amount, _desc) \
|
|
|
|
do { \
|
|
|
|
size_t __amount = _amount; /* evaluate _amount only once */ \
|
|
|
|
if (__amount > 0) { \
|
|
|
|
MOZ_COLLECT_REPORT(_path, KIND_HEAP, UNITS_BYTES, __amount, _desc); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
// The UA cache does not contain the rule tree; that's in the StyleSet.
|
|
|
|
MOZ_RELEASE_ASSERT(sizes.mRuleTree == 0);
|
|
|
|
|
|
|
|
REPORT("explicit/layout/servo-ua-cache/precomputed-pseudos",
|
|
|
|
sizes.mPrecomputedPseudos,
|
|
|
|
"Memory used by precomputed pseudo-element declarations within the "
|
|
|
|
"UA cache.");
|
|
|
|
|
|
|
|
REPORT("explicit/layout/servo-ua-cache/element-and-pseudos-maps",
|
|
|
|
sizes.mElementAndPseudosMaps,
|
|
|
|
"Memory used by element and pseudos maps within the UA cache.");
|
|
|
|
|
|
|
|
REPORT("explicit/layout/servo-ua-cache/invalidation-map",
|
|
|
|
sizes.mInvalidationMap,
|
|
|
|
"Memory used by invalidation maps within the UA cache.");
|
|
|
|
|
|
|
|
REPORT("explicit/layout/servo-ua-cache/revalidation-selectors",
|
|
|
|
sizes.mRevalidationSelectors,
|
|
|
|
"Memory used by selectors for cache revalidation within the UA "
|
|
|
|
"cache.");
|
|
|
|
|
|
|
|
REPORT("explicit/layout/servo-ua-cache/other", sizes.mOther,
|
|
|
|
"Memory used by other data within the UA cache");
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|