AttributeStyles.cpp (3598B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* Data from presentational HTML attributes and style attributes */ 8 9 #include "mozilla/AttributeStyles.h" 10 11 #include "mozilla/DeclarationBlock.h" 12 #include "mozilla/MemoryReporting.h" 13 #include "mozilla/PresShell.h" 14 #include "mozilla/RestyleManager.h" 15 #include "mozilla/ServoBindings.h" 16 #include "mozilla/ServoStyleSet.h" 17 #include "mozilla/dom/Document.h" 18 #include "mozilla/dom/DocumentInlines.h" 19 #include "mozilla/dom/Element.h" 20 #include "nsError.h" 21 #include "nsGkAtoms.h" 22 #include "nsHashKeys.h" 23 #include "nsPresContext.h" 24 #include "nsStyleConsts.h" 25 26 using namespace mozilla::dom; 27 28 namespace mozilla { 29 30 // ----------------------------------------------------------- 31 32 AttributeStyles::AttributeStyles(Document* aDocument) : mDocument(aDocument) { 33 MOZ_ASSERT(aDocument); 34 } 35 36 void AttributeStyles::SetOwningDocument(Document* aDocument) { 37 mDocument = aDocument; // not refcounted 38 } 39 40 void AttributeStyles::Reset() { 41 mServoUnvisitedLinkDecl = nullptr; 42 mServoVisitedLinkDecl = nullptr; 43 mServoActiveLinkDecl = nullptr; 44 } 45 46 nsresult AttributeStyles::ImplLinkColorSetter( 47 RefPtr<StyleLockedDeclarationBlock>& aDecl, nscolor aColor) { 48 if (!mDocument || !mDocument->GetPresShell()) { 49 return NS_OK; 50 } 51 52 MOZ_ASSERT(!ServoStyleSet::IsInServoTraversal()); 53 aDecl = Servo_DeclarationBlock_CreateEmpty().Consume(); 54 Servo_DeclarationBlock_SetColorValue(aDecl.get(), eCSSProperty_color, aColor); 55 56 // Now make sure we restyle any links that might need it. This 57 // shouldn't happen often, so just rebuilding everything is ok. 58 if (Element* root = mDocument->GetRootElement()) { 59 RestyleManager* rm = mDocument->GetPresContext()->RestyleManager(); 60 rm->PostRestyleEvent(root, RestyleHint::RestyleSubtree(), nsChangeHint(0)); 61 } 62 return NS_OK; 63 } 64 65 nsresult AttributeStyles::SetLinkColor(nscolor aColor) { 66 return ImplLinkColorSetter(mServoUnvisitedLinkDecl, aColor); 67 } 68 69 nsresult AttributeStyles::SetActiveLinkColor(nscolor aColor) { 70 return ImplLinkColorSetter(mServoActiveLinkDecl, aColor); 71 } 72 73 nsresult AttributeStyles::SetVisitedLinkColor(nscolor aColor) { 74 return ImplLinkColorSetter(mServoVisitedLinkDecl, aColor); 75 } 76 77 size_t AttributeStyles::DOMSizeOfIncludingThis( 78 MallocSizeOf aMallocSizeOf) const { 79 size_t n = aMallocSizeOf(this); 80 // Measurement of the following members may be added later if DMD finds it is 81 // worthwhile: 82 // - mServoUnvisitedLinkDecl; 83 // - mServoVisitedLinkDecl; 84 // - mServoActiveLinkDecl; 85 // 86 // The following members are not measured: 87 // - mDocument, because it's non-owning 88 return n; 89 } 90 91 AttributeStyles::~AttributeStyles() { 92 // We may go away before all of our cached style attributes do, so clean up 93 // any that are left. 94 for (auto iter = mCachedStyleAttrs.Iter(); !iter.Done(); iter.Next()) { 95 MiscContainer*& value = iter.Data(); 96 97 // Ideally we'd just call MiscContainer::Evict, but we can't do that since 98 // we're iterating the hashtable. 99 if (value->mType == nsAttrValue::eCSSDeclaration) { 100 DeclarationBlock* declaration = value->mValue.mCSSDeclaration; 101 declaration->SetAttributeStyles(nullptr); 102 } else { 103 MOZ_ASSERT_UNREACHABLE("unexpected cached nsAttrValue type"); 104 } 105 106 value->mValue.mCached = 0; 107 iter.Remove(); 108 } 109 } 110 111 } // namespace mozilla