CSSPseudoElement.cpp (3020B)
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 #include "mozilla/dom/CSSPseudoElement.h" 8 9 #include "mozilla/AnimationComparator.h" 10 #include "mozilla/dom/CSSPseudoElementBinding.h" 11 #include "mozilla/dom/Element.h" 12 #include "mozilla/dom/KeyframeEffectBinding.h" 13 14 namespace mozilla::dom { 15 16 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CSSPseudoElement, mOriginatingElement) 17 18 CSSPseudoElement::CSSPseudoElement(dom::Element* aElement, 19 PseudoStyleType aType) 20 : mOriginatingElement(aElement), mPseudoType(aType) { 21 MOZ_ASSERT(aElement); 22 MOZ_ASSERT(AnimationUtils::IsSupportedPseudoForAnimations(aType), 23 "Unexpected Pseudo Type"); 24 } 25 26 CSSPseudoElement::~CSSPseudoElement() { 27 // Element might have been unlinked already, so we have to do null check. 28 if (mOriginatingElement) { 29 mOriginatingElement->RemoveProperty( 30 GetCSSPseudoElementPropertyAtom(mPseudoType)); 31 } 32 } 33 34 ParentObject CSSPseudoElement::GetParentObject() const { 35 return mOriginatingElement->GetParentObject(); 36 } 37 38 JSObject* CSSPseudoElement::WrapObject(JSContext* aCx, 39 JS::Handle<JSObject*> aGivenProto) { 40 return CSSPseudoElement_Binding::Wrap(aCx, this, aGivenProto); 41 } 42 43 /* static */ 44 already_AddRefed<CSSPseudoElement> CSSPseudoElement::GetCSSPseudoElement( 45 dom::Element* aElement, PseudoStyleType aType) { 46 if (!aElement) { 47 return nullptr; 48 } 49 50 nsAtom* propName = CSSPseudoElement::GetCSSPseudoElementPropertyAtom(aType); 51 RefPtr<CSSPseudoElement> pseudo = 52 static_cast<CSSPseudoElement*>(aElement->GetProperty(propName)); 53 if (pseudo) { 54 return pseudo.forget(); 55 } 56 57 // CSSPseudoElement is a purely external interface created on-demand, and 58 // when all references from script to the pseudo are dropped, we can drop the 59 // CSSPseudoElement object, so use a non-owning reference from Element to 60 // CSSPseudoElement. 61 pseudo = new CSSPseudoElement(aElement, aType); 62 nsresult rv = aElement->SetProperty(propName, pseudo, nullptr, true); 63 if (NS_FAILED(rv)) { 64 NS_WARNING("SetProperty failed"); 65 return nullptr; 66 } 67 return pseudo.forget(); 68 } 69 70 /* static */ 71 nsAtom* CSSPseudoElement::GetCSSPseudoElementPropertyAtom( 72 PseudoStyleType aType) { 73 switch (aType) { 74 case PseudoStyleType::before: 75 return nsGkAtoms::cssPseudoElementBeforeProperty; 76 77 case PseudoStyleType::after: 78 return nsGkAtoms::cssPseudoElementAfterProperty; 79 80 case PseudoStyleType::marker: 81 return nsGkAtoms::cssPseudoElementMarkerProperty; 82 83 default: 84 MOZ_ASSERT_UNREACHABLE( 85 "Should not try to get CSSPseudoElement " 86 "other than ::before, ::after or ::marker"); 87 return nullptr; 88 } 89 } 90 91 } // namespace mozilla::dom