Backed out 2 changesets (bug 1420762) for merge conflicts r=merge a=merge

Backed out changeset ba350c82d823 (bug 1420762)
Backed out changeset 00287b88254b (bug 1420762)
This commit is contained in:
Brindusan Cristian 2017-12-01 00:20:10 +02:00
Родитель 7c6a84a304
Коммит 6f5b49da3e
25 изменённых файлов: 396 добавлений и 302 удалений

Просмотреть файл

@ -4733,8 +4733,6 @@ nsDocument::SetStyleSheetApplicableState(StyleSheet* aSheet,
NS_PRECONDITION(aSheet, "null arg");
// If we're actually in the document style sheet list
//
// FIXME(emilio): Shadow DOM.
MOZ_DIAGNOSTIC_ASSERT(aSheet->IsServo() == IsStyledByServo());
if (mStyleSheets.IndexOf(aSheet) != mStyleSheets.NoIndex) {
if (aApplicable) {
@ -5757,42 +5755,45 @@ nsDocument::DocumentStatesChanged(EventStates aStateMask)
}
void
nsDocument::StyleRuleChanged(StyleSheet* aSheet, css::Rule* aStyleRule)
nsDocument::StyleRuleChanged(StyleSheet* aSheet,
css::Rule* aStyleRule)
{
if (!StyleSheetChangeEventsEnabled()) {
return;
}
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleChanged, (aSheet, aStyleRule));
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
"StyleRuleChanged",
mRule,
aStyleRule);
if (StyleSheetChangeEventsEnabled()) {
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
"StyleRuleChanged",
mRule,
aStyleRule);
}
}
void
nsDocument::StyleRuleAdded(StyleSheet* aSheet, css::Rule* aStyleRule)
nsDocument::StyleRuleAdded(StyleSheet* aSheet,
css::Rule* aStyleRule)
{
if (!StyleSheetChangeEventsEnabled()) {
return;
}
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleAdded, (aSheet, aStyleRule));
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
"StyleRuleAdded",
mRule,
aStyleRule);
if (StyleSheetChangeEventsEnabled()) {
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
"StyleRuleAdded",
mRule,
aStyleRule);
}
}
void
nsDocument::StyleRuleRemoved(StyleSheet* aSheet, css::Rule* aStyleRule)
nsDocument::StyleRuleRemoved(StyleSheet* aSheet,
css::Rule* aStyleRule)
{
if (!StyleSheetChangeEventsEnabled()) {
return;
}
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleRemoved, (aSheet, aStyleRule));
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
"StyleRuleRemoved",
mRule,
aStyleRule);
if (StyleSheetChangeEventsEnabled()) {
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
"StyleRuleRemoved",
mRule,
aStyleRule);
}
}
#undef DO_STYLESHEET_NOTIFICATION

Просмотреть файл

@ -14,6 +14,12 @@
class nsIContent;
class nsIDocument;
namespace mozilla {
namespace css {
class Rule;
} // namespace css
} // namespace mozilla
#define NS_IDOCUMENT_OBSERVER_IID \
{ 0x71041fa3, 0x6dd7, 0x4cde, \
{ 0xbb, 0x76, 0xae, 0xcc, 0x69, 0xe1, 0x75, 0x78 } }
@ -120,6 +126,45 @@ public:
* @param aStyleSheet the StyleSheet that has changed state
*/
virtual void StyleSheetApplicableStateChanged(mozilla::StyleSheet* aStyleSheet) = 0;
/**
* A StyleRule has just been modified within a style sheet.
* This method is called automatically when the rule gets
* modified. The style sheet passes this notification to
* the document. The notification is passed on to all of
* the document observers.
*
* @param aStyleSheet the StyleSheet that contians the rule
* @param aStyleRule the changed rule
*/
virtual void StyleRuleChanged(mozilla::StyleSheet* aStyleSheet,
mozilla::css::Rule* aStyleRule) = 0;
/**
* A StyleRule has just been added to a style sheet.
* This method is called automatically when the rule gets
* added to the sheet. The style sheet passes this
* notification to the document. The notification is passed on
* to all of the document observers.
*
* @param aStyleSheet the StyleSheet that has been modified
* @param aStyleRule the added rule
*/
virtual void StyleRuleAdded(mozilla::StyleSheet* aStyleSheet,
mozilla::css::Rule* aStyleRule) = 0;
/**
* A StyleRule has just been removed from a style sheet.
* This method is called automatically when the rule gets
* removed from the sheet. The style sheet passes this
* notification to the document. The notification is passed on
* to all of the document observers.
*
* @param aStyleSheet the StyleSheet that has been modified
* @param aStyleRule the removed rule
*/
virtual void StyleRuleRemoved(mozilla::StyleSheet* aStyleSheet,
mozilla::css::Rule* aStyleRule) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
@ -158,6 +203,18 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
virtual void StyleSheetApplicableStateChanged( \
mozilla::StyleSheet* aStyleSheet) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED \
virtual void StyleRuleChanged(mozilla::StyleSheet* aStyleSheet, \
mozilla::css::Rule* aStyleRule) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED \
virtual void StyleRuleAdded(mozilla::StyleSheet* aStyleSheet, \
mozilla::css::Rule* aStyleRule) override;
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED \
virtual void StyleRuleRemoved(mozilla::StyleSheet* aStyleSheet, \
mozilla::css::Rule* aStyleRule) override;
#define NS_DECL_NSIDOCUMENTOBSERVER \
NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE \
NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE \
@ -168,6 +225,9 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED \
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED \
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETAPPLICABLESTATECHANGED \
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED \
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED \
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED \
NS_DECL_NSIMUTATIONOBSERVER
@ -224,5 +284,20 @@ void \
_class::StyleSheetApplicableStateChanged(mozilla::StyleSheet* aStyleSheet)\
{ \
} \
void \
_class::StyleRuleChanged(mozilla::StyleSheet* aStyleSheet, \
mozilla::css::Rule* aStyleRule) \
{ \
} \
void \
_class::StyleRuleAdded(mozilla::StyleSheet* aStyleSheet, \
mozilla::css::Rule* aStyleRule) \
{ \
} \
void \
_class::StyleRuleRemoved(mozilla::StyleSheet* aStyleSheet, \
mozilla::css::Rule* aStyleRule) \
{ \
}
#endif /* nsIDocumentObserver_h___ */

Просмотреть файл

@ -4653,6 +4653,24 @@ PresShell::StyleSheetApplicableStateChanged(StyleSheet* aStyleSheet)
}
}
void
PresShell::StyleRuleChanged(StyleSheet* aStyleSheet, css::Rule* aStyleRule)
{
RecordStyleSheetChange(aStyleSheet, StyleSheet::ChangeType::RuleChanged);
}
void
PresShell::StyleRuleAdded(StyleSheet* aStyleSheet, css::Rule* aStyleRule)
{
RecordStyleSheetChange(aStyleSheet, StyleSheet::ChangeType::RuleAdded);
}
void
PresShell::StyleRuleRemoved(StyleSheet* aStyleSheet, css::Rule* aStyleRule)
{
RecordStyleSheetChange(aStyleSheet, StyleSheet::ChangeType::RuleRemoved);
}
nsresult
PresShell::RenderDocument(const nsRect& aRect, uint32_t aFlags,
nscolor aBackgroundColor,

Просмотреть файл

@ -299,6 +299,9 @@ public:
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETAPPLICABLESTATECHANGED
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED
// nsIMutationObserver
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED

Просмотреть файл

@ -27,6 +27,8 @@ ServoStyleRuleMap::~ServoStyleRuleMap()
{
}
NS_IMPL_ISUPPORTS(ServoStyleRuleMap, nsIDocumentObserver, nsICSSLoaderObserver)
void
ServoStyleRuleMap::EnsureTable()
{
@ -36,21 +38,23 @@ ServoStyleRuleMap::EnsureTable()
mStyleSet->EnumerateStyleSheetArrays(
[this](const nsTArray<RefPtr<ServoStyleSheet>>& aArray) {
for (auto& sheet : aArray) {
FillTableFromStyleSheet(*sheet);
FillTableFromStyleSheet(sheet);
}
});
}
void
ServoStyleRuleMap::SheetAdded(ServoStyleSheet& aStyleSheet)
ServoStyleRuleMap::StyleSheetAdded(StyleSheet* aStyleSheet,
bool aDocumentSheet)
{
if (!IsEmpty()) {
FillTableFromStyleSheet(aStyleSheet);
FillTableFromStyleSheet(aStyleSheet->AsServo());
}
}
void
ServoStyleRuleMap::SheetRemoved(ServoStyleSheet& aStyleSheet)
ServoStyleRuleMap::StyleSheetRemoved(StyleSheet* aStyleSheet,
bool aDocumentSheet)
{
// Invalidate all data inside. This isn't strictly necessary since
// we should always get update from document before new queries come.
@ -62,7 +66,18 @@ ServoStyleRuleMap::SheetRemoved(ServoStyleSheet& aStyleSheet)
}
void
ServoStyleRuleMap::RuleAdded(ServoStyleSheet& aStyleSheet, css::Rule& aStyleRule)
ServoStyleRuleMap::StyleSheetApplicableStateChanged(StyleSheet* aStyleSheet)
{
// We don't care if the stylesheet is disabled. Not removing no longer
// applicable stylesheets wouldn't make anything wrong.
if (!IsEmpty() && aStyleSheet->IsApplicable()) {
FillTableFromStyleSheet(aStyleSheet->AsServo());
}
}
void
ServoStyleRuleMap::StyleRuleAdded(StyleSheet* aStyleSheet,
css::Rule* aStyleRule)
{
if (!IsEmpty()) {
FillTableFromRule(aStyleRule);
@ -70,17 +85,17 @@ ServoStyleRuleMap::RuleAdded(ServoStyleSheet& aStyleSheet, css::Rule& aStyleRule
}
void
ServoStyleRuleMap::RuleRemoved(ServoStyleSheet& aStyleSheet,
css::Rule& aStyleRule)
ServoStyleRuleMap::StyleRuleRemoved(StyleSheet* aStyleSheet,
css::Rule* aStyleRule)
{
if (IsEmpty()) {
return;
}
switch (aStyleRule.Type()) {
switch (aStyleRule->Type()) {
case nsIDOMCSSRule::STYLE_RULE: {
auto& rule = static_cast<ServoStyleRule&>(aStyleRule);
mTable.Remove(rule.Raw());
auto rule = static_cast<ServoStyleRule*>(aStyleRule);
mTable.Remove(rule->Raw());
break;
}
case nsIDOMCSSRule::IMPORT_RULE:
@ -104,6 +119,18 @@ ServoStyleRuleMap::RuleRemoved(ServoStyleSheet& aStyleSheet,
}
}
NS_IMETHODIMP
ServoStyleRuleMap::StyleSheetLoaded(StyleSheet* aSheet,
bool aWasAlternate,
nsresult aStatus)
{
MOZ_ASSERT(aSheet->IsServo());
if (!IsEmpty()) {
FillTableFromStyleSheet(aSheet->AsServo());
}
return NS_OK;
}
size_t
ServoStyleRuleMap::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
@ -113,44 +140,43 @@ ServoStyleRuleMap::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
}
void
ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule)
ServoStyleRuleMap::FillTableFromRule(css::Rule* aRule)
{
switch (aRule.Type()) {
switch (aRule->Type()) {
case nsIDOMCSSRule::STYLE_RULE: {
auto& rule = static_cast<ServoStyleRule&>(aRule);
mTable.Put(rule.Raw(), &rule);
auto rule = static_cast<ServoStyleRule*>(aRule);
mTable.Put(rule->Raw(), rule);
break;
}
case nsIDOMCSSRule::MEDIA_RULE:
case nsIDOMCSSRule::SUPPORTS_RULE:
case nsIDOMCSSRule::DOCUMENT_RULE: {
auto& rule = static_cast<css::GroupRule&>(aRule);
auto ruleList = static_cast<ServoCSSRuleList*>(rule.CssRules());
FillTableFromRuleList(*ruleList);
auto rule = static_cast<css::GroupRule*>(aRule);
auto ruleList = static_cast<ServoCSSRuleList*>(rule->CssRules());
FillTableFromRuleList(ruleList);
break;
}
case nsIDOMCSSRule::IMPORT_RULE: {
auto& rule = static_cast<ServoImportRule&>(aRule);
MOZ_ASSERT(aRule.GetStyleSheet());
FillTableFromStyleSheet(*rule.GetStyleSheet()->AsServo());
auto rule = static_cast<ServoImportRule*>(aRule);
FillTableFromStyleSheet(rule->GetStyleSheet()->AsServo());
break;
}
}
}
void
ServoStyleRuleMap::FillTableFromRuleList(ServoCSSRuleList& aRuleList)
ServoStyleRuleMap::FillTableFromRuleList(ServoCSSRuleList* aRuleList)
{
for (uint32_t i : IntegerRange(aRuleList.Length())) {
FillTableFromRule(*aRuleList.GetRule(i));
for (uint32_t i : IntegerRange(aRuleList->Length())) {
FillTableFromRule(aRuleList->GetRule(i));
}
}
void
ServoStyleRuleMap::FillTableFromStyleSheet(ServoStyleSheet& aSheet)
ServoStyleRuleMap::FillTableFromStyleSheet(ServoStyleSheet* aSheet)
{
if (aSheet.IsComplete()) {
FillTableFromRuleList(*aSheet.GetCssRulesInternal());
if (aSheet->IsComplete()) {
FillTableFromRuleList(aSheet->GetCssRulesInternal());
}
}

Просмотреть файл

@ -10,6 +10,8 @@
#include "mozilla/ServoStyleRule.h"
#include "nsDataHashtable.h"
#include "nsICSSLoaderObserver.h"
#include "nsStubDocumentObserver.h"
struct RawServoStyleRule;
@ -20,9 +22,12 @@ namespace css {
class Rule;
} // namespace css
class ServoStyleRuleMap
class ServoStyleRuleMap final : public nsStubDocumentObserver
, public nsICSSLoaderObserver
{
public:
NS_DECL_ISUPPORTS
explicit ServoStyleRuleMap(ServoStyleSet* aStyleSet);
void EnsureTable();
@ -30,25 +35,30 @@ public:
return mTable.Get(aRawRule);
}
void SheetAdded(ServoStyleSheet& aStyleSheet);
void SheetRemoved(ServoStyleSheet& aStyleSheet);
// nsIDocumentObserver methods
void StyleSheetAdded(StyleSheet* aStyleSheet, bool aDocumentSheet) final;
void StyleSheetRemoved(StyleSheet* aStyleSheet, bool aDocumentSheet) final;
void StyleSheetApplicableStateChanged(StyleSheet* aStyleSheet) final;
void StyleRuleAdded(StyleSheet* aStyleSheet, css::Rule* aStyleRule) final;
void StyleRuleRemoved(StyleSheet* aStyleSheet, css::Rule* aStyleRule) final;
void RuleAdded(ServoStyleSheet& aStyleSheet, css::Rule&);
void RuleRemoved(ServoStyleSheet& aStyleSheet, css::Rule& aStyleRule);
// nsICSSLoaderObserver
NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet,
bool aWasAlternate, nsresult aStatus) final;
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
private:
~ServoStyleRuleMap();
private:
// Since we would never have a document which contains no style rule,
// we use IsEmpty as an indication whether we need to walk through
// all stylesheets to fill the table.
bool IsEmpty() const { return mTable.Count() == 0; }
void FillTableFromRule(css::Rule& aRule);
void FillTableFromRuleList(ServoCSSRuleList& aRuleList);
void FillTableFromStyleSheet(ServoStyleSheet& aSheet);
void FillTableFromRule(css::Rule* aRule);
void FillTableFromRuleList(ServoCSSRuleList* aRuleList);
void FillTableFromStyleSheet(ServoStyleSheet* aSheet);
typedef nsDataHashtable<nsPtrHashKey<const RawServoStyleRule>,
WeakPtr<ServoStyleRule>> Hashtable;

Просмотреть файл

@ -766,8 +766,9 @@ CSSStyleSheet::InsertRuleInternal(const nsAString& aRule,
// We don't notify immediately for @import rules, but rather when
// the sheet the rule is importing is loaded (see StyleSheetLoaded)
if (type != css::Rule::IMPORT_RULE || !RuleHasPendingChildSheet(rule)) {
RuleAdded(*rule);
if ((type != css::Rule::IMPORT_RULE || !RuleHasPendingChildSheet(rule)) &&
mDocument) {
mDocument->StyleRuleAdded(this, rule);
}
return aIndex;
@ -794,7 +795,11 @@ CSSStyleSheet::DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv)
if (rule) {
Inner()->mOrderedRules.RemoveObjectAt(aIndex);
rule->SetStyleSheet(nullptr);
RuleRemoved(*rule);
DidDirty();
if (mDocument) {
mDocument->StyleRuleRemoved(this, rule);
}
}
}
@ -860,9 +865,12 @@ CSSStyleSheet::StyleSheetLoaded(StyleSheet* aSheet,
NS_ASSERTION(this == sheet->GetParentSheet(),
"We are being notified of a sheet load for a sheet that is not our child!");
if (NS_SUCCEEDED(aStatus)) {
if (mDocument && NS_SUCCEEDED(aStatus)) {
mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
RuleAdded(*sheet->GetOwnerRule());
// XXXldb @import rules shouldn't even implement nsIStyleRule (but
// they do)!
mDocument->StyleRuleAdded(this, sheet->GetOwnerRule());
}
return NS_OK;
@ -909,7 +917,9 @@ CSSStyleSheet::ReparseSheet(const nsAString& aInput)
reusableSheets.AddReusableSheet(cssSheet);
}
}
RuleRemoved(*rule);
if (mDocument) {
mDocument->StyleRuleRemoved(this, rule);
}
}
// nuke child sheets list and current namespace map
@ -939,13 +949,15 @@ CSSStyleSheet::ReparseSheet(const nsAString& aInput)
NS_ENSURE_SUCCESS(rv, rv);
// notify document of all new rules
for (int32_t index = 0; index < Inner()->mOrderedRules.Count(); ++index) {
RefPtr<css::Rule> rule = Inner()->mOrderedRules.ObjectAt(index);
if (rule->GetType() == css::Rule::IMPORT_RULE &&
RuleHasPendingChildSheet(rule)) {
continue; // notify when loaded (see StyleSheetLoaded)
if (mDocument) {
for (int32_t index = 0; index < Inner()->mOrderedRules.Count(); ++index) {
RefPtr<css::Rule> rule = Inner()->mOrderedRules.ObjectAt(index);
if (rule->GetType() == css::Rule::IMPORT_RULE &&
RuleHasPendingChildSheet(rule)) {
continue; // notify when loaded (see StyleSheetLoaded)
}
mDocument->StyleRuleAdded(this, rule);
}
RuleAdded(*rule);
}
return NS_OK;
}

Просмотреть файл

@ -120,6 +120,12 @@ public:
nsIDocument* aCloneDocument,
nsINode* aCloneOwningNode) const final;
void SetModifiedByChildRule() {
NS_ASSERTION(mDirty,
"sheet must be marked dirty before handing out child rules");
DidDirty();
}
nsresult AddRuleProcessor(nsCSSRuleProcessor* aProcessor);
nsresult DropRuleProcessor(nsCSSRuleProcessor* aProcessor);

Просмотреть файл

@ -304,7 +304,7 @@ GroupRule::AppendStyleRule(Rule* aRule)
aRule->SetStyleSheet(sheet);
aRule->SetParentRule(this);
if (sheet) {
sheet->RuleChanged(this);
sheet->AsGecko()->SetModifiedByChildRule();
}
}

Просмотреть файл

@ -62,12 +62,12 @@ MediaList::DoMediaChange(Func aCallback)
}
if (mStyleSheet) {
// FIXME(emilio): We should discern between "owned by a rule" (as in @media)
// and "owned by a sheet" (as in <style media>), and then pass something
// meaningful here.
mStyleSheet->RuleChanged(nullptr);
mStyleSheet->DidDirty();
}
/* XXXldb Pass something meaningful? */
if (doc) {
doc->StyleRuleChanged(mStyleSheet, nullptr);
}
return rv;
}

Просмотреть файл

@ -174,7 +174,10 @@ ServoKeyframeRule::UpdateRule(Func aCallback)
aCallback();
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
// FIXME sheet->AsGecko()->SetModifiedByChildRule();
if (doc) {
doc->StyleRuleChanged(sheet, this);
}
}
}

Просмотреть файл

@ -252,7 +252,10 @@ ServoKeyframesRule::UpdateRule(Func aCallback)
aCallback();
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
// FIXME sheet->AsGecko()->SetModifiedByChildRule();
if (doc) {
doc->StyleRuleChanged(sheet, this);
}
}
}

Просмотреть файл

@ -81,7 +81,9 @@ ServoStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
mDecls = decls.forget();
mDecls->SetOwningRule(rule);
}
sheet->RuleChanged(rule);
if (doc) {
doc->StyleRuleChanged(sheet, rule);
}
}
return NS_OK;
}

Просмотреть файл

@ -171,6 +171,19 @@ ServoStyleSet::Init(nsPresContext* aPresContext, nsBindingManager* aBindingManag
SetStylistStyleSheetsDirty();
}
void
ServoStyleSet::BeginShutdown()
{
nsIDocument* doc = mPresContext->Document();
// Remove the style rule map from document's observer and drop it.
if (mStyleRuleMap) {
doc->RemoveObserver(mStyleRuleMap);
doc->CSSLoader()->RemoveObserver(mStyleRuleMap);
mStyleRuleMap = nullptr;
}
}
void
ServoStyleSet::Shutdown()
{
@ -178,7 +191,6 @@ ServoStyleSet::Shutdown()
// starts going away.
ClearNonInheritingStyleContexts();
mRawSet = nullptr;
mStyleRuleMap = nullptr;
}
void
@ -673,10 +685,6 @@ ServoStyleSet::AppendStyleSheet(SheetType aType,
SetStylistStyleSheetsDirty();
}
if (mStyleRuleMap) {
mStyleRuleMap->SheetAdded(*aSheet);
}
return NS_OK;
}
@ -701,10 +709,6 @@ ServoStyleSet::PrependStyleSheet(SheetType aType,
SetStylistStyleSheetsDirty();
}
if (mStyleRuleMap) {
mStyleRuleMap->SheetAdded(*aSheet);
}
return NS_OK;
}
@ -722,10 +726,6 @@ ServoStyleSet::RemoveStyleSheet(SheetType aType,
SetStylistStyleSheetsDirty();
}
if (mStyleRuleMap) {
mStyleRuleMap->SheetRemoved(*aSheet);
}
return NS_OK;
}
@ -758,9 +758,6 @@ ServoStyleSet::ReplaceSheets(SheetType aType,
}
}
// Just don't bother calling SheetRemoved / SheetAdded, and recreate the rule
// map when needed.
mStyleRuleMap = nullptr;
return NS_OK;
}
@ -788,10 +785,6 @@ ServoStyleSet::InsertStyleSheetBefore(SheetType aType,
SetStylistStyleSheetsDirty();
}
if (mStyleRuleMap) {
mStyleRuleMap->SheetAdded(*aNewSheet);
}
return NS_OK;
}
@ -858,10 +851,6 @@ ServoStyleSet::AddDocStyleSheet(ServoStyleSheet* aSheet,
}
}
if (mStyleRuleMap) {
mStyleRuleMap->SheetAdded(*aSheet);
}
return NS_OK;
}
@ -1037,32 +1026,24 @@ ServoStyleSet::MarkOriginsDirty(OriginFlags aChangedOrigins)
}
void
ServoStyleSet::RuleAdded(ServoStyleSheet& aSheet, css::Rule& aRule)
ServoStyleSet::RecordStyleSheetChange(
ServoStyleSheet* aSheet,
StyleSheet::ChangeType aChangeType)
{
if (mStyleRuleMap) {
mStyleRuleMap->RuleAdded(aSheet, aRule);
switch (aChangeType) {
case StyleSheet::ChangeType::RuleAdded:
case StyleSheet::ChangeType::RuleRemoved:
case StyleSheet::ChangeType::RuleChanged:
case StyleSheet::ChangeType::ReparsedFromInspector:
// FIXME(emilio): We can presumably do better in a bunch of these.
return MarkOriginsDirty(aSheet->GetOrigin());
case StyleSheet::ChangeType::ApplicableStateChanged:
case StyleSheet::ChangeType::Added:
case StyleSheet::ChangeType::Removed:
// Do nothing, we've already recorded the change in the
// Append/Remove/Replace methods, etc, and will act consequently.
return;
}
// FIXME(emilio): Could be more granular based on aRule.
MarkOriginsDirty(aSheet.GetOrigin());
}
void
ServoStyleSet::RuleRemoved(ServoStyleSheet& aSheet, css::Rule& aRule)
{
if (mStyleRuleMap) {
mStyleRuleMap->RuleRemoved(aSheet, aRule);
}
// FIXME(emilio): Could be more granular based on aRule.
MarkOriginsDirty(aSheet.GetOrigin());
}
void
ServoStyleSet::RuleChanged(ServoStyleSheet& aSheet, css::Rule* aRule)
{
// FIXME(emilio): Could be more granular based on aRule.
MarkOriginsDirty(aSheet.GetOrigin());
}
#ifdef DEBUG
@ -1450,9 +1431,14 @@ ServoStyleRuleMap*
ServoStyleSet::StyleRuleMap()
{
if (!mStyleRuleMap) {
mStyleRuleMap = MakeUnique<ServoStyleRuleMap>(this);
mStyleRuleMap = new ServoStyleRuleMap(this);
if (mPresContext) {
nsIDocument* doc = mPresContext->Document();
doc->AddObserver(mStyleRuleMap);
doc->CSSLoader()->AddObserver(mStyleRuleMap);
}
}
return mStyleRuleMap.get();
return mStyleRuleMap;
}
bool

Просмотреть файл

@ -133,20 +133,12 @@ public:
const nsTArray<RefPtr<ServoStyleSheet>>& aNewSheets);
void Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager);
void BeginShutdown() {}
void BeginShutdown();
void Shutdown();
// Called when a rules in a stylesheet in this set, or a child sheet of that,
// are mutated from CSSOM.
void RuleAdded(ServoStyleSheet&, css::Rule&);
void RuleRemoved(ServoStyleSheet&, css::Rule&);
void RuleChanged(ServoStyleSheet& aSheet, css::Rule* aRule);
void RecordStyleSheetChange(mozilla::ServoStyleSheet*, StyleSheet::ChangeType);
// All the relevant changes are handled in RuleAdded / RuleRemoved / etc, and
// the relevant AppendSheet / RemoveSheet...
void RecordStyleSheetChange(ServoStyleSheet*, StyleSheet::ChangeType) {}
void RecordShadowStyleChange(dom::ShadowRoot* aShadowRoot) {
void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot) {
// FIXME(emilio): When we properly support shadow dom we'll need to do
// better.
MarkOriginsDirty(OriginFlags::All);
@ -294,7 +286,7 @@ public:
// check whether there is ::before/::after style for an element
already_AddRefed<ServoStyleContext>
ProbePseudoElementStyle(dom::Element* aOriginatingElement,
CSSPseudoElementType aType,
mozilla::CSSPseudoElementType aType,
ServoStyleContext* aParentContext);
/**
@ -450,6 +442,7 @@ public:
// Called by StyleSheet::EnsureUniqueInner to let us know it cloned
// its inner.
void SetNeedsRestyleAfterEnsureUniqueInner() {
MOZ_ASSERT(!IsForXBL(), "Should not be cloning things for XBL stylesheet");
mNeedsRestyleAfterEnsureUniqueInner = true;
}
@ -638,7 +631,7 @@ private:
// Map from raw Servo style rule to Gecko's wrapper object.
// Constructed lazily when requested by devtools.
UniquePtr<ServoStyleRuleMap> mStyleRuleMap;
RefPtr<ServoStyleRuleMap> mStyleRuleMap;
// This can be null if we are used to hold XBL style sheets.
RefPtr<nsBindingManager> mBindingManager;

Просмотреть файл

@ -281,8 +281,9 @@ ServoStyleSheet::ReparseSheet(const nsAString& aInput)
}
}
// Notify to the stylesets about the old rules going away.
{
// Notify mDocument that all our rules are removed.
if (mDocument) {
// Get the rule list.
ServoCSSRuleList* ruleList = GetCssRulesInternal();
MOZ_ASSERT(ruleList);
@ -294,7 +295,13 @@ ServoStyleSheet::ReparseSheet(const nsAString& aInput)
RuleHasPendingChildSheet(rule)) {
continue; // notify when loaded (see StyleSheetLoaded)
}
RuleRemoved(*rule);
mDocument->StyleRuleRemoved(this, rule);
// Document observers could possibly detach document from this sheet.
if (!mDocument) {
// If detached, don't process any more rules.
break;
}
}
}
@ -311,8 +318,8 @@ ServoStyleSheet::ReparseSheet(const nsAString& aInput)
DidDirty();
NS_ENSURE_SUCCESS(rv, rv);
// Notify the stylesets about the new rules.
{
// Notify mDocument that all our new rules are added.
if (mDocument) {
// Get the rule list (which will need to be regenerated after ParseSheet).
ServoCSSRuleList* ruleList = GetCssRulesInternal();
MOZ_ASSERT(ruleList);
@ -326,10 +333,29 @@ ServoStyleSheet::ReparseSheet(const nsAString& aInput)
continue; // notify when loaded (see StyleSheetLoaded)
}
RuleAdded(*rule);
mDocument->StyleRuleAdded(this, rule);
// Document observers could possibly detach document from this sheet.
if (!mDocument) {
// If detached, don't process any more rules.
break;
}
}
}
// FIXME(emilio): This is kind-of a hack for bug 1420713. As you may notice,
// there's nothing that triggers a style flush or anything similar (neither
// here or in the relevant Gecko path inside DidDirty).
//
// The tl;dr is: if we want to make sure scripted changes to sheets not
// associated with any document get properly reflected, we need to rejigger a
// fair amount of stuff. I'm probably doing that work as part of the shadow
// DOM stuff.
for (StyleSetHandle handle : mStyleSets) {
handle->AsServo()->RecordStyleSheetChange(
this, StyleSheet::ChangeType::ReparsedFromInspector);
}
return NS_OK;
}
@ -343,15 +369,15 @@ ServoStyleSheet::StyleSheetLoaded(StyleSheet* aSheet,
"why we were called back with a CSSStyleSheet?");
ServoStyleSheet* sheet = aSheet->AsServo();
if (!sheet->GetParentSheet()) {
if (sheet->GetParentSheet() == nullptr) {
return NS_OK; // ignore if sheet has been detached already
}
NS_ASSERTION(this == sheet->GetParentSheet(),
"We are being notified of a sheet load for a sheet that is not our child!");
if (NS_SUCCEEDED(aStatus)) {
if (mDocument && NS_SUCCEEDED(aStatus)) {
mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
RuleAdded(*sheet->GetOwnerRule());
mDocument->StyleRuleAdded(this, sheet->GetOwnerRule());
}
return NS_OK;
@ -406,15 +432,14 @@ ServoStyleSheet::InsertRuleInternal(const nsAString& aRule,
if (aRv.Failed()) {
return 0;
}
// XXX We may not want to get the rule when stylesheet change event
// is not enabled.
css::Rule* rule = mRuleList->GetRule(aIndex);
if (rule->GetType() != css::Rule::IMPORT_RULE ||
!RuleHasPendingChildSheet(rule)) {
RuleAdded(*rule);
if (mDocument) {
if (mRuleList->GetDOMCSSRuleType(aIndex) != nsIDOMCSSRule::IMPORT_RULE ||
!RuleHasPendingChildSheet(mRuleList->GetRule(aIndex))) {
// XXX We may not want to get the rule when stylesheet change event
// is not enabled.
mDocument->StyleRuleAdded(this, mRuleList->GetRule(aIndex));
}
}
return aIndex;
}
@ -436,8 +461,8 @@ ServoStyleSheet::DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv)
aRv = mRuleList->DeleteRule(aIndex);
MOZ_ASSERT(!aRv.ErrorCodeIs(NS_ERROR_DOM_INDEX_SIZE_ERR),
"IndexSizeError should have been handled earlier");
if (!aRv.Failed()) {
RuleRemoved(*rule);
if (!aRv.Failed() && mDocument) {
mDocument->StyleRuleRemoved(this, rule);
}
}

Просмотреть файл

@ -1162,7 +1162,11 @@ DOMCSSDeclarationImpl::SetCSSDeclaration(DeclarationBlock* aDecl)
mRule->SetDeclaration(aDecl->AsGecko());
if (sheet) {
sheet->RuleChanged(mRule);
sheet->DidDirty();
}
if (doc) {
doc->StyleRuleChanged(sheet, mRule);
}
return NS_OK;
}

Просмотреть файл

@ -18,6 +18,14 @@
#include "nsCSSPseudoElements.h"
#include "nsTArray.h"
namespace mozilla {
class CSSStyleSheet;
class ServoStyleSet;
namespace dom {
class Element;
class ShadowRoot;
} // namespace dom
} // namespace mozilla
class nsBindingManager;
class nsCSSCounterStyleRule;
struct nsFontFaceRuleContainer;
@ -33,16 +41,6 @@ struct TreeMatchContext;
namespace mozilla {
class CSSStyleSheet;
class ServoStyleSet;
namespace dom {
class Element;
class ShadowRoot;
} // namespace dom
namespace css {
class Rule;
} // namespace css
#define SERVO_BIT 0x1
/**
@ -168,12 +166,6 @@ public:
inline void AppendAllXBLStyleSheets(nsTArray<StyleSheet*>& aArray) const;
inline nsresult RemoveDocStyleSheet(StyleSheet* aSheet);
inline nsresult AddDocStyleSheet(StyleSheet* aSheet, nsIDocument* aDocument);
inline void RuleRemoved(StyleSheet&, css::Rule&);
inline void RuleAdded(StyleSheet&, css::Rule&);
inline void RuleChanged(StyleSheet&, css::Rule*);
// TODO(emilio): Remove in favor of Rule* methods.
inline void RecordStyleSheetChange(StyleSheet* aSheet, StyleSheet::ChangeType);
inline void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot);
inline bool StyleSheetsHaveChanged() const;

Просмотреть файл

@ -249,27 +249,6 @@ StyleSetHandle::Ptr::AddDocStyleSheet(StyleSheet* aSheet,
(aSheet->AsServo(), aDocument));
}
void
StyleSetHandle::Ptr::RuleRemoved(StyleSheet& aSheet, css::Rule& aRule)
{
FORWARD_CONCRETE(RuleRemoved, (*aSheet.AsGecko(), aRule),
(*aSheet.AsServo(), aRule));
}
void
StyleSetHandle::Ptr::RuleAdded(StyleSheet& aSheet, css::Rule& aRule)
{
FORWARD_CONCRETE(RuleAdded, (*aSheet.AsGecko(), aRule),
(*aSheet.AsServo(), aRule));
}
void
StyleSetHandle::Ptr::RuleChanged(StyleSheet& aSheet, css::Rule* aRule)
{
FORWARD_CONCRETE(RuleChanged, (*aSheet.AsGecko(), aRule),
(*aSheet.AsServo(), aRule));
}
void
StyleSetHandle::Ptr::RecordStyleSheetChange(StyleSheet* aSheet,
StyleSheet::ChangeType aChangeType)

Просмотреть файл

@ -454,18 +454,12 @@ StyleSheet::EnsureUniqueInner()
// already unique
return;
}
// If this stylesheet is for XBL with Servo, don't bother cloning
// it, as it may break ServoStyleRuleMap. XBL stylesheets are not
// supposed to change anyway.
//
// The mDocument check is used as a fast reject path because no
// XBL stylesheets would have associated document, but in normal
// cases, content stylesheets should usually have one.
//
// FIXME(emilio): Shadow DOM definitely modifies stylesheets! Right now all of
// them are unique anyway because we don't support <link>, but that needs to
// change.
if (!mDocument && IsServo() &&
mStyleSets.Length() == 1 &&
mStyleSets[0]->AsServo()->IsForXBL()) {
@ -609,53 +603,16 @@ StyleSheet::DeleteRuleFromGroup(css::GroupRule* aGroup, uint32_t aIndex)
NS_ENSURE_SUCCESS(result, result);
rule->SetStyleSheet(nullptr);
RuleRemoved(*rule);
DidDirty();
if (mDocument) {
mDocument->StyleRuleRemoved(this, rule);
}
return NS_OK;
}
#define NOTIFY_STYLE_SETS(function_, args_) do { \
StyleSheet* current = this; \
do { \
for (StyleSetHandle handle : current->mStyleSets) { \
handle->function_ args_; \
} \
current = current->mParent; \
} while (current); \
} while (0)
void
StyleSheet::RuleAdded(css::Rule& aRule)
{
DidDirty();
NOTIFY_STYLE_SETS(RuleAdded, (*this, aRule));
if (mDocument) {
mDocument->StyleRuleAdded(this, &aRule);
}
}
void
StyleSheet::RuleRemoved(css::Rule& aRule)
{
DidDirty();
NOTIFY_STYLE_SETS(RuleRemoved, (*this, aRule));
if (mDocument) {
mDocument->StyleRuleRemoved(this, &aRule);
}
}
void
StyleSheet::RuleChanged(css::Rule* aRule)
{
DidDirty();
NOTIFY_STYLE_SETS(RuleChanged, (*this, aRule));
if (mDocument) {
mDocument->StyleRuleChanged(this, aRule);
}
}
nsresult
StyleSheet::InsertRuleIntoGroup(const nsAString& aRule,
css::GroupRule* aGroup,
@ -679,7 +636,12 @@ StyleSheet::InsertRuleIntoGroup(const nsAString& aRule,
result = AsServo()->InsertRuleIntoGroupInternal(aRule, aGroup, aIndex);
}
NS_ENSURE_SUCCESS(result, result);
RuleAdded(*aGroup->GetStyleRuleAt(aIndex));
DidDirty();
if (mDocument) {
mDocument->StyleRuleAdded(this, aGroup->GetStyleRuleAt(aIndex));
}
return NS_OK;
}

Просмотреть файл

@ -77,6 +77,7 @@ public:
RuleAdded,
RuleRemoved,
RuleChanged,
ReparsedFromInspector,
};
void SetOwningNode(nsINode* aOwningNode)
@ -261,12 +262,6 @@ public:
void WillDirty();
virtual void DidDirty() {}
// Called when a rule changes from CSSOM.
//
// FIXME(emilio): This shouldn't allow null, but MediaList doesn't know about
// it's owning media rule, plus it's used for the stylesheet media itself.
void RuleChanged(css::Rule*);
void AddStyleSet(const StyleSetHandle& aStyleSet);
void DropStyleSet(const StyleSetHandle& aStyleSet);
@ -298,15 +293,6 @@ private:
ErrorResult& aRv);
protected:
// Called when a rule is removed from the sheet from CSSOM.
void RuleAdded(css::Rule&);
// Called when a rule is added to the sheet from CSSOM.
void RuleRemoved(css::Rule&);
// Called from SetEnabled when the enabled state changed.
void EnabledStateChanged();
struct ChildSheetListBuilder {
RefPtr<StyleSheet>* sheetSlot;
StyleSheet* parent;
@ -331,6 +317,9 @@ protected:
// Drop our reference to mMedia
void DropMedia();
// Called from SetEnabled when the enabled state changed.
void EnabledStateChanged();
// Unlink our inner, if needed, for cycle collection
virtual void UnlinkInner();
// Traverse our inner, if needed, for cycle collection

Просмотреть файл

@ -140,7 +140,12 @@ nsCSSCounterStyleRule::SetName(const nsAString& aName)
mName = name;
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
if (sheet->IsGecko()) {
sheet->AsGecko()->SetModifiedByChildRule();
}
if (doc) {
doc->StyleRuleChanged(sheet, this);
}
}
}
return NS_OK;
@ -182,7 +187,12 @@ nsCSSCounterStyleRule::SetDesc(nsCSSCounterDesc aDescID, const nsCSSValue& aValu
mGeneration++;
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
if (sheet->IsGecko()) {
sheet->AsGecko()->SetModifiedByChildRule();
}
if (doc) {
doc->StyleRuleChanged(sheet, this);
}
}
}

Просмотреть файл

@ -1151,7 +1151,10 @@ nsCSSKeyframeRule::SetKeyText(const nsAString& aKeyText)
newSelectors.SwapElements(mKeys);
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
sheet->AsGecko()->SetModifiedByChildRule();
if (doc) {
doc->StyleRuleChanged(sheet, this);
}
}
return NS_OK;
@ -1182,7 +1185,10 @@ nsCSSKeyframeRule::ChangeDeclaration(css::Declaration* aDeclaration)
}
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
sheet->AsGecko()->SetModifiedByChildRule();
if (doc) {
doc->StyleRuleChanged(sheet, this);
}
}
}
@ -1282,7 +1288,10 @@ nsCSSKeyframesRule::SetName(const nsAString& aName)
mName = NS_Atomize(aName);
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
sheet->AsGecko()->SetModifiedByChildRule();
if (doc) {
doc->StyleRuleChanged(sheet, this);
}
}
return NS_OK;
@ -1306,7 +1315,10 @@ nsCSSKeyframesRule::AppendRule(const nsAString& aRule)
AppendStyleRule(rule);
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
sheet->AsGecko()->SetModifiedByChildRule();
if (doc) {
doc->StyleRuleChanged(sheet, this);
}
}
}
@ -1350,7 +1362,11 @@ nsCSSKeyframesRule::DeleteRule(const nsAString& aKey)
DeleteStyleRuleAt(index);
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
sheet->AsGecko()->SetModifiedByChildRule();
if (doc) {
doc->StyleRuleChanged(sheet, this);
}
}
}
return NS_OK;
@ -1556,10 +1572,8 @@ nsCSSPageRule::ChangeDeclaration(css::Declaration* aDeclaration)
mDeclaration->SetOwningRule(this);
}
nsIDocument* doc = GetDocument();
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
if (StyleSheet* sheet = GetStyleSheet()) {
sheet->RuleChanged(this);
sheet->AsGecko()->SetModifiedByChildRule();
}
}

Просмотреть файл

@ -2354,7 +2354,8 @@ nsStyleSet::Shutdown()
}
void
nsStyleSet::SheetChanged(CSSStyleSheet& aStyleSheet)
nsStyleSet::RecordStyleSheetChange(CSSStyleSheet* aStyleSheet,
StyleSheet::ChangeType)
{
MOZ_ASSERT(mBatching != 0, "Should be in an update");
@ -2362,7 +2363,7 @@ nsStyleSet::SheetChanged(CSSStyleSheet& aStyleSheet)
return;
}
if (Element* scopeElement = aStyleSheet.GetScopeElement()) {
if (Element* scopeElement = aStyleSheet->GetScopeElement()) {
mChangedScopeStyleRoots.AppendElement(scopeElement);
return;
}

Просмотреть файл

@ -341,29 +341,9 @@ class nsStyleSet final
// Free all of the data associated with this style set.
void Shutdown();
void RuleAdded(mozilla::CSSStyleSheet& aSheet, mozilla::css::Rule&)
{
SheetChanged(aSheet);
}
void RuleRemoved(mozilla::CSSStyleSheet& aSheet, mozilla::css::Rule&)
{
SheetChanged(aSheet);
}
void RuleChanged(mozilla::CSSStyleSheet& aSheet, mozilla::css::Rule*)
{
SheetChanged(aSheet);
}
// Notes that a style sheet has changed.
void RecordStyleSheetChange(mozilla::CSSStyleSheet* aSheet,
mozilla::StyleSheet::ChangeType)
{
SheetChanged(*aSheet);
}
void SheetChanged(mozilla::CSSStyleSheet&);
void RecordStyleSheetChange(mozilla::CSSStyleSheet* aStyleSheet,
mozilla::StyleSheet::ChangeType);
// Notes that style sheets have changed in a shadow root.
void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot);