mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Merge inbound to m-c. a=merge
This commit is contained in:
commit
634d37ccd0
@ -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:
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -239,12 +239,6 @@ SharedDecoderProxy::Shutdown()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
SharedDecoderProxy::IsWaitingMediaResources()
|
||||
{
|
||||
return mManager->mDecoder->IsWaitingMediaResources();
|
||||
}
|
||||
|
||||
bool
|
||||
SharedDecoderProxy::IsHardwareAccelerated() const
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -69,7 +69,6 @@ public:
|
||||
|
||||
virtual nsresult Shutdown() override;
|
||||
|
||||
virtual bool IsWaitingMediaResources() { return false; };
|
||||
virtual bool IsHardwareAccelerated() const override;
|
||||
|
||||
private:
|
||||
|
@ -108,15 +108,6 @@ H264Converter::Shutdown()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
H264Converter::IsWaitingMediaResources()
|
||||
{
|
||||
if (mDecoder) {
|
||||
return mDecoder->IsWaitingMediaResources();
|
||||
}
|
||||
return MediaDataDecoder::IsWaitingMediaResources();
|
||||
}
|
||||
|
||||
bool
|
||||
H264Converter::IsHardwareAccelerated() const
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
);
|
||||
|
@ -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;
|
||||
|
@ -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');
|
||||
|
@ -1,4 +1,8 @@
|
||||
function handleRequest(request, response) {
|
||||
if (request.queryString == 'clearcounter') {
|
||||
setState('periodiccounter', '');
|
||||
return;
|
||||
}
|
||||
if (!getState('periodiccounter')) {
|
||||
setState('periodiccounter', '1');
|
||||
} else {
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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..."));
|
||||
|
@ -630,6 +630,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void FlushContentDrawing() {}
|
||||
protected:
|
||||
gfxPlatform();
|
||||
virtual ~gfxPlatform();
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
34
js/src/jit-test/tests/ion/lazyLink-bug1150783.js
Normal file
34
js/src/jit-test/tests/ion/lazyLink-bug1150783.js
Normal 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 })();
|
@ -0,0 +1,8 @@
|
||||
|
||||
function f(x) {
|
||||
for (var i = 0; i < 40; ++i) {
|
||||
var stack = getBacktrace({args: true});
|
||||
(function() { g = x;});
|
||||
}
|
||||
}
|
||||
f(1);
|
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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>();
|
||||
}
|
||||
|
@ -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_;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
|
@ -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),
|
||||
|
@ -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_);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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(),
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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
@ -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)
|
||||
|
@ -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());
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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: {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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",
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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", ¬ebook_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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user