123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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/. */
- #include "mozilla/dom/ListBoxObject.h"
- #include "nsCOMPtr.h"
- #include "nsIFrame.h"
- #include "nsGkAtoms.h"
- #include "nsIScrollableFrame.h"
- #include "nsListBoxBodyFrame.h"
- #include "ChildIterator.h"
- #include "mozilla/dom/Element.h"
- #include "mozilla/dom/ListBoxObjectBinding.h"
- namespace mozilla {
- namespace dom {
- NS_IMPL_ISUPPORTS_INHERITED(ListBoxObject, BoxObject, nsIListBoxObject,
- nsPIListBoxObject)
- ListBoxObject::ListBoxObject()
- : mListBoxBody(nullptr)
- {
- }
- ListBoxObject::~ListBoxObject()
- {
- }
- JSObject* ListBoxObject::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
- {
- return ListBoxObjectBinding::Wrap(aCx, this, aGivenProto);
- }
- // nsIListBoxObject
- NS_IMETHODIMP
- ListBoxObject::GetRowCount(int32_t *aResult)
- {
- *aResult = GetRowCount();
- return NS_OK;
- }
- NS_IMETHODIMP
- ListBoxObject::GetItemAtIndex(int32_t index, nsIDOMElement **_retval)
- {
- nsListBoxBodyFrame* body = GetListBoxBody(true);
- if (body) {
- return body->GetItemAtIndex(index, _retval);
- }
- return NS_OK;
- }
- NS_IMETHODIMP
- ListBoxObject::GetIndexOfItem(nsIDOMElement* aElement, int32_t *aResult)
- {
- *aResult = 0;
- nsListBoxBodyFrame* body = GetListBoxBody(true);
- if (body) {
- return body->GetIndexOfItem(aElement, aResult);
- }
- return NS_OK;
- }
- // ListBoxObject
- int32_t
- ListBoxObject::GetRowCount()
- {
- nsListBoxBodyFrame* body = GetListBoxBody(true);
- if (body) {
- return body->GetRowCount();
- }
- return 0;
- }
- int32_t
- ListBoxObject::GetNumberOfVisibleRows()
- {
- nsListBoxBodyFrame* body = GetListBoxBody(true);
- if (body) {
- return body->GetNumberOfVisibleRows();
- }
- return 0;
- }
- int32_t
- ListBoxObject::GetIndexOfFirstVisibleRow()
- {
- nsListBoxBodyFrame* body = GetListBoxBody(true);
- if (body) {
- return body->GetIndexOfFirstVisibleRow();
- }
- return 0;
- }
- void
- ListBoxObject::EnsureIndexIsVisible(int32_t aRowIndex)
- {
- nsListBoxBodyFrame* body = GetListBoxBody(true);
- if (body) {
- body->EnsureIndexIsVisible(aRowIndex);
- }
- }
- void
- ListBoxObject::ScrollToIndex(int32_t aRowIndex)
- {
- nsListBoxBodyFrame* body = GetListBoxBody(true);
- if (body) {
- body->ScrollToIndex(aRowIndex);
- }
- }
- void
- ListBoxObject::ScrollByLines(int32_t aNumLines)
- {
- nsListBoxBodyFrame* body = GetListBoxBody(true);
- if (body) {
- body->ScrollByLines(aNumLines);
- }
- }
- already_AddRefed<Element>
- ListBoxObject::GetItemAtIndex(int32_t index)
- {
- nsCOMPtr<nsIDOMElement> el;
- GetItemAtIndex(index, getter_AddRefs(el));
- nsCOMPtr<Element> ret(do_QueryInterface(el));
- return ret.forget();
- }
- int32_t
- ListBoxObject::GetIndexOfItem(Element& aElement)
- {
- int32_t ret;
- nsCOMPtr<nsIDOMElement> el(do_QueryInterface(&aElement));
- GetIndexOfItem(el, &ret);
- return ret;
- }
- //////////////////////
- static nsIContent*
- FindBodyContent(nsIContent* aParent)
- {
- if (aParent->IsXULElement(nsGkAtoms::listboxbody)) {
- return aParent;
- }
- mozilla::dom::FlattenedChildIterator iter(aParent);
- for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
- nsIContent* result = FindBodyContent(child);
- if (result) {
- return result;
- }
- }
- return nullptr;
- }
- nsListBoxBodyFrame*
- ListBoxObject::GetListBoxBody(bool aFlush)
- {
- if (mListBoxBody) {
- return mListBoxBody;
- }
- nsIPresShell* shell = GetPresShell(false);
- if (!shell) {
- return nullptr;
- }
- nsIFrame* frame = aFlush ?
- GetFrame(false) /* does Flush_Frames */ :
- mContent->GetPrimaryFrame();
- if (!frame) {
- return nullptr;
- }
- // Iterate over our content model children looking for the body.
- nsCOMPtr<nsIContent> content = FindBodyContent(frame->GetContent());
- if (!content) {
- return nullptr;
- }
- // this frame will be a nsGFXScrollFrame
- frame = content->GetPrimaryFrame();
- if (!frame) {
- return nullptr;
- }
- nsIScrollableFrame* scrollFrame = do_QueryFrame(frame);
- if (!scrollFrame) {
- return nullptr;
- }
- // this frame will be the one we want
- nsIFrame* yeahBaby = scrollFrame->GetScrolledFrame();
- if (!yeahBaby) {
- return nullptr;
- }
- // It's a frame. Refcounts are irrelevant.
- nsListBoxBodyFrame* listBoxBody = do_QueryFrame(yeahBaby);
- NS_ENSURE_TRUE(listBoxBody &&
- listBoxBody->SetBoxObject(this),
- nullptr);
- mListBoxBody = listBoxBody;
- return mListBoxBody;
- }
- void
- ListBoxObject::Clear()
- {
- ClearCachedValues();
- BoxObject::Clear();
- }
- void
- ListBoxObject::ClearCachedValues()
- {
- mListBoxBody = nullptr;
- }
- } // namespace dom
- } // namespace mozilla
- // Creation Routine ///////////////////////////////////////////////////////////////////////
- nsresult
- NS_NewListBoxObject(nsIBoxObject** aResult)
- {
- NS_ADDREF(*aResult = new mozilla::dom::ListBoxObject());
- return NS_OK;
- }
|