CustomStateSet.cpp (3073B)
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 file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "CustomStateSet.h" 8 9 #include "mozilla/PresShell.h" 10 #include "mozilla/dom/Document.h" 11 #include "mozilla/dom/ElementInternalsBinding.h" 12 #include "mozilla/dom/HTMLElement.h" 13 14 namespace mozilla::dom { 15 16 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CustomStateSet, mTarget); 17 18 NS_IMPL_CYCLE_COLLECTING_ADDREF(CustomStateSet) 19 NS_IMPL_CYCLE_COLLECTING_RELEASE(CustomStateSet) 20 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CustomStateSet) 21 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 22 NS_INTERFACE_MAP_END 23 24 CustomStateSet::CustomStateSet(HTMLElement* aTarget) : mTarget(aTarget) {} 25 26 // WebIDL interface 27 nsISupports* CustomStateSet::GetParentObject() const { 28 return ToSupports(mTarget); 29 } 30 31 JSObject* CustomStateSet::WrapObject(JSContext* aCx, 32 JS::Handle<JSObject*> aGivenProto) { 33 return CustomStateSet_Binding::Wrap(aCx, this, aGivenProto); 34 } 35 36 void CustomStateSet::Clear(ErrorResult& aRv) { 37 CustomStateSet_Binding::SetlikeHelpers::Clear(this, aRv); 38 if (aRv.Failed()) { 39 return; 40 } 41 42 nsTArray<RefPtr<nsAtom>>& states = mTarget->EnsureCustomStates(); 43 Document* doc = mTarget->GetComposedDoc(); 44 PresShell* presShell = doc ? doc->GetPresShell() : nullptr; 45 if (presShell) { 46 presShell->CustomStatesWillChange(*mTarget); 47 // Iterate over each state to ensure each one is invalidated. 48 while (!states.IsEmpty()) { 49 RefPtr<nsAtom> atom = states.PopLastElement(); 50 presShell->CustomStateChanged(*mTarget, atom); 51 } 52 return; 53 } 54 55 states.Clear(); 56 } 57 58 bool CustomStateSet::Delete(const nsAString& aState, ErrorResult& aRv) { 59 CustomStateSet_Binding::SetlikeHelpers::Delete(this, aState, aRv); 60 if (aRv.Failed()) { 61 return false; 62 } 63 64 RefPtr<nsAtom> atom = NS_AtomizeMainThread(aState); 65 Document* doc = mTarget->GetComposedDoc(); 66 PresShell* presShell = doc ? doc->GetPresShell() : nullptr; 67 if (presShell) { 68 presShell->CustomStatesWillChange(*mTarget); 69 } 70 71 bool deleted = mTarget->EnsureCustomStates().RemoveElement(atom); 72 73 if (presShell) { 74 presShell->CustomStateChanged(*mTarget, atom); 75 } 76 return deleted; 77 } 78 79 void CustomStateSet::Add(const nsAString& aState, ErrorResult& aRv) { 80 CustomStateSet_Binding::SetlikeHelpers::Add(this, aState, aRv); 81 if (aRv.Failed()) { 82 return; 83 } 84 85 nsTArray<RefPtr<nsAtom>>& states = mTarget->EnsureCustomStates(); 86 RefPtr<nsAtom> atom = NS_AtomizeMainThread(aState); 87 if (states.Contains(atom)) { 88 return; 89 } 90 91 Document* doc = mTarget->GetComposedDoc(); 92 PresShell* presShell = doc ? doc->GetPresShell() : nullptr; 93 if (presShell) { 94 presShell->CustomStatesWillChange(*mTarget); 95 } 96 97 states.AppendElement(atom); 98 99 if (presShell) { 100 presShell->CustomStateChanged(*mTarget, atom); 101 } 102 } 103 104 } // namespace mozilla::dom