mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 1840b15583fd (bug 636564) for bustage.
CLOSED TREE
This commit is contained in:
parent
a446620df6
commit
a213f7964d
@ -27,7 +27,7 @@
|
||||
style="margin: 0; padding: 0; border: 0;"/>
|
||||
</vbox>
|
||||
<vbox id="scrollbox-test">
|
||||
<scrollbar orient="vertical" style="border: 0; padding: 0;"/>
|
||||
<scrollbar orient="vertical" style="margin: 0; border: 0; padding: 0;"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
@ -4,260 +4,35 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ScrollbarActivity.h"
|
||||
#include "nsIScrollbarOwner.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsIDOMElementCSSInlineStyle.h"
|
||||
#include "nsIDOMCSSStyleDeclaration.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsQueryFrame.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ScrollbarActivity, nsIDOMEventListener)
|
||||
|
||||
void
|
||||
ScrollbarActivity::Destroy()
|
||||
ScrollbarActivity::~ScrollbarActivity()
|
||||
{
|
||||
StopListeningForEvents();
|
||||
UnregisterFromRefreshDriver();
|
||||
CancelFadeBeginTimer();
|
||||
CancelActivityFinishedTimer();
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::ActivityOccurred()
|
||||
{
|
||||
ActivityStarted();
|
||||
ActivityStopped();
|
||||
}
|
||||
CancelActivityFinishedTimer();
|
||||
StartActivityFinishedTimer();
|
||||
|
||||
void
|
||||
ScrollbarActivity::ActivityStarted()
|
||||
{
|
||||
mNestedActivityCounter++;
|
||||
CancelFadeBeginTimer();
|
||||
SetIsFading(false);
|
||||
UnregisterFromRefreshDriver();
|
||||
StartListeningForEvents();
|
||||
SetIsActive(true);
|
||||
|
||||
NS_ASSERTION(mIsActive, "need to be active during activity");
|
||||
NS_ASSERTION(!mIsFading, "must not be fading during activity");
|
||||
NS_ASSERTION(!mFadeBeginTimer, "fade begin timer shouldn't be running");
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::ActivityStopped()
|
||||
ScrollbarActivity::ActivityFinished()
|
||||
{
|
||||
NS_ASSERTION(IsActivityOngoing(), "activity stopped while none was going on");
|
||||
NS_ASSERTION(mIsActive, "need to be active during activity");
|
||||
NS_ASSERTION(!mIsFading, "must not be fading during ongoing activity");
|
||||
NS_ASSERTION(!mFadeBeginTimer, "must not be waiting for fade during ongoing activity");
|
||||
|
||||
mNestedActivityCounter--;
|
||||
|
||||
if (!IsActivityOngoing()) {
|
||||
StartFadeBeginTimer();
|
||||
|
||||
NS_ASSERTION(mIsActive, "need to be active right after activity");
|
||||
NS_ASSERTION(!mIsFading, "must not be fading right after activity");
|
||||
NS_ASSERTION(mFadeBeginTimer, "fade begin timer should be running");
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ScrollbarActivity::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mIsActive)
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString type;
|
||||
aEvent->GetType(type);
|
||||
|
||||
if (type.EqualsLiteral("mousemove")) {
|
||||
// Mouse motions anywhere in the scrollable frame should keep the
|
||||
// scrollbars visible.
|
||||
ActivityOccurred();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> target;
|
||||
aEvent->GetOriginalTarget(getter_AddRefs(target));
|
||||
nsCOMPtr<nsIContent> targetContent = do_QueryInterface(target);
|
||||
|
||||
HandleEventForScrollbar(type, targetContent, GetHorizontalScrollbar(),
|
||||
&mHScrollbarHovered);
|
||||
HandleEventForScrollbar(type, targetContent, GetVerticalScrollbar(),
|
||||
&mVScrollbarHovered);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::WillRefresh(TimeStamp aTime)
|
||||
{
|
||||
NS_ASSERTION(mIsActive, "should only fade while scrollbars are visible");
|
||||
NS_ASSERTION(!IsActivityOngoing(), "why weren't we unregistered from the refresh driver when scrollbar activity started?");
|
||||
NS_ASSERTION(mIsFading, "should only animate fading during fade");
|
||||
|
||||
UpdateOpacity(aTime);
|
||||
|
||||
if (!IsStillFading(aTime)) {
|
||||
EndFade();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ScrollbarActivity::IsStillFading(TimeStamp aTime)
|
||||
{
|
||||
return !mFadeBeginTime.IsNull() && (aTime - mFadeBeginTime < FadeDuration());
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::HandleEventForScrollbar(const nsAString& aType,
|
||||
nsIContent* aTarget,
|
||||
nsIContent* aScrollbar,
|
||||
bool* aStoredHoverState)
|
||||
{
|
||||
if (!aTarget || !aScrollbar ||
|
||||
!nsContentUtils::ContentIsDescendantOf(aTarget, aScrollbar))
|
||||
return;
|
||||
|
||||
if (aType.EqualsLiteral("mousedown")) {
|
||||
ActivityStarted();
|
||||
} else if (aType.EqualsLiteral("mouseup")) {
|
||||
ActivityStopped();
|
||||
} else if (aType.EqualsLiteral("mouseover") ||
|
||||
aType.EqualsLiteral("mouseout")) {
|
||||
bool newHoveredState = aType.EqualsLiteral("mouseover");
|
||||
if (newHoveredState && !*aStoredHoverState) {
|
||||
ActivityStarted();
|
||||
HoveredScrollbar(aScrollbar);
|
||||
} else if (*aStoredHoverState && !newHoveredState) {
|
||||
ActivityStopped();
|
||||
// Don't call HoveredScrollbar(nullptr) here because we want the hover
|
||||
// attribute to stick until the scrollbars are hidden.
|
||||
}
|
||||
*aStoredHoverState = newHoveredState;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::StartListeningForEvents()
|
||||
{
|
||||
if (mListeningForEvents)
|
||||
return;
|
||||
|
||||
nsIFrame* scrollArea = do_QueryFrame(mScrollableFrame);
|
||||
nsCOMPtr<nsIDOMEventTarget> scrollAreaTarget = do_QueryInterface(
|
||||
scrollArea->GetContent());
|
||||
mHorizontalScrollbar = do_QueryInterface(GetHorizontalScrollbar());
|
||||
mVerticalScrollbar = do_QueryInterface(GetVerticalScrollbar());
|
||||
|
||||
if (scrollAreaTarget) {
|
||||
scrollAreaTarget->AddEventListener(NS_LITERAL_STRING("mousemove"), this,
|
||||
true);
|
||||
}
|
||||
StartListeningForEventsOnScrollbar(mHorizontalScrollbar);
|
||||
StartListeningForEventsOnScrollbar(mVerticalScrollbar);
|
||||
mListeningForEvents = true;
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::StartListeningForEventsOnScrollbar(nsIDOMEventTarget* aScrollbar)
|
||||
{
|
||||
if (aScrollbar) {
|
||||
aScrollbar->AddEventListener(NS_LITERAL_STRING("mousedown"), this, true);
|
||||
aScrollbar->AddEventListener(NS_LITERAL_STRING("mouseup"), this, true);
|
||||
aScrollbar->AddEventListener(NS_LITERAL_STRING("mouseover"), this, true);
|
||||
aScrollbar->AddEventListener(NS_LITERAL_STRING("mouseout"), this, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::StopListeningForEvents()
|
||||
{
|
||||
if (!mListeningForEvents)
|
||||
return;
|
||||
|
||||
nsIFrame* scrollArea = do_QueryFrame(mScrollableFrame);
|
||||
nsCOMPtr<nsIDOMEventTarget> scrollAreaTarget = do_QueryInterface(scrollArea->GetContent());
|
||||
|
||||
if (scrollAreaTarget) {
|
||||
scrollAreaTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"), this, true);
|
||||
}
|
||||
StopListeningForEventsOnScrollbar(mHorizontalScrollbar);
|
||||
StopListeningForEventsOnScrollbar(mVerticalScrollbar);
|
||||
|
||||
mHorizontalScrollbar = nullptr;
|
||||
mVerticalScrollbar = nullptr;
|
||||
mListeningForEvents = false;
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::StopListeningForEventsOnScrollbar(nsIDOMEventTarget* aScrollbar)
|
||||
{
|
||||
if (aScrollbar) {
|
||||
aScrollbar->RemoveEventListener(NS_LITERAL_STRING("mousedown"), this, true);
|
||||
aScrollbar->RemoveEventListener(NS_LITERAL_STRING("mouseup"), this, true);
|
||||
aScrollbar->RemoveEventListener(NS_LITERAL_STRING("mouseover"), this, true);
|
||||
aScrollbar->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::BeginFade()
|
||||
{
|
||||
NS_ASSERTION(mIsActive, "can't begin fade when we're already inactive");
|
||||
NS_ASSERTION(!IsActivityOngoing(), "why wasn't the fade begin timer cancelled when scrollbar activity started?");
|
||||
NS_ASSERTION(!mIsFading, "shouldn't be fading just yet");
|
||||
|
||||
CancelFadeBeginTimer();
|
||||
mFadeBeginTime = TimeStamp::Now();
|
||||
SetIsFading(true);
|
||||
RegisterWithRefreshDriver();
|
||||
|
||||
NS_ASSERTION(mIsActive, "only fade while scrollbars are visible");
|
||||
NS_ASSERTION(mIsFading, "should be fading now");
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::EndFade()
|
||||
{
|
||||
NS_ASSERTION(mIsActive, "still need to be active at this point");
|
||||
NS_ASSERTION(!IsActivityOngoing(), "why wasn't the fade end timer cancelled when scrollbar activity started?");
|
||||
|
||||
SetIsFading(false);
|
||||
SetIsActive(false);
|
||||
UnregisterFromRefreshDriver();
|
||||
StopListeningForEvents();
|
||||
|
||||
NS_ASSERTION(!mIsActive, "should have gone inactive after fade end");
|
||||
NS_ASSERTION(!mIsFading, "shouldn't be fading anymore");
|
||||
NS_ASSERTION(!mFadeBeginTimer, "fade begin timer shouldn't be running");
|
||||
NS_ASSERTION(!mIsActive, "need to be unactive once activity is finished");
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::RegisterWithRefreshDriver()
|
||||
{
|
||||
nsRefreshDriver* refreshDriver = GetRefreshDriver();
|
||||
if (refreshDriver) {
|
||||
refreshDriver->AddRefreshObserver(this, Flush_Style);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::UnregisterFromRefreshDriver()
|
||||
{
|
||||
nsRefreshDriver* refreshDriver = GetRefreshDriver();
|
||||
if (refreshDriver) {
|
||||
refreshDriver->RemoveRefreshObserver(this, Flush_Style);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SetBooleanAttribute(nsIContent* aContent, nsIAtom* aAttribute, bool aValue)
|
||||
@ -277,114 +52,38 @@ ScrollbarActivity::SetIsActive(bool aNewActive)
|
||||
{
|
||||
if (mIsActive == aNewActive)
|
||||
return;
|
||||
|
||||
mIsActive = aNewActive;
|
||||
if (!mIsActive) {
|
||||
// Clear sticky scrollbar hover status.
|
||||
HoveredScrollbar(nullptr);
|
||||
}
|
||||
|
||||
SetBooleanAttribute(GetHorizontalScrollbar(), nsGkAtoms::active, mIsActive);
|
||||
SetBooleanAttribute(GetVerticalScrollbar(), nsGkAtoms::active, mIsActive);
|
||||
}
|
||||
|
||||
static void
|
||||
SetOpacityOnElement(nsIContent* aContent, double aOpacity)
|
||||
void
|
||||
ScrollbarActivity::StartActivityFinishedTimer()
|
||||
{
|
||||
nsCOMPtr<nsIDOMElementCSSInlineStyle> inlineStyleContent =
|
||||
do_QueryInterface(aContent);
|
||||
if (inlineStyleContent) {
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
|
||||
inlineStyleContent->GetStyle(getter_AddRefs(decl));
|
||||
if (decl) {
|
||||
nsAutoString str;
|
||||
str.AppendFloat(aOpacity);
|
||||
decl->SetProperty(NS_LITERAL_STRING("opacity"), str, EmptyString());
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(!mActivityFinishedTimer, "timer already alive!");
|
||||
mActivityFinishedTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mActivityFinishedTimer->InitWithFuncCallback(ActivityFinishedTimerFired, this,
|
||||
kScrollbarActivityFinishedDelay,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::UpdateOpacity(TimeStamp aTime)
|
||||
ScrollbarActivity::CancelActivityFinishedTimer()
|
||||
{
|
||||
double progress = (aTime - mFadeBeginTime) / FadeDuration();
|
||||
double opacity = 1.0 - std::max(0.0, std::min(1.0, progress));
|
||||
SetOpacityOnElement(GetHorizontalScrollbar(), opacity);
|
||||
SetOpacityOnElement(GetVerticalScrollbar(), opacity);
|
||||
}
|
||||
|
||||
static void
|
||||
UnsetOpacityOnElement(nsIContent* aContent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElementCSSInlineStyle> inlineStyleContent =
|
||||
do_QueryInterface(aContent);
|
||||
if (inlineStyleContent) {
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
|
||||
inlineStyleContent->GetStyle(getter_AddRefs(decl));
|
||||
if (decl) {
|
||||
nsAutoString dummy;
|
||||
decl->RemoveProperty(NS_LITERAL_STRING("opacity"), dummy);
|
||||
}
|
||||
if (mActivityFinishedTimer) {
|
||||
mActivityFinishedTimer->Cancel();
|
||||
mActivityFinishedTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::SetIsFading(bool aNewFading)
|
||||
{
|
||||
if (mIsFading == aNewFading)
|
||||
return;
|
||||
|
||||
mIsFading = aNewFading;
|
||||
if (!mIsFading) {
|
||||
mFadeBeginTime = TimeStamp();
|
||||
UnsetOpacityOnElement(GetHorizontalScrollbar());
|
||||
UnsetOpacityOnElement(GetVerticalScrollbar());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::StartFadeBeginTimer()
|
||||
{
|
||||
NS_ASSERTION(!mFadeBeginTimer, "timer already alive!");
|
||||
mFadeBeginTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mFadeBeginTimer->InitWithFuncCallback(FadeBeginTimerFired, this,
|
||||
kScrollbarFadeBeginDelay,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::CancelFadeBeginTimer()
|
||||
{
|
||||
if (mFadeBeginTimer) {
|
||||
mFadeBeginTimer->Cancel();
|
||||
mFadeBeginTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScrollbarActivity::HoveredScrollbar(nsIContent* aScrollbar)
|
||||
{
|
||||
SetBooleanAttribute(GetHorizontalScrollbar(), nsGkAtoms::hover, false);
|
||||
SetBooleanAttribute(GetVerticalScrollbar(), nsGkAtoms::hover, false);
|
||||
SetBooleanAttribute(aScrollbar, nsGkAtoms::hover, true);
|
||||
}
|
||||
|
||||
nsRefreshDriver*
|
||||
ScrollbarActivity::GetRefreshDriver()
|
||||
{
|
||||
nsIFrame* box = mScrollableFrame->GetScrollbarBox(false);
|
||||
if (!box) {
|
||||
box = mScrollableFrame->GetScrollbarBox(true);
|
||||
}
|
||||
return box ? box->PresContext()->RefreshDriver() : nullptr;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
ScrollbarActivity::GetScrollbarContent(bool aVertical)
|
||||
{
|
||||
nsIFrame* box = mScrollableFrame->GetScrollbarBox(aVertical);
|
||||
return box ? box->GetContent() : nullptr;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
|
@ -7,138 +7,82 @@
|
||||
#define ScrollbarActivity_h___
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsRefreshDriver.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsIScrollbarOwner;
|
||||
class nsITimer;
|
||||
class nsIAtom;
|
||||
class nsIScrollableFrame;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
/**
|
||||
* ScrollbarActivity
|
||||
*
|
||||
* This class manages scrollbar behavior that imitates the native Mac OS X
|
||||
* Lion overlay scrollbar behavior: Scrollbars are only shown while "scrollbar
|
||||
* activity" occurs, and they're hidden with a fade animation after a short
|
||||
* delay.
|
||||
* This class manages scrollbar active state. When some activity occured
|
||||
* the 'active' attribute of the both the horizontal scrollbar and vertical
|
||||
* scrollbar is set.
|
||||
* After a small amount of time of inactivity this attribute is unset from
|
||||
* both scrollbars.
|
||||
* Some css specific rules can affect the scrollbar, like showing/hiding it
|
||||
* with a fade transition.
|
||||
*
|
||||
* Scrollbar activity has these states:
|
||||
* - inactive:
|
||||
* Scrollbars are hidden.
|
||||
* - ongoing activity:
|
||||
* Scrollbars are visible and being operated on in some way, for example
|
||||
* because they're hovered or pressed.
|
||||
* - active, but waiting for fade out
|
||||
* Scrollbars are still completely visible but are about to fade away.
|
||||
* - fading out
|
||||
* Scrollbars are subject to a fade-out animation.
|
||||
*
|
||||
* Initial scrollbar activity needs to be reported by the scrollbar holder that
|
||||
* Initial scrollbar activity needs to be reported by the scrollbar frame that
|
||||
* owns the ScrollbarActivity instance. This needs to happen via a call to
|
||||
* ActivityOccurred(), for example when the current scroll position or the size
|
||||
* of the scroll area changes.
|
||||
*
|
||||
* As soon as scrollbars are visible, the ScrollbarActivity class manages the
|
||||
* rest of the activity behavior: It ensures that mouse motions inside the
|
||||
* scroll area keep the scrollbars visible, and that scrollbars don't fade away
|
||||
* while they're being hovered / dragged. It also sets a sticky hover attribute
|
||||
* on the most recently hovered scrollbar.
|
||||
*
|
||||
* ScrollbarActivity falls into hibernation after the scrollbars have faded
|
||||
* out. It only starts acting after the next call to ActivityOccurred() /
|
||||
* ActivityStarted().
|
||||
* ScrollbarActivity then wait until a timeout has expired or a new call to
|
||||
* ActivityOccured() has been made. When the timeout expires ActivityFinished()
|
||||
* is call and reset the active state.
|
||||
*/
|
||||
|
||||
class ScrollbarActivity : public nsIDOMEventListener,
|
||||
public nsARefreshObserver {
|
||||
class ScrollbarActivity {
|
||||
public:
|
||||
ScrollbarActivity(nsIScrollbarOwner* aScrollableFrame)
|
||||
: mScrollableFrame(aScrollableFrame)
|
||||
, mNestedActivityCounter(0)
|
||||
, mIsActive(false)
|
||||
, mIsFading(false)
|
||||
, mListeningForEvents(false)
|
||||
, mHScrollbarHovered(false)
|
||||
, mVScrollbarHovered(false)
|
||||
ScrollbarActivity(nsIScrollableFrame* aScrollableFrame)
|
||||
: mIsActive(false)
|
||||
, mScrollableFrame(aScrollableFrame)
|
||||
{}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
virtual ~ScrollbarActivity() {}
|
||||
|
||||
void Destroy();
|
||||
|
||||
void ActivityOccurred();
|
||||
void ActivityStarted();
|
||||
void ActivityStopped();
|
||||
|
||||
virtual void WillRefresh(TimeStamp aTime);
|
||||
|
||||
static void FadeBeginTimerFired(nsITimer* aTimer, void* aSelf) {
|
||||
reinterpret_cast<ScrollbarActivity*>(aSelf)->BeginFade();
|
||||
}
|
||||
|
||||
static const uint32_t kScrollbarFadeBeginDelay = 450; // milliseconds
|
||||
static const uint32_t kScrollbarFadeDuration = 200; // milliseconds
|
||||
void ActivityFinished();
|
||||
~ScrollbarActivity();
|
||||
|
||||
protected:
|
||||
/*
|
||||
* mIsActive is true once any type of activity occurent on the scrollable
|
||||
* frame and until kScrollbarActivityFinishedDelay has expired.
|
||||
* This does not reflect the value of the 'active' attributes on scrollbars.
|
||||
*/
|
||||
bool mIsActive;
|
||||
|
||||
bool IsActivityOngoing()
|
||||
{ return mNestedActivityCounter > 0; }
|
||||
bool IsStillFading(TimeStamp aTime);
|
||||
/*
|
||||
* Hold a reference to the scrollable frame in order to retrieve the
|
||||
* horizontal and vertical scrollbar boxes where to set the 'active'
|
||||
* attribute.
|
||||
*/
|
||||
nsIScrollableFrame* mScrollableFrame;
|
||||
|
||||
void HandleEventForScrollbar(const nsAString& aType,
|
||||
nsIContent* aTarget,
|
||||
nsIContent* aScrollbar,
|
||||
bool* aStoredHoverState);
|
||||
nsCOMPtr<nsITimer> mActivityFinishedTimer;
|
||||
|
||||
void SetIsActive(bool aNewActive);
|
||||
void SetIsFading(bool aNewFading);
|
||||
|
||||
void BeginFade();
|
||||
void EndFade();
|
||||
|
||||
void StartFadeBeginTimer();
|
||||
void CancelFadeBeginTimer();
|
||||
void StartListeningForEvents();
|
||||
void StartListeningForEventsOnScrollbar(nsIDOMEventTarget* aScrollbar);
|
||||
void StopListeningForEvents();
|
||||
void StopListeningForEventsOnScrollbar(nsIDOMEventTarget* aScrollbar);
|
||||
void RegisterWithRefreshDriver();
|
||||
void UnregisterFromRefreshDriver();
|
||||
|
||||
void UpdateOpacity(TimeStamp aTime);
|
||||
void HoveredScrollbar(nsIContent* aScrollbar);
|
||||
|
||||
nsRefreshDriver* GetRefreshDriver();
|
||||
nsIContent* GetScrollbarContent(bool aVertical);
|
||||
nsIContent* GetHorizontalScrollbar() { return GetScrollbarContent(false); }
|
||||
nsIContent* GetVerticalScrollbar() { return GetScrollbarContent(true); }
|
||||
|
||||
static const TimeDuration FadeDuration() {
|
||||
return TimeDuration::FromMilliseconds(kScrollbarFadeDuration);
|
||||
enum { kScrollbarActivityFinishedDelay = 450 }; // milliseconds
|
||||
static void ActivityFinishedTimerFired(nsITimer* aTimer, void* aSelf) {
|
||||
reinterpret_cast<ScrollbarActivity*>(aSelf)->ActivityFinished();
|
||||
}
|
||||
void StartActivityFinishedTimer();
|
||||
void CancelActivityFinishedTimer();
|
||||
|
||||
nsIScrollbarOwner* mScrollableFrame;
|
||||
TimeStamp mFadeBeginTime;
|
||||
nsCOMPtr<nsITimer> mFadeBeginTimer;
|
||||
nsCOMPtr<nsIDOMEventTarget> mHorizontalScrollbar; // null while inactive
|
||||
nsCOMPtr<nsIDOMEventTarget> mVerticalScrollbar; // null while inactive
|
||||
int mNestedActivityCounter;
|
||||
bool mIsActive;
|
||||
bool mIsFading;
|
||||
bool mListeningForEvents;
|
||||
bool mHScrollbarHovered;
|
||||
bool mVScrollbarHovered;
|
||||
nsIContent* GetScrollbarContent(bool aVertical);
|
||||
nsIContent* GetHorizontalScrollbar() {
|
||||
return GetScrollbarContent(false);
|
||||
}
|
||||
nsIContent* GetVerticalScrollbar() {
|
||||
return GetScrollbarContent(true);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* ScrollbarActivity_h___ */
|
||||
|
@ -25,7 +25,6 @@ EXPORTS += [
|
||||
'nsIObjectFrame.h',
|
||||
'nsIPageSequenceFrame.h',
|
||||
'nsIScrollableFrame.h',
|
||||
'nsIScrollbarOwner.h',
|
||||
'nsIStatefulFrame.h',
|
||||
'nsObjectFrame.h',
|
||||
'nsQueryFrame.h',
|
||||
|
@ -55,7 +55,6 @@ FRAME_ID(nsISVGGlyphFragmentNode)
|
||||
FRAME_ID(nsISVGSVGFrame)
|
||||
FRAME_ID(nsIScrollableFrame)
|
||||
FRAME_ID(nsIScrollbarMediator)
|
||||
FRAME_ID(nsIScrollbarOwner)
|
||||
FRAME_ID(nsISelectControlFrame)
|
||||
FRAME_ID(nsIStatefulFrame)
|
||||
FRAME_ID(nsITableCellLayout)
|
||||
|
@ -60,7 +60,6 @@
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::layout;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
@ -226,23 +225,11 @@ GetScrollbarMetrics(nsBoxLayoutState& aState, nsIFrame* aBox, nsSize* aMin,
|
||||
if (aMin) {
|
||||
*aMin = aBox->GetMinSize(aState);
|
||||
nsBox::AddMargin(aBox, *aMin);
|
||||
if (aMin->width < 0) {
|
||||
aMin->width = 0;
|
||||
}
|
||||
if (aMin->height < 0) {
|
||||
aMin->height = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (aPref) {
|
||||
*aPref = aBox->GetPrefSize(aState);
|
||||
nsBox::AddMargin(aBox, *aPref);
|
||||
if (aPref->width < 0) {
|
||||
aPref->width = 0;
|
||||
}
|
||||
if (aPref->height < 0) {
|
||||
aPref->height = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -881,7 +868,6 @@ nsHTMLScrollFrame::AccessibleType()
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsHTMLScrollFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
||||
NS_QUERYFRAME_ENTRY(nsIScrollbarOwner)
|
||||
NS_QUERYFRAME_ENTRY(nsIScrollableFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIStatefulFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||
@ -1129,7 +1115,6 @@ nsXULScrollFrame::DoLayout(nsBoxLayoutState& aState)
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsXULScrollFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
||||
NS_QUERYFRAME_ENTRY(nsIScrollbarOwner)
|
||||
NS_QUERYFRAME_ENTRY(nsIScrollableFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIStatefulFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsBoxFrame)
|
||||
@ -1482,7 +1467,7 @@ nsGfxScrollFrameInner::nsGfxScrollFrameInner(nsContainerFrame* aOuter,
|
||||
{
|
||||
mScrollingActive = IsAlwaysActive();
|
||||
|
||||
if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
|
||||
if (LookAndFeel::GetInt(LookAndFeel::eIntID_ShowHideScrollbars) != 0) {
|
||||
mScrollbarActivity = new ScrollbarActivity(do_QueryFrame(aOuter));
|
||||
}
|
||||
}
|
||||
@ -2836,7 +2821,6 @@ void
|
||||
nsGfxScrollFrameInner::Destroy()
|
||||
{
|
||||
if (mScrollbarActivity) {
|
||||
mScrollbarActivity->Destroy();
|
||||
mScrollbarActivity = nullptr;
|
||||
}
|
||||
|
||||
@ -3618,26 +3602,6 @@ nsGfxScrollFrameInner::AdjustScrollbarRectForResizer(
|
||||
aRect.width = std::max(0, resizerRect.x - aRect.x);
|
||||
}
|
||||
|
||||
static void
|
||||
AdjustOverlappingScrollbars(nsRect& aVRect, nsRect& aHRect)
|
||||
{
|
||||
if (aVRect.IsEmpty() || aHRect.IsEmpty())
|
||||
return;
|
||||
|
||||
const nsRect oldVRect = aVRect;
|
||||
const nsRect oldHRect = aHRect;
|
||||
if (oldVRect.Contains(oldHRect.BottomRight() - nsPoint(1, 1))) {
|
||||
aHRect.width = std::max(0, oldVRect.x - oldHRect.x);
|
||||
} else if (oldVRect.Contains(oldHRect.BottomLeft() - nsPoint(0, 1))) {
|
||||
nscoord overlap = std::min(oldHRect.width, oldVRect.XMost() - oldHRect.x);
|
||||
aHRect.x += overlap;
|
||||
aHRect.width -= overlap;
|
||||
}
|
||||
if (oldHRect.Contains(oldVRect.BottomRight() - nsPoint(1, 1))) {
|
||||
aVRect.height = std::max(0, oldHRect.y - oldVRect.y);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
||||
const nsRect& aContentArea,
|
||||
@ -3680,21 +3644,22 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
||||
|
||||
if (hasResizer) {
|
||||
// if a resizer is present, get its size. Assume a default size of 15 pixels.
|
||||
nsSize resizerSize;
|
||||
nscoord defaultSize = nsPresContext::CSSPixelsToAppUnits(15);
|
||||
nsSize resizerMinSize = mResizerBox->GetMinSize(aState);
|
||||
|
||||
nscoord vScrollbarWidth = mVScrollbarBox ?
|
||||
resizerSize.width = mVScrollbarBox ?
|
||||
mVScrollbarBox->GetPrefSize(aState).width : defaultSize;
|
||||
r.width = std::max(std::max(r.width, vScrollbarWidth), resizerMinSize.width);
|
||||
if (aContentArea.x == mScrollPort.x && !scrollbarOnLeft) {
|
||||
r.x = aContentArea.XMost() - r.width;
|
||||
if (resizerSize.width > r.width) {
|
||||
r.width = resizerSize.width;
|
||||
if (aContentArea.x == mScrollPort.x && !scrollbarOnLeft)
|
||||
r.x = aContentArea.XMost() - r.width;
|
||||
}
|
||||
|
||||
nscoord hScrollbarHeight = mHScrollbarBox ?
|
||||
resizerSize.height = mHScrollbarBox ?
|
||||
mHScrollbarBox->GetPrefSize(aState).height : defaultSize;
|
||||
r.height = std::max(std::max(r.height, hScrollbarHeight), resizerMinSize.height);
|
||||
if (aContentArea.y == mScrollPort.y) {
|
||||
r.y = aContentArea.YMost() - r.height;
|
||||
if (resizerSize.height > r.height) {
|
||||
r.height = resizerSize.height;
|
||||
if (aContentArea.y == mScrollPort.y)
|
||||
r.y = aContentArea.YMost() - r.height;
|
||||
}
|
||||
|
||||
nsBoxFrame::LayoutChildAt(aState, mResizerBox, r);
|
||||
@ -3706,10 +3671,9 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
||||
}
|
||||
|
||||
nsPresContext* presContext = mScrolledFrame->PresContext();
|
||||
nsRect vRect;
|
||||
if (mVScrollbarBox) {
|
||||
NS_PRECONDITION(mVScrollbarBox->IsBoxFrame(), "Must be a box frame!");
|
||||
vRect = mScrollPort;
|
||||
nsRect vRect(mScrollPort);
|
||||
vRect.width = aContentArea.width - mScrollPort.width;
|
||||
vRect.x = scrollbarOnLeft ? aContentArea.x : mScrollPort.XMost();
|
||||
if (mHasVerticalScrollbar) {
|
||||
@ -3718,12 +3682,12 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
||||
vRect.Deflate(margin);
|
||||
}
|
||||
AdjustScrollbarRectForResizer(mOuter, presContext, vRect, hasResizer, true);
|
||||
nsBoxFrame::LayoutChildAt(aState, mVScrollbarBox, vRect);
|
||||
}
|
||||
|
||||
nsRect hRect;
|
||||
if (mHScrollbarBox) {
|
||||
NS_PRECONDITION(mHScrollbarBox->IsBoxFrame(), "Must be a box frame!");
|
||||
hRect = mScrollPort;
|
||||
nsRect hRect(mScrollPort);
|
||||
hRect.height = aContentArea.height - mScrollPort.height;
|
||||
hRect.y = true ? mScrollPort.YMost() : aContentArea.y;
|
||||
if (mHasHorizontalScrollbar) {
|
||||
@ -3732,13 +3696,6 @@ nsGfxScrollFrameInner::LayoutScrollbars(nsBoxLayoutState& aState,
|
||||
hRect.Deflate(margin);
|
||||
}
|
||||
AdjustScrollbarRectForResizer(mOuter, presContext, hRect, hasResizer, false);
|
||||
}
|
||||
|
||||
AdjustOverlappingScrollbars(vRect, hRect);
|
||||
if (mVScrollbarBox) {
|
||||
nsBoxFrame::LayoutChildAt(aState, mVScrollbarBox, vRect);
|
||||
}
|
||||
if (mHScrollbarBox) {
|
||||
nsBoxFrame::LayoutChildAt(aState, mHScrollbarBox, hRect);
|
||||
}
|
||||
|
||||
|
@ -34,10 +34,8 @@ class nsPresState;
|
||||
struct ScrollReflowState;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
class ScrollbarActivity;
|
||||
}
|
||||
}
|
||||
|
||||
// When set, the next scroll operation on the scrollframe will invalidate its
|
||||
// entire contents. Useful for text-overflow.
|
||||
@ -48,7 +46,6 @@ class ScrollbarActivity;
|
||||
class nsGfxScrollFrameInner : public nsIReflowCallback {
|
||||
public:
|
||||
typedef mozilla::gfx::Point Point;
|
||||
typedef mozilla::layout::ScrollbarActivity ScrollbarActivity;
|
||||
|
||||
class AsyncScroll;
|
||||
|
||||
@ -284,7 +281,7 @@ public:
|
||||
nsIFrame* mResizerBox;
|
||||
nsContainerFrame* mOuter;
|
||||
nsRefPtr<AsyncScroll> mAsyncScroll;
|
||||
nsCOMPtr<ScrollbarActivity> mScrollbarActivity;
|
||||
nsAutoPtr<mozilla::ScrollbarActivity> mScrollbarActivity;
|
||||
nsTArray<nsIScrollPositionListener*> mListeners;
|
||||
nsRect mScrollPort;
|
||||
// Where we're currently scrolling to, if we're scrolling asynchronously.
|
||||
@ -460,11 +457,6 @@ public:
|
||||
virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
|
||||
uint32_t aFilter) MOZ_OVERRIDE;
|
||||
|
||||
// nsIScrollbarOwner
|
||||
virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
|
||||
return mInner.GetScrollbarBox(aVertical);
|
||||
}
|
||||
|
||||
// nsIScrollableFrame
|
||||
virtual nsIFrame* GetScrolledFrame() const {
|
||||
return mInner.GetScrolledFrame();
|
||||
@ -533,6 +525,9 @@ public:
|
||||
virtual void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) MOZ_OVERRIDE {
|
||||
mInner.RemoveScrollPositionListener(aListener);
|
||||
}
|
||||
virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
|
||||
return mInner.GetScrollbarBox(aVertical);
|
||||
}
|
||||
virtual void CurPosAttributeChanged(nsIContent* aChild) MOZ_OVERRIDE {
|
||||
mInner.CurPosAttributeChanged(aChild);
|
||||
}
|
||||
@ -718,11 +713,6 @@ public:
|
||||
static void AdjustReflowStateForPrintPreview(nsBoxLayoutState& aState, bool& aSetBack);
|
||||
static void AdjustReflowStateBack(nsBoxLayoutState& aState, bool aSetBack);
|
||||
|
||||
// nsIScrollbarOwner
|
||||
virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
|
||||
return mInner.GetScrollbarBox(aVertical);
|
||||
}
|
||||
|
||||
// nsIScrollableFrame
|
||||
virtual nsIFrame* GetScrolledFrame() const {
|
||||
return mInner.GetScrolledFrame();
|
||||
@ -791,6 +781,9 @@ public:
|
||||
virtual void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) MOZ_OVERRIDE {
|
||||
mInner.RemoveScrollPositionListener(aListener);
|
||||
}
|
||||
virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
|
||||
return mInner.GetScrollbarBox(aVertical);
|
||||
}
|
||||
virtual void CurPosAttributeChanged(nsIContent* aChild) MOZ_OVERRIDE {
|
||||
mInner.CurPosAttributeChanged(aChild);
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "nsCoord.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "mozilla/gfx/Point.h"
|
||||
#include "nsIScrollbarOwner.h"
|
||||
|
||||
#define NS_DEFAULT_VERTICAL_SCROLL_DISTANCE 3
|
||||
#define NS_DEFAULT_HORIZONTAL_SCROLL_DISTANCE 5
|
||||
@ -28,7 +27,7 @@ class nsIFrame;
|
||||
* APIs for examining scroll state, observing changes to scroll state,
|
||||
* and triggering scrolling.
|
||||
*/
|
||||
class nsIScrollableFrame : public nsIScrollbarOwner {
|
||||
class nsIScrollableFrame : public nsQueryFrame {
|
||||
public:
|
||||
typedef mozilla::gfx::Point Point;
|
||||
|
||||
@ -203,6 +202,14 @@ public:
|
||||
*/
|
||||
virtual void RemoveScrollPositionListener(nsIScrollPositionListener* aListener) = 0;
|
||||
|
||||
/**
|
||||
* Obtain the XUL box for the horizontal or vertical scrollbar, or null
|
||||
* if there is no such box. Avoid using this, but may be useful for
|
||||
* setting up a scrollbar mediator if you want to redirect scrollbar
|
||||
* input.
|
||||
*/
|
||||
virtual nsIFrame* GetScrollbarBox(bool aVertical) = 0;
|
||||
|
||||
/**
|
||||
* Internal method used by scrollbars to notify their scrolling
|
||||
* container of changes.
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef nsIScrollbarOwner_h___
|
||||
#define nsIScrollbarOwner_h___
|
||||
|
||||
#include "nsQueryFrame.h"
|
||||
|
||||
class nsIDOMEventTarget;
|
||||
class nsIFrame;
|
||||
|
||||
/**
|
||||
* An interface that represents a frame which manages scrollbars.
|
||||
*/
|
||||
class nsIScrollbarOwner : public nsQueryFrame {
|
||||
public:
|
||||
NS_DECL_QUERYFRAME_TARGET(nsIScrollbarOwner)
|
||||
|
||||
/**
|
||||
* Obtain the frame for the horizontal or vertical scrollbar, or null
|
||||
* if there is no such box.
|
||||
*/
|
||||
virtual nsIFrame* GetScrollbarBox(bool aVertical) = 0;
|
||||
};
|
||||
|
||||
#endif
|
@ -168,18 +168,18 @@ skip-if(B2G) == 192767-26.xul 192767-36.xul
|
||||
skip-if(B2G) == 192767-27.xul 192767-37.xul
|
||||
!= 192767-01.xul 192767-21.xul
|
||||
!= 192767-02.xul 192767-22.xul
|
||||
skip-if(B2G) fails-if(Android) != 192767-03.xul 192767-23.xul
|
||||
fails-if(Android) != 192767-03.xul 192767-23.xul
|
||||
!= 192767-04.xul 192767-24.xul
|
||||
!= 192767-05.xul 192767-25.xul
|
||||
skip-if(B2G) fails-if(Android) != 192767-06.xul 192767-26.xul
|
||||
skip-if(B2G) fails-if(Android) != 192767-07.xul 192767-27.xul
|
||||
fails-if(Android) != 192767-06.xul 192767-26.xul
|
||||
fails-if(Android) != 192767-07.xul 192767-27.xul
|
||||
!= 192767-11.xul 192767-31.xul
|
||||
!= 192767-12.xul 192767-32.xul
|
||||
skip-if(B2G) fails-if(Android) != 192767-13.xul 192767-33.xul
|
||||
fails-if(Android) != 192767-13.xul 192767-33.xul
|
||||
!= 192767-14.xul 192767-34.xul
|
||||
!= 192767-15.xul 192767-35.xul
|
||||
skip-if(B2G) fails-if(Android) != 192767-16.xul 192767-36.xul
|
||||
skip-if(B2G) fails-if(Android) != 192767-17.xul 192767-37.xul
|
||||
fails-if(Android) != 192767-16.xul 192767-36.xul
|
||||
fails-if(Android) != 192767-17.xul 192767-37.xul
|
||||
!= 200774-1.html about:blank
|
||||
== 201215-1.html 201215-1-ref.html
|
||||
== 201293-1a.html 201293-1-ref.html
|
||||
|
@ -60,7 +60,6 @@
|
||||
#include "nsRenderingContext.h"
|
||||
#include "nsIScriptableRegion.h"
|
||||
#include <algorithm>
|
||||
#include "ScrollbarActivity.h"
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsAccessibilityService.h"
|
||||
@ -70,7 +69,6 @@
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::layout;
|
||||
|
||||
// Enumeration function that cancels all the image requests in our cache
|
||||
static PLDHashOperator
|
||||
@ -104,7 +102,6 @@ NS_IMPL_FRAMEARENA_HELPERS(nsTreeBodyFrame)
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsTreeBodyFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIScrollbarMediator)
|
||||
NS_QUERYFRAME_ENTRY(nsIScrollbarOwner)
|
||||
NS_QUERYFRAME_ENTRY(nsTreeBodyFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsLeafBoxFrame)
|
||||
|
||||
@ -172,11 +169,6 @@ nsTreeBodyFrame::Init(nsIContent* aContent,
|
||||
|
||||
mImageCache.Init(16);
|
||||
EnsureBoxObject();
|
||||
|
||||
if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
|
||||
mScrollbarActivity = new ScrollbarActivity(
|
||||
static_cast<nsIScrollbarOwner*>(this));
|
||||
}
|
||||
}
|
||||
|
||||
nsSize
|
||||
@ -274,11 +266,6 @@ nsTreeBodyFrame::CalcMaxRowWidth()
|
||||
void
|
||||
nsTreeBodyFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
if (mScrollbarActivity) {
|
||||
mScrollbarActivity->Destroy();
|
||||
mScrollbarActivity = nullptr;
|
||||
}
|
||||
|
||||
mScrollEvent.Revoke();
|
||||
// Make sure we cancel any posted callbacks.
|
||||
if (mReflowCallbackPosted) {
|
||||
@ -850,13 +837,15 @@ nsTreeBodyFrame::UpdateScrollbars(const ScrollParts& aParts)
|
||||
{
|
||||
nscoord rowHeightAsPixels = nsPresContext::AppUnitsToIntCSSPixels(mRowHeight);
|
||||
|
||||
nsWeakFrame weakFrame(this);
|
||||
|
||||
if (aParts.mVScrollbar) {
|
||||
nsWeakFrame self(this);
|
||||
nsAutoString curPos;
|
||||
curPos.AppendInt(mTopRowIndex*rowHeightAsPixels);
|
||||
aParts.mVScrollbarContent->
|
||||
SetAttr(kNameSpaceID_None, nsGkAtoms::curpos, curPos, true);
|
||||
if (!self.IsAlive()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (aParts.mHScrollbar) {
|
||||
@ -866,10 +855,6 @@ nsTreeBodyFrame::UpdateScrollbars(const ScrollParts& aParts)
|
||||
SetAttr(kNameSpaceID_None, nsGkAtoms::curpos, curPos, true);
|
||||
// 'this' might be deleted here
|
||||
}
|
||||
|
||||
if (weakFrame.IsAlive() && mScrollbarActivity) {
|
||||
mScrollbarActivity->ActivityOccurred();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -972,10 +957,6 @@ nsTreeBodyFrame::InvalidateScrollbars(const ScrollParts& aParts, nsWeakFrame& aW
|
||||
aParts.mHScrollbarContent->
|
||||
SetAttr(kNameSpaceID_None, nsGkAtoms::increment, pageStr, true);
|
||||
}
|
||||
|
||||
if (mScrollbarActivity) {
|
||||
mScrollbarActivity->ActivityOccurred();
|
||||
}
|
||||
}
|
||||
|
||||
// Takes client x/y in pixels, converts them to appunits, and converts into
|
||||
|
@ -24,17 +24,10 @@
|
||||
#include "nsScrollbarFrame.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "nsIScrollbarOwner.h"
|
||||
|
||||
class nsOverflowChecker;
|
||||
class nsTreeImageListener;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
class ScrollbarActivity;
|
||||
}
|
||||
}
|
||||
|
||||
// An entry in the tree's image cache
|
||||
struct nsTreeImageCacheEntry
|
||||
{
|
||||
@ -52,11 +45,8 @@ class nsTreeBodyFrame MOZ_FINAL
|
||||
, public nsICSSPseudoComparator
|
||||
, public nsIScrollbarMediator
|
||||
, public nsIReflowCallback
|
||||
, public nsIScrollbarOwner
|
||||
{
|
||||
public:
|
||||
typedef mozilla::layout::ScrollbarActivity ScrollbarActivity;
|
||||
|
||||
nsTreeBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
~nsTreeBodyFrame();
|
||||
|
||||
@ -136,12 +126,6 @@ public:
|
||||
NS_IMETHOD ScrollbarButtonPressed(nsScrollbarFrame* aScrollbar, int32_t aOldIndex, int32_t aNewIndex) MOZ_OVERRIDE;
|
||||
NS_IMETHOD VisibilityChanged(bool aVisible) MOZ_OVERRIDE { Invalidate(); return NS_OK; }
|
||||
|
||||
// nsIScrollbarOwner
|
||||
virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
|
||||
ScrollParts parts = GetScrollParts();
|
||||
return aVertical ? parts.mVScrollbar : parts.mHScrollbar;
|
||||
}
|
||||
|
||||
// Overridden from nsIFrame to cache our pres context.
|
||||
virtual void Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
@ -541,8 +525,6 @@ protected: // Data Members
|
||||
|
||||
nsRevocableEventPtr<ScrollEvent> mScrollEvent;
|
||||
|
||||
nsCOMPtr<ScrollbarActivity> mScrollbarActivity;
|
||||
|
||||
// The cached box object parent.
|
||||
nsCOMPtr<nsITreeBoxObject> mTreeBoxObject;
|
||||
|
||||
|
@ -80,7 +80,7 @@ function test()
|
||||
<select id="f" style="width: 100px; height: 100px;"><option>a</option><option>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</option><option>a</option>\
|
||||
<option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option>\
|
||||
<option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option></select>\
|
||||
<div id="g" style="width: 99px; height: 99px; border: 10px solid black; margin: 10px; overflow: auto;"><div style="width: 100px; height: 100px;"></div></div>\
|
||||
<div id="g" style="width: 99px; height: 99px; padding: 10px; border: 10px solid black; margin: 10px; overflow: auto;"><div style="width: 100px; height: 100px; margin: 10px;"></div></div>\
|
||||
<div id="h" style="width: 100px; height: 100px; overflow: -moz-hidden-unscrollable;"><div style="width: 200px; height: 200px;"></div></div>\
|
||||
<iframe id="iframe" style="display: none;"></iframe>\
|
||||
</body>';
|
||||
|
@ -98,13 +98,11 @@ function testListbox()
|
||||
var id = "listbox";
|
||||
var listbox = document.getElementById(id);
|
||||
|
||||
if (!window.matchMedia("(-moz-overlay-scrollbars)").matches) {
|
||||
// Check that a scrollbar is visible by comparing the width of the listitem
|
||||
// with the width of the listbox. This is a simple way to do this without
|
||||
// checking the anonymous content.
|
||||
ok(listbox.firstChild.getBoundingClientRect().width < listbox.getBoundingClientRect().width - 10,
|
||||
id + ": Scrollbar visible");
|
||||
}
|
||||
// Check that a scrollbar is visible by comparing the width of the listitem
|
||||
// with the width of the listbox. This is a simple way to do this without
|
||||
// checking the anonymous content.
|
||||
ok(listbox.firstChild.getBoundingClientRect().width < listbox.getBoundingClientRect().width - 10,
|
||||
id + ": Scrollbar visible");
|
||||
|
||||
var rowHeight = listbox.firstChild.getBoundingClientRect().height;
|
||||
|
||||
|
@ -88,8 +88,7 @@ function differentPressed()
|
||||
list.open = true;
|
||||
is(list.getBoundingClientRect().width, list.firstChild.getBoundingClientRect().width,
|
||||
"menu and popup width match");
|
||||
var minScrollbarWidth = window.matchMedia("(-moz-overlay-scrollbars)").matches ? 0 : 3;
|
||||
ok(list.getBoundingClientRect().width >= list.getItemAtIndex(0).getBoundingClientRect().width + minScrollbarWidth,
|
||||
ok(list.getBoundingClientRect().width > list.getItemAtIndex(0).getBoundingClientRect().width + 2,
|
||||
"menuitem width accounts for scrollbar");
|
||||
list.open = false;
|
||||
|
||||
|
@ -18,8 +18,7 @@
|
||||
curpos="0"
|
||||
maxpos="600"
|
||||
pageincrement="400"
|
||||
width="500"
|
||||
style="margin:0"/>
|
||||
width="500"/>
|
||||
</hbox>
|
||||
|
||||
<!-- test code goes here -->
|
||||
|
@ -925,7 +925,7 @@ grippy {
|
||||
/********** scrollbar **********/
|
||||
|
||||
/* Scrollbars are never flipped even if BiDI kicks in. */
|
||||
scrollbar[orient="horizontal"] {
|
||||
scrollbar {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
|
@ -17,26 +17,6 @@ html|select[multiple] > scrollbar {
|
||||
-moz-appearance: scrollbar-small;
|
||||
}
|
||||
|
||||
@media all and (-moz-overlay-scrollbars) {
|
||||
scrollbar {
|
||||
position: relative;
|
||||
z-index: 2147483647;
|
||||
}
|
||||
|
||||
scrollbar:not([active="true"]),
|
||||
scrollbar[disabled="true"] {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
scrollbar[orient="vertical"] {
|
||||
-moz-margin-start: -16px;
|
||||
}
|
||||
|
||||
scrollbar[orient="horizontal"] {
|
||||
margin-top: -16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ..... track ..... */
|
||||
|
||||
slider {
|
||||
|
@ -9,9 +9,7 @@ resizer {
|
||||
background: url("chrome://global/skin/icons/resizer.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
cursor: se-resize;
|
||||
min-width: 15px;
|
||||
width: 15px;
|
||||
min-height: 15px;
|
||||
height: 15px;
|
||||
}
|
||||
@media (min-resolution: 2dppx) {
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIDOMHTMLMeterElement.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsLookAndFeel.h"
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxQuartzSurface.h"
|
||||
@ -2285,73 +2284,34 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
|
||||
}
|
||||
|
||||
case NS_THEME_SCROLLBAR_SMALL:
|
||||
case NS_THEME_SCROLLBAR:
|
||||
if (!nsLookAndFeel::UseOverlayScrollbars()) {
|
||||
DrawScrollbar(cgContext, macRect, aFrame);
|
||||
}
|
||||
case NS_THEME_SCROLLBAR: {
|
||||
DrawScrollbar(cgContext, macRect, aFrame);
|
||||
}
|
||||
break;
|
||||
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
||||
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
||||
if (nsLookAndFeel::UseOverlayScrollbars()) {
|
||||
BOOL isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_THUMB_HORIZONTAL);
|
||||
BOOL isRolledOver = CheckBooleanAttr(GetParentScrollbarFrame(aFrame),
|
||||
nsGkAtoms::hover);
|
||||
if (!isRolledOver) {
|
||||
if (isHorizontal) {
|
||||
macRect.origin.y += 4;
|
||||
macRect.size.height -= 4;
|
||||
} else {
|
||||
macRect.origin.x += 4;
|
||||
macRect.size.width -= 4;
|
||||
}
|
||||
}
|
||||
const BOOL isOnTopOfBrightBackground = YES; // TODO: detect this properly
|
||||
CUIDraw([NSWindow coreUIRenderer], macRect, cgContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"kCUIWidgetOverlayScrollBar", @"widget",
|
||||
@"regular", @"size",
|
||||
(isRolledOver ? @"rollover" : @""), @"state",
|
||||
(isHorizontal ? @"kCUIOrientHorizontal" : @"kCUIOrientVertical"), @"kCUIOrientationKey",
|
||||
(isOnTopOfBrightBackground ? @"" : @"kCUIVariantWhite"), @"kCUIVariantKey",
|
||||
[NSNumber numberWithBool:YES], @"indiconly",
|
||||
[NSNumber numberWithBool:YES], @"kCUIThumbProportionKey",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
nil],
|
||||
nil);
|
||||
}
|
||||
break;
|
||||
#if SCROLLBARS_VISUAL_DEBUG
|
||||
CGContextSetRGBFillColor(cgContext, 1.0, 1.0, 0, 0.6);
|
||||
CGContextFillRect(cgContext, macRect);
|
||||
break;
|
||||
#endif
|
||||
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
||||
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
||||
#if SCROLLBARS_VISUAL_DEBUG
|
||||
CGContextSetRGBFillColor(cgContext, 1.0, 0, 0, 0.6);
|
||||
CGContextFillRect(cgContext, macRect);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
||||
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
|
||||
#if SCROLLBARS_VISUAL_DEBUG
|
||||
CGContextSetRGBFillColor(cgContext, 0, 1.0, 0, 0.6);
|
||||
CGContextFillRect(cgContext, macRect);
|
||||
break;
|
||||
#endif
|
||||
break;
|
||||
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
||||
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
||||
if (nsLookAndFeel::UseOverlayScrollbars() &&
|
||||
CheckBooleanAttr(GetParentScrollbarFrame(aFrame), nsGkAtoms::hover)) {
|
||||
BOOL isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL);
|
||||
const BOOL isOnTopOfBrightBackground = YES; // TODO: detect this properly
|
||||
CUIDraw([NSWindow coreUIRenderer], macRect, cgContext,
|
||||
(CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"kCUIWidgetOverlayScrollBar", @"widget",
|
||||
@"regular", @"size",
|
||||
(isHorizontal ? @"kCUIOrientHorizontal" : @"kCUIOrientVertical"), @"kCUIOrientationKey",
|
||||
(isOnTopOfBrightBackground ? @"" : @"kCUIVariantWhite"), @"kCUIVariantKey",
|
||||
[NSNumber numberWithBool:YES], @"noindicator",
|
||||
[NSNumber numberWithBool:YES], @"kCUIThumbProportionKey",
|
||||
[NSNumber numberWithBool:YES], @"is.flipped",
|
||||
nil],
|
||||
nil);
|
||||
}
|
||||
// do nothing, drawn by scrollbar
|
||||
break;
|
||||
|
||||
case NS_THEME_TEXTFIELD_MULTILINE: {
|
||||
@ -2523,13 +2483,13 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDeviceContext* aContext,
|
||||
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
||||
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
||||
{
|
||||
bool isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL);
|
||||
|
||||
// On Lion and later, scrollbars have no arrows.
|
||||
if (!nsCocoaFeatures::OnLionOrLater()) {
|
||||
// There's only an endcap to worry about when both arrows are on the bottom
|
||||
NSString *buttonPlacement = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleScrollBarVariant"];
|
||||
if (!buttonPlacement || [buttonPlacement isEqualToString:@"DoubleMax"]) {
|
||||
bool isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL);
|
||||
|
||||
nsIFrame *scrollbarFrame = GetParentScrollbarFrame(aFrame);
|
||||
if (!scrollbarFrame) return NS_ERROR_FAILURE;
|
||||
bool isSmall = (scrollbarFrame->StyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL);
|
||||
@ -2544,15 +2504,6 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDeviceContext* aContext,
|
||||
aResult->SizeTo(endcapSize, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (nsLookAndFeel::UseOverlayScrollbars()) {
|
||||
if (isHorizontal) {
|
||||
aResult->SizeTo(1, 2, 1, 1);
|
||||
} else {
|
||||
aResult->SizeTo(2, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2639,7 +2590,7 @@ nsNativeThemeCocoa::GetWidgetOverflow(nsDeviceContext* aContext, nsIFrame* aFram
|
||||
return false;
|
||||
}
|
||||
|
||||
static const int32_t kRegularScrollbarThumbMinSize = 26;
|
||||
static const int32_t kRegularScrollbarThumbMinSize = 22;
|
||||
static const int32_t kSmallScrollbarThumbMinSize = 19;
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -2778,6 +2729,15 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsRenderingContext* aContext,
|
||||
*aIsOverridable = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case NS_THEME_SCROLLBAR_SMALL:
|
||||
{
|
||||
SInt32 scrollbarWidth = 0;
|
||||
::GetThemeMetric(kThemeMetricSmallScrollBarWidth, &scrollbarWidth);
|
||||
aResult->SizeTo(scrollbarWidth, scrollbarWidth);
|
||||
*aIsOverridable = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
||||
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
||||
@ -2796,17 +2756,9 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsRenderingContext* aContext,
|
||||
}
|
||||
|
||||
case NS_THEME_SCROLLBAR:
|
||||
case NS_THEME_SCROLLBAR_SMALL:
|
||||
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
||||
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
||||
{
|
||||
*aIsOverridable = false;
|
||||
|
||||
if (nsLookAndFeel::UseOverlayScrollbars()) {
|
||||
aResult->SizeTo(16, 16);
|
||||
break;
|
||||
}
|
||||
|
||||
// yeah, i know i'm cheating a little here, but i figure that it
|
||||
// really doesn't matter if the scrollbar is vertical or horizontal
|
||||
// and the width metric is a really good metric for every piece
|
||||
@ -2821,6 +2773,7 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsRenderingContext* aContext,
|
||||
SInt32 scrollbarWidth = 0;
|
||||
::GetThemeMetric(themeMetric, &scrollbarWidth);
|
||||
aResult->SizeTo(scrollbarWidth, scrollbarWidth);
|
||||
*aIsOverridable = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2882,6 +2835,8 @@ nsNativeThemeCocoa::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
|
||||
case NS_THEME_TOOLBOX:
|
||||
case NS_THEME_TOOLBAR:
|
||||
case NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR:
|
||||
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
||||
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
||||
case NS_THEME_STATUSBAR:
|
||||
case NS_THEME_STATUSBAR_PANEL:
|
||||
case NS_THEME_STATUSBAR_RESIZER_PANEL:
|
||||
@ -2918,8 +2873,7 @@ nsNativeThemeCocoa::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType,
|
||||
aAttribute == nsGkAtoms::sortDirection ||
|
||||
aAttribute == nsGkAtoms::focused ||
|
||||
aAttribute == nsGkAtoms::_default ||
|
||||
aAttribute == nsGkAtoms::open ||
|
||||
aAttribute == nsGkAtoms::hover)
|
||||
aAttribute == nsGkAtoms::open)
|
||||
*aShouldRepaint = true;
|
||||
}
|
||||
|
||||
@ -3031,12 +2985,11 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a
|
||||
|
||||
// Note that IsWidgetStyled is not called for resizers on Mac. This is
|
||||
// because for scrollable containers, the native resizer looks better
|
||||
// when (non-overlay) scrollbars are present even when the style is
|
||||
// overriden, and the custom transparent resizer looks better when
|
||||
// scrollbars are not present.
|
||||
// when scrollbars are present even when the style is overriden, and the
|
||||
// custom transparent resizer looks better when scrollbars are not
|
||||
// present.
|
||||
nsIScrollableFrame* scrollFrame = do_QueryFrame(parentFrame);
|
||||
return (!nsLookAndFeel::UseOverlayScrollbars() &&
|
||||
scrollFrame && scrollFrame->GetScrollbarVisibility());
|
||||
return (scrollFrame && scrollFrame->GetScrollbarVisibility());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3091,8 +3044,6 @@ nsNativeThemeCocoa::GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType)
|
||||
|
||||
case NS_THEME_SCROLLBAR_SMALL:
|
||||
case NS_THEME_SCROLLBAR:
|
||||
return nsLookAndFeel::UseOverlayScrollbars() ? eTransparent : eOpaque;
|
||||
|
||||
case NS_THEME_STATUSBAR:
|
||||
// Knowing that scrollbars and statusbars are opaque improves
|
||||
// performance, because we create layers for them.
|
||||
|
@ -58,7 +58,7 @@ function runTest() {
|
||||
var elem = document.getElementById(orient + size);
|
||||
var thumbRect = document.getAnonymousElementByAttribute(elem, 'sbattr', 'scrollbar-thumb').getBoundingClientRect();
|
||||
var sizeToCheck = orient == "horizontal" ? "width" : "height";
|
||||
var expectedSize = size == "Small" ? 19 : 26;
|
||||
var expectedSize = size == "Small" ? 19 : 22;
|
||||
is(thumbRect[sizeToCheck], expectedSize, size + " scrollbar has wrong minimum " + sizeToCheck);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user