1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
/* -*- 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/. */
/* Data from presentational HTML attributes and style attributes */
#include "mozilla/AttributeStyles.h"
#include "nsGkAtoms.h"
#include "nsPresContext.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/DocumentInlines.h"
#include "mozilla/dom/Element.h"
#include "nsStyleConsts.h"
#include "nsError.h"
#include "nsHashKeys.h"
#include "mozilla/DeclarationBlock.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/OperatorNewExtensions.h"
#include "mozilla/PresShell.h"
#include "mozilla/RestyleManager.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/ServoStyleSet.h"
using namespace mozilla::dom;
namespace mozilla {
// -----------------------------------------------------------
AttributeStyles::AttributeStyles(Document* aDocument) : mDocument(aDocument) {
MOZ_ASSERT(aDocument);
}
void AttributeStyles::SetOwningDocument(Document* aDocument) {
mDocument = aDocument; // not refcounted
}
void AttributeStyles::Reset() {
mServoUnvisitedLinkDecl = nullptr;
mServoVisitedLinkDecl = nullptr;
mServoActiveLinkDecl = nullptr;
}
nsresult AttributeStyles::ImplLinkColorSetter(
RefPtr<StyleLockedDeclarationBlock>& aDecl, nscolor aColor) {
if (!mDocument || !mDocument->GetPresShell()) {
return NS_OK;
}
MOZ_ASSERT(!ServoStyleSet::IsInServoTraversal());
aDecl = Servo_DeclarationBlock_CreateEmpty().Consume();
Servo_DeclarationBlock_SetColorValue(aDecl.get(), eCSSProperty_color, aColor);
// Now make sure we restyle any links that might need it. This
// shouldn't happen often, so just rebuilding everything is ok.
if (Element* root = mDocument->GetRootElement()) {
RestyleManager* rm = mDocument->GetPresContext()->RestyleManager();
rm->PostRestyleEvent(root, RestyleHint::RestyleSubtree(), nsChangeHint(0));
}
return NS_OK;
}
nsresult AttributeStyles::SetLinkColor(nscolor aColor) {
return ImplLinkColorSetter(mServoUnvisitedLinkDecl, aColor);
}
nsresult AttributeStyles::SetActiveLinkColor(nscolor aColor) {
return ImplLinkColorSetter(mServoActiveLinkDecl, aColor);
}
nsresult AttributeStyles::SetVisitedLinkColor(nscolor aColor) {
return ImplLinkColorSetter(mServoVisitedLinkDecl, aColor);
}
size_t AttributeStyles::DOMSizeOfIncludingThis(
MallocSizeOf aMallocSizeOf) const {
size_t n = aMallocSizeOf(this);
// Measurement of the following members may be added later if DMD finds it is
// worthwhile:
// - mServoUnvisitedLinkDecl;
// - mServoVisitedLinkDecl;
// - mServoActiveLinkDecl;
//
// The following members are not measured:
// - mDocument, because it's non-owning
return n;
}
AttributeStyles::~AttributeStyles() {
// We may go away before all of our cached style attributes do, so clean up
// any that are left.
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.
if (value->mType == nsAttrValue::eCSSDeclaration) {
DeclarationBlock* declaration = value->mValue.mCSSDeclaration;
declaration->SetAttributeStyles(nullptr);
} else {
MOZ_ASSERT_UNREACHABLE("unexpected cached nsAttrValue type");
}
value->mValue.mCached = 0;
iter.Remove();
}
}
} // namespace mozilla
|