2015-11-23 08:12:49 +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: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
1999-02-27 04:35:25 +03:00
|
|
|
|
2006-03-25 08:47:31 +03:00
|
|
|
/*
|
|
|
|
* style sheet and style rule processor representing style attributes
|
|
|
|
*/
|
|
|
|
|
2009-12-31 18:56:32 +03:00
|
|
|
#include "nsHTMLCSSStyleSheet.h"
|
2013-06-23 16:03:39 +04:00
|
|
|
#include "mozilla/MemoryReporting.h"
|
2011-03-11 05:48:57 +03:00
|
|
|
#include "mozilla/css/StyleRule.h"
|
1999-10-08 07:09:31 +04:00
|
|
|
#include "nsIStyleRuleProcessor.h"
|
2004-08-01 03:15:21 +04:00
|
|
|
#include "nsPresContext.h"
|
2001-10-24 04:01:09 +04:00
|
|
|
#include "nsRuleWalker.h"
|
2009-08-01 19:53:40 +04:00
|
|
|
#include "nsRuleProcessorData.h"
|
2010-05-05 22:18:05 +04:00
|
|
|
#include "mozilla/dom/Element.h"
|
2012-09-30 20:40:24 +04:00
|
|
|
#include "nsAttrValue.h"
|
|
|
|
#include "nsAttrValueInlines.h"
|
2016-02-17 23:37:00 +03:00
|
|
|
#include "nsCSSPseudoElements.h"
|
2016-02-24 10:01:12 +03:00
|
|
|
#include "mozilla/RestyleManagerHandle.h"
|
|
|
|
#include "mozilla/RestyleManagerHandleInlines.h"
|
2010-04-30 17:12:06 +04:00
|
|
|
|
2013-11-15 06:42:57 +04:00
|
|
|
using namespace mozilla;
|
2010-04-30 17:12:06 +04:00
|
|
|
using namespace mozilla::dom;
|
2001-06-01 02:19:43 +04:00
|
|
|
|
2013-06-14 09:34:37 +04:00
|
|
|
nsHTMLCSSStyleSheet::nsHTMLCSSStyleSheet()
|
1998-05-14 03:42:18 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2012-09-30 20:40:24 +04:00
|
|
|
nsHTMLCSSStyleSheet::~nsHTMLCSSStyleSheet()
|
|
|
|
{
|
|
|
|
// We may go away before all of our cached style attributes do,
|
|
|
|
// so clean up any that are left.
|
2015-11-23 08:12:49 +03:00
|
|
|
for (auto iter = mCachedStyleAttrs.Iter(); !iter.Done(); iter.Next()) {
|
|
|
|
MiscContainer*& value = iter.Data();
|
|
|
|
|
|
|
|
// Ideally we'd just call MiscContainer::Evict, but we can't do that since
|
|
|
|
// we're iterating the hashtable.
|
2016-06-24 06:35:12 +03:00
|
|
|
MOZ_ASSERT(value->mType == nsAttrValue::eGeckoCSSDeclaration);
|
2015-11-23 08:12:49 +03:00
|
|
|
|
2016-06-24 06:35:12 +03:00
|
|
|
css::Declaration* declaration = value->mValue.mGeckoCSSDeclaration;
|
2015-11-23 08:12:49 +03:00
|
|
|
declaration->SetHTMLCSSStyleSheet(nullptr);
|
|
|
|
value->mValue.mCached = 0;
|
|
|
|
|
|
|
|
iter.Remove();
|
|
|
|
}
|
2012-09-30 20:40:24 +04:00
|
|
|
}
|
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS(nsHTMLCSSStyleSheet, nsIStyleRuleProcessor)
|
1998-05-14 03:42:18 +04:00
|
|
|
|
2010-07-19 01:20:40 +04:00
|
|
|
/* virtual */ void
|
2009-12-31 18:56:32 +03:00
|
|
|
nsHTMLCSSStyleSheet::RulesMatching(ElementRuleProcessorData* aData)
|
1998-05-14 03:42:18 +04:00
|
|
|
{
|
2014-09-13 17:17:36 +04:00
|
|
|
ElementRulesMatching(aData->mPresContext, aData->mElement,
|
|
|
|
aData->mRuleWalker);
|
|
|
|
}
|
2009-12-11 10:37:40 +03:00
|
|
|
|
2014-09-13 17:17:36 +04:00
|
|
|
void
|
|
|
|
nsHTMLCSSStyleSheet::ElementRulesMatching(nsPresContext* aPresContext,
|
|
|
|
Element* aElement,
|
|
|
|
nsRuleWalker* aRuleWalker)
|
|
|
|
{
|
2009-12-11 10:37:40 +03:00
|
|
|
// just get the one and only style rule from the content's STYLE attribute
|
2015-11-09 10:57:16 +03:00
|
|
|
css::Declaration* declaration = aElement->GetInlineStyleDeclaration();
|
|
|
|
if (declaration) {
|
2015-11-05 11:44:10 +03:00
|
|
|
declaration->SetImmutable();
|
|
|
|
aRuleWalker->Forward(declaration);
|
2009-12-11 19:13:19 +03:00
|
|
|
}
|
2009-09-03 04:28:37 +04:00
|
|
|
|
2015-11-09 10:57:16 +03:00
|
|
|
declaration = aElement->GetSMILOverrideStyleDeclaration();
|
|
|
|
if (declaration) {
|
2016-02-24 10:01:12 +03:00
|
|
|
MOZ_ASSERT(aPresContext->RestyleManager()->IsGecko(),
|
|
|
|
"stylo: ElementRulesMatching must not be called when we have "
|
|
|
|
"a Servo-backed style system");
|
|
|
|
RestyleManager* restyleManager = aPresContext->RestyleManager()->AsGecko();
|
Bug 960465 patch 17 - Remove separate animation and non-animation phases of restyling. r=birtles
Note that this means that when we start transitions, we post restyles
that are processed during the current restyling operation, rather than
in a later phase. This depends on patch 11, which makes the transition
manager skip style changes that it posts while starting transitions, to
ensure that this doesn't lead to an infinite loop. This also depends on
patch 16, which only consumes restyle data for the primary frame, to
ensure that the animation restyles posted are processed properly. It
also depends on patch 14, which makes us retain data on finished
transitions, to avoid triggering extra transitions on descendants when
both an ancestor and a descendant transition an inherited property, and
the descendant does so faster.
This fixes a known failure in layout/style/test/test_animations.html and
test_animations_omta.html (as visible in the patch). I believe this is
because this patch changes us to compute keyframe values for animations
on top of a style context *with* animation data rather than one without,
which means what we're computing them on top of changes each time. (The
purpose of patch 3 was to avoid this in the case where avoiding it
matters, i.e., implicit 0% and 100% keyframes.)
2015-02-17 01:15:05 +03:00
|
|
|
if (!restyleManager->SkipAnimationRules()) {
|
2010-03-01 22:31:45 +03:00
|
|
|
// Animation restyle (or non-restyle traversal of rules)
|
|
|
|
// Now we can walk SMIL overrride style, without triggering transitions.
|
2015-11-05 11:44:10 +03:00
|
|
|
declaration->SetImmutable();
|
|
|
|
aRuleWalker->Forward(declaration);
|
2010-03-01 22:31:45 +03:00
|
|
|
}
|
2009-12-11 19:13:19 +03:00
|
|
|
}
|
1998-05-14 03:42:18 +04:00
|
|
|
}
|
|
|
|
|
2015-02-17 01:15:05 +03:00
|
|
|
void
|
|
|
|
nsHTMLCSSStyleSheet::PseudoElementRulesMatching(Element* aPseudoElement,
|
2016-02-17 23:37:00 +03:00
|
|
|
CSSPseudoElementType
|
2015-02-17 01:15:05 +03:00
|
|
|
aPseudoType,
|
|
|
|
nsRuleWalker* aRuleWalker)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(nsCSSPseudoElements::
|
|
|
|
PseudoElementSupportsStyleAttribute(aPseudoType));
|
|
|
|
MOZ_ASSERT(aPseudoElement);
|
|
|
|
|
|
|
|
// just get the one and only style rule from the content's STYLE attribute
|
2015-11-09 10:57:16 +03:00
|
|
|
css::Declaration* declaration = aPseudoElement->GetInlineStyleDeclaration();
|
|
|
|
if (declaration) {
|
2015-11-05 11:44:10 +03:00
|
|
|
declaration->SetImmutable();
|
|
|
|
aRuleWalker->Forward(declaration);
|
2015-02-17 01:15:05 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-19 01:20:40 +04:00
|
|
|
/* virtual */ void
|
2009-12-31 18:56:32 +03:00
|
|
|
nsHTMLCSSStyleSheet::RulesMatching(PseudoElementRuleProcessorData* aData)
|
2009-12-11 10:37:40 +03:00
|
|
|
{
|
2015-05-27 02:44:52 +03:00
|
|
|
if (nsCSSPseudoElements::PseudoElementSupportsStyleAttribute(aData->mPseudoType) &&
|
|
|
|
aData->mPseudoElement) {
|
2015-02-17 01:15:05 +03:00
|
|
|
PseudoElementRulesMatching(aData->mPseudoElement, aData->mPseudoType,
|
|
|
|
aData->mRuleWalker);
|
2013-07-10 02:25:27 +04:00
|
|
|
}
|
2009-12-11 10:37:40 +03:00
|
|
|
}
|
|
|
|
|
2010-07-19 01:20:40 +04:00
|
|
|
/* virtual */ void
|
2009-12-31 18:56:32 +03:00
|
|
|
nsHTMLCSSStyleSheet::RulesMatching(AnonBoxRuleProcessorData* aData)
|
2009-12-11 10:37:40 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-12-11 10:37:40 +03:00
|
|
|
#ifdef MOZ_XUL
|
2010-07-19 01:20:40 +04:00
|
|
|
/* virtual */ void
|
2009-12-31 18:56:32 +03:00
|
|
|
nsHTMLCSSStyleSheet::RulesMatching(XULTreeRuleProcessorData* aData)
|
1998-05-19 01:11:08 +04:00
|
|
|
{
|
|
|
|
}
|
2009-12-11 10:37:40 +03:00
|
|
|
#endif
|
1998-05-19 01:11:08 +04:00
|
|
|
|
1999-04-20 04:05:54 +04:00
|
|
|
// Test if style is dependent on content state
|
2010-05-14 23:05:14 +04:00
|
|
|
/* virtual */ nsRestyleHint
|
2009-12-31 18:56:32 +03:00
|
|
|
nsHTMLCSSStyleSheet::HasStateDependentStyle(StateRuleProcessorData* aData)
|
1999-04-20 04:05:54 +04:00
|
|
|
{
|
2010-04-01 04:43:32 +04:00
|
|
|
return nsRestyleHint(0);
|
1999-04-20 04:05:54 +04:00
|
|
|
}
|
|
|
|
|
2013-11-28 10:46:39 +04:00
|
|
|
/* virtual */ nsRestyleHint
|
|
|
|
nsHTMLCSSStyleSheet::HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData)
|
|
|
|
{
|
|
|
|
return nsRestyleHint(0);
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
/* virtual */ bool
|
2010-03-17 20:10:57 +03:00
|
|
|
nsHTMLCSSStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
|
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2010-03-17 20:10:57 +03:00
|
|
|
}
|
|
|
|
|
2003-02-22 19:10:53 +03:00
|
|
|
// Test if style is dependent on attribute
|
2010-05-14 23:05:14 +04:00
|
|
|
/* virtual */ nsRestyleHint
|
2015-08-05 15:42:21 +03:00
|
|
|
nsHTMLCSSStyleSheet::HasAttributeDependentStyle(
|
|
|
|
AttributeRuleProcessorData* aData,
|
|
|
|
RestyleHintData& aRestyleHintDataResult)
|
2003-02-22 19:10:53 +03:00
|
|
|
{
|
2010-05-14 21:04:51 +04:00
|
|
|
// Perhaps should check that it's XUL, SVG, (or HTML) namespace, but
|
|
|
|
// it doesn't really matter.
|
|
|
|
if (aData->mAttrHasChanged && aData->mAttribute == nsGkAtoms::style) {
|
2015-02-17 01:15:05 +03:00
|
|
|
return eRestyle_StyleAttribute;
|
2010-05-14 21:04:51 +04:00
|
|
|
}
|
|
|
|
|
2010-04-01 04:43:32 +04:00
|
|
|
return nsRestyleHint(0);
|
2003-02-22 19:10:53 +03:00
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
/* virtual */ bool
|
2010-07-19 01:20:40 +04:00
|
|
|
nsHTMLCSSStyleSheet::MediumFeaturesChanged(nsPresContext* aPresContext)
|
2008-07-26 20:14:48 +04:00
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2008-07-26 20:14:48 +04:00
|
|
|
}
|
1999-04-20 04:05:54 +04:00
|
|
|
|
2011-12-09 09:01:52 +04:00
|
|
|
/* virtual */ size_t
|
2013-06-23 16:03:39 +04:00
|
|
|
nsHTMLCSSStyleSheet::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
2011-12-09 09:01:52 +04:00
|
|
|
{
|
2014-06-23 02:02:05 +04:00
|
|
|
// The size of mCachedStyleAttrs's mTable member (a PLDHashTable) is
|
|
|
|
// significant in itself, but more significant is the size of the nsString
|
|
|
|
// members of the nsStringHashKeys.
|
2015-07-31 07:19:57 +03:00
|
|
|
size_t n = 0;
|
|
|
|
n += mCachedStyleAttrs.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
|
|
|
for (auto iter = mCachedStyleAttrs.ConstIter(); !iter.Done(); iter.Next()) {
|
|
|
|
// We don't own the MiscContainers (the hash table values) so we don't
|
|
|
|
// count them. We do care about the size of the nsString members in the
|
|
|
|
// keys though.
|
|
|
|
n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
|
|
|
}
|
|
|
|
return n;
|
2011-12-09 09:01:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* virtual */ size_t
|
2013-06-23 16:03:39 +04:00
|
|
|
nsHTMLCSSStyleSheet::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
2011-12-09 09:01:52 +04:00
|
|
|
{
|
2012-01-25 12:52:51 +04:00
|
|
|
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
2011-12-09 09:01:52 +04:00
|
|
|
}
|
1999-04-20 04:05:54 +04:00
|
|
|
|
2012-09-30 20:40:24 +04:00
|
|
|
void
|
|
|
|
nsHTMLCSSStyleSheet::CacheStyleAttr(const nsAString& aSerialized,
|
|
|
|
MiscContainer* aValue)
|
|
|
|
{
|
|
|
|
mCachedStyleAttrs.Put(aSerialized, aValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsHTMLCSSStyleSheet::EvictStyleAttr(const nsAString& aSerialized,
|
|
|
|
MiscContainer* aValue)
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
{
|
2015-04-20 21:43:06 +03:00
|
|
|
NS_ASSERTION(aValue == mCachedStyleAttrs.Get(aSerialized),
|
2012-09-30 20:40:24 +04:00
|
|
|
"Cached value does not match?!");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
mCachedStyleAttrs.Remove(aSerialized);
|
|
|
|
}
|
|
|
|
|
|
|
|
MiscContainer*
|
|
|
|
nsHTMLCSSStyleSheet::LookupStyleAttr(const nsAString& aSerialized)
|
|
|
|
{
|
|
|
|
return mCachedStyleAttrs.Get(aSerialized);
|
|
|
|
}
|