Merge inbound to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2015-05-04 15:59:00 -04:00
commit 634d37ccd0
98 changed files with 1257 additions and 1212 deletions

View File

@ -2769,9 +2769,9 @@ Element::PreHandleEventForLinks(EventChainPreVisitor& aVisitor)
// Optimisation: return early if this event doesn't interest us.
// IMPORTANT: this switch and the switch below it must be kept in sync!
switch (aVisitor.mEvent->message) {
case NS_MOUSE_ENTER_SYNTH:
case NS_MOUSE_OVER:
case NS_FOCUS_CONTENT:
case NS_MOUSE_EXIT_SYNTH:
case NS_MOUSE_OUT:
case NS_BLUR_CONTENT:
break;
default:
@ -2790,7 +2790,7 @@ Element::PreHandleEventForLinks(EventChainPreVisitor& aVisitor)
// updated even if the event is consumed before we have a chance to set it.
switch (aVisitor.mEvent->message) {
// Set the status bar similarly for mouseover and focus
case NS_MOUSE_ENTER_SYNTH:
case NS_MOUSE_OVER:
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
// FALL THROUGH
case NS_FOCUS_CONTENT: {
@ -2805,7 +2805,7 @@ Element::PreHandleEventForLinks(EventChainPreVisitor& aVisitor)
}
break;
}
case NS_MOUSE_EXIT_SYNTH:
case NS_MOUSE_OUT:
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
// FALL THROUGH
case NS_BLUR_CONTENT:

View File

@ -676,8 +676,8 @@ nsIContent::PreHandleEvent(EventChainPreVisitor& aVisitor)
// Don't propagate mouseover and mouseout events when mouse is moving
// inside chrome access only content.
bool isAnonForEvents = IsRootOfChromeAccessOnlySubtree();
if ((aVisitor.mEvent->message == NS_MOUSE_ENTER_SYNTH ||
aVisitor.mEvent->message == NS_MOUSE_EXIT_SYNTH ||
if ((aVisitor.mEvent->message == NS_MOUSE_OVER ||
aVisitor.mEvent->message == NS_MOUSE_OUT ||
aVisitor.mEvent->message == NS_POINTER_OVER ||
aVisitor.mEvent->message == NS_POINTER_OUT) &&
// Check if we should stop event propagation when event has just been
@ -738,7 +738,7 @@ nsIContent::PreHandleEvent(EventChainPreVisitor& aVisitor)
printf("Stopping %s propagation:"
"\n\toriginalTarget=%s \n\tcurrentTarget=%s %s"
"\n\trelatedTarget=%s %s \n%s",
(aVisitor.mEvent->message == NS_MOUSE_ENTER_SYNTH)
(aVisitor.mEvent->message == NS_MOUSE_OVER)
? "mouseover" : "mouseout",
NS_ConvertUTF16toUTF8(ot).get(),
NS_ConvertUTF16toUTF8(ct).get(),

View File

@ -7653,9 +7653,9 @@ nsContentUtils::SendMouseEvent(nsCOMPtr<nsIPresShell> aPresShell,
else if (aType.EqualsLiteral("mousemove"))
msg = NS_MOUSE_MOVE;
else if (aType.EqualsLiteral("mouseover"))
msg = NS_MOUSE_ENTER;
msg = NS_MOUSE_ENTER_WIDGET;
else if (aType.EqualsLiteral("mouseout"))
msg = NS_MOUSE_EXIT;
msg = NS_MOUSE_EXIT_WIDGET;
else if (aType.EqualsLiteral("contextmenu")) {
msg = NS_CONTEXTMENU;
contextMenuKey = (aButton == 0);

View File

@ -145,6 +145,8 @@ NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
const nsAString& aExpression,
mozilla::ErrorResult& aError);
extern const js::Class OuterWindowProxyClass;
/*
* Timeout struct that holds information about each script
* timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which

View File

@ -365,9 +365,16 @@ DOMCameraControlListener::OnTakePictureComplete(const uint8_t* aData, uint32_t a
static_cast<uint64_t>(mLength),
mMimeType);
aDOMCameraControl->OnTakePictureComplete(picture);
mData = NULL;
}
protected:
virtual
~Callback()
{
free(mData);
}
uint8_t* mData;
uint32_t mLength;
nsString mMimeType;

View File

@ -94,7 +94,7 @@ DataTransfer::DataTransfer(nsISupports* aParent, uint32_t aEventType,
} else if (mIsExternal) {
if (aEventType == NS_PASTE) {
CacheExternalClipboardFormats();
} else if (aEventType >= NS_DRAGDROP_EVENT_START && aEventType <= NS_DRAGDROP_LEAVE_SYNTH) {
} else if (aEventType >= NS_DRAGDROP_EVENT_START && aEventType <= NS_DRAGDROP_LEAVE) {
CacheExternalDragFormats();
}
}

View File

@ -191,11 +191,11 @@ EVENT(dragenter,
EventNameType_HTMLXUL,
eDragEventClass)
EVENT(dragleave,
NS_DRAGDROP_LEAVE_SYNTH,
NS_DRAGDROP_LEAVE,
EventNameType_HTMLXUL,
eDragEventClass)
EVENT(dragover,
NS_DRAGDROP_OVER_SYNTH,
NS_DRAGDROP_OVER,
EventNameType_HTMLXUL,
eDragEventClass)
EVENT(dragstart,
@ -283,11 +283,11 @@ EVENT(mousemove,
EventNameType_All,
eMouseEventClass)
EVENT(mouseout,
NS_MOUSE_EXIT_SYNTH,
NS_MOUSE_OUT,
EventNameType_All,
eMouseEventClass)
EVENT(mouseover,
NS_MOUSE_ENTER_SYNTH,
NS_MOUSE_OVER,
EventNameType_All,
eMouseEventClass)
EVENT(mouseup,
@ -720,7 +720,7 @@ NON_IDL_EVENT(commandupdate,
EventNameType_XUL,
eBasicEventClass)
NON_IDL_EVENT(dragexit,
NS_DRAGDROP_EXIT_SYNTH,
NS_DRAGDROP_EXIT,
EventNameType_XUL,
eDragEventClass)
NON_IDL_EVENT(dragdrop,

View File

@ -491,13 +491,13 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
mCurrentTarget = aTargetFrame;
mCurrentTargetContent = nullptr;
// Do not take account NS_MOUSE_ENTER/EXIT so that loading a page
// Do not take account NS_MOUSE_ENTER_WIDGET/EXIT_WIDGET so that loading a page
// when user is not active doesn't change the state to active.
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
if (aEvent->mFlags.mIsTrusted &&
((mouseEvent && mouseEvent->IsReal() &&
mouseEvent->message != NS_MOUSE_ENTER &&
mouseEvent->message != NS_MOUSE_EXIT) ||
mouseEvent->message != NS_MOUSE_ENTER_WIDGET &&
mouseEvent->message != NS_MOUSE_EXIT_WIDGET) ||
aEvent->mClass == eWheelEventClass ||
aEvent->mClass == eKeyboardEventClass)) {
if (gMouseOrKeyboardEventCounter == 0) {
@ -580,8 +580,8 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
}
break;
}
case NS_MOUSE_EXIT:
// If this is a remote frame, we receive NS_MOUSE_EXIT from the parent
case NS_MOUSE_EXIT_WIDGET:
// If this is a remote frame, we receive NS_MOUSE_EXIT_WIDGET from the parent
// the mouse exits our content. Since the parent may update the cursor
// while the mouse is outside our frame, and since PuppetWidget caches the
// current cursor internally, re-entering our content (say from over a
@ -1181,9 +1181,9 @@ CrossProcessSafeEvent(const WidgetEvent& aEvent)
case NS_MOUSE_BUTTON_UP:
case NS_MOUSE_MOVE:
case NS_CONTEXTMENU:
case NS_MOUSE_ENTER:
case NS_MOUSE_EXIT:
case NS_MOUSE_ENTER_SYNTH:
case NS_MOUSE_ENTER_WIDGET:
case NS_MOUSE_EXIT_WIDGET:
case NS_MOUSE_OVER:
return true;
default:
return false;
@ -3325,7 +3325,7 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
}
break;
case NS_MOUSE_ENTER:
case NS_MOUSE_ENTER_WIDGET:
if (mCurrentTarget) {
nsCOMPtr<nsIContent> targetContent;
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(targetContent));
@ -3747,8 +3747,8 @@ EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
if (sIsPointerLocked &&
(aMessage == NS_MOUSELEAVE ||
aMessage == NS_MOUSEENTER ||
aMessage == NS_MOUSE_ENTER_SYNTH ||
aMessage == NS_MOUSE_EXIT_SYNTH)) {
aMessage == NS_MOUSE_OVER ||
aMessage == NS_MOUSE_OUT)) {
mCurrentTargetContent = nullptr;
nsCOMPtr<Element> pointerLockedElement =
do_QueryReferent(EventStateManager::sPointerLockedElement);
@ -3793,10 +3793,10 @@ EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
// If we are entering/leaving remote content, dispatch a mouse enter/exit
// event to the remote frame.
if (IsRemoteTarget(aTargetContent)) {
if (aMessage == NS_MOUSE_EXIT_SYNTH) {
if (aMessage == NS_MOUSE_OUT) {
// For remote content, send a "top-level" widget mouse exit event.
nsAutoPtr<WidgetMouseEvent> remoteEvent;
CreateMouseOrPointerWidgetEvent(aMouseEvent, NS_MOUSE_EXIT,
CreateMouseOrPointerWidgetEvent(aMouseEvent, NS_MOUSE_EXIT_WIDGET,
aRelatedContent, remoteEvent);
remoteEvent->exit = WidgetMouseEvent::eTopLevel;
@ -3806,9 +3806,9 @@ EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
// proper target via GetEventTarget which will return mCurrentTarget.
mCurrentTarget = targetFrame;
HandleCrossProcessEvent(remoteEvent, &status);
} else if (aMessage == NS_MOUSE_ENTER_SYNTH) {
} else if (aMessage == NS_MOUSE_OVER) {
nsAutoPtr<WidgetMouseEvent> remoteEvent;
CreateMouseOrPointerWidgetEvent(aMouseEvent, NS_MOUSE_ENTER,
CreateMouseOrPointerWidgetEvent(aMouseEvent, NS_MOUSE_ENTER_WIDGET,
aRelatedContent, remoteEvent);
HandleCrossProcessEvent(remoteEvent, &status);
}
@ -3933,7 +3933,7 @@ EventStateManager::NotifyMouseOut(WidgetMouseEvent* aMouseEvent,
NS_MOUSELEAVE);
// Fire mouseout
DispatchMouseOrPointerEvent(aMouseEvent, isPointer ? NS_POINTER_OUT : NS_MOUSE_EXIT_SYNTH,
DispatchMouseOrPointerEvent(aMouseEvent, isPointer ? NS_POINTER_OUT : NS_MOUSE_OUT,
wrapper->mLastOverElement, aMovingInto);
wrapper->mLastOverFrame = nullptr;
@ -4006,7 +4006,7 @@ EventStateManager::NotifyMouseOver(WidgetMouseEvent* aMouseEvent,
// Fire mouseover
wrapper->mLastOverFrame =
DispatchMouseOrPointerEvent(aMouseEvent,
isPointer ? NS_POINTER_OVER : NS_MOUSE_ENTER_SYNTH,
isPointer ? NS_POINTER_OVER : NS_MOUSE_OVER,
aContent, lastOverElement);
wrapper->mLastOverElement = aContent;
} else {
@ -4164,7 +4164,7 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent)
break;
case NS_POINTER_LEAVE:
case NS_POINTER_CANCEL:
case NS_MOUSE_EXIT:
case NS_MOUSE_EXIT_WIDGET:
{
// This is actually the window mouse exit or pointer leave event. We're not moving
// into any new element.
@ -4293,7 +4293,7 @@ EventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
getter_AddRefs(lastContent));
FireDragEnterOrExit(sLastDragOverFrame->PresContext(),
aDragEvent, NS_DRAGDROP_EXIT_SYNTH,
aDragEvent, NS_DRAGDROP_EXIT,
targetContent, lastContent, sLastDragOverFrame);
}
@ -4302,7 +4302,7 @@ EventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
if (sLastDragOverFrame) {
FireDragEnterOrExit(sLastDragOverFrame->PresContext(),
aDragEvent, NS_DRAGDROP_LEAVE_SYNTH,
aDragEvent, NS_DRAGDROP_LEAVE,
targetContent, lastContent, sLastDragOverFrame);
}
@ -4321,10 +4321,10 @@ EventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
nsRefPtr<nsPresContext> lastDragOverFramePresContext = sLastDragOverFrame->PresContext();
FireDragEnterOrExit(lastDragOverFramePresContext,
aDragEvent, NS_DRAGDROP_EXIT_SYNTH,
aDragEvent, NS_DRAGDROP_EXIT,
nullptr, lastContent, sLastDragOverFrame);
FireDragEnterOrExit(lastDragOverFramePresContext,
aDragEvent, NS_DRAGDROP_LEAVE_SYNTH,
aDragEvent, NS_DRAGDROP_LEAVE,
nullptr, lastContent, sLastDragOverFrame);
sLastDragOverFrame = nullptr;
@ -4373,7 +4373,7 @@ EventStateManager::FireDragEnterOrExit(nsPresContext* aPresContext,
// collect any changes to moz cursor settings stored in the event's
// data transfer.
if (aMsg == NS_DRAGDROP_LEAVE_SYNTH || aMsg == NS_DRAGDROP_EXIT_SYNTH ||
if (aMsg == NS_DRAGDROP_LEAVE || aMsg == NS_DRAGDROP_EXIT ||
aMsg == NS_DRAGDROP_ENTER)
UpdateDragDataTransfer(&event);
}

View File

@ -347,7 +347,7 @@ HTMLButtonElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
}
break;
case NS_MOUSE_ENTER_SYNTH:
case NS_MOUSE_OVER:
{
aVisitor.mPresContext->EventStateManager()->
SetContentState(this, NS_EVENT_STATE_HOVER);
@ -356,7 +356,7 @@ HTMLButtonElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
break;
// XXX this doesn't seem to do anything yet
case NS_MOUSE_EXIT_SYNTH:
case NS_MOUSE_OUT:
{
aVisitor.mPresContext->EventStateManager()->
SetContentState(nullptr, NS_EVENT_STATE_HOVER);

View File

@ -3370,10 +3370,10 @@ HTMLInputElement::NeedToInitializeEditorForEvent(
switch (aVisitor.mEvent->message) {
case NS_MOUSE_MOVE:
case NS_MOUSE_ENTER:
case NS_MOUSE_EXIT:
case NS_MOUSE_ENTER_SYNTH:
case NS_MOUSE_EXIT_SYNTH:
case NS_MOUSE_ENTER_WIDGET:
case NS_MOUSE_EXIT_WIDGET:
case NS_MOUSE_OVER:
case NS_MOUSE_OUT:
case NS_SCROLLPORT_UNDERFLOW:
case NS_SCROLLPORT_OVERFLOW:
return false;

View File

@ -1220,16 +1220,16 @@ bool TabParent::SendRealMouseEvent(WidgetMouseEvent& event)
if (widget) {
// When we mouseenter the tab, the tab's cursor should become the current
// cursor. When we mouseexit, we stop.
if (event.message == NS_MOUSE_ENTER ||
event.message == NS_MOUSE_ENTER_SYNTH) {
if (event.message == NS_MOUSE_ENTER_WIDGET ||
event.message == NS_MOUSE_OVER) {
mTabSetsCursor = true;
if (mCursor != nsCursor(-1)) {
widget->SetCursor(mCursor);
}
// We don't actually want to forward NS_MOUSE_ENTER messages.
// We don't actually want to forward NS_MOUSE_ENTER_WIDGET messages.
return true;
} else if (event.message == NS_MOUSE_EXIT ||
event.message == NS_MOUSE_EXIT_SYNTH) {
} else if (event.message == NS_MOUSE_EXIT_WIDGET ||
event.message == NS_MOUSE_OUT) {
mTabSetsCursor = false;
}
}

View File

@ -624,7 +624,10 @@ private:
{
MOZ_ASSERT(NS_IsMainThread());
if (NS_FAILED(rv)) {
mRecorder->NotifyError(rv);
nsCOMPtr<nsIRunnable> runnable =
NS_NewRunnableMethodWithArg<nsresult>(mRecorder,
&MediaRecorder::NotifyError, rv);
NS_DispatchToMainThread(runnable);
}
CleanupStreams();

View File

@ -8,6 +8,7 @@
#define TIME_UNITS_H
#include "VideoUtils.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/FloatingPoint.h"
namespace mozilla {
@ -55,8 +56,81 @@ struct Microseconds {
int64_t mValue;
};
class TimeUnit final {
public:
static TimeUnit FromSeconds(double aValue) {
MOZ_ASSERT(!IsNaN(aValue));
}
}
double val = aValue * USECS_PER_S;
if (val >= double(INT64_MAX)) {
return FromMicroseconds(INT64_MAX);
} else if (val <= double(INT64_MIN)) {
return FromMicroseconds(INT64_MIN);
} else {
return FromMicroseconds(int64_t(val));
}
}
static TimeUnit FromMicroseconds(int64_t aValue) {
return TimeUnit(aValue);
}
static TimeUnit FromMicroseconds(Microseconds aValue) {
return TimeUnit(aValue.mValue);
}
int64_t ToMicroseconds() const {
return mValue.value();
}
double ToSeconds() const {
return double(mValue.value()) / USECS_PER_S;
}
bool operator >= (const TimeUnit& aOther) const {
MOZ_ASSERT(IsValid() && aOther.IsValid());
return mValue.value() >= aOther.mValue.value();
}
bool operator > (const TimeUnit& aOther) const {
return !(*this <= aOther);
}
bool operator <= (const TimeUnit& aOther) const {
MOZ_ASSERT(IsValid() && aOther.IsValid());
return mValue.value() <= aOther.mValue.value();
}
bool operator < (const TimeUnit& aOther) const {
return !(*this >= aOther);
}
TimeUnit operator + (const TimeUnit& aOther) const {
return TimeUnit(mValue + aOther.mValue);
}
TimeUnit operator - (const TimeUnit& aOther) const {
return TimeUnit(mValue - aOther.mValue);
}
bool IsValid() const
{
return mValue.isValid();
}
explicit TimeUnit(const Microseconds& aMicroseconds)
: mValue(aMicroseconds.mValue)
{}
TimeUnit(const TimeUnit&) = default;
TimeUnit& operator = (const TimeUnit&) = default;
private:
explicit TimeUnit(CheckedInt64 aMicroseconds)
: mValue(aMicroseconds)
{}
// Our internal representation is in microseconds.
CheckedInt64 mValue;
};
} // namespace media
} // namespace mozilla
#endif // TIME_UNITS_H

View File

@ -73,7 +73,7 @@ TrackTypeToStr(TrackInfo::TrackType aTrack)
}
#endif
uint8_t sTestExtraData[40] = { 0x01, 0x64, 0x00, 0x0a, 0xff, 0xe1, 0x00, 0x17, 0x67, 0x64, 0x00, 0x0a, 0xac, 0xd9, 0x44, 0x26, 0x84, 0x00, 0x00, 0x03,
uint8_t sTestExtraData[40] = { 0x01, 0x64, 0x00, 0x0a, 0xff, 0xe1, 0x00, 0x17, 0x67, 0x64, 0x00, 0x0a, 0xac, 0xd9, 0x44, 0x26, 0x84, 0x00, 0x00, 0x03,
0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xc8, 0x3c, 0x48, 0x96, 0x58, 0x01, 0x00, 0x06, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0 };
/* static */ bool
@ -333,10 +333,6 @@ private:
};
#endif // MOZ_EME
bool MP4Reader::IsWaitingMediaResources() {
return mVideo.mDecoder && mVideo.mDecoder->IsWaitingMediaResources();
}
bool MP4Reader::IsWaitingOnCDMResource() {
#ifdef MOZ_EME
nsRefPtr<CDMProxy> proxy;
@ -378,6 +374,7 @@ MP4Reader::IsSupportedAudioMimeType(const nsACString& aMimeType)
{
return (aMimeType.EqualsLiteral("audio/mpeg") ||
aMimeType.EqualsLiteral("audio/mp4a-latm") ||
aMimeType.EqualsLiteral("audio/amr-wb") ||
aMimeType.EqualsLiteral("audio/3gpp")) &&
mPlatform->SupportsMimeType(aMimeType);
}
@ -434,6 +431,8 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
} else if (mPlatform && !IsWaitingMediaResources()) {
*aInfo = mInfo;
*aTags = nullptr;
NS_ENSURE_TRUE(EnsureDecodersSetup(), NS_ERROR_FAILURE);
return NS_OK;
}
if (HasAudio()) {
@ -492,67 +491,49 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo,
return NS_OK;
}
bool MP4Reader::CheckIfDecoderSetup()
{
if (!mDemuxerInitialized) {
return false;
}
if (HasAudio() && !mAudio.mDecoder) {
return false;
}
if (HasVideo() && !mVideo.mDecoder) {
return false;
}
return true;
}
bool
MP4Reader::EnsureDecodersSetup()
{
if (CheckIfDecoderSetup()) {
return true;
}
MOZ_ASSERT(mDemuxerInitialized);
if (mIsEncrypted) {
if (!mPlatform) {
if (mIsEncrypted) {
#ifdef MOZ_EME
// We have encrypted audio or video. We'll need a CDM to decrypt and
// possibly decode this. Wait until we've received a CDM from the
// JavaScript player app. Note: we still go through the motions here
// even if EME is disabled, so that if script tries and fails to create
// a CDM, we can detect that and notify chrome and show some UI explaining
// that we failed due to EME being disabled.
nsRefPtr<CDMProxy> proxy;
if (IsWaitingMediaResources()) {
return true;
}
MOZ_ASSERT(!IsWaitingMediaResources());
// We have encrypted audio or video. We'll need a CDM to decrypt and
// possibly decode this. Wait until we've received a CDM from the
// JavaScript player app. Note: we still go through the motions here
// even if EME is disabled, so that if script tries and fails to create
// a CDM, we can detect that and notify chrome and show some UI
// explaining that we failed due to EME being disabled.
nsRefPtr<CDMProxy> proxy;
if (IsWaitingMediaResources()) {
return true;
}
MOZ_ASSERT(!IsWaitingMediaResources());
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
proxy = mDecoder->GetCDMProxy();
}
MOZ_ASSERT(proxy);
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
proxy = mDecoder->GetCDMProxy();
}
MOZ_ASSERT(proxy);
mPlatform = PlatformDecoderModule::CreateCDMWrapper(proxy,
HasAudio(),
HasVideo());
NS_ENSURE_TRUE(mPlatform, false);
mPlatform = PlatformDecoderModule::CreateCDMWrapper(proxy,
HasAudio(),
HasVideo());
NS_ENSURE_TRUE(mPlatform, false);
#else
// EME not supported.
return false;
// EME not supported.
return false;
#endif
} else {
// mPlatform doesn't need to be recreated when resuming from dormant.
if (!mPlatform) {
} else {
mPlatform = PlatformDecoderModule::Create();
NS_ENSURE_TRUE(mPlatform, false);
}
}
if (HasAudio()) {
MOZ_ASSERT(mPlatform);
if (HasAudio() && !mAudio.mDecoder) {
NS_ENSURE_TRUE(IsSupportedAudioMimeType(mDemuxer->AudioConfig().mMimeType),
false);
@ -565,7 +546,7 @@ MP4Reader::EnsureDecodersSetup()
NS_ENSURE_SUCCESS(rv, false);
}
if (HasVideo()) {
if (HasVideo() && !mVideo.mDecoder) {
NS_ENSURE_TRUE(IsSupportedVideoMimeType(mDemuxer->VideoConfig().mMimeType),
false);
@ -591,6 +572,8 @@ MP4Reader::EnsureDecodersSetup()
NS_ENSURE_SUCCESS(rv, false);
}
NotifyResourcesStatusChanged();
return true;
}

View File

@ -72,7 +72,6 @@ public:
// For Media Resource Management
virtual void SetIdle() override;
virtual bool IsWaitingMediaResources() override;
virtual bool IsDormantNeeded() override;
virtual void ReleaseMediaResources() override;
virtual void SetSharedDecoderManager(SharedDecoderManager* aManager)
@ -97,8 +96,6 @@ private:
bool EnsureDecodersSetup();
bool CheckIfDecoderSetup();
// Sends input to decoder for aTrack, and output to the state machine,
// if necessary.
void Update(TrackType aTrack);

View File

@ -245,10 +245,6 @@ public:
// returned.
virtual nsresult Shutdown() = 0;
// For Codec Resource Management
virtual bool IsWaitingMediaResources() {
return false;
};
virtual bool IsHardwareAccelerated() const { return false; }
// ConfigurationChanged will be called to inform the video or audio decoder

View File

@ -239,12 +239,6 @@ SharedDecoderProxy::Shutdown()
return NS_OK;
}
bool
SharedDecoderProxy::IsWaitingMediaResources()
{
return mManager->mDecoder->IsWaitingMediaResources();
}
bool
SharedDecoderProxy::IsHardwareAccelerated() const
{

View File

@ -73,7 +73,6 @@ public:
virtual nsresult Flush() override;
virtual nsresult Drain() override;
virtual nsresult Shutdown() override;
virtual bool IsWaitingMediaResources() override;
virtual bool IsHardwareAccelerated() const override;
friend class SharedDecoderManager;

View File

@ -66,6 +66,7 @@ GonkDecoderModule::SupportsMimeType(const nsACString& aMimeType)
{
return aMimeType.EqualsLiteral("audio/mp4a-latm") ||
aMimeType.EqualsLiteral("audio/3gpp") ||
aMimeType.EqualsLiteral("audio/amr-wb") ||
aMimeType.EqualsLiteral("video/mp4") ||
aMimeType.EqualsLiteral("video/mp4v-es") ||
aMimeType.EqualsLiteral("video/avc");

View File

@ -26,94 +26,54 @@ using namespace android;
namespace mozilla {
GonkDecoderManager::GonkDecoderManager(MediaTaskQueue* aTaskQueue)
: mTaskQueue(aTaskQueue)
: mMonitor("GonkDecoderManager")
{
}
nsresult
GonkDecoderManager::Input(MediaRawData* aSample)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
// To maintain the order of the MP4Sample, it needs to send the queued samples
// to OMX first. And then the current input aSample.
// If it fails to input sample to OMX, it needs to add current into queue
// for next round.
uint32_t len = mQueueSample.Length();
status_t rv = OK;
for (uint32_t i = 0; i < len; i++) {
rv = SendSampleToOMX(mQueueSample.ElementAt(0));
if (rv != OK) {
break;
}
mQueueSample.RemoveElementAt(0);
}
// When EOS, aSample will be null and sends this empty MediaRawData to nofity
// OMX it reachs EOS.
ReentrantMonitorAutoEnter mon(mMonitor);
nsRefPtr<MediaRawData> sample;
if (!aSample) {
// It means EOS with empty sample.
sample = new MediaRawData();
}
// If rv is OK, that means mQueueSample is empty, now try to queue current input
// aSample.
if (rv == OK) {
MOZ_ASSERT(!mQueueSample.Length());
MediaRawData* tmp;
if (aSample) {
tmp = aSample;
if (!PerformFormatSpecificProcess(aSample)) {
return NS_ERROR_FAILURE;
}
} else {
tmp = sample;
}
rv = SendSampleToOMX(tmp);
if (rv == OK) {
return NS_OK;
} else {
sample = aSample;
if (!PerformFormatSpecificProcess(sample)) {
return NS_ERROR_FAILURE;
}
}
// Current valid sample can't be sent into OMX, adding the clone one into queue
// for next round.
if (!sample) {
sample = aSample->Clone();
if (!sample) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
mQueueSample.AppendElement(sample);
// In most cases, EAGAIN or ETIMEOUT safe due to OMX can't process the
// filled buffer on time. It should be gone When requeuing sample next time.
if (rv == -EAGAIN || rv == -ETIMEDOUT) {
return NS_OK;
status_t rv;
while (mQueueSample.Length()) {
nsRefPtr<MediaRawData> data = mQueueSample.ElementAt(0);
{
ReentrantMonitorAutoExit mon_exit(mMonitor);
rv = SendSampleToOMX(data);
}
if (rv == OK) {
mQueueSample.RemoveElementAt(0);
} else if (rv == -EAGAIN || rv == -ETIMEDOUT) {
// In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill
// buffer on time.
return NS_OK;
} else {
return NS_ERROR_UNEXPECTED;
}
}
return NS_ERROR_UNEXPECTED;
return NS_OK;
}
nsresult
GonkDecoderManager::Flush()
{
class ClearQueueRunnable : public nsRunnable
{
public:
explicit ClearQueueRunnable(GonkDecoderManager* aManager)
: mManager(aManager) {}
NS_IMETHOD Run()
{
mManager->ClearQueuedSample();
return NS_OK;
}
GonkDecoderManager* mManager;
};
mTaskQueue->SyncDispatch(new ClearQueueRunnable(this));
ReentrantMonitorAutoEnter mon(mMonitor);
mQueueSample.Clear();
return NS_OK;
}
@ -262,12 +222,4 @@ GonkMediaDataDecoder::Drain()
return NS_OK;
}
bool
GonkMediaDataDecoder::IsWaitingMediaResources() {
if (!mDecoder.get()) {
return true;
}
return false;
}
} // namespace mozilla

View File

@ -44,17 +44,12 @@ public:
// in the overrided function.
virtual nsresult Flush();
// It should be called in MediaTash thread.
// It should be called in MediaTask thread.
bool HasQueuedSample() {
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
ReentrantMonitorAutoEnter mon(mMonitor);
return mQueueSample.Length();
}
void ClearQueuedSample() {
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
mQueueSample.Clear();
}
protected:
// It performs special operation to MP4 sample, the real action is depended on
// the codec type.
@ -63,13 +58,14 @@ protected:
// It sends MP4Sample to OMX layer. It must be overrided by subclass.
virtual android::status_t SendSampleToOMX(MediaRawData* aSample) = 0;
// This monitor protects mQueueSample.
ReentrantMonitor mMonitor;
// An queue with the MP4 samples which are waiting to be sent into OMX.
// If an element is an empty MP4Sample, that menas EOS. There should not
// any sample be queued after EOS.
nsTArray<nsRefPtr<MediaRawData>> mQueueSample;
RefPtr<MediaTaskQueue> mTaskQueue;
nsRefPtr<MediaByteBuffer> mCodecSpecificData;
nsAutoCString mMimeType;
@ -98,8 +94,6 @@ public:
virtual nsresult Shutdown() override;
virtual bool IsWaitingMediaResources() override;
private:
// Called on the task queue. Inserts the sample into the decoder, and

View File

@ -50,6 +50,7 @@ GonkVideoDecoderManager::GonkVideoDecoderManager(
: GonkDecoderManager(aTaskQueue)
, mImageContainer(aImageContainer)
, mReaderCallback(nullptr)
, mLastDecodedTime(0)
, mColorConverterBufferSize(0)
, mNativeWindow(nullptr)
, mPendingVideoBuffersLock("GonkVideoDecoderManager::mPendingVideoBuffersLock")
@ -113,56 +114,9 @@ GonkVideoDecoderManager::Init(MediaDataDecoderCallback* aCallback)
mNativeWindow = new GonkNativeWindow();
}
mReaderCallback->NotifyResourcesStatusChanged();
return mDecoder;
}
void
GonkVideoDecoderManager::QueueFrameTimeIn(int64_t aPTS, int64_t aDuration)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
FrameTimeInfo timeInfo = {aPTS, aDuration};
mFrameTimeInfo.AppendElement(timeInfo);
}
nsresult
GonkVideoDecoderManager::QueueFrameTimeOut(int64_t aPTS, int64_t& aDuration)
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
// Set default to 1 here.
// During seeking, frames could still in MediaCodec and the mFrameTimeInfo could
// be cleared before these frames are out from MediaCodec. This is ok because
// these frames are old frame before seeking.
aDuration = 1;
for (uint32_t i = 0; i < mFrameTimeInfo.Length(); i++) {
const FrameTimeInfo& entry = mFrameTimeInfo.ElementAt(i);
if (i == 0) {
if (entry.pts > aPTS) {
// Codec sent a frame with rollbacked PTS time. It could
// be codec's problem.
ReleaseVideoBuffer();
return NS_ERROR_NOT_AVAILABLE;
}
}
// Ideally, the first entry in mFrameTimeInfo should be the one we are looking
// for. However, MediaCodec could dropped frame and the first entry doesn't
// match current decoded frame's PTS.
if (entry.pts == aPTS) {
aDuration = entry.duration;
if (i > 0) {
LOG("Frame could be dropped by MediaCodec, %d dropped frames.", i);
}
mFrameTimeInfo.RemoveElementsAt(0, i+1);
break;
}
}
return NS_OK;
}
nsresult
GonkVideoDecoderManager::CreateVideoData(int64_t aStreamOffset, VideoData **v)
{
@ -181,9 +135,12 @@ GonkVideoDecoderManager::CreateVideoData(int64_t aStreamOffset, VideoData **v)
return NS_ERROR_UNEXPECTED;
}
int64_t duration;
nsresult rv = QueueFrameTimeOut(timeUs, duration);
NS_ENSURE_SUCCESS(rv, rv);
if (mLastDecodedTime > timeUs) {
ReleaseVideoBuffer();
GVDM_LOG("Output decoded sample time is revert. time=%lld", timeUs);
return NS_ERROR_NOT_AVAILABLE;
}
mLastDecodedTime = timeUs;
if (mVideoBuffer->range_length() == 0) {
// Some decoders may return spurious empty buffers that we just want to ignore
@ -224,7 +181,8 @@ GonkVideoDecoderManager::CreateVideoData(int64_t aStreamOffset, VideoData **v)
mImageContainer,
aStreamOffset,
timeUs,
duration,
1, // No way to pass sample duration from muxer to
// OMX codec, so we hardcode the duration here.
textureClient,
keyFrame,
-1,
@ -438,47 +396,17 @@ void GonkVideoDecoderManager::ReleaseVideoBuffer() {
status_t
GonkVideoDecoderManager::SendSampleToOMX(MediaRawData* aSample)
{
// An empty MediaRawData is going to notify EOS to decoder. It doesn't need
// to keep PTS and duration.
if (aSample->mData && aSample->mDuration && aSample->mTime) {
QueueFrameTimeIn(aSample->mTime, aSample->mDuration);
}
return mDecoder->Input(reinterpret_cast<const uint8_t*>(aSample->mData),
aSample->mSize,
aSample->mTime,
0);
}
void
GonkVideoDecoderManager::ClearQueueFrameTime()
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
mFrameTimeInfo.Clear();
}
nsresult
GonkVideoDecoderManager::Flush()
{
GonkDecoderManager::Flush();
class ClearFrameTimeRunnable : public nsRunnable
{
public:
explicit ClearFrameTimeRunnable(GonkVideoDecoderManager* aManager)
: mManager(aManager) {}
NS_IMETHOD Run()
{
mManager->ClearQueueFrameTime();
return NS_OK;
}
GonkVideoDecoderManager* mManager;
};
mTaskQueue->SyncDispatch(new ClearFrameTimeRunnable(this));
mLastDecodedTime = 0;
status_t err = mDecoder->flush();
if (err != OK) {
return NS_ERROR_FAILURE;

View File

@ -108,15 +108,6 @@ private:
};
friend class VideoResourceListener;
// FrameTimeInfo keeps the presentation time stamp (pts) and its duration.
// On MediaDecoderStateMachine, it needs pts and duration to display decoded
// frame correctly. But OMX can carry one field of time info (kKeyTime) so
// we use FrameTimeInfo to keep pts and duration.
struct FrameTimeInfo {
int64_t pts; // presentation time stamp of this frame.
int64_t duration; // the playback duration.
};
bool SetVideoFormat();
nsresult CreateVideoData(int64_t aStreamOffset, VideoData** aOutData);
@ -131,10 +122,6 @@ private:
void ReleaseAllPendingVideoBuffers();
void PostReleaseVideoBuffer(android::MediaBuffer *aBuffer);
void QueueFrameTimeIn(int64_t aPTS, int64_t aDuration);
nsresult QueueFrameTimeOut(int64_t aPTS, int64_t& aDuration);
void ClearQueueFrameTime();
uint32_t mVideoWidth;
uint32_t mVideoHeight;
uint32_t mDisplayWidth;
@ -155,11 +142,7 @@ private:
android::sp<ALooper> mManagerLooper;
FrameInfo mFrameInfo;
// Array of FrameTimeInfo whose corresponding frames are sent to OMX.
// Ideally, it is a FIFO. Input() adds the entry to the end element and
// CreateVideoData() takes the first entry. However, there are exceptions
// due to MediaCodec error or seeking.
nsTArray<FrameTimeInfo> mFrameTimeInfo;
int64_t mLastDecodedTime; // The last decoded frame presentation time.
// color converter
android::I420ColorConverterHelper mColorConverter;

View File

@ -69,7 +69,6 @@ public:
virtual nsresult Shutdown() override;
virtual bool IsWaitingMediaResources() { return false; };
virtual bool IsHardwareAccelerated() const override;
private:

View File

@ -108,15 +108,6 @@ H264Converter::Shutdown()
return NS_OK;
}
bool
H264Converter::IsWaitingMediaResources()
{
if (mDecoder) {
return mDecoder->IsWaitingMediaResources();
}
return MediaDataDecoder::IsWaitingMediaResources();
}
bool
H264Converter::IsHardwareAccelerated() const
{

View File

@ -34,7 +34,6 @@ public:
virtual nsresult Flush() override;
virtual nsresult Drain() override;
virtual nsresult Shutdown() override;
virtual bool IsWaitingMediaResources() override;
virtual bool IsHardwareAccelerated() const override;
// Return true if mimetype is H.264.

View File

@ -58,7 +58,6 @@ SpecialPowers.pushPrefEnv({"set": [["media.ogg.enabled", false]]},
is(mediaRecorder.stream, stream,
'Media recorder stream = element stream at the start of recording');
mediaRecorder.requestData();
mediaRecorder.stop();
}, 100);
}
);

View File

@ -1759,9 +1759,9 @@ CocoaEventTypeForEvent(const WidgetGUIEvent& anEvent, nsIFrame* aObjectFrame)
}
switch (anEvent.message) {
case NS_MOUSE_ENTER_SYNTH:
case NS_MOUSE_OVER:
return NPCocoaEventMouseEntered;
case NS_MOUSE_EXIT_SYNTH:
case NS_MOUSE_OUT:
return NPCocoaEventMouseExited;
case NS_MOUSE_MOVE:
{
@ -1803,8 +1803,8 @@ TranslateToNPCocoaEvent(WidgetGUIEvent* anEvent, nsIFrame* aObjectFrame)
anEvent->message == NS_MOUSE_BUTTON_DOWN ||
anEvent->message == NS_MOUSE_BUTTON_UP ||
anEvent->message == NS_MOUSE_SCROLL ||
anEvent->message == NS_MOUSE_ENTER_SYNTH ||
anEvent->message == NS_MOUSE_EXIT_SYNTH)
anEvent->message == NS_MOUSE_OVER ||
anEvent->message == NS_MOUSE_OUT)
{
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(anEvent, aObjectFrame) -
aObjectFrame->GetContentRectRelativeToSelf().TopLeft();
@ -2059,8 +2059,8 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
NS_ASSERTION(anEvent.message == NS_MOUSE_BUTTON_DOWN ||
anEvent.message == NS_MOUSE_BUTTON_UP ||
anEvent.message == NS_MOUSE_DOUBLECLICK ||
anEvent.message == NS_MOUSE_ENTER_SYNTH ||
anEvent.message == NS_MOUSE_EXIT_SYNTH ||
anEvent.message == NS_MOUSE_OVER ||
anEvent.message == NS_MOUSE_OUT ||
anEvent.message == NS_MOUSE_MOVE,
"Incorrect event type for coordinate translation");
nsPoint pt =
@ -2145,11 +2145,11 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
switch (anEvent.message)
{
case NS_MOUSE_ENTER_SYNTH:
case NS_MOUSE_EXIT_SYNTH:
case NS_MOUSE_OVER:
case NS_MOUSE_OUT:
{
XCrossingEvent& event = pluginEvent.xcrossing;
event.type = anEvent.message == NS_MOUSE_ENTER_SYNTH ?
event.type = anEvent.message == NS_MOUSE_OVER ?
EnterNotify : LeaveNotify;
event.root = root;
event.time = anEvent.time;

View File

@ -1,5 +1,7 @@
function handleRequest(request, response) {
if (!getState('counter')) {
if (request.queryString == 'clearcounter') {
setState('counter', '');
} else if (!getState('counter')) {
response.setHeader("Content-Type", "application/javascript", false);
response.write("callByScript();");
setState('counter', '1');

View File

@ -1,4 +1,8 @@
function handleRequest(request, response) {
if (request.queryString == 'clearcounter') {
setState('periodiccounter', '');
return;
}
if (!getState('periodiccounter')) {
setState('periodiccounter', '1');
} else {

View File

@ -1,6 +1,8 @@
<!DOCTYPE html>
<script>
navigator.serviceWorker.getRegistration(".").then(function(registration) {
fetch("../periodic.sjs?clearcounter").then(function() {
return navigator.serviceWorker.getRegistration(".");
}).then(function(registration) {
registration.unregister().then(function(success) {
if (success) {
parent.callback();

View File

@ -19,7 +19,9 @@
}
function unregister() {
return registration.unregister().then(function(result) {
return fetch("importscript.sjs?clearcounter").then(function() {
return registration.unregister();
}).then(function(result) {
ok(result, "Unregister should return true.");
}, function(e) {
dump("Unregistering the SW failed with " + e + "\n");

View File

@ -374,12 +374,12 @@ nsEditorEventListener::HandleEvent(nsIDOMEvent* aEvent)
return DragEnter(dragEvent);
}
// dragover
case NS_DRAGDROP_OVER_SYNTH: {
case NS_DRAGDROP_OVER: {
nsCOMPtr<nsIDOMDragEvent> dragEvent = do_QueryInterface(aEvent);
return DragOver(dragEvent);
}
// dragexit
case NS_DRAGDROP_EXIT_SYNTH: {
case NS_DRAGDROP_EXIT: {
nsCOMPtr<nsIDOMDragEvent> dragEvent = do_QueryInterface(aEvent);
return DragExit(dragEvent);
}

View File

@ -538,6 +538,13 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
return true;
}
if (!mTxn->mPaints.empty()) {
// With some platforms, telling the drawing backend that there will be no more
// drawing for this frame helps with preventing command queues from spanning
// across multiple frames.
gfxPlatform::GetPlatform()->FlushContentDrawing();
}
MOZ_LAYERS_LOG(("[LayersForwarder] destroying buffers..."));
MOZ_LAYERS_LOG(("[LayersForwarder] building transaction..."));

View File

@ -630,6 +630,7 @@ public:
return false;
}
virtual void FlushContentDrawing() {}
protected:
gfxPlatform();
virtual ~gfxPlatform();

View File

@ -30,6 +30,7 @@
#include "gfxXlibSurface.h"
#include "cairo-xlib.h"
#include "mozilla/Preferences.h"
#include "mozilla/X11Util.h"
/* Undefine the Status from Xlib since it will conflict with system headers on OSX */
#if defined(__APPLE__) && defined(Status)
@ -81,6 +82,14 @@ gfxPlatformGtk::~gfxPlatformGtk()
gfxPangoFontGroup::Shutdown();
}
void
gfxPlatformGtk::FlushContentDrawing()
{
if (UseXRender()) {
XFlush(DefaultXDisplay());
}
}
already_AddRefed<gfxASurface>
gfxPlatformGtk::CreateOffscreenSurface(const IntSize& size,
gfxContentType contentType)

View File

@ -75,6 +75,11 @@ public:
virtual bool IsFontFormatSupported(nsIURI *aFontURI,
uint32_t aFormatFlags) override;
/**
* Calls XFlush if xrender is enabled.
*/
virtual void FlushContentDrawing() override;
#if (MOZ_WIDGET_GTK == 2)
static void SetGdkDrawable(cairo_surface_t *target,
GdkDrawable *drawable);

View File

@ -69,6 +69,15 @@ nsStringBundle::LoadProperties()
rv = NS_NewURI(getter_AddRefs(uri), mPropertiesURL);
if (NS_FAILED(rv)) return rv;
// whitelist check for local schemes
nsCString scheme;
uri->GetScheme(scheme);
if (!scheme.EqualsLiteral("chrome") && !scheme.EqualsLiteral("jar") &&
!scheme.EqualsLiteral("resource") && !scheme.EqualsLiteral("file") &&
!scheme.EqualsLiteral("data")) {
return NS_ERROR_ABORT;
}
nsCOMPtr<nsIChannel> channel;
rv = NS_NewChannel(getter_AddRefs(channel),
uri,

View File

@ -0,0 +1,34 @@
var path = '';
// trigger off-main-thread compilation
for (var i = 0; i < 11; i++)
path.substr(-1);
// maybe link to the the result of the off-main-thread compilation.
function load(unsigned) {
if (unsigned)
path.substr(-1);
}
(function(global, env) {
'use asm';
var load = env.load;
function _main() {
var $l1 = 0, $l2 = 0, $l3 = 0;
do {
load();
$l1 = $l1 + 1 | 0;
} while (($l1 | 0) != 10);
load(1);
load(1);
do {
load();
$l2 = $l2 + 1 | 0;
} while (($l2 | 0) != 1024);
while (($l3 | 0) < 10000) {
load(1);
$l3 = $l3 + 1 | 0;
}
}
return _main;
})({}, { 'load':load })();

View File

@ -0,0 +1,8 @@
function f(x) {
for (var i = 0; i < 40; ++i) {
var stack = getBacktrace({args: true});
(function() { g = x;});
}
}
f(1);

View File

@ -45,6 +45,9 @@ BytecodeAnalysis::init(TempAllocator& alloc, GSNCache& gsn)
if (!infos_.growByUninitialized(script_->length()))
return false;
// We need a scope chain if any of the bindings are aliased.
usesScopeChain_ = script_->hasAnyAliasedBindings();
jsbytecode* end = script_->codeEnd();
// Clear all BytecodeInfo.

View File

@ -436,10 +436,32 @@ FinishAllOffThreadCompilations(JSCompartment* comp)
}
}
class AutoLazyLinkExitFrame
{
JitActivation* jitActivation_;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
public:
explicit AutoLazyLinkExitFrame(JitActivation* jitActivation
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: jitActivation_(jitActivation)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
MOZ_ASSERT(!jitActivation_->isLazyLinkExitFrame(),
"Cannot stack multiple lazy-link frames.");
jitActivation_->setLazyLinkExitFrame(true);
}
~AutoLazyLinkExitFrame() {
jitActivation_->setLazyLinkExitFrame(false);
}
};
uint8_t*
jit::LazyLinkTopActivation(JSContext* cx)
{
JitActivationIterator iter(cx->runtime());
AutoLazyLinkExitFrame lazyLinkExitFrame(iter->asJit());
// First frame should be an exit frame.
JitFrameIterator it(iter);
@ -2499,11 +2521,12 @@ InvalidateActivation(FreeOp* fop, const JitActivationIterator& activations, bool
size_t frameno = 1;
for (JitFrameIterator it(activations); !it.done(); ++it, ++frameno) {
MOZ_ASSERT_IF(frameno == 1, it.type() == JitFrame_Exit || it.type() == JitFrame_Bailout);
MOZ_ASSERT_IF(frameno == 1, it.isExitFrame() || it.type() == JitFrame_Bailout);
#ifdef DEBUG
switch (it.type()) {
case JitFrame_Exit:
case JitFrame_LazyLink:
JitSpew(JitSpew_IonInvalidate, "#%d exit frame @ %p", frameno, it.fp());
break;
case JitFrame_BaselineJS:

View File

@ -476,7 +476,8 @@ static void*
GetReturnAddressToIonCode(JSContext* cx)
{
JitFrameIterator iter(cx);
MOZ_ASSERT(iter.type() == JitFrame_Exit);
MOZ_ASSERT(iter.type() == JitFrame_Exit,
"An exit frame is expected as update functions are called with a VMFunction.");
void* returnAddr = iter.returnAddress();
#ifdef DEBUG

View File

@ -40,7 +40,7 @@ template <typename T>
bool
JitFrameIterator::isExitFrameLayout() const
{
if (type_ != JitFrame_Exit || isFakeExitFrame())
if (!isExitFrame() || isFakeExitFrame())
return false;
return exitFrame()->is<T>();
}

View File

@ -65,7 +65,14 @@ enum FrameType
// the reconstruction of the BaselineJS frame. From within C++, a bailout
// frame is always the last frame in a JitActivation iff the bailout frame
// information is recorded on the JitActivation.
JitFrame_Bailout
JitFrame_Bailout,
// A lazy link frame is a special exit frame where a IonJS frame is reused
// for linking the newly compiled code. A special frame is needed to
// work-around the fact that we can make stack patterns which are similar to
// unwound frames. As opposed to unwound frames, we still have to mark all
// the arguments of the original IonJS frame.
JitFrame_LazyLink
};
enum ReadFrameArgsBehavior {
@ -142,6 +149,9 @@ class JitFrameIterator
bool checkInvalidation(IonScript** ionScript) const;
bool checkInvalidation() const;
bool isExitFrame() const {
return type_ == JitFrame_Exit || type_ == JitFrame_LazyLink;
}
bool isScripted() const {
return type_ == JitFrame_BaselineJS || type_ == JitFrame_IonJS || type_ == JitFrame_Bailout;
}
@ -198,7 +208,7 @@ class JitFrameIterator
// Returns the stack space used by the current frame, in bytes. This does
// not include the size of its fixed header.
size_t frameSize() const {
MOZ_ASSERT(type_ != JitFrame_Exit);
MOZ_ASSERT(!isExitFrame());
return frameSize_;
}

View File

@ -51,6 +51,8 @@ JitFrameIterator::prevType() const
inline bool
JitFrameIterator::isFakeExitFrame() const
{
if (type() == JitFrame_LazyLink)
return false;
bool res = (prevType() == JitFrame_Unwound_Rectifier ||
prevType() == JitFrame_Unwound_IonJS ||
prevType() == JitFrame_Unwound_BaselineJS ||
@ -64,7 +66,7 @@ JitFrameIterator::isFakeExitFrame() const
inline ExitFrameLayout*
JitFrameIterator::exitFrame() const
{
MOZ_ASSERT(type() == JitFrame_Exit);
MOZ_ASSERT(isExitFrame());
MOZ_ASSERT(!isFakeExitFrame());
return (ExitFrameLayout*) fp();
}

View File

@ -117,6 +117,9 @@ JitFrameIterator::JitFrameIterator(JSContext* cx)
current_ = activation_->bailoutData()->fp();
frameSize_ = activation_->bailoutData()->topFrameSize();
type_ = JitFrame_Bailout;
} else if (activation_->isLazyLinkExitFrame()) {
type_ = JitFrame_LazyLink;
MOZ_ASSERT(isExitFrameLayout<LazyLinkExitFrameLayout>());
}
}
@ -132,6 +135,9 @@ JitFrameIterator::JitFrameIterator(const ActivationIterator& activations)
current_ = activation_->bailoutData()->fp();
frameSize_ = activation_->bailoutData()->topFrameSize();
type_ = JitFrame_Bailout;
} else if (activation_->isLazyLinkExitFrame()) {
type_ = JitFrame_LazyLink;
MOZ_ASSERT(isExitFrameLayout<LazyLinkExitFrameLayout>());
}
}
@ -264,6 +270,7 @@ SizeOfFramePrefix(FrameType type)
case JitFrame_Unwound_Rectifier:
return IonUnwoundRectifierFrameLayout::Size();
case JitFrame_Exit:
case JitFrame_LazyLink:
return ExitFrameLayout::Size();
case JitFrame_IonAccessorIC:
case JitFrame_Unwound_IonAccessorIC:
@ -957,6 +964,7 @@ EnsureExitFrame(CommonFrameLayout* frame)
case JitFrame_Exit:
case JitFrame_Bailout:
case JitFrame_LazyLink:
// Fall-through to MOZ_CRASH below.
break;
}
@ -1495,6 +1503,7 @@ MarkJitActivation(JSTracer* trc, const JitActivationIterator& activations)
for (JitFrameIterator frames(activations); !frames.done(); ++frames) {
switch (frames.type()) {
case JitFrame_Exit:
case JitFrame_LazyLink:
MarkJitExitFrame(trc, frames);
break;
case JitFrame_BaselineJS:
@ -1569,7 +1578,7 @@ GetPcScript(JSContext* cx, JSScript** scriptRes, jsbytecode** pcRes)
JitActivationIterator iter(rt);
JitFrameIterator it(iter);
uint8_t* retAddr;
if (it.type() == JitFrame_Exit) {
if (it.isExitFrame()) {
++it;
// Skip rectifier frames.
@ -2771,6 +2780,7 @@ JitFrameIterator::dump() const
fprintf(stderr, "Warning! Unwound JS frames are not observable.\n");
break;
case JitFrame_Exit:
case JitFrame_LazyLink:
break;
};
fputc('\n', stderr);
@ -3219,7 +3229,7 @@ AssertJitStackInvariants(JSContext* cx)
"The frame size is optimal");
}
if (frames.type() == JitFrame_Exit) {
if (frames.isExitFrame()) {
// For the moment, we do not keep the JitStackAlignment
// alignment for exit frames.
frameSize -= ExitFrameLayout::Size();

View File

@ -1895,6 +1895,16 @@ RangeAnalysis::analyzeLoop(MBasicBlock* header)
return true;
}
// Unbox beta nodes in order to hoist instruction properly, and not be limited
// by the beta nodes which are added after each branch.
static inline MDefinition*
DefinitionOrBetaInputDefinition(MDefinition* ins)
{
while (ins->isBeta())
ins = ins->toBeta()->input();
return ins;
}
LoopIterationBound*
RangeAnalysis::analyzeLoopIterationCount(MBasicBlock* header,
MTest* test, BranchDirection direction)
@ -1940,9 +1950,8 @@ RangeAnalysis::analyzeLoopIterationCount(MBasicBlock* header,
// The second operand of the phi should be a value written by an add/sub
// in every loop iteration, i.e. in a block which dominates the backedge.
MDefinition* lhsWrite = lhs.term->toPhi()->getLoopBackedgeOperand();
if (lhsWrite->isBeta())
lhsWrite = lhsWrite->getOperand(0);
MDefinition* lhsWrite =
DefinitionOrBetaInputDefinition(lhs.term->toPhi()->getLoopBackedgeOperand());
if (!lhsWrite->isAdd() && !lhsWrite->isSub())
return nullptr;
if (!lhsWrite->block()->isMarked())
@ -2107,7 +2116,8 @@ bool
RangeAnalysis::tryHoistBoundsCheck(MBasicBlock* header, MBoundsCheck* ins)
{
// The bounds check's length must be loop invariant.
if (ins->length()->block()->isMarked())
MDefinition *length = DefinitionOrBetaInputDefinition(ins->length());
if (length->block()->isMarked())
return false;
// The bounds check's index should not be loop invariant (else we would
@ -2165,7 +2175,7 @@ RangeAnalysis::tryHoistBoundsCheck(MBasicBlock* header, MBoundsCheck* ins)
lowerCheck->computeRange(alloc());
lowerCheck->collectRangeInfoPreTrunc();
MBoundsCheck* upperCheck = MBoundsCheck::New(alloc(), upperTerm, ins->length());
MBoundsCheck* upperCheck = MBoundsCheck::New(alloc(), upperTerm, length);
upperCheck->setMinimum(upperConstant);
upperCheck->setMaximum(upperConstant);
upperCheck->computeRange(alloc());

View File

@ -1391,6 +1391,7 @@ AbstractFramePtr::hasPushedSPSFrame() const
jit::JitActivation::JitActivation(JSContext* cx, bool active)
: Activation(cx, Jit),
active_(active),
isLazyLinkExitFrame_(false),
rematerializedFrames_(nullptr),
ionRecovery_(cx),
bailoutData_(nullptr),

View File

@ -1286,6 +1286,15 @@ class JitActivation : public Activation
JSContext* prevJitJSContext_;
bool active_;
// The lazy link stub reuse the frame pushed for calling a function as an
// exit frame. In a few cases, such as after calls from asm.js, we might
// have an entry frame followed by an exit frame. This pattern can be
// assimilated as a fake exit frame (unwound frame), in which case we skip
// marking during a GC. To ensure that we do mark the stack as expected we
// have to keep a flag set by the LazyLink VM function to safely mark the
// stack if a GC happens during the link phase.
bool isLazyLinkExitFrame_;
// Rematerialized Ion frames which has info copied out of snapshots. Maps
// frame pointers (i.e. jitTop) to a vector of rematerializations of all
// inline frames associated with that frame.
@ -1417,6 +1426,14 @@ class JitActivation : public Activation
// Unregister the bailout data when the frame is reconstructed.
void cleanBailoutData();
// Return the bailout information if it is registered.
bool isLazyLinkExitFrame() const { return isLazyLinkExitFrame_; }
// Register the bailout data when it is constructed.
void setLazyLinkExitFrame(bool isExitFrame) {
isLazyLinkExitFrame_ = isExitFrame;
}
static size_t offsetOfLastProfilingFrame() {
return offsetof(JitActivation, lastProfilingFrame_);
}

View File

@ -63,8 +63,10 @@ function run_test()
{
Cu.setAddonInterposition(ADDONID, TestInterposition);
Cu.importGlobalProperties(["XMLHttpRequest"]);
let sandbox = Cu.Sandbox(this, {addonId: ADDONID});
sandbox.outerObj = {};
sandbox.outerObj = new XMLHttpRequest();
expectAccess("abcxyz", () => {
Cu.evalInSandbox("outerObj.abcxyz = 12;", sandbox);

View File

@ -11,6 +11,8 @@
#include "jsfriendapi.h"
#include "nsIAddonInterposition.h"
#include "xpcprivate.h"
#include "mozilla/dom/BindingUtils.h"
#include "nsGlobalWindow.h"
#include "nsID.h"
@ -23,6 +25,17 @@ bool
Interpose(JSContext* cx, HandleObject target, const nsIID* iid, HandleId id,
MutableHandle<JSPropertyDescriptor> descriptor)
{
// We only want to do interpostion on DOM instances and
// wrapped natives.
RootedObject unwrapped(cx, UncheckedUnwrap(target));
const js::Class* clasp = js::GetObjectClass(unwrapped);
if (!mozilla::dom::IsDOMClass(clasp) &&
!IS_WN_CLASS(clasp) &&
!IS_PROTO_CLASS(clasp) &&
clasp != &OuterWindowProxyClass) {
return true;
}
XPCWrappedNativeScope* scope = ObjectScope(CurrentGlobalOrNull(cx));
MOZ_ASSERT(scope->HasInterposition());

View File

@ -3020,19 +3020,24 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
} else {
EventRegions regions;
regions.mHitRegion = ScaleRegionToOutsidePixels(data->mHitRegion);
regions.mNoActionRegion = ScaleRegionToOutsidePixels(data->mNoActionRegion);
regions.mHorizontalPanRegion = ScaleRegionToOutsidePixels(data->mHorizontalPanRegion);
regions.mVerticalPanRegion = ScaleRegionToOutsidePixels(data->mVerticalPanRegion);
regions.mHitRegion =
data->mHitRegion.ToOutsidePixels(mAppUnitsPerDevPixel);
regions.mNoActionRegion =
data->mNoActionRegion.ToOutsidePixels(mAppUnitsPerDevPixel);
regions.mHorizontalPanRegion =
data->mHorizontalPanRegion.ToOutsidePixels(mAppUnitsPerDevPixel);
regions.mVerticalPanRegion =
data->mVerticalPanRegion.ToOutsidePixels(mAppUnitsPerDevPixel);
// Points whose hit-region status we're not sure about need to be dispatched
// to the content thread. If a point is in both maybeHitRegion and hitRegion
// then it's not a "maybe" any more, and doesn't go into the dispatch-to-
// content region.
nsIntRegion maybeHitRegion = ScaleRegionToOutsidePixels(data->mMaybeHitRegion);
nsIntRegion maybeHitRegion =
data->mMaybeHitRegion.ToOutsidePixels(mAppUnitsPerDevPixel);
regions.mDispatchToContentHitRegion.Sub(maybeHitRegion, regions.mHitRegion);
regions.mDispatchToContentHitRegion.OrWith(
ScaleRegionToOutsidePixels(data->mDispatchToContentHitRegion));
data->mDispatchToContentHitRegion.ToOutsidePixels(mAppUnitsPerDevPixel));
regions.mHitRegion.OrWith(maybeHitRegion);
Matrix mat = layer->GetBaseTransform().As2D();

View File

@ -7590,7 +7590,7 @@ nsLayoutUtils::GetContentViewerSize(nsPresContext* aPresContext,
}
/* static */ nsSize
nsLayoutUtils::CalculateCompositionSizeForFrame(nsIFrame* aFrame)
nsLayoutUtils::CalculateCompositionSizeForFrame(nsIFrame* aFrame, bool aSubtractScrollbars)
{
// If we have a scrollable frame, restrict the composition bounds to its
// scroll port. The scroll port excludes the frame borders and the scroll
@ -7646,7 +7646,7 @@ nsLayoutUtils::CalculateCompositionSizeForFrame(nsIFrame* aFrame)
}
}
if (scrollableFrame && !LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) {
if (aSubtractScrollbars && scrollableFrame && !LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars)) {
nsMargin margins = scrollableFrame->GetActualScrollbarSizes();
size.width -= margins.LeftRight();
size.height -= margins.TopBottom();

View File

@ -2465,7 +2465,7 @@ public:
* are likely to need special-case handling of the RCD-RSF.
*/
static nsSize
CalculateCompositionSizeForFrame(nsIFrame* aFrame);
CalculateCompositionSizeForFrame(nsIFrame* aFrame, bool aSubtractScrollbars = true);
/**
* Calculate the composition size for the root scroll frame of the root

View File

@ -6518,7 +6518,7 @@ void
PresShell::UpdateActivePointerState(WidgetGUIEvent* aEvent)
{
switch (aEvent->message) {
case NS_MOUSE_ENTER:
case NS_MOUSE_ENTER_WIDGET:
// In this case we have to know information about available mouse pointers
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
gActivePointersIds->Put(mouseEvent->pointerId,
@ -6543,7 +6543,7 @@ PresShell::UpdateActivePointerState(WidgetGUIEvent* aEvent)
}
}
break;
case NS_MOUSE_EXIT:
case NS_MOUSE_EXIT_WIDGET:
// In this case we have to remove information about disappeared mouse pointers
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
gActivePointersIds->Remove(mouseEvent->pointerId);
@ -6739,7 +6739,7 @@ PresShell::RecordMouseLocation(WidgetGUIEvent* aEvent)
if ((aEvent->message == NS_MOUSE_MOVE &&
aEvent->AsMouseEvent()->reason == WidgetMouseEvent::eReal) ||
aEvent->message == NS_MOUSE_ENTER ||
aEvent->message == NS_MOUSE_ENTER_WIDGET ||
aEvent->message == NS_MOUSE_BUTTON_DOWN ||
aEvent->message == NS_MOUSE_BUTTON_UP) {
nsIFrame* rootFrame = GetRootFrame();
@ -6752,15 +6752,15 @@ PresShell::RecordMouseLocation(WidgetGUIEvent* aEvent)
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, rootFrame);
}
#ifdef DEBUG_MOUSE_LOCATION
if (aEvent->message == NS_MOUSE_ENTER)
if (aEvent->message == NS_MOUSE_ENTER_WIDGET)
printf("[ps=%p]got mouse enter for %p\n",
this, aEvent->widget);
printf("[ps=%p]setting mouse location to (%d,%d)\n",
this, mMouseLocation.x, mMouseLocation.y);
#endif
if (aEvent->message == NS_MOUSE_ENTER)
if (aEvent->message == NS_MOUSE_ENTER_WIDGET)
SynthesizeMouseMove(false);
} else if (aEvent->message == NS_MOUSE_EXIT) {
} else if (aEvent->message == NS_MOUSE_EXIT_WIDGET) {
// Although we only care about the mouse moving into an area for which this
// pres shell doesn't receive mouse move events, we don't check which widget
// the mouse exit was for since this seems to vary by platform. Hopefully
@ -7458,7 +7458,7 @@ PresShell::HandleEvent(nsIFrame* aFrame,
}
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
bool isWindowLevelMouseExit = (aEvent->message == NS_MOUSE_EXIT) &&
bool isWindowLevelMouseExit = (aEvent->message == NS_MOUSE_EXIT_WIDGET) &&
(mouseEvent && mouseEvent->exit == WidgetMouseEvent::eTopLevel);
// Get the frame at the event point. However, don't do this if we're

View File

@ -862,8 +862,8 @@ nsListControlFrame::HandleEvent(nsPresContext* aPresContext,
"<NA>","<NA>","<NA>","<NA>","<NA>","<NA>","<NA>","<NA>",
"NS_MOUSE_RIGHT_BUTTON_UP",
"NS_MOUSE_RIGHT_BUTTON_DOWN",
"NS_MOUSE_ENTER_SYNTH",
"NS_MOUSE_EXIT_SYNTH",
"NS_MOUSE_OVER",
"NS_MOUSE_OUT",
"NS_MOUSE_LEFT_DOUBLECLICK",
"NS_MOUSE_MIDDLE_DOUBLECLICK",
"NS_MOUSE_RIGHT_DOUBLECLICK",

View File

@ -1278,6 +1278,13 @@ public:
IStart() + aMargin.IStart());
}
LogicalMargin operator+=(const LogicalMargin& aMargin)
{
CHECK_WRITING_MODE(aMargin.GetWritingMode());
mMargin += aMargin.mMargin;
return *this;
}
LogicalMargin operator-(const LogicalMargin& aMargin) const {
CHECK_WRITING_MODE(aMargin.GetWritingMode());
return LogicalMargin(GetWritingMode(),

View File

@ -352,10 +352,16 @@ nsHTMLScrollFrame::TryLayout(ScrollReflowState* aState,
ComputeInsideBorderSize(aState, desiredInsideBorderSize);
nsSize scrollPortSize = nsSize(std::max(0, aState->mInsideBorderSize.width - vScrollbarDesiredWidth),
std::max(0, aState->mInsideBorderSize.height - hScrollbarDesiredHeight));
nsSize visualScrollPortSize = scrollPortSize;
nsIPresShell* presShell = PresContext()->PresShell();
if (mHelper.mIsRoot && presShell->IsScrollPositionClampingScrollPortSizeSet()) {
visualScrollPortSize = presShell->GetScrollPositionClampingScrollPortSize();
nsSize compositionSize = nsLayoutUtils::CalculateCompositionSizeForFrame(this, false);
float resolution = presShell->GetResolution();
compositionSize.width /= resolution;
compositionSize.height /= resolution;
visualScrollPortSize = nsSize(std::max(0, compositionSize.width - vScrollbarDesiredWidth),
std::max(0, compositionSize.height - hScrollbarDesiredHeight));
}
if (!aForce) {

View File

@ -1783,7 +1783,7 @@ nsPluginFrame::HandleEvent(nsPresContext* aPresContext,
#ifdef XP_MACOSX
// we want to process some native mouse events in the cocoa event model
if ((anEvent->message == NS_MOUSE_ENTER ||
if ((anEvent->message == NS_MOUSE_ENTER_WIDGET ||
anEvent->message == NS_WHEEL_WHEEL) &&
mInstanceOwner->GetEventModel() == NPEventModelCocoa) {
*anEventStatus = mInstanceOwner->ProcessEvent(*anEvent);

View File

@ -1239,13 +1239,12 @@ nsMathMLmtdFrame::ProcessBorders(nsTableFrame* aFrame,
return NS_OK;
}
nsMargin*
nsMathMLmtdFrame::GetBorderWidth(nsMargin& aBorder) const
LogicalMargin
nsMathMLmtdFrame::GetBorderWidth(WritingMode aWM) const
{
nsStyleBorder styleBorder = *StyleBorder();
ApplyBorderToStyle(this, styleBorder);
aBorder = styleBorder.GetComputedBorder();
return &aBorder;
return LogicalMargin(aWM, styleBorder.GetComputedBorder());
}
nsMargin

View File

@ -264,7 +264,7 @@ public:
return nsTableCellFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
}
virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const override;
virtual LogicalMargin GetBorderWidth(WritingMode aWM) const override;
virtual nsMargin GetBorderOverflow() override;

View File

@ -165,19 +165,19 @@ typedef uint16_t BCPixelSize;
// the actual value is computed when needed.
#define MAX_BORDER_WIDTH nscoord((1u << (sizeof(BCPixelSize) * 8)) - 1)
static inline nscoord
BC_BORDER_TOP_HALF_COORD(int32_t p2t, uint16_t px) { return (px - px / 2) * p2t; }
static inline nscoord
BC_BORDER_RIGHT_HALF_COORD(int32_t p2t, uint16_t px) { return ( px / 2) * p2t; }
static inline nscoord
BC_BORDER_BOTTOM_HALF_COORD(int32_t p2t, uint16_t px) { return ( px / 2) * p2t; }
static inline nscoord
BC_BORDER_LEFT_HALF_COORD(int32_t p2t, uint16_t px) { return (px - px / 2) * p2t; }
// The half of border on inline/block-axis start side
static inline BCPixelSize
BC_BORDER_START_HALF(BCPixelSize px) { return px - px / 2; }
// The half of border on inline/block-axis end side
static inline BCPixelSize
BC_BORDER_END_HALF(BCPixelSize px) { return px / 2; }
#define BC_BORDER_TOP_HALF(px) ((px) - (px) / 2)
#define BC_BORDER_RIGHT_HALF(px) ((px) / 2)
#define BC_BORDER_BOTTOM_HALF(px) ((px) / 2)
#define BC_BORDER_LEFT_HALF(px) ((px) - (px) / 2)
static inline nscoord
BC_BORDER_START_HALF_COORD(int32_t p2t, BCPixelSize px)
{ return BC_BORDER_START_HALF(px) * p2t; }
static inline nscoord
BC_BORDER_END_HALF_COORD(int32_t p2t, BCPixelSize px)
{ return BC_BORDER_END_HALF(px) * p2t; }
// BCData stores the top and left border info and the corner connecting the two.
class BCData

View File

@ -796,9 +796,8 @@ nsTableCellFrame::IntrinsicISizeOffsets(nsRenderingContext* aRenderingContext)
result.hMargin = 0;
result.hPctMargin = 0;
nsMargin border;
GetBorderWidth(border);
result.hBorder = border.LeftRight();
WritingMode wm = GetWritingMode();
result.hBorder = GetBorderWidth(wm).IStartEnd(wm);
return result;
}
@ -875,15 +874,15 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
aStatus = NS_FRAME_COMPLETE;
nsSize availSize(aReflowState.AvailableWidth(), aReflowState.AvailableHeight());
nsMargin borderPadding = aReflowState.ComputedPhysicalPadding();
nsMargin border;
GetBorderWidth(border);
WritingMode wm = aReflowState.GetWritingMode();
LogicalMargin borderPadding = aReflowState.ComputedLogicalPadding();
LogicalMargin border = GetBorderWidth(wm);
borderPadding += border;
nscoord topInset = borderPadding.top;
nscoord rightInset = borderPadding.right;
nscoord bottomInset = borderPadding.bottom;
nscoord leftInset = borderPadding.left;
nscoord topInset = borderPadding.Top(wm);
nscoord rightInset = borderPadding.Right(wm);
nscoord bottomInset = borderPadding.Bottom(wm);
nscoord leftInset = borderPadding.Left(wm);
// reduce available space by insets, if we're in a constrained situation
availSize.width -= leftInset + rightInset;
@ -895,7 +894,6 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
if (availSize.height < 0)
availSize.height = 1;
WritingMode wm = aReflowState.GetWritingMode();
nsHTMLReflowMetrics kidSize(wm, aDesiredSize.mFlags);
kidSize.ClearSize();
SetPriorAvailWidth(aReflowState.AvailableWidth());
@ -1080,11 +1078,10 @@ NS_NewTableCellFrame(nsIPresShell* aPresShell,
NS_IMPL_FRAMEARENA_HELPERS(nsBCTableCellFrame)
nsMargin*
nsTableCellFrame::GetBorderWidth(nsMargin& aBorder) const
LogicalMargin
nsTableCellFrame::GetBorderWidth(WritingMode aWM) const
{
aBorder = StyleBorder()->GetComputedBorder();
return &aBorder;
return LogicalMargin(aWM, StyleBorder()->GetComputedBorder());
}
nsIAtom*
@ -1107,7 +1104,7 @@ nsBCTableCellFrame::nsBCTableCellFrame(nsStyleContext* aContext,
nsTableFrame* aTableFrame)
: nsTableCellFrame(aContext, aTableFrame)
{
mTopBorder = mRightBorder = mBottomBorder = mLeftBorder = 0;
mBStartBorder = mIEndBorder = mBEndBorder = mIStartBorder = 0;
}
nsBCTableCellFrame::~nsBCTableCellFrame()
@ -1123,9 +1120,8 @@ nsBCTableCellFrame::GetType() const
/* virtual */ nsMargin
nsBCTableCellFrame::GetUsedBorder() const
{
nsMargin result;
GetBorderWidth(result);
return result;
WritingMode wm = GetWritingMode();
return GetBorderWidth(wm).GetPhysicalMargin(wm);
}
/* virtual */ bool
@ -1148,61 +1144,61 @@ nsBCTableCellFrame::GetFrameName(nsAString& aResult) const
}
#endif
nsMargin*
nsBCTableCellFrame::GetBorderWidth(nsMargin& aBorder) const
LogicalMargin
nsBCTableCellFrame::GetBorderWidth(WritingMode aWM) const
{
int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
aBorder.top = BC_BORDER_BOTTOM_HALF_COORD(aPixelsToTwips, mTopBorder);
aBorder.right = BC_BORDER_LEFT_HALF_COORD(aPixelsToTwips, mRightBorder);
aBorder.bottom = BC_BORDER_TOP_HALF_COORD(aPixelsToTwips, mBottomBorder);
aBorder.left = BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips, mLeftBorder);
return &aBorder;
int32_t pixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
return LogicalMargin(aWM,
BC_BORDER_END_HALF_COORD(pixelsToTwips, mBStartBorder),
BC_BORDER_START_HALF_COORD(pixelsToTwips, mIEndBorder),
BC_BORDER_START_HALF_COORD(pixelsToTwips, mBEndBorder),
BC_BORDER_END_HALF_COORD(pixelsToTwips, mIStartBorder));
}
BCPixelSize
nsBCTableCellFrame::GetBorderWidth(mozilla::css::Side aSide) const
nsBCTableCellFrame::GetBorderWidth(LogicalSide aSide) const
{
switch(aSide) {
case NS_SIDE_TOP:
return BC_BORDER_BOTTOM_HALF(mTopBorder);
case NS_SIDE_RIGHT:
return BC_BORDER_LEFT_HALF(mRightBorder);
case NS_SIDE_BOTTOM:
return BC_BORDER_TOP_HALF(mBottomBorder);
case eLogicalSideBStart:
return BC_BORDER_END_HALF(mBStartBorder);
case eLogicalSideIEnd:
return BC_BORDER_START_HALF(mIEndBorder);
case eLogicalSideBEnd:
return BC_BORDER_START_HALF(mBEndBorder);
default:
return BC_BORDER_RIGHT_HALF(mLeftBorder);
return BC_BORDER_END_HALF(mIStartBorder);
}
}
void
nsBCTableCellFrame::SetBorderWidth(mozilla::css::Side aSide,
BCPixelSize aValue)
nsBCTableCellFrame::SetBorderWidth(LogicalSide aSide, BCPixelSize aValue)
{
switch(aSide) {
case NS_SIDE_TOP:
mTopBorder = aValue;
case eLogicalSideBStart:
mBStartBorder = aValue;
break;
case NS_SIDE_RIGHT:
mRightBorder = aValue;
case eLogicalSideIEnd:
mIEndBorder = aValue;
break;
case NS_SIDE_BOTTOM:
mBottomBorder = aValue;
case eLogicalSideBEnd:
mBEndBorder = aValue;
break;
default:
mLeftBorder = aValue;
mIStartBorder = aValue;
}
}
/* virtual */ nsMargin
nsBCTableCellFrame::GetBorderOverflow()
{
nsMargin halfBorder;
WritingMode wm = GetWritingMode();
int32_t p2t = nsPresContext::AppUnitsPerCSSPixel();
halfBorder.top = BC_BORDER_TOP_HALF_COORD(p2t, mTopBorder);
halfBorder.right = BC_BORDER_RIGHT_HALF_COORD(p2t, mRightBorder);
halfBorder.bottom = BC_BORDER_BOTTOM_HALF_COORD(p2t, mBottomBorder);
halfBorder.left = BC_BORDER_LEFT_HALF_COORD(p2t, mLeftBorder);
return halfBorder;
LogicalMargin halfBorder(wm,
BC_BORDER_START_HALF_COORD(p2t, mBStartBorder),
BC_BORDER_END_HALF_COORD(p2t, mIEndBorder),
BC_BORDER_END_HALF_COORD(p2t, mBEndBorder),
BC_BORDER_START_HALF_COORD(p2t, mIStartBorder));
return halfBorder.GetPhysicalMargin(wm);
}
@ -1214,8 +1210,8 @@ nsBCTableCellFrame::PaintBackground(nsRenderingContext& aRenderingContext,
{
// make border-width reflect the half of the border-collapse
// assigned border that's inside the cell
nsMargin borderWidth;
GetBorderWidth(borderWidth);
WritingMode wm = GetWritingMode();
nsMargin borderWidth = GetBorderWidth(wm).GetPhysicalMargin(wm);
nsStyleBorder myBorder(*StyleBorder());

View File

@ -17,6 +17,7 @@
#include "nsLayoutUtils.h"
#include "nsTArray.h"
#include "nsTableRowFrame.h"
#include "mozilla/WritingModes.h"
/**
* nsTableCellFrame
@ -35,6 +36,11 @@ class nsTableCellFrame : public nsContainerFrame,
{
typedef mozilla::image::DrawResult DrawResult;
protected:
typedef mozilla::WritingMode WritingMode;
typedef mozilla::LogicalSide LogicalSide;
typedef mozilla::LogicalMargin LogicalMargin;
public:
NS_DECL_QUERYFRAME_TARGET(nsTableCellFrame)
NS_DECL_QUERYFRAME
@ -215,7 +221,7 @@ public:
nsTableCellFrame* GetNextCell() const;
virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const;
virtual LogicalMargin GetBorderWidth(WritingMode aWM) const;
virtual DrawResult PaintBackground(nsRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
@ -321,13 +327,13 @@ public:
nscoord aRadii[8]) const override;
// Get the *inner half of the border only*, in twips.
virtual nsMargin* GetBorderWidth(nsMargin& aBorder) const override;
virtual LogicalMargin GetBorderWidth(WritingMode aWM) const override;
// Get the *inner half of the border only*, in pixels.
BCPixelSize GetBorderWidth(mozilla::css::Side aSide) const;
BCPixelSize GetBorderWidth(LogicalSide aSide) const;
// Set the full (both halves) width of the border
void SetBorderWidth(mozilla::css::Side aSide, BCPixelSize aPixelValue);
void SetBorderWidth(LogicalSide aSide, BCPixelSize aPixelValue);
virtual nsMargin GetBorderOverflow() override;
@ -344,10 +350,10 @@ private:
// These are the entire width of the border (the cell edge contains only
// the inner half, per the macros in nsTablePainter.h).
BCPixelSize mTopBorder;
BCPixelSize mRightBorder;
BCPixelSize mBottomBorder;
BCPixelSize mLeftBorder;
BCPixelSize mBStartBorder;
BCPixelSize mIEndBorder;
BCPixelSize mBEndBorder;
BCPixelSize mIStartBorder;
};
#endif

View File

@ -13,6 +13,8 @@
#include "nsCSSRendering.h"
#include "nsIContent.h"
using namespace mozilla;
#define COL_TYPE_BITS (NS_FRAME_STATE_BIT(28) | \
NS_FRAME_STATE_BIT(29) | \
NS_FRAME_STATE_BIT(30) | \
@ -69,18 +71,18 @@ nsTableColFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
}
}
void nsTableColFrame::SetContinuousBCBorderWidth(uint8_t aForSide,
void nsTableColFrame::SetContinuousBCBorderWidth(LogicalSide aForSide,
BCPixelSize aPixelValue)
{
switch (aForSide) {
case NS_SIDE_TOP:
mTopContBorderWidth = aPixelValue;
case eLogicalSideBStart:
mBStartContBorderWidth = aPixelValue;
return;
case NS_SIDE_RIGHT:
mRightContBorderWidth = aPixelValue;
case eLogicalSideIEnd:
mIEndContBorderWidth = aPixelValue;
return;
case NS_SIDE_BOTTOM:
mBottomContBorderWidth = aPixelValue;
case eLogicalSideBEnd:
mBEndContBorderWidth = aPixelValue;
return;
default:
NS_ERROR("invalid side arg");

View File

@ -88,10 +88,10 @@ public:
/** convenience method, calls into cellmap */
int32_t Count() const;
nscoord GetLeftBorderWidth();
void SetLeftBorderWidth(BCPixelSize aWidth);
nscoord GetRightBorderWidth();
void SetRightBorderWidth(BCPixelSize aWidth);
nscoord GetIStartBorderWidth() const { return mIStartBorderWidth; }
nscoord GetIEndBorderWidth() const { return mIEndBorderWidth; }
void SetIStartBorderWidth(BCPixelSize aWidth) { mIStartBorderWidth = aWidth; }
void SetIEndBorderWidth(BCPixelSize aWidth) { mIEndBorderWidth = aWidth; }
/**
* Gets inner border widths before collapsing with cell borders
@ -104,9 +104,9 @@ public:
nscoord GetContinuousBCBorderWidth(nsMargin& aBorder);
/**
* Set full border widths before collapsing with cell borders
* @param aForSide - side to set; only valid for top, right, and bottom
* @param aForSide - side to set; only valid for bstart, iend, and bend
*/
void SetContinuousBCBorderWidth(uint8_t aForSide,
void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide,
BCPixelSize aPixelValue);
#ifdef DEBUG
void Dump(int32_t aIndent);
@ -305,11 +305,11 @@ protected:
uint32_t mColIndex;
// border width in pixels of the inner half of the border only
BCPixelSize mLeftBorderWidth;
BCPixelSize mRightBorderWidth;
BCPixelSize mTopContBorderWidth;
BCPixelSize mRightContBorderWidth;
BCPixelSize mBottomContBorderWidth;
BCPixelSize mIStartBorderWidth;
BCPixelSize mIEndBorderWidth;
BCPixelSize mBStartContBorderWidth;
BCPixelSize mIEndContBorderWidth;
BCPixelSize mBEndContBorderWidth;
bool mHasSpecifiedCoord;
};
@ -324,37 +324,20 @@ inline void nsTableColFrame::SetColIndex (int32_t aColIndex)
mColIndex = aColIndex;
}
inline nscoord nsTableColFrame::GetLeftBorderWidth()
{
return mLeftBorderWidth;
}
inline void nsTableColFrame::SetLeftBorderWidth(BCPixelSize aWidth)
{
mLeftBorderWidth = aWidth;
}
inline nscoord nsTableColFrame::GetRightBorderWidth()
{
return mRightBorderWidth;
}
inline void nsTableColFrame::SetRightBorderWidth(BCPixelSize aWidth)
{
mRightBorderWidth = aWidth;
}
inline nscoord
nsTableColFrame::GetContinuousBCBorderWidth(nsMargin& aBorder)
{
int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
aBorder.top = BC_BORDER_BOTTOM_HALF_COORD(aPixelsToTwips,
mTopContBorderWidth);
aBorder.right = BC_BORDER_LEFT_HALF_COORD(aPixelsToTwips,
mRightContBorderWidth);
aBorder.bottom = BC_BORDER_TOP_HALF_COORD(aPixelsToTwips,
mBottomContBorderWidth);
return BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips, mRightContBorderWidth);
mozilla::WritingMode wm = GetWritingMode();
mozilla::LogicalMargin border(wm, aBorder);
border.BStart(wm) = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
mBStartContBorderWidth);
border.IEnd(wm) = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
mIEndContBorderWidth);
border.BEnd(wm) = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
mBEndContBorderWidth);
aBorder = border.GetPhysicalMargin(wm);
return BC_BORDER_END_HALF_COORD(aPixelsToTwips, mIEndContBorderWidth);
}
#endif

View File

@ -437,10 +437,10 @@ void nsTableColGroupFrame::GetContinuousBCBorderWidth(nsMargin& aBorder)
nsTableColFrame* col = GetTableFrame()->
GetColFrame(mStartColIndex + mColCount - 1);
col->GetContinuousBCBorderWidth(aBorder);
aBorder.top = BC_BORDER_BOTTOM_HALF_COORD(aPixelsToTwips,
mTopContBorderWidth);
aBorder.bottom = BC_BORDER_TOP_HALF_COORD(aPixelsToTwips,
mBottomContBorderWidth);
aBorder.top = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
mTopContBorderWidth);
aBorder.bottom = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
mBottomContBorderWidth);
}
/* ----- global methods ----- */

File diff suppressed because it is too large Load Diff

View File

@ -986,7 +986,7 @@ inline nscoord
nsTableFrame::GetContinuousLeftBCBorderWidth() const
{
int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
return BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips, mBits.mLeftContBCBorder);
return BC_BORDER_END_HALF_COORD(aPixelsToTwips, mBits.mLeftContBCBorder);
}
inline void nsTableFrame::SetContinuousLeftBCBorderWidth(nscoord aValue)

View File

@ -12,6 +12,7 @@
#include "nsTablePainter.h"
#include "nsCSSRendering.h"
#include "nsDisplayList.h"
#include "mozilla/WritingModes.h"
/* ~*~ Table Background Painting ~*~
@ -95,6 +96,7 @@
XXX views are going
*/
using namespace mozilla;
using namespace mozilla::image;
TableBackgroundPainter::TableBackgroundData::TableBackgroundData()
@ -489,7 +491,9 @@ TableBackgroundPainter::PaintRow(nsTableRowFrame* aFrame,
nsMargin border;
nsTableRowFrame* nextRow = aFrame->GetNextRow();
if (nextRow) { //outer top below us is inner bottom for us
border.bottom = nextRow->GetOuterTopContBCBorderWidth();
WritingMode wm = nextRow->GetWritingMode();
border.Side(wm.PhysicalSide(eLogicalSideBEnd)) =
nextRow->GetOuterBStartContBCBorderWidth();
}
else { //acquire rg's bottom border
nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame->GetParent());

View File

@ -75,7 +75,9 @@ nsTableRowFrame::InitChildReflowState(nsPresContext& aPresContext,
// we only reflow cells, so don't need to check frame type
nsBCTableCellFrame* bcCellFrame = (nsBCTableCellFrame*)aReflowState.frame;
if (bcCellFrame) {
pCollapseBorder = bcCellFrame->GetBorderWidth(collapseBorder);
WritingMode wm = GetWritingMode();
collapseBorder = bcCellFrame->GetBorderWidth(wm).GetPhysicalMargin(wm);
pCollapseBorder = &collapseBorder;
}
}
aReflowState.Init(&aPresContext, -1, -1, pCollapseBorder);
@ -1373,18 +1375,18 @@ nsTableRowFrame::GetUnpaginatedHeight(nsPresContext* aPresContext)
return NS_PTR_TO_INT32(props.Get(RowUnpaginatedHeightProperty()));
}
void nsTableRowFrame::SetContinuousBCBorderWidth(uint8_t aForSide,
void nsTableRowFrame::SetContinuousBCBorderWidth(LogicalSide aForSide,
BCPixelSize aPixelValue)
{
switch (aForSide) {
case NS_SIDE_RIGHT:
mRightContBorderWidth = aPixelValue;
case eLogicalSideIEnd:
mIEndContBorderWidth = aPixelValue;
return;
case NS_SIDE_TOP:
mTopContBorderWidth = aPixelValue;
case eLogicalSideBStart:
mBStartContBorderWidth = aPixelValue;
return;
case NS_SIDE_LEFT:
mLeftContBorderWidth = aPixelValue;
case eLogicalSideIStart:
mIStartContBorderWidth = aPixelValue;
return;
default:
NS_ERROR("invalid NS_SIDE arg");

View File

@ -211,28 +211,28 @@ public:
nscoord GetUnpaginatedHeight(nsPresContext* aPresContext);
void SetUnpaginatedHeight(nsPresContext* aPresContext, nscoord aValue);
nscoord GetTopBCBorderWidth();
void SetTopBCBorderWidth(BCPixelSize aWidth);
nscoord GetBottomBCBorderWidth();
void SetBottomBCBorderWidth(BCPixelSize aWidth);
nsMargin* GetBCBorderWidth(nsMargin& aBorder);
nscoord GetBStartBCBorderWidth() const { return mBStartBorderWidth; }
nscoord GetBEndBCBorderWidth() const { return mBEndBorderWidth; }
void SetBStartBCBorderWidth(BCPixelSize aWidth) { mBStartBorderWidth = aWidth; }
void SetBEndBCBorderWidth(BCPixelSize aWidth) { mBEndBorderWidth = aWidth; }
mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM);
/**
* Gets inner border widths before collapsing with cell borders
* Caller must get bottom border from next row or from table
* GetContinuousBCBorderWidth will not overwrite aBorder.bottom
* Caller must get block-end border from next row or from table
* GetContinuousBCBorderWidth will not overwrite that border
* see nsTablePainter about continuous borders
*/
void GetContinuousBCBorderWidth(nsMargin& aBorder);
/**
* @returns outer top bc border == prev row's bottom inner
* @returns outer block-start bc border == prev row's block-end inner
*/
nscoord GetOuterTopContBCBorderWidth();
nscoord GetOuterBStartContBCBorderWidth();
/**
* Sets full border widths before collapsing with cell borders
* @param aForSide - side to set; only accepts right, left, and top
* @param aForSide - side to set; only accepts iend, istart, and bstart
*/
void SetContinuousBCBorderWidth(uint8_t aForSide,
void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide,
BCPixelSize aPixelValue);
virtual bool IsFrameOfType(uint32_t aFlags) const override
@ -300,11 +300,11 @@ private:
// border widths in pixels in the collapsing border model of the *inner*
// half of the border only
BCPixelSize mTopBorderWidth;
BCPixelSize mBottomBorderWidth;
BCPixelSize mRightContBorderWidth;
BCPixelSize mTopContBorderWidth;
BCPixelSize mLeftContBorderWidth;
BCPixelSize mBStartBorderWidth;
BCPixelSize mBEndBorderWidth;
BCPixelSize mIEndContBorderWidth;
BCPixelSize mBStartContBorderWidth;
BCPixelSize mIStartContBorderWidth;
/**
* Sets the NS_ROW_HAS_CELL_WITH_STYLE_HEIGHT bit to indicate whether
@ -401,52 +401,33 @@ inline void nsTableRowFrame::SetHasUnpaginatedHeight(bool aValue)
}
}
inline nscoord nsTableRowFrame::GetTopBCBorderWidth()
inline mozilla::LogicalMargin
nsTableRowFrame::GetBCBorderWidth(mozilla::WritingMode aWM)
{
return mTopBorderWidth;
}
inline void nsTableRowFrame::SetTopBCBorderWidth(BCPixelSize aWidth)
{
mTopBorderWidth = aWidth;
}
inline nscoord nsTableRowFrame::GetBottomBCBorderWidth()
{
return mBottomBorderWidth;
}
inline void nsTableRowFrame::SetBottomBCBorderWidth(BCPixelSize aWidth)
{
mBottomBorderWidth = aWidth;
}
inline nsMargin* nsTableRowFrame::GetBCBorderWidth(nsMargin& aBorder)
{
aBorder.left = aBorder.right = 0;
aBorder.top = nsPresContext::CSSPixelsToAppUnits(mTopBorderWidth);
aBorder.bottom = nsPresContext::CSSPixelsToAppUnits(mBottomBorderWidth);
return &aBorder;
return mozilla::LogicalMargin(
aWM, nsPresContext::CSSPixelsToAppUnits(mBStartBorderWidth), 0,
nsPresContext::CSSPixelsToAppUnits(mBEndBorderWidth), 0);
}
inline void
nsTableRowFrame::GetContinuousBCBorderWidth(nsMargin& aBorder)
{
int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
aBorder.right = BC_BORDER_LEFT_HALF_COORD(aPixelsToTwips,
mLeftContBorderWidth);
aBorder.top = BC_BORDER_BOTTOM_HALF_COORD(aPixelsToTwips,
mTopContBorderWidth);
aBorder.left = BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips,
mRightContBorderWidth);
mozilla::WritingMode wm = GetWritingMode();
mozilla::LogicalMargin border(wm, aBorder);
border.IEnd(wm) = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
mIStartContBorderWidth);
border.BStart(wm) = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
mBStartContBorderWidth);
border.IStart(wm) = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
mIEndContBorderWidth);
aBorder = border.GetPhysicalMargin(wm);
}
inline nscoord nsTableRowFrame::GetOuterTopContBCBorderWidth()
inline nscoord nsTableRowFrame::GetOuterBStartContBCBorderWidth()
{
int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
return BC_BORDER_TOP_HALF_COORD(aPixelsToTwips, mTopContBorderWidth);
return BC_BORDER_START_HALF_COORD(aPixelsToTwips, mBStartContBorderWidth);
}
#endif

View File

@ -296,7 +296,10 @@ nsTableRowGroupFrame::InitChildReflowState(nsPresContext& aPresContext,
if (aBorderCollapse) {
nsTableRowFrame *rowFrame = do_QueryFrame(aReflowState.frame);
if (rowFrame) {
pCollapseBorder = rowFrame->GetBCBorderWidth(collapseBorder);
WritingMode wm = GetWritingMode();
LogicalMargin border = rowFrame->GetBCBorderWidth(wm);
collapseBorder = border.GetPhysicalMargin(wm);
pCollapseBorder = &collapseBorder;
}
}
aReflowState.Init(&aPresContext, -1, -1, pCollapseBorder, &padding);
@ -1600,11 +1603,10 @@ nsTableRowGroupFrame::GetFrameName(nsAString& aResult) const
}
#endif
nsMargin*
nsTableRowGroupFrame::GetBCBorderWidth(nsMargin& aBorder)
LogicalMargin
nsTableRowGroupFrame::GetBCBorderWidth(WritingMode aWM)
{
aBorder.left = aBorder.right = aBorder.top = aBorder.bottom = 0;
LogicalMargin border(aWM);
nsTableRowFrame* firstRowFrame = nullptr;
nsTableRowFrame* lastRowFrame = nullptr;
for (nsTableRowFrame* rowFrame = GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) {
@ -1614,11 +1616,12 @@ nsTableRowGroupFrame::GetBCBorderWidth(nsMargin& aBorder)
lastRowFrame = rowFrame;
}
if (firstRowFrame) {
aBorder.top = nsPresContext::CSSPixelsToAppUnits(firstRowFrame->GetTopBCBorderWidth());
aBorder.bottom = nsPresContext::CSSPixelsToAppUnits(lastRowFrame->GetBottomBCBorderWidth());
border.BStart(aWM) = nsPresContext::
CSSPixelsToAppUnits(firstRowFrame->GetBStartBCBorderWidth());
border.BEnd(aWM) = nsPresContext::
CSSPixelsToAppUnits(lastRowFrame->GetBEndBCBorderWidth());
}
return &aBorder;
return border;
}
void nsTableRowGroupFrame::SetContinuousBCBorderWidth(uint8_t aForSide,

View File

@ -13,6 +13,7 @@
#include "nsTablePainter.h"
#include "nsTArray.h"
#include "nsTableFrame.h"
#include "mozilla/WritingModes.h"
class nsTableRowFrame;
@ -161,7 +162,7 @@ public:
*/
nscoord GetHeightBasis(const nsHTMLReflowState& aReflowState);
nsMargin* GetBCBorderWidth(nsMargin& aBorder);
mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM);
/**
* Gets inner border widths before collapsing with cell borders
@ -450,12 +451,12 @@ inline void
nsTableRowGroupFrame::GetContinuousBCBorderWidth(nsMargin& aBorder)
{
int32_t aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
aBorder.right = BC_BORDER_LEFT_HALF_COORD(aPixelsToTwips,
mRightContBorderWidth);
aBorder.bottom = BC_BORDER_TOP_HALF_COORD(aPixelsToTwips,
mBottomContBorderWidth);
aBorder.left = BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips,
mLeftContBorderWidth);
aBorder.right = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
mRightContBorderWidth);
aBorder.bottom = BC_BORDER_START_HALF_COORD(aPixelsToTwips,
mBottomContBorderWidth);
aBorder.left = BC_BORDER_END_HALF_COORD(aPixelsToTwips,
mLeftContBorderWidth);
return;
}
#endif

View File

@ -462,7 +462,7 @@ nsMenuFrame::HandleEvent(nsPresContext* aPresContext,
*aEventStatus = nsEventStatus_eConsumeNoDefault;
Execute(aEvent);
}
else if (aEvent->message == NS_MOUSE_EXIT_SYNTH) {
else if (aEvent->message == NS_MOUSE_OUT) {
// Kill our timer if one is active.
if (mOpenTimer) {
mOpenTimer->Cancel();

View File

@ -88,16 +88,16 @@ nsAutoRepeatBoxFrame::HandleEvent(nsPresContext* aPresContext,
// repeat mode may be "hover" for repeating while the mouse is hovering
// over the element, otherwise repetition is done while the element is
// active (pressed).
case NS_MOUSE_ENTER:
case NS_MOUSE_ENTER_SYNTH:
case NS_MOUSE_ENTER_WIDGET:
case NS_MOUSE_OVER:
if (IsActivatedOnHover()) {
StartRepeat();
mTrustedEvent = aEvent->mFlags.mIsTrusted;
}
break;
case NS_MOUSE_EXIT:
case NS_MOUSE_EXIT_SYNTH:
case NS_MOUSE_EXIT_WIDGET:
case NS_MOUSE_OUT:
// always stop on mouse exit
StopRepeat();
// Not really necessary but do this to be safe

View File

@ -63,7 +63,7 @@ nsScrollbarButtonFrame::HandleEvent(nsPresContext* aPresContext,
case NS_MOUSE_BUTTON_UP:
HandleRelease(aPresContext, aEvent, aEventStatus);
break;
case NS_MOUSE_EXIT_SYNTH:
case NS_MOUSE_OUT:
mCursorOnThis = false;
break;
case NS_MOUSE_MOVE: {

View File

@ -607,10 +607,10 @@ nsSliderFrame::HandleEvent(nsPresContext* aPresContext,
#endif
// XXX hack until handle release is actually called in nsframe.
// if (aEvent->message == NS_MOUSE_EXIT_SYNTH || aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP || aEvent->message == NS_MOUSE_LEFT_BUTTON_UP)
// if (aEvent->message == NS_MOUSE_OUT || aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP || aEvent->message == NS_MOUSE_LEFT_BUTTON_UP)
// HandleRelease(aPresContext, aEvent, aEventStatus);
if (aEvent->message == NS_MOUSE_EXIT_SYNTH && mChange)
if (aEvent->message == NS_MOUSE_OUT && mChange)
HandleRelease(aPresContext, aEvent, aEventStatus);
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);

View File

@ -2564,7 +2564,7 @@ nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext,
WidgetGUIEvent* aEvent,
nsEventStatus* aEventStatus)
{
if (aEvent->message == NS_MOUSE_ENTER_SYNTH || aEvent->message == NS_MOUSE_MOVE) {
if (aEvent->message == NS_MOUSE_OVER || aEvent->message == NS_MOUSE_MOVE) {
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
int32_t xTwips = pt.x - mInnerBox.x;
int32_t yTwips = pt.y - mInnerBox.y;
@ -2578,7 +2578,7 @@ nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext,
InvalidateRow(mMouseOverRow);
}
}
else if (aEvent->message == NS_MOUSE_EXIT_SYNTH) {
else if (aEvent->message == NS_MOUSE_OUT) {
if (mMouseOverRow != -1) {
InvalidateRow(mMouseOverRow);
mMouseOverRow = -1;

View File

@ -2,8 +2,8 @@
# 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/.
SSL_ERROR_EXPORT_ONLY_SERVER=Unable to communicate securely. Peer does not support high-grade encryption.
SSL_ERROR_US_ONLY_SERVER=Unable to communicate securely. Peer requires high-grade encryption which is not supported.
SSL_ERROR_EXPORT_ONLY_SERVER=Unable to communicate securely. Peer does not support high-grade encryption.
SSL_ERROR_US_ONLY_SERVER=Unable to communicate securely. Peer requires high-grade encryption which is not supported.
SSL_ERROR_NO_CYPHER_OVERLAP=Cannot communicate securely with peer: no common encryption algorithm(s).
SSL_ERROR_NO_CERTIFICATE=Unable to find the certificate or key necessary for authentication.
SSL_ERROR_BAD_CERTIFICATE=Unable to communicate securely with peer: peers's certificate was rejected.
@ -150,7 +150,7 @@ SEC_ERROR_REVOKED_CERTIFICATE=Peer's Certificate has been revoked.
SEC_ERROR_UNKNOWN_ISSUER=Peer's Certificate issuer is not recognized.
SEC_ERROR_BAD_KEY=Peer's public key is invalid.
SEC_ERROR_BAD_PASSWORD=The security password entered is incorrect.
SEC_ERROR_RETRY_PASSWORD=New password entered incorrectly. Please try again.
SEC_ERROR_RETRY_PASSWORD=New password entered incorrectly. Please try again.
SEC_ERROR_NO_NODELOCK=security library: no nodelock.
SEC_ERROR_BAD_DATABASE=security library: bad database.
SEC_ERROR_NO_MEMORY=security library: memory allocation failure.
@ -164,8 +164,8 @@ SEC_ERROR_NO_KEY=The private key for this certificate cannot be found in key dat
SEC_ERROR_CERT_VALID=This certificate is valid.
SEC_ERROR_CERT_NOT_VALID=This certificate is not valid.
SEC_ERROR_CERT_NO_RESPONSE=Cert Library: No Response
SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE=The certificate issuer's certificate has expired. Check your system date and time.
SEC_ERROR_CRL_EXPIRED=The CRL for the certificate's issuer has expired. Update it or check your system date and time.
SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE=The certificate issuer's certificate has expired. Check your system date and time.
SEC_ERROR_CRL_EXPIRED=The CRL for the certificate's issuer has expired. Update it or check your system date and time.
SEC_ERROR_CRL_BAD_SIGNATURE=The CRL for the certificate's issuer has an invalid signature.
SEC_ERROR_CRL_INVALID=New CRL has an invalid format.
SEC_ERROR_EXTENSION_VALUE_INVALID=Certificate extension value is invalid.
@ -184,7 +184,7 @@ SEC_ERROR_PKCS7_KEYALG_MISMATCH=Cannot decrypt: key encryption algorithm does no
SEC_ERROR_PKCS7_BAD_SIGNATURE=Signature verification failed: no signer found, too many signers found, or improper or corrupted data.
SEC_ERROR_UNSUPPORTED_KEYALG=Unsupported or unknown key algorithm.
SEC_ERROR_DECRYPTION_DISALLOWED=Cannot decrypt: encrypted using a disallowed algorithm or key size.
XP_SEC_FORTEZZA_BAD_CARD=Fortezza card has not been properly initialized. Please remove it and return it to your issuer.
XP_SEC_FORTEZZA_BAD_CARD=Fortezza card has not been properly initialized. Please remove it and return it to your issuer.
XP_SEC_FORTEZZA_NO_CARD=No Fortezza cards Found
XP_SEC_FORTEZZA_NONE_SELECTED=No Fortezza card selected
XP_SEC_FORTEZZA_MORE_INFO=Please select a personality to get more info on
@ -212,31 +212,31 @@ XP_JAVA_CERT_NOT_EXISTS_ERROR=This principal doesn't have a certificate
SEC_ERROR_BAD_EXPORT_ALGORITHM=Required algorithm is not allowed.
SEC_ERROR_EXPORTING_CERTIFICATES=Error attempting to export certificates.
SEC_ERROR_IMPORTING_CERTIFICATES=Error attempting to import certificates.
SEC_ERROR_PKCS12_DECODING_PFX=Unable to import. Decoding error. File not valid.
SEC_ERROR_PKCS12_INVALID_MAC=Unable to import. Invalid MAC. Incorrect password or corrupt file.
SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM=Unable to import. MAC algorithm not supported.
SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE=Unable to import. Only password integrity and privacy modes supported.
SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE=Unable to import. File structure is corrupt.
SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM=Unable to import. Encryption algorithm not supported.
SEC_ERROR_PKCS12_UNSUPPORTED_VERSION=Unable to import. File version not supported.
SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT=Unable to import. Incorrect privacy password.
SEC_ERROR_PKCS12_CERT_COLLISION=Unable to import. Same nickname already exists in database.
SEC_ERROR_PKCS12_DECODING_PFX=Unable to import. Decoding error. File not valid.
SEC_ERROR_PKCS12_INVALID_MAC=Unable to import. Invalid MAC. Incorrect password or corrupt file.
SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM=Unable to import. MAC algorithm not supported.
SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE=Unable to import. Only password integrity and privacy modes supported.
SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE=Unable to import. File structure is corrupt.
SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM=Unable to import. Encryption algorithm not supported.
SEC_ERROR_PKCS12_UNSUPPORTED_VERSION=Unable to import. File version not supported.
SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT=Unable to import. Incorrect privacy password.
SEC_ERROR_PKCS12_CERT_COLLISION=Unable to import. Same nickname already exists in database.
SEC_ERROR_USER_CANCELLED=The user pressed cancel.
SEC_ERROR_PKCS12_DUPLICATE_DATA=Not imported, already in database.
SEC_ERROR_MESSAGE_SEND_ABORTED=Message not sent.
SEC_ERROR_INADEQUATE_KEY_USAGE=Certificate key usage inadequate for attempted operation.
SEC_ERROR_INADEQUATE_CERT_TYPE=Certificate type not approved for application.
SEC_ERROR_CERT_ADDR_MISMATCH=Address in signing certificate does not match address in message headers.
SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY=Unable to import. Error attempting to import private key.
SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN=Unable to import. Error attempting to import certificate chain.
SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME=Unable to export. Unable to locate certificate or key by nickname.
SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY=Unable to export. Private Key could not be located and exported.
SEC_ERROR_PKCS12_UNABLE_TO_WRITE=Unable to export. Unable to write the export file.
SEC_ERROR_PKCS12_UNABLE_TO_READ=Unable to import. Unable to read the import file.
SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED=Unable to export. Key database corrupt or deleted.
SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY=Unable to import. Error attempting to import private key.
SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN=Unable to import. Error attempting to import certificate chain.
SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME=Unable to export. Unable to locate certificate or key by nickname.
SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY=Unable to export. Private Key could not be located and exported.
SEC_ERROR_PKCS12_UNABLE_TO_WRITE=Unable to export. Unable to write the export file.
SEC_ERROR_PKCS12_UNABLE_TO_READ=Unable to import. Unable to read the import file.
SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED=Unable to export. Key database corrupt or deleted.
SEC_ERROR_KEYGEN_FAIL=Unable to generate public/private key pair.
SEC_ERROR_INVALID_PASSWORD=Password entered is invalid. Please pick a different one.
SEC_ERROR_RETRY_OLD_PASSWORD=Old password entered incorrectly. Please try again.
SEC_ERROR_INVALID_PASSWORD=Password entered is invalid. Please pick a different one.
SEC_ERROR_RETRY_OLD_PASSWORD=Old password entered incorrectly. Please try again.
SEC_ERROR_BAD_NICKNAME=Certificate nickname already in use.
SEC_ERROR_NOT_FORTEZZA_ISSUER=Peer FORTEZZA chain has a non-FORTEZZA Certificate.
SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY=A sensitive key cannot be moved to the slot where it is needed.
@ -245,7 +245,7 @@ SEC_ERROR_JS_INVALID_DLL=Invalid module path/filename
SEC_ERROR_JS_ADD_MOD_FAILURE=Unable to add module
SEC_ERROR_JS_DEL_MOD_FAILURE=Unable to delete module
SEC_ERROR_OLD_KRL=New KRL is not later than the current one.
SEC_ERROR_CKL_CONFLICT=New CKL has different issuer than current CKL. Delete current CKL.
SEC_ERROR_CKL_CONFLICT=New CKL has different issuer than current CKL. Delete current CKL.
SEC_ERROR_CERT_NOT_IN_NAME_SPACE=The Certifying Authority for this certificate is not permitted to issue a certificate with this name.
SEC_ERROR_KRL_NOT_YET_VALID=The key revocation list for this certificate is not yet valid.
SEC_ERROR_CRL_NOT_YET_VALID=The certificate revocation list for this certificate is not yet valid.
@ -302,7 +302,7 @@ SEC_ERROR_FAILED_TO_ENCODE_DATA=Failed to encode data with ASN1 encoder
SEC_ERROR_BAD_INFO_ACCESS_LOCATION=Bad information access location in cert extension
SEC_ERROR_LIBPKIX_INTERNAL=Libpkix internal error occurred during cert validation.
SEC_ERROR_PKCS11_GENERAL_ERROR=A PKCS #11 module returned CKR_GENERAL_ERROR, indicating that an unrecoverable error has occurred.
SEC_ERROR_PKCS11_FUNCTION_FAILED=A PKCS #11 module returned CKR_FUNCTION_FAILED, indicating that the requested function could not be performed. Trying the same operation again might succeed.
SEC_ERROR_PKCS11_FUNCTION_FAILED=A PKCS #11 module returned CKR_FUNCTION_FAILED, indicating that the requested function could not be performed. Trying the same operation again might succeed.
SEC_ERROR_PKCS11_DEVICE_ERROR=A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot.
SEC_ERROR_BAD_INFO_ACCESS_METHOD=Unknown information access method in certificate extension.
SEC_ERROR_CRL_IMPORT_FAILED=Error attempting to import a CRL.

View File

@ -1141,27 +1141,24 @@ GeckoDriver.prototype.executeWithCallback = function(cmd, resp, directInject) {
};
/**
* Navigate to to given URL.
* Navigate to given URL.
*
* This will follow redirects issued by the server. When the method
* returns is based on the page load strategy that the user has
* selected.
* Navigates the current browsing context to the given URL and waits for
* the document to load or the session's page timeout duration to elapse
* before returning.
*
* Documents that contain a META tag with the "http-equiv" attribute
* set to "refresh" will return if the timeout is greater than 1
* second and the other criteria for determining whether a page is
* loaded are met. When the refresh period is 1 second or less and
* the page load strategy is "normal" or "conservative", it will
* wait for the page to complete loading before returning.
* The command will return with a failure if there is an error loading
* the document or the URL is blocked. This can occur if it fails to
* reach host, the URL is malformed, or if there is a certificate issue
* to name some examples.
*
* If any modal dialog box, such as those opened on
* window.onbeforeunload or window.alert, is opened at any point in
* the page load, it will return immediately.
* The document is considered successfully loaded when the
* DOMContentLoaded event on the frame element associated with the
* current window triggers and document.readyState is "complete".
*
* If a 401 response is seen by the browser, it will return
* immediately. That is, if BASIC, DIGEST, NTLM or similar
* authentication is required, the page load is assumed to be
* complete. This does not include FORM-based authentication.
* In chrome context it will change the current window's location to
* the supplied URL and wait until document.readyState equals "complete"
* or the page timeout duration has elapsed.
*
* @param {string} url
* URL to navigate to.

View File

@ -1182,35 +1182,29 @@ class Marionette(object):
return response
def navigate(self, url):
"""Navigate to to given URL.
"""Navigate to given `url`.
This will follow redirects issued by the server. When the
method returns is based on the page load strategy that the
user has selected.
Navigates the current top-level browsing context's content
frame to the given URL and waits for the document to load or
the session's page timeout duration to elapse before returning.
Documents that contain a META tag with the "http-equiv"
attribute set to "refresh" will return if the timeout is
greater than 1 second and the other criteria for determining
whether a page is loaded are met. When the refresh period is
1 second or less and the page load strategy is "normal" or
"conservative", it will wait for the page to complete loading
before returning.
The command will return with a failure if there is an error
loading the document or the URL is blocked. This can occur if
it fails to reach the host, the URL is malformed, the page is
restricted (about:* pages), or if there is a certificate issue
to name some examples.
If any modal dialog box, such as those opened on
window.onbeforeunload or window.alert, is opened at any point
in the page load, it will return immediately.
The document is considered successfully loaded when the
`DOMContentLoaded` event on the frame element associated with the
`window` triggers and `document.readState` is "complete".
If a 401 response is seen by the browser, it will return
immediately. That is, if BASIC, DIGEST, NTLM or similar
authentication is required, the page load is assumed to be
complete. This does not include FORM-based authentication.
:param url: The url to navigate to.
In chrome context it will change the current `window`'s location
to the supplied URL and wait until `document.readState` equals
"complete" or the page timeout duration has elapsed.
:param url: The URL to navigate to.
"""
response = self._send_message("get", "ok", url=url)
return response
return self._send_message("get", "ok", url=url)
def timeouts(self, timeout_type, ms):
"""An interface for managing timeout behaviour of a Marionette instance.

View File

@ -1209,9 +1209,9 @@ function pollForReadyState(msg, start, callback) {
/**
* Navigate to the given URL. The operation will be performed on the
* current browser context, and handles the case where we navigate
* within an iframe. All other navigation is handled by the server
* (in chrome space).
* current browsing context, which means it handles the case where we
* navigate within an iframe. All other navigation is handled by the
* driver (in chrome space).
*/
function get(msg) {
let start = new Date().getTime();

View File

@ -357,7 +357,7 @@
"expires_in_version": "never",
"kind": "enumerated",
"n_values": 10,
"description": "Use of SpiderMonkey's deprecated language extensions in web content: ForEach=0, DestructuringForIn=1, LegacyGenerator=2, ExpressionClosure=3, LetBlock=4, LetExpression=5, NoSuchMethod=6, FlagsArgument=7"
"description": "Use of SpiderMonkey's deprecated language extensions in web content: ForEach=0, DestructuringForIn=1, LegacyGenerator=2, ExpressionClosure=3, LetBlock=4, LetExpression=5, NoSuchMethod=6, FlagsArgument=7, RegExpSourceProp=8"
},
"TELEMETRY_PING": {
"expires_in_version": "never",

View File

@ -733,8 +733,8 @@ nsViewManager::DispatchEvent(WidgetGUIEvent *aEvent,
// Ignore mouse exit and enter (we'll get moves if the user
// is really moving the mouse) since we get them when we
// create and destroy widgets.
mouseEvent->message != NS_MOUSE_EXIT &&
mouseEvent->message != NS_MOUSE_ENTER) ||
mouseEvent->message != NS_MOUSE_EXIT_WIDGET &&
mouseEvent->message != NS_MOUSE_ENTER_WIDGET) ||
aEvent->HasKeyEventMessage() ||
aEvent->HasIMEEventMessage() ||
aEvent->message == NS_PLUGIN_INPUT_EVENT) {

View File

@ -71,13 +71,13 @@
#define NS_MOUSE_MOVE (NS_MOUSE_MESSAGE_START)
#define NS_MOUSE_BUTTON_UP (NS_MOUSE_MESSAGE_START + 1)
#define NS_MOUSE_BUTTON_DOWN (NS_MOUSE_MESSAGE_START + 2)
#define NS_MOUSE_ENTER (NS_MOUSE_MESSAGE_START + 22)
#define NS_MOUSE_EXIT (NS_MOUSE_MESSAGE_START + 23)
#define NS_MOUSE_ENTER_WIDGET (NS_MOUSE_MESSAGE_START + 22)
#define NS_MOUSE_EXIT_WIDGET (NS_MOUSE_MESSAGE_START + 23)
#define NS_MOUSE_DOUBLECLICK (NS_MOUSE_MESSAGE_START + 24)
#define NS_MOUSE_CLICK (NS_MOUSE_MESSAGE_START + 27)
#define NS_MOUSE_ACTIVATE (NS_MOUSE_MESSAGE_START + 30)
#define NS_MOUSE_ENTER_SYNTH (NS_MOUSE_MESSAGE_START + 31)
#define NS_MOUSE_EXIT_SYNTH (NS_MOUSE_MESSAGE_START + 32)
#define NS_MOUSE_OVER (NS_MOUSE_MESSAGE_START + 31)
#define NS_MOUSE_OUT (NS_MOUSE_MESSAGE_START + 32)
#define NS_MOUSE_MOZHITTEST (NS_MOUSE_MESSAGE_START + 33)
#define NS_MOUSEENTER (NS_MOUSE_MESSAGE_START + 34)
#define NS_MOUSELEAVE (NS_MOUSE_MESSAGE_START + 35)
@ -132,9 +132,7 @@
#define NS_DRAGDROP_END (NS_DRAGDROP_EVENT_START + 6)
#define NS_DRAGDROP_START (NS_DRAGDROP_EVENT_START + 7)
#define NS_DRAGDROP_DROP (NS_DRAGDROP_EVENT_START + 8)
#define NS_DRAGDROP_OVER_SYNTH (NS_DRAGDROP_EVENT_START + 1)
#define NS_DRAGDROP_EXIT_SYNTH (NS_DRAGDROP_EVENT_START + 2)
#define NS_DRAGDROP_LEAVE_SYNTH (NS_DRAGDROP_EVENT_START + 9)
#define NS_DRAGDROP_LEAVE (NS_DRAGDROP_EVENT_START + 9)
// Events for popups
#define NS_XUL_EVENT_START 1500

View File

@ -195,7 +195,7 @@ MultiTouchInput::MultiTouchInput(const WidgetMouseEvent& aMouseEvent)
// manner, such as a synchronous event or action cancelling the touch, or a
// touch point leaving the document window and going into a non-document
// area capable of handling user interactions.
case NS_MOUSE_EXIT:
case NS_MOUSE_EXIT_WIDGET:
mType = MULTITOUCH_CANCEL;
break;
default:

View File

@ -322,8 +322,8 @@ public:
, mDefaultPreventedOnContent(false)
{
mFlags.mCancelable =
(aMessage != NS_DRAGDROP_EXIT_SYNTH &&
aMessage != NS_DRAGDROP_LEAVE_SYNTH &&
(aMessage != NS_DRAGDROP_EXIT &&
aMessage != NS_DRAGDROP_LEAVE &&
aMessage != NS_DRAGDROP_END);
}

View File

@ -82,11 +82,11 @@ WidgetEvent::HasMouseEventMessage() const
case NS_MOUSE_BUTTON_UP:
case NS_MOUSE_CLICK:
case NS_MOUSE_DOUBLECLICK:
case NS_MOUSE_ENTER:
case NS_MOUSE_EXIT:
case NS_MOUSE_ENTER_WIDGET:
case NS_MOUSE_EXIT_WIDGET:
case NS_MOUSE_ACTIVATE:
case NS_MOUSE_ENTER_SYNTH:
case NS_MOUSE_EXIT_SYNTH:
case NS_MOUSE_OVER:
case NS_MOUSE_OUT:
case NS_MOUSE_MOZHITTEST:
case NS_MOUSE_MOVE:
return true;
@ -108,7 +108,7 @@ WidgetEvent::HasDragEventMessage() const
case NS_DRAGDROP_END:
case NS_DRAGDROP_START:
case NS_DRAGDROP_DROP:
case NS_DRAGDROP_LEAVE_SYNTH:
case NS_DRAGDROP_LEAVE:
return true;
default:
return false;

View File

@ -834,10 +834,10 @@ AndroidGeckoEvent::MakeMouseEvent(nsIWidget* widget)
msg = NS_MOUSE_MOVE;
break;
case AndroidMotionEvent::ACTION_HOVER_ENTER:
msg = NS_MOUSE_ENTER;
msg = NS_MOUSE_ENTER_WIDGET;
break;
case AndroidMotionEvent::ACTION_HOVER_EXIT:
msg = NS_MOUSE_EXIT;
msg = NS_MOUSE_EXIT_WIDGET;
break;
default:
break;

View File

@ -382,8 +382,8 @@ nsWindow::Show(bool aState)
// XXX should we bring this to the front when it's shown,
// if it's a toplevel widget?
// XXX we should synthesize a NS_MOUSE_EXIT (for old top
// window)/NS_MOUSE_ENTER (for new top window) since we need
// XXX we should synthesize a NS_MOUSE_EXIT_WIDGET (for old top
// window)/NS_MOUSE_ENTER_WIDGET (for new top window) since we need
// to pretend that the top window always has focus. Not sure
// if Show() is the right place to do this, though.

View File

@ -4549,7 +4549,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
NSPoint windowEventLocation = nsCocoaUtils::EventLocationForWindow(aEvent, [self window]);
NSPoint localEventLocation = [self convertPoint:windowEventLocation fromView:nil];
uint32_t msg = aEnter ? NS_MOUSE_ENTER : NS_MOUSE_EXIT;
uint32_t msg = aEnter ? NS_MOUSE_ENTER_WIDGET : NS_MOUSE_EXIT_WIDGET;
WidgetMouseEvent event(true, msg, mGeckoChild, WidgetMouseEvent::eReal);
event.refPoint = LayoutDeviceIntPoint::FromUntyped(
mGeckoChild->CocoaPointsToDevPixels(localEventLocation));

View File

@ -65,6 +65,7 @@ static GtkWidget* gScrolledWindowWidget;
static style_prop_t style_prop_func;
static gboolean have_arrow_scaling;
static gboolean checkbox_check_state;
static gboolean notebook_has_tab_gap;
static gboolean is_initialized;
#define ARROW_UP 0
@ -725,6 +726,14 @@ moz_gtk_init()
else
checkbox_check_state = GTK_STATE_FLAG_ACTIVE;
if(!gtk_check_version(3, 12, 0)) {
ensure_tab_widget();
gtk_widget_style_get(gTabWidget, "has-tab-gap", &notebook_has_tab_gap, NULL);
}
else {
notebook_has_tab_gap = TRUE;
}
/* Add style property to GtkEntry.
* Adding the style property to the normal GtkEntry class means that it
* will work without issues inside GtkComboBox and for Spinbuttons. */
@ -2012,6 +2021,9 @@ moz_gtk_get_tab_thickness(void)
GtkStyleContext * style;
ensure_tab_widget();
if (!notebook_has_tab_gap)
return 0; /* tabs do not overdraw the tabpanel border with "no gap" style */
style = gtk_widget_get_style_context(gTabWidget);
gtk_style_context_add_class(style, GTK_STYLE_CLASS_NOTEBOOK);
gtk_style_context_get_border(style, 0, &border);
@ -2057,7 +2069,7 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectangle* rect,
ensure_tab_widget();
gtk_widget_set_direction(gTabWidget, direction);
style = gtk_widget_get_style_context(gTabWidget);
style = gtk_widget_get_style_context(gTabWidget);
gtk_style_context_save(style);
moz_gtk_tab_prepare_style_context(style, flags);
@ -2074,144 +2086,156 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectangle* rect,
focusRect = backRect = tabRect;
if ((flags & MOZ_GTK_TAB_SELECTED) == 0) {
/* Only draw the tab */
gtk_render_extension(style, cr,
tabRect.x, tabRect.y, tabRect.width, tabRect.height,
(flags & MOZ_GTK_TAB_BOTTOM) ?
GTK_POS_TOP : GTK_POS_BOTTOM );
} else {
/* Draw the tab and the gap
* We want the gap to be positioned exactly on the tabpanel top
* border; since tabbox.css may set a negative margin so that the tab
* frame rect already overlaps the tabpanel frame rect, we need to take
* that into account when drawing. To that effect, nsNativeThemeGTK
* passes us this negative margin (bmargin in the graphic below) in the
* lowest bits of |flags|. We use it to set gap_voffset, the distance
* between the top of the gap and the bottom of the tab (resp. the
* bottom of the gap and the top of the tab when we draw a bottom tab),
* while ensuring that the gap always touches the border of the tab,
* i.e. 0 <= gap_voffset <= gap_height, to avoid surprinsing results
* with big negative or positive margins.
* Here is a graphical explanation in the case of top tabs:
* ___________________________
* / \
* | T A B |
* ----------|. . . . . . . . . . . . . . .|----- top of tabpanel
* : ^ bmargin : ^
* : | (-negative margin, : |
* bottom : v passed in flags) : | gap_height
* of -> :.............................: | (the size of the
* the tab . part of the gap . | tabpanel top border)
* . outside of the tab . v
* ----------------------------------------------
*
* To draw the gap, we use gtk_paint_box_gap(), see comment in
* moz_gtk_tabpanels_paint(). This box_gap is made 3 * gap_height tall,
* which should suffice to ensure that the only visible border is the
* pierced one. If the tab is in the middle, we make the box_gap begin
* a bit to the left of the tab and end a bit to the right, adjusting
* the gap position so it still is under the tab, because we want the
* rendering of a gap in the middle of a tabpanel. This is the role of
* the gints gap_{l,r}_offset. On the contrary, if the tab is the
* first, we align the start border of the box_gap with the start
* border of the tab (left if LTR, right if RTL), by setting the
* appropriate offset to 0.*/
gint gap_loffset, gap_roffset, gap_voffset, gap_height;
/* Get height needed by the gap */
gap_height = moz_gtk_get_tab_thickness();
/* Extract gap_voffset from the first bits of flags */
gap_voffset = flags & MOZ_GTK_TAB_MARGIN_MASK;
if (gap_voffset > gap_height)
gap_voffset = gap_height;
/* Set gap_{l,r}_offset to appropriate values */
gap_loffset = gap_roffset = 20; /* should be enough */
if (flags & MOZ_GTK_TAB_FIRST) {
if (direction == GTK_TEXT_DIR_RTL)
gap_roffset = initial_gap;
else
gap_loffset = initial_gap;
}
if (flags & MOZ_GTK_TAB_BOTTOM) {
/* Draw the tab on bottom */
focusRect.y += gap_voffset;
focusRect.height -= gap_voffset;
if (notebook_has_tab_gap) {
if ((flags & MOZ_GTK_TAB_SELECTED) == 0) {
/* Only draw the tab */
gtk_render_extension(style, cr,
tabRect.x, tabRect.y + gap_voffset, tabRect.width,
tabRect.height - gap_voffset, GTK_POS_TOP);
gtk_style_context_remove_region(style, GTK_STYLE_REGION_TAB);
backRect.y += (gap_voffset - gap_height);
backRect.height = gap_height;
/* Draw the gap; erase with background color before painting in
* case theme does not */
gtk_render_background(style, cr, backRect.x, backRect.y,
backRect.width, backRect.height);
cairo_save(cr);
cairo_rectangle(cr, backRect.x, backRect.y, backRect.width, backRect.height);
cairo_clip(cr);
gtk_render_frame_gap(style, cr,
tabRect.x - gap_loffset,
tabRect.y + gap_voffset - 3 * gap_height,
tabRect.width + gap_loffset + gap_roffset,
3 * gap_height, GTK_POS_BOTTOM,
gap_loffset, gap_loffset + tabRect.width);
cairo_restore(cr);
tabRect.x, tabRect.y, tabRect.width, tabRect.height,
(flags & MOZ_GTK_TAB_BOTTOM) ?
GTK_POS_TOP : GTK_POS_BOTTOM );
} else {
/* Draw the tab on top */
focusRect.height -= gap_voffset;
gtk_render_extension(style, cr,
tabRect.x, tabRect.y, tabRect.width,
tabRect.height - gap_voffset, GTK_POS_BOTTOM);
/* Draw the tab and the gap
* We want the gap to be positioned exactly on the tabpanel top
* border; since tabbox.css may set a negative margin so that the tab
* frame rect already overlaps the tabpanel frame rect, we need to take
* that into account when drawing. To that effect, nsNativeThemeGTK
* passes us this negative margin (bmargin in the graphic below) in the
* lowest bits of |flags|. We use it to set gap_voffset, the distance
* between the top of the gap and the bottom of the tab (resp. the
* bottom of the gap and the top of the tab when we draw a bottom tab),
* while ensuring that the gap always touches the border of the tab,
* i.e. 0 <= gap_voffset <= gap_height, to avoid surprinsing results
* with big negative or positive margins.
* Here is a graphical explanation in the case of top tabs:
* ___________________________
* / \
* | T A B |
* ----------|. . . . . . . . . . . . . . .|----- top of tabpanel
* : ^ bmargin : ^
* : | (-negative margin, : |
* bottom : v passed in flags) : | gap_height
* of -> :.............................: | (the size of the
* the tab . part of the gap . | tabpanel top border)
* . outside of the tab . v
* ----------------------------------------------
*
* To draw the gap, we use gtk_paint_box_gap(), see comment in
* moz_gtk_tabpanels_paint(). This box_gap is made 3 * gap_height tall,
* which should suffice to ensure that the only visible border is the
* pierced one. If the tab is in the middle, we make the box_gap begin
* a bit to the left of the tab and end a bit to the right, adjusting
* the gap position so it still is under the tab, because we want the
* rendering of a gap in the middle of a tabpanel. This is the role of
* the gints gap_{l,r}_offset. On the contrary, if the tab is the
* first, we align the start border of the box_gap with the start
* border of the tab (left if LTR, right if RTL), by setting the
* appropriate offset to 0.*/
gint gap_loffset, gap_roffset, gap_voffset, gap_height;
gtk_style_context_remove_region(style, GTK_STYLE_REGION_TAB);
/* Get height needed by the gap */
gap_height = moz_gtk_get_tab_thickness();
backRect.y += (tabRect.height - gap_voffset);
backRect.height = gap_height;
/* Extract gap_voffset from the first bits of flags */
gap_voffset = flags & MOZ_GTK_TAB_MARGIN_MASK;
if (gap_voffset > gap_height)
gap_voffset = gap_height;
/* Draw the gap; erase with background color before painting in
* case theme does not */
gtk_render_background(style, cr, backRect.x, backRect.y,
backRect.width, backRect.height);
/* Set gap_{l,r}_offset to appropriate values */
gap_loffset = gap_roffset = 20; /* should be enough */
if (flags & MOZ_GTK_TAB_FIRST) {
if (direction == GTK_TEXT_DIR_RTL)
gap_roffset = initial_gap;
else
gap_loffset = initial_gap;
}
cairo_save(cr);
cairo_rectangle(cr, backRect.x, backRect.y, backRect.width, backRect.height);
cairo_clip(cr);
if (flags & MOZ_GTK_TAB_BOTTOM) {
/* Draw the tab on bottom */
focusRect.y += gap_voffset;
focusRect.height -= gap_voffset;
gtk_render_frame_gap(style, cr,
tabRect.x - gap_loffset,
tabRect.y + tabRect.height - gap_voffset,
tabRect.width + gap_loffset + gap_roffset,
3 * gap_height, GTK_POS_TOP,
gap_loffset, gap_loffset + tabRect.width);
cairo_restore(cr);
gtk_render_extension(style, cr,
tabRect.x, tabRect.y + gap_voffset, tabRect.width,
tabRect.height - gap_voffset, GTK_POS_TOP);
gtk_style_context_remove_region(style, GTK_STYLE_REGION_TAB);
backRect.y += (gap_voffset - gap_height);
backRect.height = gap_height;
/* Draw the gap; erase with background color before painting in
* case theme does not */
gtk_render_background(style, cr, backRect.x, backRect.y,
backRect.width, backRect.height);
cairo_save(cr);
cairo_rectangle(cr, backRect.x, backRect.y, backRect.width, backRect.height);
cairo_clip(cr);
gtk_render_frame_gap(style, cr,
tabRect.x - gap_loffset,
tabRect.y + gap_voffset - 3 * gap_height,
tabRect.width + gap_loffset + gap_roffset,
3 * gap_height, GTK_POS_BOTTOM,
gap_loffset, gap_loffset + tabRect.width);
cairo_restore(cr);
} else {
/* Draw the tab on top */
focusRect.height -= gap_voffset;
gtk_render_extension(style, cr,
tabRect.x, tabRect.y, tabRect.width,
tabRect.height - gap_voffset, GTK_POS_BOTTOM);
gtk_style_context_remove_region(style, GTK_STYLE_REGION_TAB);
backRect.y += (tabRect.height - gap_voffset);
backRect.height = gap_height;
/* Draw the gap; erase with background color before painting in
* case theme does not */
gtk_render_background(style, cr, backRect.x, backRect.y,
backRect.width, backRect.height);
cairo_save(cr);
cairo_rectangle(cr, backRect.x, backRect.y, backRect.width, backRect.height);
cairo_clip(cr);
gtk_render_frame_gap(style, cr,
tabRect.x - gap_loffset,
tabRect.y + tabRect.height - gap_voffset,
tabRect.width + gap_loffset + gap_roffset,
3 * gap_height, GTK_POS_TOP,
gap_loffset, gap_loffset + tabRect.width);
cairo_restore(cr);
}
}
}
if (state->focused) {
/* Paint the focus ring */
GtkBorder border;
gtk_style_context_get_border(style, GetStateFlagsFromGtkWidgetState(state), &border);
focusRect.x += border.left;
focusRect.width -= (border.left + border.right);
focusRect.y += border.top;
focusRect.height -= (border.top + border.bottom);
gtk_render_focus(style, cr,
focusRect.x, focusRect.y, focusRect.width, focusRect.height);
} else {
gtk_render_background(style, cr, tabRect.x, tabRect.y, tabRect.width, tabRect.height);
gtk_render_frame(style, cr, tabRect.x, tabRect.y, tabRect.width, tabRect.height);
}
gtk_style_context_restore(style);
if (state->focused) {
/* Paint the focus ring */
GtkBorder padding;
gtk_style_context_save(style);
moz_gtk_tab_prepare_style_context(style, flags);
gtk_style_context_get_padding(style, GetStateFlagsFromGtkWidgetState(state), &padding);
focusRect.x += padding.left;
focusRect.width -= (padding.left + padding.right);
focusRect.y += padding.top;
focusRect.height -= (padding.top + padding.bottom);
gtk_render_focus(style, cr,
focusRect.x, focusRect.y, focusRect.width, focusRect.height);
gtk_style_context_restore(style);
}
return MOZ_GTK_SUCCESS;
}
@ -2831,11 +2855,7 @@ moz_gtk_get_tab_border(gint* left, gint* top, gint* right, gint* bottom,
gtk_style_context_save(style);
moz_gtk_tab_prepare_style_context(style, flags);
// TODO add_style_border() should be replaced
// with focus-line-width and focus-padding
// see Bug 877605
*left = *top = *right = *bottom = 0;
moz_gtk_add_style_border(style, left, top, right, bottom);
moz_gtk_add_style_padding(style, left, top, right, bottom);
gtk_widget_style_get (gTabWidget, "tab-curvature", &tab_curvature, NULL);
@ -2846,16 +2866,9 @@ moz_gtk_get_tab_border(gint* left, gint* top, gint* right, gint* bottom,
int initial_gap;
gtk_widget_style_get (gTabWidget, "initial-gap", &initial_gap, NULL);
if (direction == GTK_TEXT_DIR_RTL)
*right += initial_gap;
*right += initial_gap;
else
*left += initial_gap;
}
// Top tabs have no bottom border, bottom tabs have no top border
if (flags & MOZ_GTK_TAB_BOTTOM) {
*top = 0;
} else {
*bottom = 0;
*left += initial_gap;
}
gtk_style_context_restore(style);

View File

@ -765,6 +765,8 @@ nsNativeThemeGTK::GetExtraSizeForWidget(nsIFrame* aFrame, uint8_t aWidgetType,
return false;
gint gap_height = moz_gtk_get_tab_thickness();
if (!gap_height)
return false;
int32_t extra = gap_height - GetTabMarginPixels(aFrame);
if (extra <= 0)

View File

@ -2542,7 +2542,7 @@ nsWindow::OnEnterNotifyEvent(GdkEventCrossing *aEvent)
if (is_parent_ungrab_enter(aEvent))
return;
WidgetMouseEvent event(true, NS_MOUSE_ENTER, this, WidgetMouseEvent::eReal);
WidgetMouseEvent event(true, NS_MOUSE_ENTER_WIDGET, this, WidgetMouseEvent::eReal);
event.refPoint.x = nscoord(aEvent->x);
event.refPoint.y = nscoord(aEvent->y);
@ -2583,7 +2583,7 @@ nsWindow::OnLeaveNotifyEvent(GdkEventCrossing *aEvent)
if (aEvent->subwindow != nullptr)
return;
WidgetMouseEvent event(true, NS_MOUSE_EXIT, this, WidgetMouseEvent::eReal);
WidgetMouseEvent event(true, NS_MOUSE_EXIT_WIDGET, this, WidgetMouseEvent::eReal);
event.refPoint.x = nscoord(aEvent->x);
event.refPoint.y = nscoord(aEvent->y);

View File

@ -1938,8 +1938,8 @@ case _value: eventName.AssignLiteral(_name) ; break
_ASSIGN_eventName(NS_KEY_DOWN,"NS_KEY_DOWN");
_ASSIGN_eventName(NS_KEY_PRESS,"NS_KEY_PRESS");
_ASSIGN_eventName(NS_KEY_UP,"NS_KEY_UP");
_ASSIGN_eventName(NS_MOUSE_ENTER,"NS_MOUSE_ENTER");
_ASSIGN_eventName(NS_MOUSE_EXIT,"NS_MOUSE_EXIT");
_ASSIGN_eventName(NS_MOUSE_ENTER_WIDGET,"NS_MOUSE_ENTER_WIDGET");
_ASSIGN_eventName(NS_MOUSE_EXIT_WIDGET,"NS_MOUSE_EXIT_WIDGET");
_ASSIGN_eventName(NS_MOUSE_BUTTON_DOWN,"NS_MOUSE_BUTTON_DOWN");
_ASSIGN_eventName(NS_MOUSE_BUTTON_UP,"NS_MOUSE_BUTTON_UP");
_ASSIGN_eventName(NS_MOUSE_CLICK,"NS_MOUSE_CLICK");
@ -2099,8 +2099,8 @@ nsBaseWidget::debug_DumpEvent(FILE * aFileOut,
return;
}
if (aGuiEvent->message == NS_MOUSE_ENTER ||
aGuiEvent->message == NS_MOUSE_EXIT)
if (aGuiEvent->message == NS_MOUSE_ENTER_WIDGET ||
aGuiEvent->message == NS_MOUSE_EXIT_WIDGET)
{
if (!debug_GetCachedBoolPref("nglayout.debug.crossing_event_dumping"))
return;

View File

@ -3780,8 +3780,8 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam,
&& nsWindowType::eWindowType_toplevel == mWindowType
// Currently this scheme is used only when pointer events is enabled.
&& gfxPrefs::PointerEventsEnabled()
// NS_MOUSE_EXIT is received, when InkCollector has been already initialized.
&& NS_MOUSE_EXIT != aEventType) {
// NS_MOUSE_EXIT_WIDGET is received, when InkCollector has been already initialized.
&& NS_MOUSE_EXIT_WIDGET != aEventType) {
InkCollector::sInkCollector->SetTarget(mWnd);
}
@ -3790,11 +3790,11 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam,
CaptureMouse(true);
break;
// NS_MOUSE_MOVE and NS_MOUSE_EXIT are here because we need to make sure capture flag
// NS_MOUSE_MOVE and NS_MOUSE_EXIT_WIDGET are here because we need to make sure capture flag
// isn't left on after a drag where we wouldn't see a button up message (see bug 324131).
case NS_MOUSE_BUTTON_UP:
case NS_MOUSE_MOVE:
case NS_MOUSE_EXIT:
case NS_MOUSE_EXIT_WIDGET:
if (!(wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) && sIsInMouseCapture)
CaptureMouse(false);
break;
@ -3887,7 +3887,7 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam,
else if (aEventType == NS_MOUSE_MOVE && !insideMovementThreshold) {
sLastClickCount = 0;
}
else if (aEventType == NS_MOUSE_EXIT) {
else if (aEventType == NS_MOUSE_EXIT_WIDGET) {
event.exit = IsTopLevelMouseExit(mWnd) ?
WidgetMouseEvent::eTopLevel : WidgetMouseEvent::eChild;
}
@ -3950,7 +3950,7 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam,
case NS_MOUSE_MOVE:
pluginEvent.event = WM_MOUSEMOVE;
break;
case NS_MOUSE_EXIT:
case NS_MOUSE_EXIT_WIDGET:
pluginEvent.event = WM_MOUSELEAVE;
break;
default:
@ -3980,20 +3980,20 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam,
if (sCurrentWindow == nullptr || sCurrentWindow != this) {
if ((nullptr != sCurrentWindow) && (!sCurrentWindow->mInDtor)) {
LPARAM pos = sCurrentWindow->lParamToClient(lParamToScreen(lParam));
sCurrentWindow->DispatchMouseEvent(NS_MOUSE_EXIT, wParam, pos, false,
sCurrentWindow->DispatchMouseEvent(NS_MOUSE_EXIT_WIDGET, wParam, pos, false,
WidgetMouseEvent::eLeftButton,
aInputSource);
}
sCurrentWindow = this;
if (!mInDtor) {
LPARAM pos = sCurrentWindow->lParamToClient(lParamToScreen(lParam));
sCurrentWindow->DispatchMouseEvent(NS_MOUSE_ENTER, wParam, pos, false,
sCurrentWindow->DispatchMouseEvent(NS_MOUSE_ENTER_WIDGET, wParam, pos, false,
WidgetMouseEvent::eLeftButton,
aInputSource);
}
}
}
} else if (aEventType == NS_MOUSE_EXIT) {
} else if (aEventType == NS_MOUSE_EXIT_WIDGET) {
if (sCurrentWindow == this) {
sCurrentWindow = nullptr;
}
@ -4864,7 +4864,7 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
case WM_NCMOUSEMOVE:
// If we receive a mouse move event on non-client chrome, make sure and
// send an NS_MOUSE_EXIT event as well.
// send an NS_MOUSE_EXIT_WIDGET event as well.
if (mMousePresent && !sIsInMouseCapture)
SendMessage(mWnd, WM_MOUSELEAVE, 0, 0);
break;
@ -4901,7 +4901,7 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
// Synthesize an event position because we don't get one from
// WM_MOUSELEAVE.
LPARAM pos = lParamToClient(::GetMessagePos());
DispatchMouseEvent(NS_MOUSE_EXIT, mouseState, pos, false,
DispatchMouseEvent(NS_MOUSE_EXIT_WIDGET, mouseState, pos, false,
WidgetMouseEvent::eLeftButton, MOUSE_INPUT_SOURCE());
}
break;
@ -4909,7 +4909,7 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
case MOZ_WM_PEN_LEAVES_HOVER_OF_DIGITIZER:
{
LPARAM pos = lParamToClient(::GetMessagePos());
DispatchMouseEvent(NS_MOUSE_EXIT, wParam, pos, false,
DispatchMouseEvent(NS_MOUSE_EXIT_WIDGET, wParam, pos, false,
WidgetMouseEvent::eLeftButton,
nsIDOMMouseEvent::MOZ_SOURCE_PEN);
}