ListMutationObserver.cpp (3086B)
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 #include "ListMutationObserver.h" 7 8 #include "mozilla/dom/HTMLInputElement.h" 9 #include "nsIFrame.h" 10 11 namespace mozilla { 12 NS_IMPL_ISUPPORTS(ListMutationObserver, nsIMutationObserver) 13 14 ListMutationObserver::~ListMutationObserver() = default; 15 16 void ListMutationObserver::Attach(bool aRepaint) { 17 nsAutoString id; 18 if (InputElement().GetAttr(nsGkAtoms::list, id)) { 19 Unlink(); 20 RefPtr<nsAtom> idAtom = NS_AtomizeMainThread(id); 21 ResetToID(InputElement(), idAtom); 22 AddObserverIfNeeded(); 23 } 24 if (aRepaint) { 25 mOwningElementFrame->InvalidateFrame(); 26 } 27 } 28 29 void ListMutationObserver::AddObserverIfNeeded() { 30 if (auto* list = get()) { 31 if (list->IsHTMLElement(nsGkAtoms::datalist)) { 32 list->AddMutationObserver(this); 33 } 34 } 35 } 36 37 void ListMutationObserver::RemoveObserverIfNeeded(dom::Element* aList) { 38 if (aList && aList->IsHTMLElement(nsGkAtoms::datalist)) { 39 aList->RemoveMutationObserver(this); 40 } 41 } 42 43 void ListMutationObserver::Detach() { 44 RemoveObserverIfNeeded(); 45 Unlink(); 46 } 47 48 dom::HTMLInputElement& ListMutationObserver::InputElement() const { 49 MOZ_ASSERT(mOwningElementFrame->GetContent()->IsHTMLElement(nsGkAtoms::input), 50 "bad cast"); 51 return *static_cast<dom::HTMLInputElement*>( 52 mOwningElementFrame->GetContent()); 53 } 54 55 void ListMutationObserver::AttributeChanged(dom::Element* aElement, 56 int32_t aNameSpaceID, 57 nsAtom* aAttribute, AttrModType, 58 const nsAttrValue* aOldValue) { 59 if (aAttribute == nsGkAtoms::value && aNameSpaceID == kNameSpaceID_None && 60 aElement->IsHTMLElement(nsGkAtoms::option)) { 61 mOwningElementFrame->InvalidateFrame(); 62 } 63 } 64 65 void ListMutationObserver::CharacterDataChanged( 66 nsIContent* aContent, const CharacterDataChangeInfo& aInfo) { 67 mOwningElementFrame->InvalidateFrame(); 68 } 69 70 void ListMutationObserver::ContentAppended(nsIContent* aFirstNewContent, 71 const ContentAppendInfo&) { 72 mOwningElementFrame->InvalidateFrame(); 73 } 74 75 void ListMutationObserver::ContentInserted(nsIContent* aChild, 76 const ContentInsertInfo&) { 77 mOwningElementFrame->InvalidateFrame(); 78 } 79 80 void ListMutationObserver::ContentWillBeRemoved(nsIContent* aChild, 81 const ContentRemoveInfo&) { 82 mOwningElementFrame->InvalidateFrame(); 83 } 84 85 void ListMutationObserver::ElementChanged(dom::Element* aFrom, 86 dom::Element* aTo) { 87 IDTracker::ElementChanged(aFrom, aTo); 88 RemoveObserverIfNeeded(aFrom); 89 AddObserverIfNeeded(); 90 mOwningElementFrame->InvalidateFrame(); 91 } 92 93 } // namespace mozilla