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"
|
|
|
|
|
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"
|
2017-08-03 23:16:31 +03:00
|
|
|
#include "mozilla/LookAndFeel.h"
|
2017-06-14 02:38:16 +03:00
|
|
|
#include "mozilla/ServoBindings.h"
|
2016-07-13 23:42:47 +03:00
|
|
|
#include "mozilla/ServoRestyleManager.h"
|
2017-06-19 08:45:43 +03:00
|
|
|
#include "mozilla/ServoStyleRuleMap.h"
|
|
|
|
#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"
|
2017-05-07 17:36:47 +03:00
|
|
|
#include "mozilla/RestyleManagerInlines.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-14 04:28:25 +03:00
|
|
|
#include "nsCSSRuleProcessor.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"
|
2016-04-29 07:01:44 +03:00
|
|
|
#include "nsIDocumentInlines.h"
|
2016-07-28 06:03:49 +03:00
|
|
|
#include "nsPrintfCString.h"
|
2017-04-26 07:00:11 +03:00
|
|
|
#include "nsSMILAnimationController.h"
|
2016-03-18 23:14:07 +03:00
|
|
|
#include "nsStyleContext.h"
|
2016-02-26 04:51:02 +03:00
|
|
|
#include "nsStyleSet.h"
|
2017-05-26 17:29:10 +03:00
|
|
|
#include "gfxUserFontSet.h"
|
2016-02-24 10:01:10 +03:00
|
|
|
|
|
|
|
using namespace mozilla;
|
|
|
|
using namespace mozilla::dom;
|
|
|
|
|
2017-08-10 20:58:40 +03:00
|
|
|
ServoStyleSet* ServoStyleSet::sInServoTraversal = nullptr;
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
// 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)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(!ServoStyleSet::sInServoTraversal);
|
|
|
|
MOZ_ASSERT(aSet);
|
|
|
|
ServoStyleSet::sInServoTraversal = aSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
~AutoSetInServoTraversal()
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(ServoStyleSet::sInServoTraversal);
|
|
|
|
ServoStyleSet::sInServoTraversal = nullptr;
|
|
|
|
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
|
|
|
|
// ServoRestyleManager::PostRestyleEventForAnimations so that we don't need
|
|
|
|
// to care about animation restyles here.
|
|
|
|
: mTimelineMarker(aSet->mPresContext->GetDocShell(), false)
|
|
|
|
, mSetInServoTraversal(aSet)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(!aSet->StylistNeedsUpdate());
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
AutoRestyleTimelineMarker mTimelineMarker;
|
|
|
|
AutoSetInServoTraversal mSetInServoTraversal;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace mozilla
|
|
|
|
|
2016-02-24 10:01:12 +03:00
|
|
|
ServoStyleSet::ServoStyleSet()
|
2016-03-18 23:14:07 +03:00
|
|
|
: mPresContext(nullptr)
|
2017-04-11 10:43:14 +03:00
|
|
|
, mAuthorStyleDisabled(false)
|
2017-05-15 19:02:59 +03:00
|
|
|
, mStylistState(StylistState::NotDirty)
|
2017-05-26 17:29:10 +03:00
|
|
|
, mUserFontSetUpdateGeneration(0)
|
2017-07-07 08:35:28 +03:00
|
|
|
, mUserFontCacheUpdateGeneration(0)
|
2017-05-16 02:30:10 +03:00
|
|
|
, mNeedsRestyleAfterEnsureUniqueInner(false)
|
2016-02-24 10:01:12 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-03-08 08:18:39 +03:00
|
|
|
ServoStyleSet::~ServoStyleSet()
|
|
|
|
{
|
2017-05-24 03:02:51 +03:00
|
|
|
for (auto& sheetArray : mSheets) {
|
|
|
|
for (auto& sheet : sheetArray) {
|
|
|
|
sheet->DropStyleSet(this);
|
|
|
|
}
|
|
|
|
}
|
2017-03-08 08:18:39 +03:00
|
|
|
}
|
|
|
|
|
2016-02-24 10:01:10 +03:00
|
|
|
void
|
2017-06-29 23:43:59 +03:00
|
|
|
ServoStyleSet::Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2016-03-18 23:14:07 +03:00
|
|
|
mPresContext = aPresContext;
|
2017-01-04 22:52:26 +03:00
|
|
|
mRawSet.reset(Servo_StyleSet_Init(aPresContext));
|
2017-06-29 23:43:59 +03:00
|
|
|
mBindingManager = aBindingManager;
|
2017-01-04 22:52:26 +03:00
|
|
|
|
2017-04-08 01:49:44 +03:00
|
|
|
mPresContext->DeviceContext()->InitFontCache();
|
|
|
|
|
2017-01-04 22:52:26 +03:00
|
|
|
// Now that we have an mRawSet, go ahead and notify about whatever stylesheets
|
|
|
|
// we have so far.
|
2017-05-12 22:04:55 +03:00
|
|
|
for (auto& sheetArray : mSheets) {
|
|
|
|
for (auto& sheet : sheetArray) {
|
2017-01-04 22:52:26 +03:00
|
|
|
// There's no guarantee this will create a list on the servo side whose
|
|
|
|
// ordering matches the list that would have been created had all those
|
2017-05-02 02:46:41 +03:00
|
|
|
// sheets been appended/prepended/etc after we had mRawSet. That's okay
|
|
|
|
// because Servo only needs to maintain relative ordering within a sheet
|
|
|
|
// type, which this preserves.
|
|
|
|
|
2017-06-29 04:07:06 +03:00
|
|
|
MOZ_ASSERT(sheet->RawContents(),
|
|
|
|
"We should only append non-null raw sheets.");
|
|
|
|
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), sheet);
|
2017-01-04 22:52:26 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-08 15:41:32 +03:00
|
|
|
// We added prefilled stylesheets into mRawSet, so the stylist is dirty.
|
|
|
|
// The Stylist should be updated later when necessary.
|
|
|
|
SetStylistStyleSheetsDirty();
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ServoStyleSet::BeginShutdown()
|
|
|
|
{
|
2017-03-18 09:15:09 +03:00
|
|
|
nsIDocument* doc = mPresContext->Document();
|
|
|
|
|
2017-06-19 08:45:43 +03:00
|
|
|
// Remove the style rule map from document's observer and drop it.
|
|
|
|
if (mStyleRuleMap) {
|
|
|
|
doc->RemoveObserver(mStyleRuleMap);
|
|
|
|
doc->CSSLoader()->RemoveObserver(mStyleRuleMap);
|
|
|
|
mStyleRuleMap = nullptr;
|
|
|
|
}
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ServoStyleSet::Shutdown()
|
|
|
|
{
|
2017-03-08 08:18:39 +03:00
|
|
|
// Make sure we drop our cached style contexts before the presshell arena
|
|
|
|
// starts going away.
|
|
|
|
ClearNonInheritingStyleContexts();
|
2016-01-27 05:02:04 +03:00
|
|
|
mRawSet = nullptr;
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2017-05-24 03:53:08 +03:00
|
|
|
void
|
|
|
|
ServoStyleSet::InvalidateStyleForCSSRuleChanges()
|
|
|
|
{
|
2017-05-25 20:50:03 +03:00
|
|
|
MOZ_ASSERT(StylistNeedsUpdate());
|
2017-05-26 18:46:31 +03:00
|
|
|
mPresContext->RestyleManager()->AsServo()->PostRestyleEventForCSSRuleChanges();
|
2017-05-24 03:53:08 +03:00
|
|
|
}
|
|
|
|
|
2017-07-24 04:27:08 +03:00
|
|
|
nsRestyleHint
|
2017-08-02 15:39:32 +03:00
|
|
|
ServoStyleSet::MediumFeaturesChanged(bool aViewportChanged)
|
2017-06-02 18:55:55 +03:00
|
|
|
{
|
2017-08-02 15:39:32 +03:00
|
|
|
bool viewportUnitsUsed = false;
|
|
|
|
const bool rulesChanged =
|
|
|
|
Servo_StyleSet_MediumFeaturesChanged(mRawSet.get(), &viewportUnitsUsed);
|
|
|
|
|
|
|
|
if (rulesChanged) {
|
|
|
|
ForceAllStyleDirty();
|
|
|
|
return eRestyle_Subtree;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (viewportUnitsUsed && aViewportChanged) {
|
|
|
|
return eRestyle_ForceDescendants;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nsRestyleHint(0);
|
2017-06-02 18:55:55 +03:00
|
|
|
}
|
|
|
|
|
2017-04-06 05:22:36 +03:00
|
|
|
size_t
|
|
|
|
ServoStyleSet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
|
|
|
{
|
|
|
|
size_t n = aMallocSizeOf(this);
|
|
|
|
|
2017-06-19 08:45:43 +03:00
|
|
|
if (mStyleRuleMap) {
|
|
|
|
n += mStyleRuleMap->SizeOfIncludingThis(aMallocSizeOf);
|
|
|
|
}
|
|
|
|
|
2017-04-06 05:22:36 +03:00
|
|
|
// Measurement of the following members may be added later if DMD finds it is
|
|
|
|
// worthwhile:
|
|
|
|
// - mRawSet
|
|
|
|
// - mSheets
|
|
|
|
// - mNonInheritingStyleContexts
|
|
|
|
//
|
|
|
|
// The following members are not measured:
|
|
|
|
// - mPresContext, because it a non-owning pointer
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2016-02-24 10:01:10 +03:00
|
|
|
bool
|
|
|
|
ServoStyleSet::GetAuthorStyleDisabled() const
|
|
|
|
{
|
2017-04-11 10:43:14 +03:00
|
|
|
return mAuthorStyleDisabled;
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
ServoStyleSet::SetAuthorStyleDisabled(bool aStyleDisabled)
|
|
|
|
{
|
2017-04-11 10:43:14 +03:00
|
|
|
if (mAuthorStyleDisabled == aStyleDisabled) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
mAuthorStyleDisabled = aStyleDisabled;
|
2017-05-25 20:50:03 +03:00
|
|
|
ForceAllStyleDirty();
|
2017-04-11 10:43:14 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ServoStyleSet::BeginUpdate()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
ServoStyleSet::EndUpdate()
|
|
|
|
{
|
2016-02-24 10:01:12 +03:00
|
|
|
return NS_OK;
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2017-07-20 19:36:20 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2016-02-24 10:01:10 +03:00
|
|
|
ServoStyleSet::ResolveStyleFor(Element* aElement,
|
2017-07-17 21:42:04 +03:00
|
|
|
ServoStyleContext* aParentContext,
|
2016-11-02 09:11:24 +03:00
|
|
|
LazyComputeBehavior aMayCompute)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2017-07-17 21:42:00 +03:00
|
|
|
RefPtr<ServoStyleContext> computedValues;
|
2016-12-28 10:49:12 +03:00
|
|
|
if (aMayCompute == LazyComputeBehavior::Allow) {
|
2017-04-12 05:05:26 +03:00
|
|
|
PreTraverseSync();
|
2017-08-04 12:26:03 +03:00
|
|
|
return ResolveStyleLazilyInternal(
|
2017-07-23 06:06:07 +03:00
|
|
|
aElement, CSSPseudoElementType::NotPseudo, nullptr, aParentContext);
|
2016-12-28 10:49:12 +03:00
|
|
|
}
|
|
|
|
|
2017-07-26 04:45:37 +03:00
|
|
|
return ResolveServoStyle(aElement, ServoTraversalFlags::Empty);
|
2016-04-29 03:56:37 +03:00
|
|
|
}
|
2016-03-18 23:14:07 +03:00
|
|
|
|
2017-08-04 12:26:04 +03:00
|
|
|
/**
|
|
|
|
* Clears any stale Servo element data that might existing in the specified
|
|
|
|
* element's document. Upon destruction, asserts that the element and all
|
|
|
|
* its ancestors still have no element data, if the document has no pres shell.
|
|
|
|
*/
|
|
|
|
class MOZ_STACK_CLASS AutoClearStaleData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit AutoClearStaleData(Element* aElement)
|
|
|
|
#ifdef DEBUG
|
|
|
|
: mElement(aElement)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
aElement->OwnerDoc()->ClearStaleServoDataFromDocument();
|
|
|
|
}
|
|
|
|
|
|
|
|
~AutoClearStaleData()
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
// Assert that the element and its ancestors are all unstyled, if the
|
|
|
|
// document has no pres shell.
|
|
|
|
if (mElement->OwnerDoc()->HasShellOrBFCacheEntry()) {
|
|
|
|
// We must check whether we're in the bfcache because its presence
|
|
|
|
// means we have a "hidden" pres shell with up-to-date data in the
|
|
|
|
// tree.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (Element* e = mElement; e; e = e->GetParentElement()) {
|
|
|
|
MOZ_ASSERT(!e->HasServoData(), "expected element to be unstyled");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
#ifdef DEBUG
|
|
|
|
Element* mElement;
|
|
|
|
#endif
|
|
|
|
};
|
2016-02-24 10:01:10 +03:00
|
|
|
|
2017-05-07 17:36:47 +03:00
|
|
|
const ServoElementSnapshotTable&
|
|
|
|
ServoStyleSet::Snapshots()
|
|
|
|
{
|
|
|
|
return mPresContext->RestyleManager()->AsServo()->Snapshots();
|
|
|
|
}
|
|
|
|
|
2017-01-20 02:56:53 +03:00
|
|
|
void
|
|
|
|
ServoStyleSet::ResolveMappedAttrDeclarationBlocks()
|
|
|
|
{
|
|
|
|
if (nsHTMLStyleSheet* sheet = mPresContext->Document()->GetAttributeStyleSheet()) {
|
2017-04-08 17:42:43 +03:00
|
|
|
sheet->CalculateMappedServoDeclarations(mPresContext);
|
2017-01-20 02:56:53 +03:00
|
|
|
}
|
2017-02-23 04:19:04 +03:00
|
|
|
|
|
|
|
mPresContext->Document()->ResolveScheduledSVGPresAttrs();
|
2017-01-20 02:56:53 +03:00
|
|
|
}
|
|
|
|
|
2017-03-08 23:20:17 +03:00
|
|
|
void
|
2017-03-17 00:10:22 +03:00
|
|
|
ServoStyleSet::PreTraverseSync()
|
2017-03-08 23:20:17 +03:00
|
|
|
{
|
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.
|
|
|
|
mozilla::Unused << mPresContext->Document()->GetRootElement();
|
|
|
|
|
2017-01-20 02:56:53 +03:00
|
|
|
ResolveMappedAttrDeclarationBlocks();
|
2017-02-02 22:48:28 +03:00
|
|
|
|
2017-04-14 04:28:25 +03:00
|
|
|
nsCSSRuleProcessor::InitSystemMetrics();
|
|
|
|
|
2017-08-03 23:16:31 +03:00
|
|
|
LookAndFeel::NativeInit();
|
|
|
|
|
2017-03-17 00:10:22 +03:00
|
|
|
// This is lazily computed and pseudo matching needs to access
|
|
|
|
// it so force computation early.
|
|
|
|
mPresContext->Document()->GetDocumentState();
|
2017-04-08 01:49:44 +03:00
|
|
|
|
2017-05-26 17:29:10 +03:00
|
|
|
if (gfxUserFontSet* userFontSet = mPresContext->Document()->GetUserFontSet()) {
|
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) {
|
|
|
|
mPresContext->DeviceContext()->UpdateFontCacheUserFonts(userFontSet);
|
|
|
|
mUserFontSetUpdateGeneration = generation;
|
|
|
|
}
|
2017-07-07 08:35:28 +03:00
|
|
|
|
2017-07-08 13:00:24 +03:00
|
|
|
// Ensure that the FontFaceSet's cached document principal is up to date.
|
|
|
|
FontFaceSet* fontFaceSet =
|
|
|
|
static_cast<FontFaceSet::UserFontSet*>(userFontSet)->GetFontFaceSet();
|
|
|
|
fontFaceSet->UpdateStandardFontLoadPrincipal();
|
|
|
|
bool principalChanged = fontFaceSet->HasStandardFontLoadPrincipalChanged();
|
|
|
|
|
2017-07-07 08:35:28 +03:00
|
|
|
// Ensure that the user font cache holds up-to-date data on whether
|
|
|
|
// our font set is allowed to re-use fonts from the cache.
|
|
|
|
uint32_t cacheGeneration = gfxUserFontSet::UserFontCache::Generation();
|
2017-07-08 13:00:24 +03:00
|
|
|
if (principalChanged) {
|
|
|
|
gfxUserFontSet::UserFontCache::ClearAllowedFontSets(userFontSet);
|
|
|
|
}
|
|
|
|
if (cacheGeneration != mUserFontCacheUpdateGeneration || principalChanged) {
|
2017-07-07 08:35:28 +03:00
|
|
|
gfxUserFontSet::UserFontCache::UpdateAllowedFontSets(userFontSet);
|
|
|
|
mUserFontCacheUpdateGeneration = cacheGeneration;
|
|
|
|
}
|
2017-05-26 17:29:10 +03:00
|
|
|
}
|
2017-05-15 19:02:59 +03:00
|
|
|
|
|
|
|
UpdateStylistIfNeeded();
|
2017-05-20 22:47:36 +03:00
|
|
|
mPresContext->CacheAllLangs();
|
2017-03-17 00:10:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-05-19 11:16:41 +03:00
|
|
|
ServoStyleSet::PreTraverse(Element* aRoot,
|
|
|
|
EffectCompositor::AnimationRestyleType aRestyleType)
|
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.
|
2017-04-26 07:00:11 +03:00
|
|
|
nsSMILAnimationController* smilController =
|
|
|
|
mPresContext->Document()->GetAnimationController();
|
2017-04-04 14:34:30 +03:00
|
|
|
if (aRoot) {
|
2017-05-19 11:16:41 +03:00
|
|
|
mPresContext->EffectCompositor()
|
|
|
|
->PreTraverseInSubtree(aRoot, aRestyleType);
|
2017-04-26 07:00:11 +03:00
|
|
|
if (smilController) {
|
|
|
|
smilController->PreTraverseInSubtree(aRoot);
|
|
|
|
}
|
2017-04-04 14:34:30 +03:00
|
|
|
} else {
|
2017-05-19 11:16:41 +03:00
|
|
|
mPresContext->EffectCompositor()->PreTraverse(aRestyleType);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2017-05-07 17:36:47 +03:00
|
|
|
ServoStyleSet::PrepareAndTraverseSubtree(
|
|
|
|
RawGeckoElementBorrowed aRoot,
|
2017-07-26 04:45:37 +03:00
|
|
|
ServoTraversalFlags aFlags)
|
2017-03-08 23:20:17 +03:00
|
|
|
{
|
2017-07-26 20:43:48 +03:00
|
|
|
MOZ_ASSERT(MayTraverseFrom(const_cast<Element*>(aRoot)));
|
2017-08-10 20:58:40 +03:00
|
|
|
AutoPrepareTraversal guard(this);
|
2017-05-07 17:36:47 +03:00
|
|
|
const SnapshotTable& snapshots = Snapshots();
|
|
|
|
|
2017-03-24 01:21:18 +03:00
|
|
|
bool isInitial = !aRoot->HasServoData();
|
2017-07-27 02:57:13 +03:00
|
|
|
bool forReconstruct = !!(aFlags & ServoTraversalFlags::AggressivelyForgetful);
|
2017-07-26 04:45:37 +03:00
|
|
|
bool postTraversalRequired =
|
|
|
|
Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, aFlags);
|
2017-07-26 20:43:48 +03:00
|
|
|
MOZ_ASSERT(!(isInitial || forReconstruct) || !postTraversalRequired);
|
2017-04-04 14:34:30 +03:00
|
|
|
|
2017-07-15 07:08:47 +03:00
|
|
|
// We don't need to trigger a second traversal if this restyle only for
|
|
|
|
// flushing throttled animations. That's because the first traversal only
|
|
|
|
// performs the animation-only restyle, skipping the normal restyle, and so
|
|
|
|
// will not generate any SequentialTask that could update animation state
|
|
|
|
// requiring a subsequent traversal.
|
2017-08-11 02:44:11 +03:00
|
|
|
if (aFlags & ServoTraversalFlags::AnimationOnly) {
|
2017-05-19 11:16:41 +03:00
|
|
|
return postTraversalRequired;
|
|
|
|
}
|
|
|
|
|
2017-04-04 14:34:30 +03:00
|
|
|
auto root = const_cast<Element*>(aRoot);
|
2017-03-10 05:53:19 +03:00
|
|
|
|
|
|
|
// If there are still animation restyles needed, trigger a second traversal to
|
2017-04-17 09:22:28 +03:00
|
|
|
// update CSS animations or transitions' styles.
|
2017-04-26 07:00:11 +03:00
|
|
|
//
|
|
|
|
// 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.
|
2017-04-04 14:34:30 +03:00
|
|
|
EffectCompositor* compositor = mPresContext->EffectCompositor();
|
2017-05-19 11:16:41 +03:00
|
|
|
EffectCompositor::AnimationRestyleType restyleType =
|
|
|
|
EffectCompositor::AnimationRestyleType::Throttled;
|
|
|
|
if (forReconstruct ? compositor->PreTraverseInSubtree(root, restyleType)
|
|
|
|
: compositor->PreTraverse(restyleType)) {
|
2017-07-28 08:51:27 +03:00
|
|
|
if (isInitial) {
|
|
|
|
// We're doing initial styling, and the additional animation
|
|
|
|
// traversal will change the styles that were set by the first traversal.
|
|
|
|
// This would normally require a post-traversal to update the style
|
|
|
|
// contexts, but since this is actually the initial styling, there are
|
|
|
|
// no style contexts to update and no frames to apply the change hints to,
|
|
|
|
// so we just do a forgetful traversal and clear the flags on the way.
|
|
|
|
aFlags |= ServoTraversalFlags::Forgetful |
|
|
|
|
ServoTraversalFlags::ClearAnimationOnlyDirtyDescendants;
|
2017-03-24 01:21:18 +03:00
|
|
|
}
|
2017-07-28 08:51:27 +03:00
|
|
|
|
|
|
|
postTraversalRequired =
|
|
|
|
Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, aFlags);
|
|
|
|
MOZ_ASSERT_IF(isInitial || forReconstruct, !postTraversalRequired);
|
2017-03-10 05:53:19 +03:00
|
|
|
}
|
|
|
|
|
2017-02-10 05:42:30 +03:00
|
|
|
return postTraversalRequired;
|
2017-01-20 02:56:53 +03:00
|
|
|
}
|
|
|
|
|
2017-08-05 00:34:18 +03:00
|
|
|
static inline already_AddRefed<ServoStyleContext>
|
|
|
|
ResolveStyleForTextOrFirstLetterContinuation(
|
|
|
|
RawServoStyleSetBorrowed aStyleSet,
|
|
|
|
ServoStyleContext& aParent,
|
|
|
|
nsIAtom* aAnonBox)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aAnonBox == nsCSSAnonBoxes::mozText ||
|
|
|
|
aAnonBox == nsCSSAnonBoxes::firstLetterContinuation);
|
|
|
|
auto inheritTarget = aAnonBox == nsCSSAnonBoxes::mozText
|
|
|
|
? InheritTarget::Text
|
|
|
|
: InheritTarget::FirstLetterContinuation;
|
|
|
|
|
|
|
|
RefPtr<ServoStyleContext> style =
|
|
|
|
aParent.GetCachedInheritingAnonBoxStyle(aAnonBox);
|
|
|
|
if (!style) {
|
|
|
|
style = Servo_ComputedValues_Inherit(aStyleSet,
|
|
|
|
aAnonBox,
|
|
|
|
&aParent,
|
|
|
|
inheritTarget).Consume();
|
|
|
|
MOZ_ASSERT(style);
|
2017-08-06 19:42:55 +03:00
|
|
|
aParent.SetCachedInheritedAnonBoxStyle(aAnonBox, style);
|
2017-08-05 00:34:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return style.forget();
|
|
|
|
}
|
|
|
|
|
2017-07-20 19:36:20 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2016-04-29 07:01:44 +03:00
|
|
|
ServoStyleSet::ResolveStyleForText(nsIContent* aTextNode,
|
2017-07-17 21:42:04 +03:00
|
|
|
ServoStyleContext* aParentContext)
|
2016-04-29 07:01:44 +03:00
|
|
|
{
|
2016-04-29 07:04:16 +03:00
|
|
|
MOZ_ASSERT(aTextNode && aTextNode->IsNodeOfType(nsINode::eTEXT));
|
2016-08-12 21:30:29 +03:00
|
|
|
MOZ_ASSERT(aTextNode->GetParent());
|
2016-10-26 02:27:08 +03:00
|
|
|
MOZ_ASSERT(aParentContext);
|
|
|
|
|
2017-08-05 00:34:18 +03:00
|
|
|
return ResolveStyleForTextOrFirstLetterContinuation(
|
|
|
|
mRawSet.get(), *aParentContext, nsCSSAnonBoxes::mozText);
|
2016-04-29 07:01:44 +03:00
|
|
|
}
|
|
|
|
|
2017-07-20 19:36:20 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2017-07-17 21:42:04 +03:00
|
|
|
ServoStyleSet::ResolveStyleForFirstLetterContinuation(ServoStyleContext* aParentContext)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2017-08-05 00:34:18 +03:00
|
|
|
MOZ_ASSERT(aParentContext);
|
|
|
|
|
|
|
|
return ResolveStyleForTextOrFirstLetterContinuation(
|
|
|
|
mRawSet.get(), *aParentContext, nsCSSAnonBoxes::firstLetterContinuation);
|
2017-03-08 08:18:32 +03:00
|
|
|
}
|
|
|
|
|
2017-07-20 19:36:20 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2017-03-08 08:18:40 +03:00
|
|
|
ServoStyleSet::ResolveStyleForPlaceholder()
|
2017-03-08 08:18:32 +03:00
|
|
|
{
|
2017-07-20 19:36:20 +03:00
|
|
|
RefPtr<ServoStyleContext>& cache =
|
2017-03-09 07:39:45 +03:00
|
|
|
mNonInheritingStyleContexts[nsCSSAnonBoxes::NonInheriting::oofPlaceholder];
|
2017-03-08 08:18:40 +03:00
|
|
|
if (cache) {
|
2017-07-20 19:36:20 +03:00
|
|
|
RefPtr<ServoStyleContext> retval = cache;
|
2017-03-08 08:18:40 +03:00
|
|
|
return retval.forget();
|
|
|
|
}
|
|
|
|
|
2017-07-17 21:42:00 +03:00
|
|
|
RefPtr<ServoStyleContext> computedValues =
|
2017-04-28 14:10:00 +03:00
|
|
|
Servo_ComputedValues_Inherit(mRawSet.get(),
|
2017-07-17 21:42:00 +03:00
|
|
|
nsCSSAnonBoxes::oofPlaceholder,
|
2017-04-28 14:10:00 +03:00
|
|
|
nullptr,
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2017-07-20 19:36:20 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2016-12-22 04:58:38 +03:00
|
|
|
ServoStyleSet::ResolvePseudoElementStyle(Element* aOriginatingElement,
|
2016-02-24 10:01:10 +03:00
|
|
|
CSSPseudoElementType aType,
|
2017-07-17 21:42:04 +03:00
|
|
|
ServoStyleContext* aParentContext,
|
2016-02-24 10:01:10 +03:00
|
|
|
Element* aPseudoElement)
|
|
|
|
{
|
2017-05-15 19:02:59 +03:00
|
|
|
UpdateStylistIfNeeded();
|
2017-05-10 20:13:39 +03:00
|
|
|
|
2016-04-29 03:56:37 +03:00
|
|
|
MOZ_ASSERT(aType < CSSPseudoElementType::Count);
|
|
|
|
|
2017-07-17 21:42:00 +03:00
|
|
|
RefPtr<ServoStyleContext> computedValues;
|
|
|
|
|
2017-05-13 20:29:14 +03:00
|
|
|
if (aPseudoElement) {
|
|
|
|
MOZ_ASSERT(aType == aPseudoElement->GetPseudoElementType());
|
2017-07-18 14:56:15 +03:00
|
|
|
computedValues =
|
|
|
|
Servo_ResolveStyle(aPseudoElement,
|
|
|
|
mRawSet.get(),
|
2017-07-26 04:45:37 +03:00
|
|
|
ServoTraversalFlags::Empty).Consume();
|
2017-05-13 20:29:14 +03:00
|
|
|
} else {
|
2017-08-06 19:42:55 +03:00
|
|
|
bool cacheable =
|
|
|
|
!nsCSSPseudoElements::IsEagerlyCascadedInServo(aType) && aParentContext;
|
2017-05-13 20:29:14 +03:00
|
|
|
computedValues =
|
2017-08-06 19:42:55 +03:00
|
|
|
cacheable ? aParentContext->GetCachedLazyPseudoStyle(aType) : nullptr;
|
|
|
|
|
|
|
|
if (!computedValues) {
|
|
|
|
computedValues = Servo_ResolvePseudoStyle(aOriginatingElement,
|
|
|
|
aType,
|
|
|
|
/* is_probe = */ false,
|
|
|
|
aParentContext,
|
|
|
|
mRawSet.get()).Consume();
|
|
|
|
if (cacheable) {
|
|
|
|
aParentContext->SetCachedLazyPseudoStyle(computedValues);
|
|
|
|
}
|
|
|
|
}
|
2017-05-13 20:29:14 +03:00
|
|
|
}
|
|
|
|
|
2016-04-29 03:56:37 +03:00
|
|
|
MOZ_ASSERT(computedValues);
|
2017-07-17 21:42:24 +03:00
|
|
|
return computedValues.forget();
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2017-07-20 19:36:20 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2017-08-04 12:26:03 +03:00
|
|
|
ServoStyleSet::ResolveStyleLazily(Element* aElement,
|
|
|
|
CSSPseudoElementType aPseudoType,
|
|
|
|
nsIAtom* aPseudoTag,
|
|
|
|
StyleRuleInclusion aRuleInclusion)
|
2017-04-15 01:37:34 +03:00
|
|
|
{
|
2017-08-04 12:26:04 +03:00
|
|
|
// Lazy style computation avoids storing any new data in the tree.
|
|
|
|
// If the tree has stale data in it, then the AutoClearStaleData below
|
|
|
|
// will ensure it's cleared so we don't use it. But if the document is
|
|
|
|
// in the bfcache, then we will have valid, usable data in the tree,
|
|
|
|
// but we don't want to use it. Instead we want to pretend as if the
|
|
|
|
// document has no pres shell and no styles.
|
|
|
|
//
|
|
|
|
// If we don't do this, then we can very easily mix styles from different
|
|
|
|
// style sets in the tree. For example, calling getComputedStyle on an
|
|
|
|
// element in a display:none iframe (which has no pres shell) will use the
|
|
|
|
// caller's style set for any styling. If we allowed this to re-use any
|
|
|
|
// existing styles in the DOM, then we would do selector matching on the
|
|
|
|
// undisplayed element with the caller's style set's rules, but inherit from
|
|
|
|
// values that were computed with the style set from the target element's
|
|
|
|
// hidden-by-the-bfcache-entry pres shell.
|
|
|
|
bool ignoreExistingStyles = aElement->OwnerDoc()->GetBFCacheEntry();
|
|
|
|
|
|
|
|
AutoClearStaleData guard(aElement);
|
2017-04-15 01:37:34 +03:00
|
|
|
PreTraverseSync();
|
2017-08-04 12:26:03 +03:00
|
|
|
return ResolveStyleLazilyInternal(aElement, aPseudoType, aPseudoTag,
|
2017-08-04 12:26:04 +03:00
|
|
|
nullptr, aRuleInclusion,
|
|
|
|
ignoreExistingStyles);
|
2016-12-28 10:49:12 +03:00
|
|
|
}
|
|
|
|
|
2017-06-28 04:34:06 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2017-03-09 07:50:28 +03:00
|
|
|
ServoStyleSet::ResolveInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag,
|
2017-07-17 21:42:04 +03:00
|
|
|
ServoStyleContext* aParentContext)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2017-03-09 07:41:04 +03:00
|
|
|
MOZ_ASSERT(nsCSSAnonBoxes::IsAnonBox(aPseudoTag) &&
|
|
|
|
!nsCSSAnonBoxes::IsNonInheritingAnonBox(aPseudoTag));
|
2017-08-05 00:34:18 +03:00
|
|
|
RefPtr<ServoStyleContext> style = nullptr;
|
|
|
|
|
|
|
|
if (aParentContext) {
|
|
|
|
style = aParentContext->GetCachedInheritingAnonBoxStyle(aPseudoTag);
|
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) {
|
2017-08-08 15:54:13 +03:00
|
|
|
// People like to call into here from random attribute notifications (see
|
|
|
|
// bug 1388234, and bug 1389029).
|
|
|
|
//
|
|
|
|
// We may get a wrong cached style if the stylist needs an update, but we'll
|
|
|
|
// have a whole restyle scheduled anyway.
|
|
|
|
UpdateStylistIfNeeded();
|
|
|
|
|
2017-08-05 00:34:18 +03:00
|
|
|
style =
|
|
|
|
Servo_ComputedValues_GetForAnonymousBox(aParentContext,
|
|
|
|
aPseudoTag,
|
|
|
|
mRawSet.get()).Consume();
|
|
|
|
MOZ_ASSERT(style);
|
|
|
|
if (aParentContext) {
|
2017-08-06 19:42:55 +03:00
|
|
|
aParentContext->SetCachedInheritedAnonBoxStyle(aPseudoTag, style);
|
2017-08-05 00:34:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return style.forget();
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2017-07-20 19:36:20 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2017-03-09 07:41:04 +03:00
|
|
|
ServoStyleSet::ResolveNonInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(nsCSSAnonBoxes::IsAnonBox(aPseudoTag) &&
|
|
|
|
nsCSSAnonBoxes::IsNonInheritingAnonBox(aPseudoTag));
|
|
|
|
MOZ_ASSERT(aPseudoTag != nsCSSAnonBoxes::pageContent,
|
|
|
|
"If nsCSSAnonBoxes::pageContent ends up non-inheriting, check "
|
|
|
|
"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 =
|
|
|
|
nsCSSAnonBoxes::NonInheritingTypeForPseudoTag(aPseudoTag);
|
2017-07-20 19:36:20 +03:00
|
|
|
RefPtr<ServoStyleContext>& cache = mNonInheritingStyleContexts[type];
|
2017-03-09 07:41:04 +03:00
|
|
|
if (cache) {
|
2017-07-20 19:36:20 +03:00
|
|
|
RefPtr<ServoStyleContext> 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.)
|
2017-03-13 19:53:45 +03:00
|
|
|
MOZ_ASSERT(!nsCSSAnonBoxes::IsNonInheritingAnonBox(nsCSSAnonBoxes::viewport),
|
|
|
|
"viewport needs fixup to handle blockifying it");
|
2017-07-17 21:42:00 +03:00
|
|
|
RefPtr<ServoStyleContext> computedValues =
|
2017-07-18 15:29:12 +03:00
|
|
|
Servo_ComputedValues_GetForAnonymousBox(nullptr,
|
2017-07-17 21:42:00 +03:00
|
|
|
aPseudoTag,
|
2017-03-09 07:41:04 +03:00
|
|
|
mRawSet.get()).Consume();
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (!computedValues) {
|
|
|
|
nsString pseudo;
|
|
|
|
aPseudoTag->ToString(pseudo);
|
|
|
|
NS_ERROR(nsPrintfCString("stylo: could not get anon-box: %s",
|
|
|
|
NS_ConvertUTF16toUTF8(pseudo).get()).get());
|
|
|
|
MOZ_CRASH();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-07-17 21:42:24 +03:00
|
|
|
cache = computedValues;
|
|
|
|
return computedValues.forget();
|
2017-03-09 07:41:04 +03:00
|
|
|
}
|
|
|
|
|
2016-02-24 10:01:10 +03:00
|
|
|
// manage the set of style sheets in the style set
|
|
|
|
nsresult
|
|
|
|
ServoStyleSet::AppendStyleSheet(SheetType aType,
|
2016-02-24 10:01:12 +03:00
|
|
|
ServoStyleSheet* aSheet)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2016-02-26 04:51:02 +03:00
|
|
|
MOZ_ASSERT(aSheet);
|
|
|
|
MOZ_ASSERT(aSheet->IsApplicable());
|
|
|
|
MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
|
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
|
|
|
|
2017-05-12 22:04:55 +03:00
|
|
|
RemoveSheetOfType(aType, aSheet);
|
|
|
|
AppendSheetOfType(aType, aSheet);
|
2016-02-26 04:51:02 +03:00
|
|
|
|
2017-01-04 22:52:26 +03:00
|
|
|
if (mRawSet) {
|
|
|
|
// Maintain a mirrored list of sheets on the servo side.
|
2017-05-12 22:04:55 +03:00
|
|
|
// Servo will remove aSheet from its original position as part of the call
|
|
|
|
// to Servo_StyleSet_AppendStyleSheet.
|
2017-06-29 04:07:06 +03:00
|
|
|
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), aSheet);
|
2017-05-15 19:02:59 +03:00
|
|
|
SetStylistStyleSheetsDirty();
|
2017-01-04 22:52:26 +03:00
|
|
|
}
|
2016-02-26 05:57:42 +03:00
|
|
|
|
2016-02-26 04:51:02 +03:00
|
|
|
return NS_OK;
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
ServoStyleSet::PrependStyleSheet(SheetType aType,
|
2016-02-24 10:01:12 +03:00
|
|
|
ServoStyleSheet* aSheet)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2016-02-26 04:51:02 +03:00
|
|
|
MOZ_ASSERT(aSheet);
|
|
|
|
MOZ_ASSERT(aSheet->IsApplicable());
|
|
|
|
MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
|
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
|
|
|
|
2017-05-12 22:04:55 +03:00
|
|
|
RemoveSheetOfType(aType, aSheet);
|
|
|
|
PrependSheetOfType(aType, aSheet);
|
2016-02-26 04:51:02 +03:00
|
|
|
|
2017-01-04 22:52:26 +03:00
|
|
|
if (mRawSet) {
|
|
|
|
// Maintain a mirrored list of sheets on the servo side.
|
2017-05-12 22:04:55 +03:00
|
|
|
// Servo will remove aSheet from its original position as part of the call
|
|
|
|
// to Servo_StyleSet_PrependStyleSheet.
|
2017-06-29 04:07:06 +03:00
|
|
|
Servo_StyleSet_PrependStyleSheet(mRawSet.get(), aSheet);
|
2017-05-15 19:02:59 +03:00
|
|
|
SetStylistStyleSheetsDirty();
|
2017-01-04 22:52:26 +03:00
|
|
|
}
|
2016-02-26 05:57:42 +03:00
|
|
|
|
2016-02-26 04:51:02 +03:00
|
|
|
return NS_OK;
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
ServoStyleSet::RemoveStyleSheet(SheetType aType,
|
2016-02-24 10:01:12 +03:00
|
|
|
ServoStyleSheet* aSheet)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2016-02-26 05:57:42 +03:00
|
|
|
MOZ_ASSERT(aSheet);
|
|
|
|
MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
|
|
|
|
|
2017-05-12 22:04:55 +03:00
|
|
|
RemoveSheetOfType(aType, aSheet);
|
|
|
|
if (mRawSet) {
|
2017-01-04 22:52:26 +03:00
|
|
|
// Maintain a mirrored list of sheets on the servo side.
|
2017-06-29 04:07:06 +03:00
|
|
|
Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), aSheet);
|
2017-05-15 19:02:59 +03:00
|
|
|
SetStylistStyleSheetsDirty();
|
2017-01-04 22:52:26 +03:00
|
|
|
}
|
2016-02-26 05:57:42 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
ServoStyleSet::ReplaceSheets(SheetType aType,
|
2016-02-24 10:01:12 +03:00
|
|
|
const nsTArray<RefPtr<ServoStyleSheet>>& aNewSheets)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2016-08-03 07:08:01 +03:00
|
|
|
// Gecko uses a two-dimensional array keyed by sheet type, whereas Servo
|
|
|
|
// stores a flattened list. This makes ReplaceSheets a pretty clunky thing
|
|
|
|
// to express. If the need ever arises, we can easily make this more efficent,
|
|
|
|
// probably by aligning the representations better between engines.
|
|
|
|
|
2017-05-15 19:02:59 +03:00
|
|
|
SetStylistStyleSheetsDirty();
|
2017-05-10 20:13:39 +03:00
|
|
|
|
2017-05-02 02:46:41 +03:00
|
|
|
// Remove all the existing sheets first.
|
2017-05-24 03:02:51 +03:00
|
|
|
for (const auto& sheet : mSheets[aType]) {
|
|
|
|
sheet->DropStyleSet(this);
|
|
|
|
if (mRawSet) {
|
2017-06-29 04:07:06 +03:00
|
|
|
Servo_StyleSet_RemoveStyleSheet(mRawSet.get(), sheet);
|
2017-01-04 22:52:26 +03:00
|
|
|
}
|
2016-08-03 07:08:01 +03:00
|
|
|
}
|
2017-05-12 22:04:55 +03:00
|
|
|
mSheets[aType].Clear();
|
2016-08-03 07:08:01 +03:00
|
|
|
|
2017-05-02 02:46:41 +03:00
|
|
|
// Add in all the new sheets.
|
|
|
|
for (auto& sheet : aNewSheets) {
|
2017-05-12 22:04:55 +03:00
|
|
|
AppendSheetOfType(aType, sheet);
|
2017-05-02 02:46:41 +03:00
|
|
|
if (mRawSet) {
|
2017-06-29 04:07:06 +03:00
|
|
|
MOZ_ASSERT(sheet->RawContents(), "Raw sheet should be in place before replacement.");
|
|
|
|
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), sheet);
|
2017-01-04 22:52:26 +03:00
|
|
|
}
|
2016-12-22 02:33:24 +03:00
|
|
|
}
|
|
|
|
|
2016-08-03 07:08:01 +03:00
|
|
|
return NS_OK;
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
ServoStyleSet::InsertStyleSheetBefore(SheetType aType,
|
2016-02-24 10:01:12 +03:00
|
|
|
ServoStyleSheet* aNewSheet,
|
|
|
|
ServoStyleSheet* aReferenceSheet)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
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.
|
|
|
|
RemoveSheetOfType(aType, aNewSheet);
|
|
|
|
InsertSheetOfType(aType, aNewSheet, aReferenceSheet);
|
2016-04-29 07:01:44 +03:00
|
|
|
|
2017-01-04 22:52:26 +03:00
|
|
|
if (mRawSet) {
|
|
|
|
// Maintain a mirrored list of sheets on the servo side.
|
2017-06-29 04:07:06 +03:00
|
|
|
Servo_StyleSet_InsertStyleSheetBefore(
|
|
|
|
mRawSet.get(), aNewSheet, aReferenceSheet);
|
2017-05-15 19:02:59 +03:00
|
|
|
SetStylistStyleSheetsDirty();
|
2017-01-04 22:52:26 +03:00
|
|
|
}
|
2016-04-29 07:01:44 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-19 20:47:13 +03:00
|
|
|
void
|
|
|
|
ServoStyleSet::UpdateStyleSheet(ServoStyleSheet* aSheet)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aSheet);
|
2017-06-29 04:07:06 +03:00
|
|
|
// TODO(emilio): Get rid of this.
|
2017-06-19 20:47:13 +03:00
|
|
|
}
|
|
|
|
|
2016-02-24 10:01:10 +03:00
|
|
|
int32_t
|
|
|
|
ServoStyleSet::SheetCount(SheetType aType) const
|
|
|
|
{
|
2016-02-26 04:51:02 +03:00
|
|
|
MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
|
2017-05-12 22:04:55 +03:00
|
|
|
return mSheets[aType].Length();
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2016-02-24 10:01:12 +03:00
|
|
|
ServoStyleSheet*
|
2017-06-29 04:07:06 +03:00
|
|
|
ServoStyleSet::StyleSheetAt(SheetType aType, int32_t aIndex) const
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2016-02-26 04:51:02 +03:00
|
|
|
MOZ_ASSERT(nsStyleSet::IsCSSSheetType(aType));
|
2017-05-12 22:04:55 +03:00
|
|
|
return mSheets[aType][aIndex];
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2017-06-30 02:09:22 +03:00
|
|
|
void
|
|
|
|
ServoStyleSet::AppendAllXBLStyleSheets(nsTArray<StyleSheet*>& aArray) const
|
|
|
|
{
|
|
|
|
if (mBindingManager) {
|
|
|
|
mBindingManager->AppendAllSheets(aArray);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-24 10:01:10 +03:00
|
|
|
nsresult
|
2016-02-24 10:01:12 +03:00
|
|
|
ServoStyleSet::RemoveDocStyleSheet(ServoStyleSheet* aSheet)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2016-04-29 07:01:44 +03:00
|
|
|
return RemoveStyleSheet(SheetType::Doc, aSheet);
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2016-02-24 10:01:12 +03:00
|
|
|
ServoStyleSet::AddDocStyleSheet(ServoStyleSheet* aSheet,
|
2016-02-24 10:01:10 +03:00
|
|
|
nsIDocument* aDocument)
|
|
|
|
{
|
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
|
|
|
|
2017-05-12 22:04:55 +03:00
|
|
|
RemoveSheetOfType(SheetType::Doc, aSheet);
|
2016-04-29 07:01:44 +03:00
|
|
|
|
|
|
|
size_t index =
|
2017-05-12 22:04:55 +03:00
|
|
|
aDocument->FindDocStyleSheetInsertionPoint(mSheets[SheetType::Doc], aSheet);
|
2017-05-02 02:46:41 +03:00
|
|
|
|
2017-05-12 22:04:55 +03:00
|
|
|
if (index < mSheets[SheetType::Doc].Length()) {
|
2017-05-02 02:46:41 +03:00
|
|
|
// This case is insert before.
|
2017-05-12 22:04:55 +03:00
|
|
|
ServoStyleSheet *beforeSheet = mSheets[SheetType::Doc][index];
|
|
|
|
InsertSheetOfType(SheetType::Doc, aSheet, beforeSheet);
|
2017-05-02 02:46:41 +03:00
|
|
|
|
|
|
|
if (mRawSet) {
|
|
|
|
// Maintain a mirrored list of sheets on the servo side.
|
2017-06-29 04:07:06 +03:00
|
|
|
Servo_StyleSet_InsertStyleSheetBefore(mRawSet.get(), aSheet, beforeSheet);
|
2017-05-15 19:02:59 +03:00
|
|
|
SetStylistStyleSheetsDirty();
|
2017-05-02 02:46:41 +03:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// This case is append.
|
2017-05-12 22:04:55 +03:00
|
|
|
AppendSheetOfType(SheetType::Doc, aSheet);
|
2017-05-02 02:46:41 +03:00
|
|
|
|
|
|
|
if (mRawSet) {
|
|
|
|
// Maintain a mirrored list of sheets on the servo side.
|
2017-06-29 04:07:06 +03:00
|
|
|
Servo_StyleSet_AppendStyleSheet(mRawSet.get(), aSheet);
|
2017-05-15 19:02:59 +03:00
|
|
|
SetStylistStyleSheetsDirty();
|
2017-01-04 22:52:26 +03:00
|
|
|
}
|
2016-04-29 07:01:44 +03:00
|
|
|
}
|
|
|
|
|
2016-02-26 05:57:42 +03:00
|
|
|
return NS_OK;
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
2017-07-20 19:36:20 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2016-12-22 04:58:38 +03:00
|
|
|
ServoStyleSet::ProbePseudoElementStyle(Element* aOriginatingElement,
|
2016-02-24 10:01:10 +03:00
|
|
|
CSSPseudoElementType aType,
|
2017-07-17 21:42:04 +03:00
|
|
|
ServoStyleContext* aParentContext)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2017-05-15 19:02:59 +03:00
|
|
|
UpdateStylistIfNeeded();
|
2017-05-10 20:13:39 +03:00
|
|
|
|
2017-06-27 09:35:09 +03:00
|
|
|
// NB: We ignore aParentContext, 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.
|
2016-04-29 03:56:37 +03:00
|
|
|
MOZ_ASSERT(aType < CSSPseudoElementType::Count);
|
|
|
|
|
2017-08-06 19:42:55 +03:00
|
|
|
bool cacheable =
|
|
|
|
!nsCSSPseudoElements::IsEagerlyCascadedInServo(aType) && aParentContext;
|
|
|
|
|
2017-07-17 21:42:00 +03:00
|
|
|
RefPtr<ServoStyleContext> computedValues =
|
2017-08-06 19:42:55 +03:00
|
|
|
cacheable ? aParentContext->GetCachedLazyPseudoStyle(aType) : nullptr;
|
2016-04-29 03:56:37 +03:00
|
|
|
if (!computedValues) {
|
2017-08-06 19:42:55 +03:00
|
|
|
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.
|
|
|
|
aParentContext->SetCachedLazyPseudoStyle(computedValues);
|
|
|
|
}
|
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.
|
2017-05-14 19:39:22 +03:00
|
|
|
bool isBeforeOrAfter = aType == CSSPseudoElementType::before ||
|
|
|
|
aType == CSSPseudoElementType::after;
|
2017-01-29 06:59:00 +03:00
|
|
|
if (isBeforeOrAfter) {
|
2017-07-21 07:44:02 +03:00
|
|
|
const nsStyleDisplay* display = computedValues->ComputedData()->GetStyleDisplay();
|
|
|
|
const nsStyleContent* content = computedValues->ComputedData()->GetStyleContent();
|
2016-09-03 21:46:58 +03:00
|
|
|
if (display->mDisplay == StyleDisplay::None ||
|
2016-04-29 03:56:37 +03:00
|
|
|
content->ContentCount() == 0) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-17 21:42:24 +03:00
|
|
|
return computedValues.forget();
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsRestyleHint
|
|
|
|
ServoStyleSet::HasStateDependentStyle(dom::Element* aElement,
|
|
|
|
EventStates aStateMask)
|
|
|
|
{
|
2016-07-29 01:22:54 +03:00
|
|
|
NS_WARNING("stylo: HasStateDependentStyle always returns zero!");
|
2016-07-14 00:37:56 +03:00
|
|
|
return nsRestyleHint(0);
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsRestyleHint
|
|
|
|
ServoStyleSet::HasStateDependentStyle(dom::Element* aElement,
|
|
|
|
CSSPseudoElementType aPseudoType,
|
2017-07-23 06:06:07 +03:00
|
|
|
dom::Element* aPseudoElement,
|
|
|
|
EventStates aStateMask)
|
2016-02-24 10:01:10 +03:00
|
|
|
{
|
2016-07-29 01:22:54 +03:00
|
|
|
NS_WARNING("stylo: HasStateDependentStyle always returns zero!");
|
2016-07-14 00:37:56 +03:00
|
|
|
return nsRestyleHint(0);
|
2016-02-24 10:01:10 +03:00
|
|
|
}
|
2016-05-25 09:55:49 +03:00
|
|
|
|
2017-02-10 05:42:30 +03:00
|
|
|
bool
|
2017-07-26 04:45:37 +03:00
|
|
|
ServoStyleSet::StyleDocument(ServoTraversalFlags aFlags)
|
2016-08-12 00:12:49 +03:00
|
|
|
{
|
2017-07-26 20:00:28 +03:00
|
|
|
if (!!(aFlags & ServoTraversalFlags::AnimationOnly)) {
|
|
|
|
PreTraverse(nullptr, EffectCompositor::AnimationRestyleType::Full);
|
|
|
|
} else {
|
|
|
|
PreTraverse();
|
|
|
|
}
|
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;
|
2016-12-01 11:19:50 +03:00
|
|
|
DocumentStyleRootIterator iter(mPresContext->Document());
|
|
|
|
while (Element* root = iter.GetNextStyleRoot()) {
|
2017-07-26 04:45:37 +03:00
|
|
|
if (PrepareAndTraverseSubtree(root, aFlags)) {
|
2017-02-10 05:42:30 +03:00
|
|
|
postTraversalRequired = true;
|
2016-12-01 11:19:50 +03:00
|
|
|
}
|
|
|
|
}
|
2017-02-10 05:42:30 +03:00
|
|
|
return postTraversalRequired;
|
2016-08-12 00:12:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-12-11 09:11:36 +03:00
|
|
|
ServoStyleSet::StyleNewSubtree(Element* aRoot)
|
2016-08-12 00:12:49 +03:00
|
|
|
{
|
2017-07-28 08:07:58 +03:00
|
|
|
MOZ_ASSERT(!aRoot->HasServoData(), "Should have called StyleNewChildren");
|
|
|
|
PreTraverseSync();
|
2017-03-08 23:20:17 +03:00
|
|
|
|
2017-02-10 05:42:30 +03:00
|
|
|
DebugOnly<bool> postTraversalRequired =
|
2017-07-26 04:45:37 +03:00
|
|
|
PrepareAndTraverseSubtree(aRoot, ServoTraversalFlags::Empty);
|
2017-02-10 05:42:30 +03:00
|
|
|
MOZ_ASSERT(!postTraversalRequired);
|
2016-08-12 00:12:49 +03:00
|
|
|
}
|
|
|
|
|
2016-05-25 09:55:49 +03:00
|
|
|
void
|
2016-12-11 09:11:36 +03:00
|
|
|
ServoStyleSet::StyleNewChildren(Element* aParent)
|
2016-05-25 09:55:49 +03:00
|
|
|
{
|
2017-07-28 08:07:58 +03:00
|
|
|
MOZ_ASSERT(aParent->HasServoData(), "Should have called StyleNewSubtree");
|
|
|
|
PreTraverseSync();
|
2017-03-08 23:20:17 +03:00
|
|
|
|
2017-07-26 04:45:37 +03:00
|
|
|
PrepareAndTraverseSubtree(aParent, ServoTraversalFlags::UnstyledChildrenOnly);
|
2017-02-10 05:42:30 +03:00
|
|
|
// We can't assert that Servo_TraverseSubtree returns false, since aParent
|
|
|
|
// or some of its other children might have pending restyles.
|
2016-11-02 09:11:24 +03:00
|
|
|
}
|
|
|
|
|
2017-06-11 14:11:08 +03:00
|
|
|
void
|
|
|
|
ServoStyleSet::StyleNewlyBoundElement(Element* aElement)
|
|
|
|
{
|
|
|
|
// In general the element is always styled by the time we're applying XBL
|
|
|
|
// bindings, because we need to style the element to know what the binding
|
|
|
|
// URI is. However, programmatic consumers of the XBL service (like the
|
|
|
|
// XML pretty printer) _can_ apply bindings without having styled the bound
|
|
|
|
// element. We could assert against this and require the callers manually
|
|
|
|
// resolve the style first, but it's easy enough to just handle here.
|
2017-07-28 08:07:58 +03:00
|
|
|
if (MOZ_LIKELY(aElement->HasServoData())) {
|
|
|
|
StyleNewChildren(aElement);
|
|
|
|
} else {
|
|
|
|
StyleNewSubtree(aElement);
|
|
|
|
}
|
2017-06-11 14:11:08 +03:00
|
|
|
}
|
|
|
|
|
2017-04-04 14:34:30 +03:00
|
|
|
void
|
|
|
|
ServoStyleSet::StyleSubtreeForReconstruct(Element* aRoot)
|
|
|
|
{
|
|
|
|
PreTraverse(aRoot);
|
|
|
|
|
2017-07-27 02:57:13 +03:00
|
|
|
auto flags = ServoTraversalFlags::Forgetful |
|
|
|
|
ServoTraversalFlags::AggressivelyForgetful |
|
|
|
|
ServoTraversalFlags::ClearDirtyDescendants |
|
|
|
|
ServoTraversalFlags::ClearAnimationOnlyDirtyDescendants;
|
2017-04-04 14:34:30 +03:00
|
|
|
DebugOnly<bool> postTraversalRequired =
|
2017-07-27 02:57:13 +03:00
|
|
|
PrepareAndTraverseSubtree(aRoot, flags);
|
2017-04-04 14:34:30 +03:00
|
|
|
MOZ_ASSERT(!postTraversalRequired);
|
|
|
|
}
|
|
|
|
|
2016-12-19 09:30:14 +03:00
|
|
|
void
|
2017-05-25 20:50:03 +03:00
|
|
|
ServoStyleSet::ForceAllStyleDirty()
|
2016-12-19 09:30:14 +03:00
|
|
|
{
|
2017-05-15 19:02:59 +03:00
|
|
|
SetStylistStyleSheetsDirty();
|
2017-04-11 10:59:44 +03:00
|
|
|
Servo_StyleSet_NoteStyleSheetsChanged(mRawSet.get(), mAuthorStyleDisabled);
|
2016-12-19 09:30:14 +03:00
|
|
|
}
|
|
|
|
|
2017-05-25 20:50:03 +03:00
|
|
|
void
|
|
|
|
ServoStyleSet::RecordStyleSheetChange(
|
|
|
|
ServoStyleSheet* aSheet,
|
|
|
|
StyleSheet::ChangeType aChangeType)
|
|
|
|
{
|
|
|
|
SetStylistStyleSheetsDirty();
|
|
|
|
switch (aChangeType) {
|
|
|
|
case StyleSheet::ChangeType::RuleAdded:
|
|
|
|
case StyleSheet::ChangeType::RuleRemoved:
|
|
|
|
case StyleSheet::ChangeType::RuleChanged:
|
|
|
|
// FIXME(emilio): We can presumably do better in a bunch of these.
|
|
|
|
return ForceAllStyleDirty();
|
2017-05-26 18:46:31 +03:00
|
|
|
case StyleSheet::ChangeType::ApplicableStateChanged:
|
2017-05-25 20:50:03 +03:00
|
|
|
case StyleSheet::ChangeType::Added:
|
|
|
|
case StyleSheet::ChangeType::Removed:
|
2017-05-26 18:46:31 +03:00
|
|
|
// Do nothing, we've already recorded the change in the
|
|
|
|
// Append/Remove/Replace methods, etc, and will act consequently.
|
2017-05-25 20:50:03 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-02 09:11:24 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
void
|
|
|
|
ServoStyleSet::AssertTreeIsClean()
|
|
|
|
{
|
2016-12-28 11:26:10 +03:00
|
|
|
DocumentStyleRootIterator iter(mPresContext->Document());
|
|
|
|
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
|
|
|
|
2017-01-29 06:58:28 +03:00
|
|
|
bool
|
2017-05-13 10:34:38 +03:00
|
|
|
ServoStyleSet::GetKeyframesForName(const nsString& aName,
|
|
|
|
const nsTimingFunction& aTimingFunction,
|
|
|
|
nsTArray<Keyframe>& aKeyframes)
|
2017-01-29 06:58:28 +03:00
|
|
|
{
|
2017-05-15 19:02:59 +03:00
|
|
|
UpdateStylistIfNeeded();
|
2017-05-10 20:13:39 +03:00
|
|
|
|
2017-01-29 06:58:28 +03:00
|
|
|
NS_ConvertUTF16toUTF8 name(aName);
|
2017-05-13 10:34:38 +03:00
|
|
|
return Servo_StyleSet_GetKeyframesForName(mRawSet.get(),
|
|
|
|
&name,
|
|
|
|
&aTimingFunction,
|
|
|
|
&aKeyframes);
|
2017-01-29 06:58:28 +03:00
|
|
|
}
|
|
|
|
|
2017-03-11 04:40:47 +03:00
|
|
|
nsTArray<ComputedKeyframeValues>
|
2017-03-21 10:41:23 +03:00
|
|
|
ServoStyleSet::GetComputedKeyframeValuesFor(
|
|
|
|
const nsTArray<Keyframe>& aKeyframes,
|
2017-06-02 03:38:22 +03:00
|
|
|
Element* aElement,
|
2017-07-18 15:29:12 +03:00
|
|
|
const ServoStyleContext* aContext)
|
2017-03-11 04:40:47 +03:00
|
|
|
{
|
2017-08-04 12:26:04 +03:00
|
|
|
// Servo_GetComputedKeyframeValues below won't handle ignoring existing
|
|
|
|
// element data for bfcached documents. (See comment in ResolveStyleLazily
|
|
|
|
// about these bfcache issues.)
|
|
|
|
MOZ_RELEASE_ASSERT(!aElement->OwnerDoc()->GetBFCacheEntry());
|
|
|
|
|
|
|
|
AutoClearStaleData guard(aElement);
|
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,
|
2017-06-02 03:38:22 +03:00
|
|
|
aElement,
|
2017-07-18 15:29:12 +03:00
|
|
|
aContext,
|
2017-03-11 04:40:47 +03:00
|
|
|
mRawSet.get(),
|
|
|
|
&result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-06-09 00:19:37 +03:00
|
|
|
void
|
|
|
|
ServoStyleSet::GetAnimationValues(
|
|
|
|
RawServoDeclarationBlock* aDeclarations,
|
|
|
|
Element* aElement,
|
2017-07-18 15:29:12 +03:00
|
|
|
const ServoStyleContext* aStyleContext,
|
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.)
|
|
|
|
MOZ_RELEASE_ASSERT(!aElement->OwnerDoc()->GetBFCacheEntry());
|
|
|
|
|
|
|
|
AutoClearStaleData guard(aElement);
|
2017-06-09 00:19:37 +03:00
|
|
|
Servo_GetAnimationValues(aDeclarations,
|
|
|
|
aElement,
|
2017-07-18 15:29:12 +03:00
|
|
|
aStyleContext,
|
2017-06-09 00:19:37 +03:00
|
|
|
mRawSet.get(),
|
|
|
|
&aAnimationValues);
|
|
|
|
}
|
|
|
|
|
2017-07-17 21:41:44 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
|
|
|
ServoStyleSet::GetBaseContextForElement(
|
2017-07-10 14:33:21 +03:00
|
|
|
Element* aElement,
|
2017-07-17 21:42:04 +03:00
|
|
|
ServoStyleContext* aParentContext,
|
2017-07-17 21:41:44 +03:00
|
|
|
nsPresContext* aPresContext,
|
|
|
|
nsIAtom* aPseudoTag,
|
2017-07-10 14:33:21 +03:00
|
|
|
CSSPseudoElementType aPseudoType,
|
2017-07-17 21:42:00 +03:00
|
|
|
const ServoStyleContext* aStyle)
|
2017-04-06 04:34:50 +03:00
|
|
|
{
|
2017-08-04 12:26:04 +03:00
|
|
|
// Servo_StyleSet_GetBaseComputedValuesForElement below won't handle ignoring
|
|
|
|
// existing element data for bfcached documents. (See comment in
|
|
|
|
// ResolveStyleLazily about these bfcache issues.)
|
|
|
|
MOZ_RELEASE_ASSERT(!aElement->OwnerDoc()->GetBFCacheEntry(),
|
|
|
|
"GetBaseContextForElement does not support documents in the "
|
|
|
|
"bfcache");
|
|
|
|
|
|
|
|
AutoClearStaleData guard(aElement);
|
2017-07-17 21:42:00 +03:00
|
|
|
return Servo_StyleSet_GetBaseComputedValuesForElement(mRawSet.get(),
|
2017-04-06 04:34:50 +03:00
|
|
|
aElement,
|
2017-07-10 14:33:21 +03:00
|
|
|
aStyle,
|
2017-05-07 17:36:47 +03:00
|
|
|
&Snapshots(),
|
2017-05-14 19:39:22 +03:00
|
|
|
aPseudoType).Consume();
|
2017-04-06 04:34:50 +03:00
|
|
|
}
|
|
|
|
|
2017-05-03 06:15:27 +03:00
|
|
|
already_AddRefed<RawServoAnimationValue>
|
|
|
|
ServoStyleSet::ComputeAnimationValue(
|
2017-06-02 03:38:22 +03:00
|
|
|
Element* aElement,
|
2017-05-03 06:15:27 +03:00
|
|
|
RawServoDeclarationBlock* aDeclarations,
|
2017-07-18 15:29:12 +03:00
|
|
|
const ServoStyleContext* aContext)
|
2017-05-03 06:15:27 +03:00
|
|
|
{
|
2017-08-04 12:26:04 +03:00
|
|
|
// Servo_AnimationValue_Compute below won't handle ignoring existing element
|
|
|
|
// data for bfcached documents. (See comment in ResolveStyleLazily about
|
|
|
|
// these bfcache issues.)
|
|
|
|
MOZ_RELEASE_ASSERT(!aElement->OwnerDoc()->GetBFCacheEntry());
|
|
|
|
|
|
|
|
AutoClearStaleData guard(aElement);
|
2017-06-02 03:38:22 +03:00
|
|
|
return Servo_AnimationValue_Compute(aElement,
|
|
|
|
aDeclarations,
|
2017-07-18 15:29:12 +03:00
|
|
|
aContext,
|
2017-05-03 06:15:27 +03:00
|
|
|
mRawSet.get()).Consume();
|
|
|
|
}
|
|
|
|
|
2017-05-16 02:30:10 +03:00
|
|
|
bool
|
|
|
|
ServoStyleSet::EnsureUniqueInnerOnCSSSheets()
|
|
|
|
{
|
2017-05-16 03:11:08 +03:00
|
|
|
AutoTArray<StyleSheet*, 32> queue;
|
|
|
|
for (auto& entryArray : mSheets) {
|
|
|
|
for (auto& sheet : entryArray) {
|
|
|
|
queue.AppendElement(sheet);
|
|
|
|
}
|
|
|
|
}
|
2017-05-16 02:30:10 +03:00
|
|
|
// This is a stub until more of the functionality of nsStyleSet is
|
|
|
|
// replicated for Servo here.
|
|
|
|
|
2017-05-16 03:11:08 +03:00
|
|
|
// Bug 1290276 will replicate the nsStyleSet work of checking
|
|
|
|
// a nsBindingManager
|
|
|
|
|
|
|
|
while (!queue.IsEmpty()) {
|
|
|
|
uint32_t idx = queue.Length() - 1;
|
|
|
|
StyleSheet* sheet = queue[idx];
|
|
|
|
queue.RemoveElementAt(idx);
|
|
|
|
|
|
|
|
sheet->EnsureUniqueInner();
|
|
|
|
|
|
|
|
// Enqueue all the sheet's children.
|
|
|
|
sheet->AppendAllChildSheets(queue);
|
|
|
|
}
|
|
|
|
|
2017-05-16 02:30:10 +03:00
|
|
|
bool res = mNeedsRestyleAfterEnsureUniqueInner;
|
|
|
|
mNeedsRestyleAfterEnsureUniqueInner = false;
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2017-01-04 22:52:27 +03:00
|
|
|
void
|
2017-08-02 15:39:32 +03:00
|
|
|
ServoStyleSet::ClearCachedStyleData()
|
2017-01-04 22:52:27 +03:00
|
|
|
{
|
2017-03-08 08:18:39 +03:00
|
|
|
ClearNonInheritingStyleContexts();
|
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
|
|
|
|
2017-06-10 17:22:23 +03:00
|
|
|
void
|
|
|
|
ServoStyleSet::CompatibilityModeChanged()
|
|
|
|
{
|
|
|
|
Servo_StyleSet_CompatModeChanged(mRawSet.get());
|
|
|
|
}
|
|
|
|
|
2017-07-23 06:06:07 +03:00
|
|
|
inline static void
|
|
|
|
UpdateBodyTextColorIfNeeded(
|
|
|
|
const Element& aElement,
|
|
|
|
ServoStyleContext& aStyleContext,
|
|
|
|
nsPresContext& aPresContext)
|
|
|
|
{
|
|
|
|
if (aPresContext.CompatibilityMode() != eCompatibility_NavQuirks) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aElement.IsHTMLElement(nsGkAtoms::body)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsIDocument* doc = aElement.GetUncomposedDoc();
|
|
|
|
if (!doc || doc->GetBodyElement() != &aElement) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_ASSERT(!aStyleContext.GetPseudo());
|
|
|
|
|
|
|
|
// NOTE(emilio): We do the ComputedData() dance to avoid triggering the
|
|
|
|
// IsInServoTraversal() assertion in StyleColor(), which seems useful enough
|
|
|
|
// in the general case, I guess...
|
|
|
|
aPresContext.SetBodyTextColor(
|
|
|
|
aStyleContext.ComputedData()->GetStyleColor()->mColor);
|
|
|
|
}
|
|
|
|
|
2017-07-17 21:42:00 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2017-07-26 04:45:37 +03:00
|
|
|
ServoStyleSet::ResolveServoStyle(Element* aElement, ServoTraversalFlags aFlags)
|
2017-01-04 22:52:27 +03:00
|
|
|
{
|
2017-05-15 19:02:59 +03:00
|
|
|
UpdateStylistIfNeeded();
|
2017-07-23 06:06:07 +03:00
|
|
|
RefPtr<ServoStyleContext> result =
|
|
|
|
Servo_ResolveStyle(aElement,
|
|
|
|
mRawSet.get(),
|
2017-07-26 04:45:37 +03:00
|
|
|
aFlags).Consume();
|
2017-07-23 06:06:07 +03:00
|
|
|
UpdateBodyTextColorIfNeeded(*aElement, *result, *mPresContext);
|
|
|
|
return result.forget();
|
2017-01-04 22:52:27 +03:00
|
|
|
}
|
2017-02-02 22:48:28 +03:00
|
|
|
|
2017-03-08 08:18:39 +03:00
|
|
|
void
|
|
|
|
ServoStyleSet::ClearNonInheritingStyleContexts()
|
|
|
|
{
|
2017-07-20 19:36:20 +03:00
|
|
|
for (RefPtr<ServoStyleContext>& ptr : mNonInheritingStyleContexts) {
|
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
|
|
|
}
|
|
|
|
|
2017-07-17 21:42:00 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2017-08-04 12:26:03 +03:00
|
|
|
ServoStyleSet::ResolveStyleLazilyInternal(Element* aElement,
|
|
|
|
CSSPseudoElementType aPseudoType,
|
|
|
|
nsIAtom* aPseudoTag,
|
|
|
|
const ServoStyleContext* aParentContext,
|
2017-08-04 12:26:04 +03:00
|
|
|
StyleRuleInclusion aRuleInclusion,
|
|
|
|
bool aIgnoreExistingStyles)
|
2017-03-08 23:20:17 +03:00
|
|
|
{
|
2017-05-14 19:39:22 +03:00
|
|
|
mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoType);
|
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.
|
|
|
|
*/
|
|
|
|
Element* elementForStyleResolution = aElement;
|
2017-05-14 19:39:22 +03:00
|
|
|
CSSPseudoElementType pseudoTypeForStyleResolution = aPseudoType;
|
|
|
|
if (aPseudoType == CSSPseudoElementType::before) {
|
2017-04-26 15:01:25 +03:00
|
|
|
if (Element* pseudo = nsLayoutUtils::GetBeforePseudo(aElement)) {
|
|
|
|
elementForStyleResolution = pseudo;
|
2017-05-14 19:39:22 +03:00
|
|
|
pseudoTypeForStyleResolution = CSSPseudoElementType::NotPseudo;
|
2017-04-26 15:01:25 +03:00
|
|
|
}
|
2017-05-14 19:39:22 +03:00
|
|
|
} else if (aPseudoType == CSSPseudoElementType::after) {
|
2017-04-26 15:01:25 +03:00
|
|
|
if (Element* pseudo = nsLayoutUtils::GetAfterPseudo(aElement)) {
|
|
|
|
elementForStyleResolution = pseudo;
|
2017-05-14 19:39:22 +03:00
|
|
|
pseudoTypeForStyleResolution = CSSPseudoElementType::NotPseudo;
|
2017-04-26 15:01:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-17 21:42:00 +03:00
|
|
|
RefPtr<ServoStyleContext> computedValues =
|
2017-04-26 15:01:25 +03:00
|
|
|
Servo_ResolveStyleLazily(elementForStyleResolution,
|
2017-05-14 19:39:22 +03:00
|
|
|
pseudoTypeForStyleResolution,
|
2017-05-24 09:37:47 +03:00
|
|
|
aRuleInclusion,
|
2017-05-07 17:36:47 +03:00
|
|
|
&Snapshots(),
|
2017-08-04 12:26:04 +03:00
|
|
|
mRawSet.get(),
|
|
|
|
aIgnoreExistingStyles).Consume();
|
2017-03-10 05:53:19 +03:00
|
|
|
|
2017-05-14 19:39:22 +03:00
|
|
|
if (mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoType)) {
|
2017-03-10 05:53:19 +03:00
|
|
|
computedValues =
|
2017-04-26 15:01:25 +03:00
|
|
|
Servo_ResolveStyleLazily(elementForStyleResolution,
|
2017-05-14 19:39:22 +03:00
|
|
|
pseudoTypeForStyleResolution,
|
2017-05-24 09:37:47 +03:00
|
|
|
aRuleInclusion,
|
2017-05-07 17:36:47 +03:00
|
|
|
&Snapshots(),
|
2017-08-04 12:26:04 +03:00
|
|
|
mRawSet.get(),
|
|
|
|
aIgnoreExistingStyles).Consume();
|
2017-03-10 05:53:19 +03:00
|
|
|
}
|
2017-04-26 15:01:25 +03:00
|
|
|
|
2017-07-23 06:06:07 +03:00
|
|
|
if (aPseudoType == CSSPseudoElementType::NotPseudo) {
|
|
|
|
UpdateBodyTextColorIfNeeded(*aElement, *computedValues, *mPresContext);
|
|
|
|
}
|
|
|
|
|
2017-03-10 05:53:19 +03:00
|
|
|
return computedValues.forget();
|
2017-03-08 23:20:17 +03:00
|
|
|
}
|
|
|
|
|
2017-03-27 09:53:27 +03:00
|
|
|
bool
|
|
|
|
ServoStyleSet::AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray)
|
|
|
|
{
|
2017-05-15 19:02:59 +03:00
|
|
|
UpdateStylistIfNeeded();
|
2017-03-27 09:53:27 +03:00
|
|
|
Servo_StyleSet_GetFontFaceRules(mRawSet.get(), &aArray);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-11 07:47:24 +03:00
|
|
|
nsCSSCounterStyleRule*
|
|
|
|
ServoStyleSet::CounterStyleRuleForName(nsIAtom* aName)
|
|
|
|
{
|
|
|
|
return Servo_StyleSet_GetCounterStyleRule(mRawSet.get(), aName);
|
|
|
|
}
|
|
|
|
|
2017-07-17 21:42:00 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
2017-04-15 01:37:35 +03:00
|
|
|
ServoStyleSet::ResolveForDeclarations(
|
2017-07-17 21:42:00 +03:00
|
|
|
const ServoStyleContext* aParentOrNull,
|
2017-07-07 00:56:06 +03:00
|
|
|
RawServoDeclarationBlockBorrowed aDeclarations)
|
2017-04-15 01:37:35 +03:00
|
|
|
{
|
2017-05-15 19:02:59 +03:00
|
|
|
UpdateStylistIfNeeded();
|
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-10 20:13:39 +03:00
|
|
|
void
|
2017-05-15 19:02:59 +03:00
|
|
|
ServoStyleSet::UpdateStylist()
|
2017-05-10 20:13:39 +03:00
|
|
|
{
|
2017-05-15 19:02:59 +03:00
|
|
|
MOZ_ASSERT(StylistNeedsUpdate());
|
2017-08-02 15:39:32 +03:00
|
|
|
Element* root = mPresContext->Document()->GetDocumentElement();
|
|
|
|
Servo_StyleSet_FlushStyleSheets(mRawSet.get(), root);
|
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());
|
|
|
|
}
|
|
|
|
|
2017-07-26 20:43:48 +03:00
|
|
|
bool
|
|
|
|
ServoStyleSet::MayTraverseFrom(Element* aElement)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aElement->IsInComposedDoc());
|
|
|
|
Element* parent = aElement->GetFlattenedTreeParentElementForStyle();
|
|
|
|
if (!parent) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!parent->HasServoData()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<ServoStyleContext> sc = Servo_ResolveStyleAllowStale(parent).Consume();
|
|
|
|
return sc->StyleDisplay()->mDisplay != StyleDisplay::None;
|
|
|
|
}
|
|
|
|
|
2017-05-12 22:04:55 +03:00
|
|
|
void
|
2017-05-02 02:46:41 +03:00
|
|
|
ServoStyleSet::PrependSheetOfType(SheetType aType,
|
2017-05-12 22:04:55 +03:00
|
|
|
ServoStyleSheet* aSheet)
|
2017-05-02 02:46:41 +03:00
|
|
|
{
|
2017-05-24 03:02:51 +03:00
|
|
|
aSheet->AddStyleSet(this);
|
2017-05-12 22:04:55 +03:00
|
|
|
mSheets[aType].InsertElementAt(0, aSheet);
|
2017-05-02 02:46:41 +03:00
|
|
|
}
|
|
|
|
|
2017-05-12 22:04:55 +03:00
|
|
|
void
|
2017-05-02 02:46:41 +03:00
|
|
|
ServoStyleSet::AppendSheetOfType(SheetType aType,
|
2017-05-12 22:04:55 +03:00
|
|
|
ServoStyleSheet* aSheet)
|
2017-05-02 02:46:41 +03:00
|
|
|
{
|
2017-05-24 03:02:51 +03:00
|
|
|
aSheet->AddStyleSet(this);
|
2017-05-12 22:04:55 +03:00
|
|
|
mSheets[aType].AppendElement(aSheet);
|
2017-05-02 02:46:41 +03:00
|
|
|
}
|
|
|
|
|
2017-05-12 22:04:55 +03:00
|
|
|
void
|
2017-05-02 02:46:41 +03:00
|
|
|
ServoStyleSet::InsertSheetOfType(SheetType aType,
|
|
|
|
ServoStyleSheet* aSheet,
|
2017-05-12 22:04:55 +03:00
|
|
|
ServoStyleSheet* aBeforeSheet)
|
|
|
|
{
|
|
|
|
for (uint32_t i = 0; i < mSheets[aType].Length(); ++i) {
|
|
|
|
if (mSheets[aType][i] == aBeforeSheet) {
|
2017-05-24 03:02:51 +03:00
|
|
|
aSheet->AddStyleSet(this);
|
2017-05-12 22:04:55 +03:00
|
|
|
mSheets[aType].InsertElementAt(i, aSheet);
|
|
|
|
return;
|
2017-05-02 02:46:41 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-12 22:04:55 +03:00
|
|
|
void
|
2017-05-02 02:46:41 +03:00
|
|
|
ServoStyleSet::RemoveSheetOfType(SheetType aType,
|
|
|
|
ServoStyleSheet* aSheet)
|
|
|
|
{
|
2017-05-12 22:04:55 +03:00
|
|
|
for (uint32_t i = 0; i < mSheets[aType].Length(); ++i) {
|
|
|
|
if (mSheets[aType][i] == aSheet) {
|
2017-05-24 03:02:51 +03:00
|
|
|
aSheet->DropStyleSet(this);
|
2017-05-12 22:04:55 +03:00
|
|
|
mSheets[aType].RemoveElementAt(i);
|
2017-05-02 02:46:41 +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) {
|
|
|
|
mStyleRuleMap = new ServoStyleRuleMap(this);
|
|
|
|
nsIDocument* doc = mPresContext->Document();
|
|
|
|
doc->AddObserver(mStyleRuleMap);
|
|
|
|
doc->CSSLoader()->AddObserver(mStyleRuleMap);
|
|
|
|
}
|
|
|
|
return mStyleRuleMap;
|
|
|
|
}
|
|
|
|
|
2017-05-08 11:04:31 +03:00
|
|
|
bool
|
2017-06-28 08:18:02 +03:00
|
|
|
ServoStyleSet::MightHaveAttributeDependency(const Element& aElement,
|
2017-07-04 20:16:04 +03:00
|
|
|
nsIAtom* aAttribute) const
|
2017-05-08 11:04:31 +03:00
|
|
|
{
|
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-05-09 13:13:45 +03:00
|
|
|
bool
|
2017-07-04 20:16:04 +03:00
|
|
|
ServoStyleSet::HasStateDependency(const Element& aElement,
|
|
|
|
EventStates aState) const
|
2017-05-09 13:13:45 +03:00
|
|
|
{
|
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-07-29 04:11:18 +03:00
|
|
|
already_AddRefed<ServoStyleContext>
|
|
|
|
ServoStyleSet::ReparentStyleContext(ServoStyleContext* aStyleContext,
|
|
|
|
ServoStyleContext* aNewParent,
|
|
|
|
ServoStyleContext* aNewParentIgnoringFirstLine,
|
|
|
|
ServoStyleContext* aNewLayoutParent,
|
|
|
|
Element* aElement)
|
|
|
|
{
|
2017-07-29 04:20:41 +03:00
|
|
|
return Servo_ReparentStyle(aStyleContext, aNewParent,
|
|
|
|
aNewParentIgnoringFirstLine, aNewLayoutParent,
|
|
|
|
aElement, mRawSet.get()).Consume();
|
2017-07-29 04:11:18 +03:00
|
|
|
}
|