michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "mozilla/dom/BarProps.h" michael@0: #include "mozilla/dom/BarPropBinding.h" michael@0: #include "nsContentUtils.h" michael@0: #include "nsGlobalWindow.h" michael@0: #include "nsIDocShell.h" michael@0: #include "nsIScrollable.h" michael@0: #include "nsIWebBrowserChrome.h" michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: // michael@0: // Basic (virtual) BarProp class implementation michael@0: // michael@0: BarProp::BarProp(nsGlobalWindow* aWindow) michael@0: : mDOMWindow(aWindow) michael@0: { michael@0: MOZ_ASSERT(aWindow->IsInnerWindow()); michael@0: SetIsDOMBinding(); michael@0: } michael@0: michael@0: BarProp::~BarProp() michael@0: { michael@0: } michael@0: michael@0: nsPIDOMWindow* michael@0: BarProp::GetParentObject() const michael@0: { michael@0: return mDOMWindow; michael@0: } michael@0: michael@0: JSObject* michael@0: BarProp::WrapObject(JSContext* aCx) michael@0: { michael@0: return BarPropBinding::Wrap(aCx, this); michael@0: } michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(BarProp, mDOMWindow) michael@0: NS_IMPL_CYCLE_COLLECTING_ADDREF(BarProp) michael@0: NS_IMPL_CYCLE_COLLECTING_RELEASE(BarProp) michael@0: NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BarProp) michael@0: NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY michael@0: NS_INTERFACE_MAP_ENTRY(nsISupports) michael@0: NS_INTERFACE_MAP_END michael@0: michael@0: bool michael@0: BarProp::GetVisibleByFlag(uint32_t aChromeFlag, ErrorResult& aRv) michael@0: { michael@0: nsCOMPtr browserChrome = GetBrowserChrome(); michael@0: NS_ENSURE_TRUE(browserChrome, false); michael@0: michael@0: uint32_t chromeFlags; michael@0: michael@0: if (NS_FAILED(browserChrome->GetChromeFlags(&chromeFlags))) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return false; michael@0: } michael@0: michael@0: return (chromeFlags & aChromeFlag); michael@0: } michael@0: michael@0: void michael@0: BarProp::SetVisibleByFlag(bool aVisible, uint32_t aChromeFlag, michael@0: ErrorResult& aRv) michael@0: { michael@0: nsCOMPtr browserChrome = GetBrowserChrome(); michael@0: NS_ENSURE_TRUE_VOID(browserChrome); michael@0: michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return; michael@0: } michael@0: michael@0: uint32_t chromeFlags; michael@0: michael@0: if (NS_FAILED(browserChrome->GetChromeFlags(&chromeFlags))) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: return; michael@0: } michael@0: michael@0: if (aVisible) michael@0: chromeFlags |= aChromeFlag; michael@0: else michael@0: chromeFlags &= ~aChromeFlag; michael@0: michael@0: if (NS_FAILED(browserChrome->SetChromeFlags(chromeFlags))) { michael@0: aRv.Throw(NS_ERROR_FAILURE); michael@0: } michael@0: } michael@0: michael@0: already_AddRefed michael@0: BarProp::GetBrowserChrome() michael@0: { michael@0: if (!mDOMWindow) { michael@0: return nullptr; michael@0: } michael@0: michael@0: return mDOMWindow->GetWebBrowserChrome(); michael@0: } michael@0: michael@0: // michael@0: // MenubarProp class implementation michael@0: // michael@0: michael@0: MenubarProp::MenubarProp(nsGlobalWindow *aWindow) michael@0: : BarProp(aWindow) michael@0: { michael@0: } michael@0: michael@0: MenubarProp::~MenubarProp() michael@0: { michael@0: } michael@0: michael@0: bool michael@0: MenubarProp::GetVisible(ErrorResult& aRv) michael@0: { michael@0: return BarProp::GetVisibleByFlag(nsIWebBrowserChrome::CHROME_MENUBAR, aRv); michael@0: } michael@0: michael@0: void michael@0: MenubarProp::SetVisible(bool aVisible, ErrorResult& aRv) michael@0: { michael@0: BarProp::SetVisibleByFlag(aVisible, nsIWebBrowserChrome::CHROME_MENUBAR, aRv); michael@0: } michael@0: michael@0: // michael@0: // ToolbarProp class implementation michael@0: // michael@0: michael@0: ToolbarProp::ToolbarProp(nsGlobalWindow *aWindow) michael@0: : BarProp(aWindow) michael@0: { michael@0: } michael@0: michael@0: ToolbarProp::~ToolbarProp() michael@0: { michael@0: } michael@0: michael@0: bool michael@0: ToolbarProp::GetVisible(ErrorResult& aRv) michael@0: { michael@0: return BarProp::GetVisibleByFlag(nsIWebBrowserChrome::CHROME_TOOLBAR, aRv); michael@0: } michael@0: michael@0: void michael@0: ToolbarProp::SetVisible(bool aVisible, ErrorResult& aRv) michael@0: { michael@0: BarProp::SetVisibleByFlag(aVisible, nsIWebBrowserChrome::CHROME_TOOLBAR, michael@0: aRv); michael@0: } michael@0: michael@0: // michael@0: // LocationbarProp class implementation michael@0: // michael@0: michael@0: LocationbarProp::LocationbarProp(nsGlobalWindow *aWindow) michael@0: : BarProp(aWindow) michael@0: { michael@0: } michael@0: michael@0: LocationbarProp::~LocationbarProp() michael@0: { michael@0: } michael@0: michael@0: bool michael@0: LocationbarProp::GetVisible(ErrorResult& aRv) michael@0: { michael@0: return BarProp::GetVisibleByFlag(nsIWebBrowserChrome::CHROME_LOCATIONBAR, michael@0: aRv); michael@0: } michael@0: michael@0: void michael@0: LocationbarProp::SetVisible(bool aVisible, ErrorResult& aRv) michael@0: { michael@0: BarProp::SetVisibleByFlag(aVisible, nsIWebBrowserChrome::CHROME_LOCATIONBAR, michael@0: aRv); michael@0: } michael@0: michael@0: // michael@0: // PersonalbarProp class implementation michael@0: // michael@0: michael@0: PersonalbarProp::PersonalbarProp(nsGlobalWindow *aWindow) michael@0: : BarProp(aWindow) michael@0: { michael@0: } michael@0: michael@0: PersonalbarProp::~PersonalbarProp() michael@0: { michael@0: } michael@0: michael@0: bool michael@0: PersonalbarProp::GetVisible(ErrorResult& aRv) michael@0: { michael@0: return BarProp::GetVisibleByFlag(nsIWebBrowserChrome::CHROME_PERSONAL_TOOLBAR, michael@0: aRv); michael@0: } michael@0: michael@0: void michael@0: PersonalbarProp::SetVisible(bool aVisible, ErrorResult& aRv) michael@0: { michael@0: BarProp::SetVisibleByFlag(aVisible, michael@0: nsIWebBrowserChrome::CHROME_PERSONAL_TOOLBAR, michael@0: aRv); michael@0: } michael@0: michael@0: // michael@0: // StatusbarProp class implementation michael@0: // michael@0: michael@0: StatusbarProp::StatusbarProp(nsGlobalWindow *aWindow) michael@0: : BarProp(aWindow) michael@0: { michael@0: } michael@0: michael@0: StatusbarProp::~StatusbarProp() michael@0: { michael@0: } michael@0: michael@0: bool michael@0: StatusbarProp::GetVisible(ErrorResult& aRv) michael@0: { michael@0: return BarProp::GetVisibleByFlag(nsIWebBrowserChrome::CHROME_STATUSBAR, aRv); michael@0: } michael@0: michael@0: void michael@0: StatusbarProp::SetVisible(bool aVisible, ErrorResult& aRv) michael@0: { michael@0: return BarProp::SetVisibleByFlag(aVisible, michael@0: nsIWebBrowserChrome::CHROME_STATUSBAR, aRv); michael@0: } michael@0: michael@0: // michael@0: // ScrollbarsProp class implementation michael@0: // michael@0: michael@0: ScrollbarsProp::ScrollbarsProp(nsGlobalWindow *aWindow) michael@0: : BarProp(aWindow) michael@0: { michael@0: } michael@0: michael@0: ScrollbarsProp::~ScrollbarsProp() michael@0: { michael@0: } michael@0: michael@0: bool michael@0: ScrollbarsProp::GetVisible(ErrorResult& aRv) michael@0: { michael@0: if (!mDOMWindow) { michael@0: return true; michael@0: } michael@0: michael@0: nsCOMPtr scroller = michael@0: do_QueryInterface(mDOMWindow->GetDocShell()); michael@0: michael@0: if (!scroller) { michael@0: return true; michael@0: } michael@0: michael@0: int32_t prefValue; michael@0: scroller->GetDefaultScrollbarPreferences( michael@0: nsIScrollable::ScrollOrientation_Y, &prefValue); michael@0: if (prefValue != nsIScrollable::Scrollbar_Never) { michael@0: return true; michael@0: } michael@0: michael@0: scroller->GetDefaultScrollbarPreferences( michael@0: nsIScrollable::ScrollOrientation_X, &prefValue); michael@0: return prefValue != nsIScrollable::Scrollbar_Never; michael@0: } michael@0: michael@0: void michael@0: ScrollbarsProp::SetVisible(bool aVisible, ErrorResult& aRv) michael@0: { michael@0: if (!nsContentUtils::IsCallerChrome()) { michael@0: return; michael@0: } michael@0: michael@0: /* Scrollbars, unlike the other barprops, implement visibility directly michael@0: rather than handing off to the superclass (and from there to the michael@0: chrome window) because scrollbar visibility uniquely applies only michael@0: to the window making the change (arguably. it does now, anyway.) michael@0: and because embedding apps have no interface for implementing this michael@0: themselves, and therefore the implementation must be internal. */ michael@0: michael@0: nsCOMPtr scroller = michael@0: do_QueryInterface(mDOMWindow->GetDocShell()); michael@0: michael@0: if (scroller) { michael@0: int32_t prefValue; michael@0: michael@0: if (aVisible) { michael@0: prefValue = nsIScrollable::Scrollbar_Auto; michael@0: } else { michael@0: prefValue = nsIScrollable::Scrollbar_Never; michael@0: } michael@0: michael@0: scroller->SetDefaultScrollbarPreferences( michael@0: nsIScrollable::ScrollOrientation_Y, prefValue); michael@0: scroller->SetDefaultScrollbarPreferences( michael@0: nsIScrollable::ScrollOrientation_X, prefValue); michael@0: } michael@0: michael@0: /* Notably absent is the part where we notify the chrome window using michael@0: GetBrowserChrome()->SetChromeFlags(). Given the possibility of multiple michael@0: DOM windows (multiple top-level windows, even) within a single michael@0: chrome window, the historical concept of a single "has scrollbars" michael@0: flag in the chrome is inapplicable, and we can't tell at this level michael@0: whether we represent the particular DOM window that makes this decision michael@0: for the chrome. michael@0: michael@0: So only this object (and its corresponding DOM window) knows whether michael@0: scrollbars are visible. The corresponding chrome window will need to michael@0: ask (one of) its DOM window(s) when it needs to know about scrollbar michael@0: visibility, rather than caching its own copy of that information. michael@0: */ michael@0: } michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: