mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-22 23:27:30 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
74a139ee22
19 changed files with 477 additions and 204 deletions
|
|
@ -2377,6 +2377,56 @@ nsContentUtils::GetCommonAncestor(nsINode* aNode1,
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
nsINode*
|
||||||
|
nsContentUtils::GetCommonAncestorUnderInteractiveContent(nsINode* aNode1,
|
||||||
|
nsINode* aNode2)
|
||||||
|
{
|
||||||
|
if (!aNode1 || !aNode2) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aNode1 == aNode2) {
|
||||||
|
return aNode1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the chain of parents
|
||||||
|
AutoTArray<nsINode*, 30> parents1;
|
||||||
|
do {
|
||||||
|
parents1.AppendElement(aNode1);
|
||||||
|
if (aNode1->IsElement() &&
|
||||||
|
aNode1->AsElement()->IsInteractiveHTMLContent(true)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
aNode1 = aNode1->GetFlattenedTreeParentNode();
|
||||||
|
} while (aNode1);
|
||||||
|
|
||||||
|
AutoTArray<nsINode*, 30> parents2;
|
||||||
|
do {
|
||||||
|
parents2.AppendElement(aNode2);
|
||||||
|
if (aNode2->IsElement() &&
|
||||||
|
aNode2->AsElement()->IsInteractiveHTMLContent(true)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
aNode2 = aNode2->GetFlattenedTreeParentNode();
|
||||||
|
} while (aNode2);
|
||||||
|
|
||||||
|
// Find where the parent chain differs
|
||||||
|
uint32_t pos1 = parents1.Length();
|
||||||
|
uint32_t pos2 = parents2.Length();
|
||||||
|
nsINode* parent = nullptr;
|
||||||
|
for (uint32_t len = std::min(pos1, pos2); len > 0; --len) {
|
||||||
|
nsINode* child1 = parents1.ElementAt(--pos1);
|
||||||
|
nsINode* child2 = parents2.ElementAt(--pos2);
|
||||||
|
if (child1 != child2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parent = child1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
bool
|
bool
|
||||||
nsContentUtils::PositionIsBefore(nsINode* aNode1, nsINode* aNode2)
|
nsContentUtils::PositionIsBefore(nsINode* aNode1, nsINode* aNode2)
|
||||||
|
|
|
||||||
|
|
@ -324,6 +324,15 @@ public:
|
||||||
static nsINode* GetCommonAncestor(nsINode* aNode1,
|
static nsINode* GetCommonAncestor(nsINode* aNode1,
|
||||||
nsINode* aNode2);
|
nsINode* aNode2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the common ancestor under interactive content, if any.
|
||||||
|
* If neither one has interactive content as ancestor, common ancestor will be
|
||||||
|
* returned. If only one has interactive content as ancestor, null will be
|
||||||
|
* returned. If the nodes are the same, that node is returned.
|
||||||
|
*/
|
||||||
|
static nsINode* GetCommonAncestorUnderInteractiveContent(nsINode* aNode1,
|
||||||
|
nsINode* aNode2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if aNode1 is before aNode2 in the same connected
|
* Returns true if aNode1 is before aNode2 in the same connected
|
||||||
* tree.
|
* tree.
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Event)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (WidgetMouseEvent* mouseEvent = tmp->mEvent->AsMouseEvent()) {
|
||||||
|
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvent->mClickTarget");
|
||||||
|
cb.NoteXPCOMChild(mouseEvent->mClickTarget);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExplicitOriginalTarget)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExplicitOriginalTarget)
|
||||||
|
|
|
||||||
|
|
@ -434,11 +434,8 @@ NS_IMPL_CYCLE_COLLECTION(EventStateManager,
|
||||||
mGestureDownContent,
|
mGestureDownContent,
|
||||||
mGestureDownFrameOwner,
|
mGestureDownFrameOwner,
|
||||||
mLastLeftMouseDownContent,
|
mLastLeftMouseDownContent,
|
||||||
mLastLeftMouseDownContentParent,
|
|
||||||
mLastMiddleMouseDownContent,
|
mLastMiddleMouseDownContent,
|
||||||
mLastMiddleMouseDownContentParent,
|
|
||||||
mLastRightMouseDownContent,
|
mLastRightMouseDownContent,
|
||||||
mLastRightMouseDownContentParent,
|
|
||||||
mActiveContent,
|
mActiveContent,
|
||||||
mHoverContent,
|
mHoverContent,
|
||||||
mURLTargetContent,
|
mURLTargetContent,
|
||||||
|
|
@ -3177,14 +3174,11 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||||
case eMouseUp:
|
case eMouseUp:
|
||||||
{
|
{
|
||||||
ClearGlobalActiveContent(this);
|
ClearGlobalActiveContent(this);
|
||||||
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
|
WidgetMouseEvent* mouseUpEvent = aEvent->AsMouseEvent();
|
||||||
if (mouseEvent && mouseEvent->IsReal()) {
|
if (mouseUpEvent && EventCausesClickEvents(*mouseUpEvent)) {
|
||||||
if (!mCurrentTarget) {
|
|
||||||
GetEventTarget();
|
|
||||||
}
|
|
||||||
// Make sure to dispatch the click even if there is no frame for
|
// Make sure to dispatch the click even if there is no frame for
|
||||||
// the current target element. This is required for Web compatibility.
|
// the current target element. This is required for Web compatibility.
|
||||||
ret = CheckForAndDispatchClick(mouseEvent, aStatus);
|
ret = PostHandleMouseUp(mouseUpEvent, aStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIPresShell *shell = presContext->GetPresShell();
|
nsIPresShell *shell = presContext->GetPresShell();
|
||||||
|
|
@ -4579,16 +4573,13 @@ EventStateManager::SetClickCount(WidgetMouseEvent* aEvent,
|
||||||
nsEventStatus* aStatus)
|
nsEventStatus* aStatus)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIContent> mouseContent;
|
nsCOMPtr<nsIContent> mouseContent;
|
||||||
nsIContent* mouseContentParent = nullptr;
|
|
||||||
if (mCurrentTarget) {
|
if (mCurrentTarget) {
|
||||||
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(mouseContent));
|
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(mouseContent));
|
||||||
}
|
}
|
||||||
if (mouseContent) {
|
if (mouseContent && mouseContent->IsNodeOfType(nsINode::eTEXT)) {
|
||||||
if (mouseContent->IsNodeOfType(nsINode::eTEXT)) {
|
nsINode* parent = mouseContent->GetFlattenedTreeParentNode();
|
||||||
mouseContent = mouseContent->GetParent();
|
if (parent && parent->IsContent()) {
|
||||||
}
|
mouseContent = parent->AsContent();
|
||||||
if (mouseContent && mouseContent->IsRootOfNativeAnonymousSubtree()) {
|
|
||||||
mouseContentParent = mouseContent->GetParent();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4596,54 +4587,51 @@ EventStateManager::SetClickCount(WidgetMouseEvent* aEvent,
|
||||||
case WidgetMouseEvent::eLeftButton:
|
case WidgetMouseEvent::eLeftButton:
|
||||||
if (aEvent->mMessage == eMouseDown) {
|
if (aEvent->mMessage == eMouseDown) {
|
||||||
mLastLeftMouseDownContent = mouseContent;
|
mLastLeftMouseDownContent = mouseContent;
|
||||||
mLastLeftMouseDownContentParent = mouseContentParent;
|
|
||||||
} else if (aEvent->mMessage == eMouseUp) {
|
} else if (aEvent->mMessage == eMouseUp) {
|
||||||
if (mLastLeftMouseDownContent == mouseContent ||
|
aEvent->mClickTarget =
|
||||||
mLastLeftMouseDownContentParent == mouseContent ||
|
nsContentUtils::GetCommonAncestorUnderInteractiveContent(
|
||||||
mLastLeftMouseDownContent == mouseContentParent) {
|
mouseContent, mLastLeftMouseDownContent);
|
||||||
|
if (aEvent->mClickTarget) {
|
||||||
aEvent->mClickCount = mLClickCount;
|
aEvent->mClickCount = mLClickCount;
|
||||||
mLClickCount = 0;
|
mLClickCount = 0;
|
||||||
} else {
|
} else {
|
||||||
aEvent->mClickCount = 0;
|
aEvent->mClickCount = 0;
|
||||||
}
|
}
|
||||||
mLastLeftMouseDownContent = nullptr;
|
mLastLeftMouseDownContent = nullptr;
|
||||||
mLastLeftMouseDownContentParent = nullptr;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WidgetMouseEvent::eMiddleButton:
|
case WidgetMouseEvent::eMiddleButton:
|
||||||
if (aEvent->mMessage == eMouseDown) {
|
if (aEvent->mMessage == eMouseDown) {
|
||||||
mLastMiddleMouseDownContent = mouseContent;
|
mLastMiddleMouseDownContent = mouseContent;
|
||||||
mLastMiddleMouseDownContentParent = mouseContentParent;
|
|
||||||
} else if (aEvent->mMessage == eMouseUp) {
|
} else if (aEvent->mMessage == eMouseUp) {
|
||||||
if (mLastMiddleMouseDownContent == mouseContent ||
|
aEvent->mClickTarget =
|
||||||
mLastMiddleMouseDownContentParent == mouseContent ||
|
nsContentUtils::GetCommonAncestorUnderInteractiveContent(
|
||||||
mLastMiddleMouseDownContent == mouseContentParent) {
|
mouseContent, mLastMiddleMouseDownContent);
|
||||||
|
if (aEvent->mClickTarget) {
|
||||||
aEvent->mClickCount = mMClickCount;
|
aEvent->mClickCount = mMClickCount;
|
||||||
mMClickCount = 0;
|
mMClickCount = 0;
|
||||||
} else {
|
} else {
|
||||||
aEvent->mClickCount = 0;
|
aEvent->mClickCount = 0;
|
||||||
}
|
}
|
||||||
mLastMiddleMouseDownContent = nullptr;
|
mLastMiddleMouseDownContent = nullptr;
|
||||||
mLastMiddleMouseDownContentParent = nullptr;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WidgetMouseEvent::eRightButton:
|
case WidgetMouseEvent::eRightButton:
|
||||||
if (aEvent->mMessage == eMouseDown) {
|
if (aEvent->mMessage == eMouseDown) {
|
||||||
mLastRightMouseDownContent = mouseContent;
|
mLastRightMouseDownContent = mouseContent;
|
||||||
mLastRightMouseDownContentParent = mouseContentParent;
|
|
||||||
} else if (aEvent->mMessage == eMouseUp) {
|
} else if (aEvent->mMessage == eMouseUp) {
|
||||||
if (mLastRightMouseDownContent == mouseContent ||
|
aEvent->mClickTarget =
|
||||||
mLastRightMouseDownContentParent == mouseContent ||
|
nsContentUtils::GetCommonAncestorUnderInteractiveContent(
|
||||||
mLastRightMouseDownContent == mouseContentParent) {
|
mouseContent, mLastRightMouseDownContent);
|
||||||
|
if (aEvent->mClickTarget) {
|
||||||
aEvent->mClickCount = mRClickCount;
|
aEvent->mClickCount = mRClickCount;
|
||||||
mRClickCount = 0;
|
mRClickCount = 0;
|
||||||
} else {
|
} else {
|
||||||
aEvent->mClickCount = 0;
|
aEvent->mClickCount = 0;
|
||||||
}
|
}
|
||||||
mLastRightMouseDownContent = nullptr;
|
mLastRightMouseDownContent = nullptr;
|
||||||
mLastRightMouseDownContentParent = nullptr;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -4651,89 +4639,151 @@ EventStateManager::SetClickCount(WidgetMouseEvent* aEvent,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
EventStateManager::EventCausesClickEvents(const WidgetMouseEvent& aMouseEvent)
|
||||||
|
{
|
||||||
|
if (NS_WARN_IF(aMouseEvent.mMessage != eMouseUp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// If the mouseup event is synthesized event, we don't need to dispatch
|
||||||
|
// click events.
|
||||||
|
if (!aMouseEvent.IsReal()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// If mouse is still over same element, clickcount will be > 1.
|
||||||
|
// If it has moved it will be zero, so no click.
|
||||||
|
if (!aMouseEvent.mClickCount || !aMouseEvent.mClickTarget) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Check that the window isn't disabled before firing a click
|
||||||
|
// (see bug 366544).
|
||||||
|
return !(aMouseEvent.mWidget && !aMouseEvent.mWidget->IsEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
EventStateManager::InitAndDispatchClickEvent(WidgetMouseEvent* aEvent,
|
EventStateManager::InitAndDispatchClickEvent(WidgetMouseEvent* aMouseUpEvent,
|
||||||
nsEventStatus* aStatus,
|
nsEventStatus* aStatus,
|
||||||
EventMessage aMessage,
|
EventMessage aMessage,
|
||||||
nsIPresShell* aPresShell,
|
nsIPresShell* aPresShell,
|
||||||
nsIContent* aMouseTarget,
|
nsIContent* aMouseUpContent,
|
||||||
nsWeakFrame aCurrentTarget,
|
nsWeakFrame aCurrentTarget,
|
||||||
bool aNoContentDispatch)
|
bool aNoContentDispatch)
|
||||||
{
|
{
|
||||||
WidgetMouseEvent event(aEvent->IsTrusted(), aMessage,
|
MOZ_ASSERT(aMouseUpEvent);
|
||||||
aEvent->mWidget, WidgetMouseEvent::eReal);
|
MOZ_ASSERT(EventCausesClickEvents(*aMouseUpEvent));
|
||||||
|
MOZ_ASSERT(aMouseUpContent || aCurrentTarget);
|
||||||
|
|
||||||
event.mRefPoint = aEvent->mRefPoint;
|
WidgetMouseEvent event(aMouseUpEvent->IsTrusted(), aMessage,
|
||||||
event.mClickCount = aEvent->mClickCount;
|
aMouseUpEvent->mWidget, WidgetMouseEvent::eReal);
|
||||||
event.mModifiers = aEvent->mModifiers;
|
event.mRefPoint = aMouseUpEvent->mRefPoint;
|
||||||
event.buttons = aEvent->buttons;
|
event.mClickCount = aMouseUpEvent->mClickCount;
|
||||||
event.mTime = aEvent->mTime;
|
event.mModifiers = aMouseUpEvent->mModifiers;
|
||||||
event.mTimeStamp = aEvent->mTimeStamp;
|
event.buttons = aMouseUpEvent->buttons;
|
||||||
|
event.mTime = aMouseUpEvent->mTime;
|
||||||
|
event.mTimeStamp = aMouseUpEvent->mTimeStamp;
|
||||||
event.mFlags.mNoContentDispatch = aNoContentDispatch;
|
event.mFlags.mNoContentDispatch = aNoContentDispatch;
|
||||||
event.button = aEvent->button;
|
event.button = aMouseUpEvent->button;
|
||||||
event.inputSource = aEvent->inputSource;
|
event.inputSource = aMouseUpEvent->inputSource;
|
||||||
|
|
||||||
return aPresShell->HandleEventWithTarget(&event, aCurrentTarget,
|
if (!aMouseUpContent->IsInComposedDoc()) {
|
||||||
aMouseTarget, aStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
EventStateManager::CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
|
|
||||||
nsEventStatus* aStatus)
|
|
||||||
{
|
|
||||||
nsresult ret = NS_OK;
|
|
||||||
|
|
||||||
//If mouse is still over same element, clickcount will be > 1.
|
|
||||||
//If it has moved it will be zero, so no click.
|
|
||||||
if (aEvent->mClickCount) {
|
|
||||||
//Check that the window isn't disabled before firing a click
|
|
||||||
//(see bug 366544).
|
|
||||||
if (aEvent->mWidget && !aEvent->mWidget->IsEnabled()) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
//fire click
|
|
||||||
bool notDispatchToContents =
|
|
||||||
(aEvent->button == WidgetMouseEvent::eMiddleButton ||
|
|
||||||
aEvent->button == WidgetMouseEvent::eRightButton);
|
|
||||||
|
|
||||||
bool fireAuxClick = notDispatchToContents;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
|
|
||||||
if (presShell) {
|
|
||||||
nsCOMPtr<nsIContent> mouseContent = GetEventTargetContent(aEvent);
|
|
||||||
// Click events apply to *elements* not nodes. At this point the target
|
|
||||||
// content may have been reset to some non-element content, and so we need
|
|
||||||
// to walk up the closest ancestor element, just like we do in
|
|
||||||
// nsPresShell::HandlePositionedEvent.
|
|
||||||
while (mouseContent && !mouseContent->IsElement()) {
|
|
||||||
mouseContent = mouseContent->GetParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mouseContent && !mCurrentTarget) {
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleEvent clears out mCurrentTarget which we might need again
|
// Use local event status for each click event dispatching since it'll be
|
||||||
nsWeakFrame currentTarget = mCurrentTarget;
|
// cleared by EventStateManager::PreHandleEvent(). Therefore, dispatching
|
||||||
ret = InitAndDispatchClickEvent(aEvent, aStatus, eMouseClick,
|
// an event means that previous event status will be ignored.
|
||||||
presShell, mouseContent, currentTarget,
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
notDispatchToContents);
|
nsresult rv = aPresShell->HandleEventWithTarget(&event, aCurrentTarget,
|
||||||
|
aMouseUpContent, &status);
|
||||||
|
// If current status is nsEventStatus_eConsumeNoDefault, we don't need to
|
||||||
|
// overwrite it.
|
||||||
|
if (*aStatus == nsEventStatus_eConsumeNoDefault) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
// If new status is nsEventStatus_eConsumeNoDefault or
|
||||||
|
// nsEventStatus_eConsumeDoDefault, use it.
|
||||||
|
if (status == nsEventStatus_eConsumeNoDefault ||
|
||||||
|
status == nsEventStatus_eConsumeDoDefault) {
|
||||||
|
*aStatus = status;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
// Otherwise, keep the original status.
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_SUCCEEDED(ret) && aEvent->mClickCount == 2 &&
|
nsresult
|
||||||
mouseContent && mouseContent->IsInComposedDoc()) {
|
EventStateManager::PostHandleMouseUp(WidgetMouseEvent* aMouseUpEvent,
|
||||||
//fire double click
|
nsEventStatus* aStatus)
|
||||||
ret = InitAndDispatchClickEvent(aEvent, aStatus, eMouseDoubleClick,
|
{
|
||||||
presShell, mouseContent, currentTarget,
|
MOZ_ASSERT(aMouseUpEvent);
|
||||||
|
MOZ_ASSERT(EventCausesClickEvents(*aMouseUpEvent));
|
||||||
|
MOZ_ASSERT(aStatus);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
|
||||||
|
if (!presShell) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> clickTarget = do_QueryInterface(aMouseUpEvent->mClickTarget);
|
||||||
|
NS_ENSURE_STATE(clickTarget);
|
||||||
|
|
||||||
|
// Fire click events if the event target is still available.
|
||||||
|
nsresult rv = DispatchClickEvents(presShell, aMouseUpEvent, aStatus,
|
||||||
|
clickTarget);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
EventStateManager::DispatchClickEvents(nsIPresShell* aPresShell,
|
||||||
|
WidgetMouseEvent* aMouseUpEvent,
|
||||||
|
nsEventStatus* aStatus,
|
||||||
|
nsIContent* aClickTarget)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aPresShell);
|
||||||
|
MOZ_ASSERT(aMouseUpEvent);
|
||||||
|
MOZ_ASSERT(EventCausesClickEvents(*aMouseUpEvent));
|
||||||
|
MOZ_ASSERT(aStatus);
|
||||||
|
MOZ_ASSERT(aClickTarget);
|
||||||
|
|
||||||
|
bool notDispatchToContents =
|
||||||
|
(aMouseUpEvent->button == WidgetMouseEvent::eMiddleButton ||
|
||||||
|
aMouseUpEvent->button == WidgetMouseEvent::eRightButton);
|
||||||
|
|
||||||
|
bool fireAuxClick = notDispatchToContents;
|
||||||
|
|
||||||
|
nsWeakFrame currentTarget = aClickTarget->GetPrimaryFrame();
|
||||||
|
nsresult ret =
|
||||||
|
InitAndDispatchClickEvent(aMouseUpEvent, aStatus, eMouseClick,
|
||||||
|
aPresShell, aClickTarget, currentTarget,
|
||||||
notDispatchToContents);
|
notDispatchToContents);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(ret))) {
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
if (NS_SUCCEEDED(ret) && mouseContent && fireAuxClick &&
|
|
||||||
mouseContent->IsInComposedDoc()) {
|
// Fire double click event if click count is 2.
|
||||||
ret = InitAndDispatchClickEvent(aEvent, aStatus, eMouseAuxClick,
|
if (aMouseUpEvent->mClickCount == 2 &&
|
||||||
presShell, mouseContent, currentTarget,
|
aClickTarget && aClickTarget->IsInComposedDoc()) {
|
||||||
|
ret = InitAndDispatchClickEvent(aMouseUpEvent, aStatus, eMouseDoubleClick,
|
||||||
|
aPresShell, aClickTarget, currentTarget,
|
||||||
|
notDispatchToContents);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(ret))) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fire auxclick even if necessary.
|
||||||
|
if (fireAuxClick &&
|
||||||
|
aClickTarget && aClickTarget->IsInComposedDoc()) {
|
||||||
|
ret = InitAndDispatchClickEvent(aMouseUpEvent, aStatus, eMouseAuxClick,
|
||||||
|
aPresShell, aClickTarget, currentTarget,
|
||||||
false);
|
false);
|
||||||
|
NS_WARNING_ASSERTION(NS_SUCCEEDED(ret), "Failed to dispatch eMouseAuxClick");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -414,16 +414,79 @@ protected:
|
||||||
*/
|
*/
|
||||||
void UpdateDragDataTransfer(WidgetDragEvent* dragEvent);
|
void UpdateDragDataTransfer(WidgetDragEvent* dragEvent);
|
||||||
|
|
||||||
static nsresult InitAndDispatchClickEvent(WidgetMouseEvent* aEvent,
|
/**
|
||||||
|
* InitAndDispatchClickEvent() dispatches a click event.
|
||||||
|
*
|
||||||
|
* @param aMouseUpEvent eMouseUp event which causes the click event.
|
||||||
|
* EventCausesClickEvents() must return true
|
||||||
|
* if this event is set to it.
|
||||||
|
* @param aStatus Returns the result of click event.
|
||||||
|
* If the status indicates consumed, the
|
||||||
|
* value won't be overwritten with
|
||||||
|
* nsEventStatus_eIgnore.
|
||||||
|
* @param aMessage Should be eMouseClick, eMouseDoubleClick or
|
||||||
|
* eMouseAuxClick.
|
||||||
|
* @param aPresShell The PresShell.
|
||||||
|
* @param aMouseUpContent The event target of aMouseUpEvent.
|
||||||
|
* @param aCurrentTarget Current target of the caller.
|
||||||
|
* @param aNoContentDispatch true if the event shouldn't be exposed to
|
||||||
|
* web contents (although will be fired on
|
||||||
|
* document and window).
|
||||||
|
* @param aOverrideClickTarget Preferred click event target. If this is
|
||||||
|
* not nullptr, aMouseUpContent and
|
||||||
|
* aCurrentTarget are ignored.
|
||||||
|
*/
|
||||||
|
static nsresult InitAndDispatchClickEvent(WidgetMouseEvent* aMouseUpEvent,
|
||||||
nsEventStatus* aStatus,
|
nsEventStatus* aStatus,
|
||||||
EventMessage aMessage,
|
EventMessage aMessage,
|
||||||
nsIPresShell* aPresShell,
|
nsIPresShell* aPresShell,
|
||||||
nsIContent* aMouseTarget,
|
nsIContent* aMouseUpContent,
|
||||||
nsWeakFrame aCurrentTarget,
|
nsWeakFrame aCurrentTarget,
|
||||||
bool aNoContentDispatch);
|
bool aNoContentDispatch);
|
||||||
nsresult SetClickCount(WidgetMouseEvent* aEvent, nsEventStatus* aStatus);
|
nsresult SetClickCount(WidgetMouseEvent* aEvent, nsEventStatus* aStatus);
|
||||||
nsresult CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
|
|
||||||
|
/**
|
||||||
|
* EventCausesClickEvents() returns true when aMouseEvent is an eMouseUp
|
||||||
|
* event and it should cause eMouseClick, eMouseDoubleClick and/or
|
||||||
|
* eMouseAuxClick events. Note that this method assumes that
|
||||||
|
* aMouseEvent.mClickCount has already been initialized with SetClickCount().
|
||||||
|
*/
|
||||||
|
static bool EventCausesClickEvents(const WidgetMouseEvent& aMouseEvent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PostHandleMouseUp() handles default actions of eMouseUp event.
|
||||||
|
*
|
||||||
|
* @param aMouseUpEvent eMouseUp event which causes the click event.
|
||||||
|
* EventCausesClickEvents() must return true
|
||||||
|
* if this event is set to it.
|
||||||
|
* @param aStatus Returns the result of event status.
|
||||||
|
* If one of dispatching event is consumed or
|
||||||
|
* this does something as default action,
|
||||||
|
* returns nsEventStatus_eConsumeNoDefault.
|
||||||
|
*/
|
||||||
|
nsresult PostHandleMouseUp(WidgetMouseEvent* aMouseUpEvent,
|
||||||
nsEventStatus* aStatus);
|
nsEventStatus* aStatus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DispatchClickEvents() dispatches eMouseClick, eMouseDoubleClick and
|
||||||
|
* eMouseAuxClick events for aMouseUpEvent. aMouseUpEvent should cause
|
||||||
|
* click event.
|
||||||
|
*
|
||||||
|
* @param aPresShell The PresShell.
|
||||||
|
* @param aMouseUpEvent eMouseUp event which causes the click event.
|
||||||
|
* EventCausesClickEvents() must return true
|
||||||
|
* if this event is set to it.
|
||||||
|
* @param aStatus Returns the result of event status.
|
||||||
|
* If one of dispatching click event is
|
||||||
|
* consumed, returns
|
||||||
|
* nsEventStatus_eConsumeNoDefault.
|
||||||
|
* @param aMouseUpContent The event target of aMouseUpEvent.
|
||||||
|
*/
|
||||||
|
nsresult DispatchClickEvents(nsIPresShell* aPresShell,
|
||||||
|
WidgetMouseEvent* aMouseUpEvent,
|
||||||
|
nsEventStatus* aStatus,
|
||||||
|
nsIContent* aMouseUpContent);
|
||||||
|
|
||||||
void EnsureDocument(nsPresContext* aPresContext);
|
void EnsureDocument(nsPresContext* aPresContext);
|
||||||
void FlushPendingEvents(nsPresContext* aPresContext);
|
void FlushPendingEvents(nsPresContext* aPresContext);
|
||||||
|
|
||||||
|
|
@ -951,11 +1014,8 @@ private:
|
||||||
uint16_t mGestureDownButtons;
|
uint16_t mGestureDownButtons;
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> mLastLeftMouseDownContent;
|
nsCOMPtr<nsIContent> mLastLeftMouseDownContent;
|
||||||
nsCOMPtr<nsIContent> mLastLeftMouseDownContentParent;
|
|
||||||
nsCOMPtr<nsIContent> mLastMiddleMouseDownContent;
|
nsCOMPtr<nsIContent> mLastMiddleMouseDownContent;
|
||||||
nsCOMPtr<nsIContent> mLastMiddleMouseDownContentParent;
|
|
||||||
nsCOMPtr<nsIContent> mLastRightMouseDownContent;
|
nsCOMPtr<nsIContent> mLastRightMouseDownContent;
|
||||||
nsCOMPtr<nsIContent> mLastRightMouseDownContentParent;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> mActiveContent;
|
nsCOMPtr<nsIContent> mActiveContent;
|
||||||
nsCOMPtr<nsIContent> mHoverContent;
|
nsCOMPtr<nsIContent> mHoverContent;
|
||||||
|
|
|
||||||
|
|
@ -228,26 +228,20 @@ UIEvent::GetWhich(uint32_t* aWhich)
|
||||||
already_AddRefed<nsINode>
|
already_AddRefed<nsINode>
|
||||||
UIEvent::GetRangeParent()
|
UIEvent::GetRangeParent()
|
||||||
{
|
{
|
||||||
nsIFrame* targetFrame = nullptr;
|
if (NS_WARN_IF(!mPresContext)) {
|
||||||
|
|
||||||
if (mPresContext) {
|
|
||||||
targetFrame = mPresContext->EventStateManager()->GetEventTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetFrame) {
|
|
||||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
|
|
||||||
targetFrame);
|
|
||||||
nsCOMPtr<nsIContent> parent = targetFrame->GetContentOffsetsFromPoint(pt).content;
|
|
||||||
if (parent) {
|
|
||||||
if (parent->ChromeOnlyAccess() &&
|
|
||||||
!nsContentUtils::CanAccessNativeAnon()) {
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return parent.forget();
|
|
||||||
}
|
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
|
||||||
|
if (NS_WARN_IF(!presShell)) {
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
nsCOMPtr<nsIContent> container;
|
||||||
|
nsLayoutUtils::GetContainerAndOffsetAtEvent(presShell, mEvent,
|
||||||
|
getter_AddRefs(container),
|
||||||
|
nullptr);
|
||||||
|
return container.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
@ -273,18 +267,19 @@ UIEvent::GetRangeOffset(int32_t* aRangeOffset)
|
||||||
int32_t
|
int32_t
|
||||||
UIEvent::RangeOffset() const
|
UIEvent::RangeOffset() const
|
||||||
{
|
{
|
||||||
if (!mPresContext) {
|
if (NS_WARN_IF(!mPresContext)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame* targetFrame = mPresContext->EventStateManager()->GetEventTarget();
|
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
|
||||||
if (!targetFrame) {
|
if (NS_WARN_IF(!presShell)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
|
int32_t offset = 0;
|
||||||
targetFrame);
|
nsLayoutUtils::GetContainerAndOffsetAtEvent(presShell, mEvent,
|
||||||
return targetFrame->GetContentOffsetsFromPoint(pt).offset;
|
nullptr, &offset);
|
||||||
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIntPoint
|
nsIntPoint
|
||||||
|
|
|
||||||
|
|
@ -221,11 +221,14 @@ HTMLButtonElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||||
bool outerActivateEvent =
|
bool outerActivateEvent =
|
||||||
((mouseEvent && mouseEvent->IsLeftClickEvent()) ||
|
((mouseEvent && mouseEvent->IsLeftClickEvent()) ||
|
||||||
(aVisitor.mEvent->mMessage == eLegacyDOMActivate &&
|
(aVisitor.mEvent->mMessage == eLegacyDOMActivate &&
|
||||||
!mInInternalActivate));
|
!mInInternalActivate &&
|
||||||
|
aVisitor.mEvent->mOriginalTarget == this));
|
||||||
|
|
||||||
if (outerActivateEvent) {
|
if (outerActivateEvent) {
|
||||||
aVisitor.mItemFlags |= NS_OUTER_ACTIVATE_EVENT;
|
aVisitor.mItemFlags |= NS_OUTER_ACTIVATE_EVENT;
|
||||||
if (mType == NS_FORM_BUTTON_SUBMIT && mForm) {
|
if (mType == NS_FORM_BUTTON_SUBMIT && mForm &&
|
||||||
|
!aVisitor.mEvent->mFlags.mMultiplePreActionsPrevented) {
|
||||||
|
aVisitor.mEvent->mFlags.mMultiplePreActionsPrevented = true;
|
||||||
aVisitor.mItemFlags |= NS_IN_SUBMIT_CLICK;
|
aVisitor.mItemFlags |= NS_IN_SUBMIT_CLICK;
|
||||||
// tell the form that we are about to enter a click handler.
|
// tell the form that we are about to enter a click handler.
|
||||||
// that means that if there are scripted submissions, the
|
// that means that if there are scripted submissions, the
|
||||||
|
|
|
||||||
|
|
@ -143,11 +143,14 @@ namespace dom {
|
||||||
#define NS_ORIGINAL_CHECKED_VALUE (1 << 10)
|
#define NS_ORIGINAL_CHECKED_VALUE (1 << 10)
|
||||||
#define NS_NO_CONTENT_DISPATCH (1 << 11)
|
#define NS_NO_CONTENT_DISPATCH (1 << 11)
|
||||||
#define NS_ORIGINAL_INDETERMINATE_VALUE (1 << 12)
|
#define NS_ORIGINAL_INDETERMINATE_VALUE (1 << 12)
|
||||||
#define NS_CONTROL_TYPE(bits) ((bits) & ~( \
|
|
||||||
NS_OUTER_ACTIVATE_EVENT | NS_ORIGINAL_CHECKED_VALUE | NS_NO_CONTENT_DISPATCH | \
|
|
||||||
NS_ORIGINAL_INDETERMINATE_VALUE))
|
|
||||||
#define NS_PRE_HANDLE_BLUR_EVENT (1 << 13)
|
#define NS_PRE_HANDLE_BLUR_EVENT (1 << 13)
|
||||||
#define NS_PRE_HANDLE_INPUT_EVENT (1 << 14)
|
#define NS_PRE_HANDLE_INPUT_EVENT (1 << 14)
|
||||||
|
#define NS_IN_SUBMIT_CLICK (1 << 15)
|
||||||
|
#define NS_CONTROL_TYPE(bits) \
|
||||||
|
((bits) & ~(NS_OUTER_ACTIVATE_EVENT | NS_ORIGINAL_CHECKED_VALUE | \
|
||||||
|
NS_NO_CONTENT_DISPATCH | NS_ORIGINAL_INDETERMINATE_VALUE | \
|
||||||
|
NS_PRE_HANDLE_BLUR_EVENT | NS_PRE_HANDLE_INPUT_EVENT | \
|
||||||
|
NS_IN_SUBMIT_CLICK))
|
||||||
|
|
||||||
// whether textfields should be selected once focused:
|
// whether textfields should be selected once focused:
|
||||||
// -1: no, 1: yes, 0: uninitialized
|
// -1: no, 1: yes, 0: uninitialized
|
||||||
|
|
@ -3800,7 +3803,10 @@ HTMLInputElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
|
||||||
|
|
||||||
case NS_FORM_INPUT_SUBMIT:
|
case NS_FORM_INPUT_SUBMIT:
|
||||||
case NS_FORM_INPUT_IMAGE:
|
case NS_FORM_INPUT_IMAGE:
|
||||||
if (mForm) {
|
if (mForm && !aVisitor.mEvent->mFlags.mMultiplePreActionsPrevented) {
|
||||||
|
// Make sure other submit elements don't try to trigger submission.
|
||||||
|
aVisitor.mEvent->mFlags.mMultiplePreActionsPrevented = true;
|
||||||
|
aVisitor.mItemFlags |= NS_IN_SUBMIT_CLICK;
|
||||||
// tell the form that we are about to enter a click handler.
|
// tell the form that we are about to enter a click handler.
|
||||||
// that means that if there are scripted submissions, the
|
// that means that if there are scripted submissions, the
|
||||||
// latest one will be deferred until after the exit point of the handler.
|
// latest one will be deferred until after the exit point of the handler.
|
||||||
|
|
@ -4394,17 +4400,15 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outerActivateEvent) {
|
if ((aVisitor.mItemFlags & NS_IN_SUBMIT_CLICK) && mForm) {
|
||||||
switch(oldType) {
|
switch(oldType) {
|
||||||
case NS_FORM_INPUT_SUBMIT:
|
case NS_FORM_INPUT_SUBMIT:
|
||||||
case NS_FORM_INPUT_IMAGE:
|
case NS_FORM_INPUT_IMAGE:
|
||||||
if (mForm) {
|
|
||||||
// tell the form that we are about to exit a click handler
|
// tell the form that we are about to exit a click handler
|
||||||
// so the form knows not to defer subsequent submissions
|
// so the form knows not to defer subsequent submissions
|
||||||
// the pending ones that were created during the handler
|
// the pending ones that were created during the handler
|
||||||
// will be flushed or forgoten.
|
// will be flushed or forgoten.
|
||||||
mForm->OnSubmitClickEnd();
|
mForm->OnSubmitClickEnd();
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -4770,7 +4774,8 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||||
if (outerActivateEvent) {
|
if (outerActivateEvent) {
|
||||||
if (mForm && (oldType == NS_FORM_INPUT_SUBMIT ||
|
if (mForm && (oldType == NS_FORM_INPUT_SUBMIT ||
|
||||||
oldType == NS_FORM_INPUT_IMAGE)) {
|
oldType == NS_FORM_INPUT_IMAGE)) {
|
||||||
if (mType != NS_FORM_INPUT_SUBMIT && mType != NS_FORM_INPUT_IMAGE) {
|
if (mType != NS_FORM_INPUT_SUBMIT && mType != NS_FORM_INPUT_IMAGE &&
|
||||||
|
aVisitor.mItemFlags & NS_IN_SUBMIT_CLICK) {
|
||||||
// If the type has changed to a non-submit type, then we want to
|
// If the type has changed to a non-submit type, then we want to
|
||||||
// flush the stored submission if there is one (as if the submit()
|
// flush the stored submission if there is one (as if the submit()
|
||||||
// was allowed to succeed)
|
// was allowed to succeed)
|
||||||
|
|
@ -4809,7 +4814,7 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||||
break;
|
break;
|
||||||
} //switch
|
} //switch
|
||||||
} //click or outer activate event
|
} //click or outer activate event
|
||||||
} else if (outerActivateEvent &&
|
} else if ((aVisitor.mItemFlags & NS_IN_SUBMIT_CLICK) &&
|
||||||
(oldType == NS_FORM_INPUT_SUBMIT ||
|
(oldType == NS_FORM_INPUT_SUBMIT ||
|
||||||
oldType == NS_FORM_INPUT_IMAGE) &&
|
oldType == NS_FORM_INPUT_IMAGE) &&
|
||||||
mForm) {
|
mForm) {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "mozilla/EffectCompositor.h"
|
#include "mozilla/EffectCompositor.h"
|
||||||
#include "mozilla/EffectSet.h"
|
#include "mozilla/EffectSet.h"
|
||||||
#include "mozilla/EventDispatcher.h"
|
#include "mozilla/EventDispatcher.h"
|
||||||
|
#include "mozilla/EventStateManager.h"
|
||||||
#include "mozilla/FloatingPoint.h"
|
#include "mozilla/FloatingPoint.h"
|
||||||
#include "mozilla/gfx/gfxVars.h"
|
#include "mozilla/gfx/gfxVars.h"
|
||||||
#include "mozilla/gfx/PathHelpers.h"
|
#include "mozilla/gfx/PathHelpers.h"
|
||||||
|
|
@ -2255,6 +2256,59 @@ nsLayoutUtils::GetPopupFrameForEventCoordinates(nsPresContext* aPresContext,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsLayoutUtils::GetContainerAndOffsetAtEvent(nsIPresShell* aPresShell,
|
||||||
|
const WidgetEvent* aEvent,
|
||||||
|
nsIContent** aContainer,
|
||||||
|
int32_t* aOffset)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aContainer || aOffset);
|
||||||
|
|
||||||
|
if (aContainer) {
|
||||||
|
*aContainer = nullptr;
|
||||||
|
}
|
||||||
|
if (aOffset) {
|
||||||
|
*aOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!aPresShell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aPresShell->FlushPendingNotifications(Flush_Layout);
|
||||||
|
|
||||||
|
RefPtr<nsPresContext> presContext = aPresShell->GetPresContext();
|
||||||
|
if (!presContext) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIFrame* targetFrame = presContext->EventStateManager()->GetEventTarget();
|
||||||
|
if (!targetFrame) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPoint point =
|
||||||
|
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, targetFrame);
|
||||||
|
|
||||||
|
if (aContainer) {
|
||||||
|
// TODO: This result may be useful to change to Selection. However, this
|
||||||
|
// may return improper node (e.g., native anonymous node) for the
|
||||||
|
// Selection. Perhaps, this should take Selection optionally and
|
||||||
|
// if it's specified, needs to check if it's proper for the
|
||||||
|
// Selection.
|
||||||
|
nsCOMPtr<nsIContent> container =
|
||||||
|
targetFrame->GetContentOffsetsFromPoint(point).content;
|
||||||
|
if (container &&
|
||||||
|
(!container->ChromeOnlyAccess() ||
|
||||||
|
nsContentUtils::CanAccessNativeAnon())) {
|
||||||
|
container.forget(aContainer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (aOffset) {
|
||||||
|
*aOffset = targetFrame->GetContentOffsetsFromPoint(point).offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ConstrainToCoordValues(float& aStart, float& aSize)
|
static void ConstrainToCoordValues(float& aStart, float& aSize)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aSize >= 0);
|
MOZ_ASSERT(aSize >= 0);
|
||||||
|
|
|
||||||
|
|
@ -728,6 +728,21 @@ public:
|
||||||
nsPresContext* aPresContext,
|
nsPresContext* aPresContext,
|
||||||
const mozilla::WidgetEvent* aEvent);
|
const mozilla::WidgetEvent* aEvent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get container and offset if aEvent collapses Selection.
|
||||||
|
* @param aPresShell The PresShell handling aEvent.
|
||||||
|
* @param aEvent The event having coordinates where you want to
|
||||||
|
* collapse Selection.
|
||||||
|
* @param aContainer Returns the container node at the point.
|
||||||
|
* Set nullptr if you don't need this.
|
||||||
|
* @param aOffset Returns offset in the container node at the point.
|
||||||
|
* Set nullptr if you don't need this.
|
||||||
|
*/
|
||||||
|
static void GetContainerAndOffsetAtEvent(nsIPresShell* aPresShell,
|
||||||
|
const mozilla::WidgetEvent* aEvent,
|
||||||
|
nsIContent** aContainer,
|
||||||
|
int32_t* aOffset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate from widget coordinates to the view's coordinates
|
* Translate from widget coordinates to the view's coordinates
|
||||||
* @param aPresContext the PresContext for the view
|
* @param aPresContext the PresContext for the view
|
||||||
|
|
|
||||||
|
|
@ -118,8 +118,8 @@ nsHTMLButtonControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||||
|
|
||||||
nsDisplayListCollection set(aBuilder);
|
nsDisplayListCollection set(aBuilder);
|
||||||
|
|
||||||
// Do not allow the child subtree to receive events.
|
// HTMLInputElement buttons are opaque to hit tests, HTMLButtonElement buttons are not.
|
||||||
if (!isForEventDelivery) {
|
if (!(isForEventDelivery && this->IsInput())) {
|
||||||
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
||||||
|
|
||||||
if (ShouldClipPaintingToBorderBox()) {
|
if (ShouldClipPaintingToBorderBox()) {
|
||||||
|
|
|
||||||
|
|
@ -699,6 +699,16 @@ button {
|
||||||
justify-items: inherit;
|
justify-items: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@supports -moz-bool-pref("dom.forms.button.standards_compliant") {
|
||||||
|
/*
|
||||||
|
* Button content does historically not receive pointer events.
|
||||||
|
* This pref is enabled by default and can disabled to get Webkit behavior.
|
||||||
|
*/
|
||||||
|
button * {
|
||||||
|
pointer-events: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
button:hover,
|
button:hover,
|
||||||
input[type="color"]:-moz-system-metric(color-picker-available):hover,
|
input[type="color"]:-moz-system-metric(color-picker-available):hover,
|
||||||
input[type="reset"]:hover,
|
input[type="reset"]:hover,
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ extern "C" {
|
||||||
/* # include <sys/varargs.h> */
|
/* # include <sys/varargs.h> */
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#if !defined(XP_OS2) && !defined(DARWIN)
|
#if !defined(XP_OS2)
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
# endif /* defined( _WINDOWS ) */
|
# endif /* defined( _WINDOWS ) */
|
||||||
|
|
|
||||||
|
|
@ -1198,6 +1198,9 @@ pref("dom.forms.datetime.timepicker", false);
|
||||||
// TODO: implement/fix these.
|
// TODO: implement/fix these.
|
||||||
pref("dom.forms.datetime.others", false);
|
pref("dom.forms.datetime.others", false);
|
||||||
|
|
||||||
|
// <button> elements are opaque to pointer events.
|
||||||
|
pref("dom.forms.button.standards_compliant", true);
|
||||||
|
|
||||||
// Support for new @autocomplete values
|
// Support for new @autocomplete values
|
||||||
pref("dom.forms.autocomplete.experimental", false);
|
pref("dom.forms.autocomplete.experimental", false);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,8 @@ public:
|
||||||
// the first <label> element is clicked, that one may set this true.
|
// the first <label> element is clicked, that one may set this true.
|
||||||
// Then, the second <label> element won't handle the event.
|
// Then, the second <label> element won't handle the event.
|
||||||
bool mMultipleActionsPrevented : 1;
|
bool mMultipleActionsPrevented : 1;
|
||||||
|
// Similar to above but expected to be used during PreHandleEvent phase.
|
||||||
|
bool mMultiplePreActionsPrevented : 1;
|
||||||
// If mIsBeingDispatched is true, the DOM event created from the event is
|
// If mIsBeingDispatched is true, the DOM event created from the event is
|
||||||
// dispatching into the DOM tree and not completed.
|
// dispatching into the DOM tree and not completed.
|
||||||
bool mIsBeingDispatched : 1;
|
bool mIsBeingDispatched : 1;
|
||||||
|
|
|
||||||
|
|
@ -275,6 +275,10 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If during mouseup handling we detect that click event might need to be
|
||||||
|
// dispatched, this is setup to be the target of the click event.
|
||||||
|
nsCOMPtr<dom::EventTarget> mClickTarget;
|
||||||
|
|
||||||
// mReason indicates the reason why the event is fired:
|
// mReason indicates the reason why the event is fired:
|
||||||
// - Representing mouse operation.
|
// - Representing mouse operation.
|
||||||
// - Synthesized for emulating mousemove event when the content under the
|
// - Synthesized for emulating mousemove event when the content under the
|
||||||
|
|
|
||||||
|
|
@ -2905,7 +2905,7 @@ static NSMutableSet *gSwizzledFrameViewClasses = nil;
|
||||||
[super initWithContentRect:aContentRect styleMask:aStyle backing:aBufferingType defer:aFlag];
|
[super initWithContentRect:aContentRect styleMask:aStyle backing:aBufferingType defer:aFlag];
|
||||||
// MacOS 13 Ventura, doesn't seem to create the contentView... so create it ourselves
|
// MacOS 13 Ventura, doesn't seem to create the contentView... so create it ourselves
|
||||||
if(![super contentView]) {
|
if(![super contentView]) {
|
||||||
[super setContentView:[[NSView alloc] initWithFrame:aContentRect]];
|
[super setContentView:[[[NSView alloc] initWithFrame:aContentRect] autorelease]];
|
||||||
}
|
}
|
||||||
mState = nil;
|
mState = nil;
|
||||||
mActiveTitlebarColor = nil;
|
mActiveTitlebarColor = nil;
|
||||||
|
|
@ -3213,64 +3213,6 @@ static const NSString* kStateCollectionBehavior = @"collectionBehavior";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override methods that translate between content rect and frame rect.
|
|
||||||
- (NSRect)contentRectForFrameRect:(NSRect)aRect
|
|
||||||
{
|
|
||||||
if ([self drawsContentsIntoWindowFrame]) {
|
|
||||||
return aRect;
|
|
||||||
}
|
|
||||||
return [super contentRectForFrameRect:aRect];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSRect)contentRectForFrameRect:(NSRect)aRect styleMask:(NSUInteger)aMask
|
|
||||||
{
|
|
||||||
if ([self drawsContentsIntoWindowFrame]) {
|
|
||||||
return aRect;
|
|
||||||
}
|
|
||||||
if ([super respondsToSelector:@selector(contentRectForFrameRect:styleMask:)]) {
|
|
||||||
return [super contentRectForFrameRect:aRect styleMask:aMask];
|
|
||||||
} else {
|
|
||||||
return [NSWindow contentRectForFrameRect:aRect styleMask:aMask];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSRect)frameRectForContentRect:(NSRect)aRect
|
|
||||||
{
|
|
||||||
if ([self drawsContentsIntoWindowFrame]) {
|
|
||||||
return aRect;
|
|
||||||
}
|
|
||||||
return [super frameRectForContentRect:aRect];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSRect)frameRectForContentRect:(NSRect)aRect styleMask:(NSUInteger)aMask
|
|
||||||
{
|
|
||||||
if ([self drawsContentsIntoWindowFrame]) {
|
|
||||||
return aRect;
|
|
||||||
}
|
|
||||||
if ([super respondsToSelector:@selector(frameRectForContentRect:styleMask:)]) {
|
|
||||||
return [super frameRectForContentRect:aRect styleMask:aMask];
|
|
||||||
} else {
|
|
||||||
return [NSWindow frameRectForContentRect:aRect styleMask:aMask];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setContentView:(NSView*)aView
|
|
||||||
{
|
|
||||||
[super setContentView:aView];
|
|
||||||
|
|
||||||
// Now move the contentView to the bottommost layer so that it's guaranteed
|
|
||||||
// to be under the window buttons.
|
|
||||||
NSView* frameView = [aView superview];
|
|
||||||
[aView removeFromSuperview];
|
|
||||||
if ([frameView respondsToSelector:@selector(_addKnownSubview:positioned:relativeTo:)]) {
|
|
||||||
// 10.10 prints a warning when we call addSubview on the frame view, so we
|
|
||||||
// silence the warning by calling a private method instead.
|
|
||||||
[frameView _addKnownSubview:aView positioned:NSWindowBelow relativeTo:nil];
|
|
||||||
} else {
|
|
||||||
[frameView addSubview:aView positioned:NSWindowBelow relativeTo:nil];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray*)titlebarControls
|
- (NSArray*)titlebarControls
|
||||||
{
|
{
|
||||||
// Return all subviews of the frameView which are not the content view.
|
// Return all subviews of the frameView which are not the content view.
|
||||||
|
|
@ -3504,6 +3446,64 @@ static const NSString* kStateCollectionBehavior = @"collectionBehavior";
|
||||||
return NSMaxY(frameRect) - NSMaxY(originalContentRect);
|
return NSMaxY(frameRect) - NSMaxY(originalContentRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Override methods that translate between content rect and frame rect.
|
||||||
|
- (NSRect)contentRectForFrameRect:(NSRect)aRect
|
||||||
|
{
|
||||||
|
if ([self drawsContentsIntoWindowFrame]) {
|
||||||
|
return aRect;
|
||||||
|
}
|
||||||
|
return [super contentRectForFrameRect:aRect];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSRect)contentRectForFrameRect:(NSRect)aRect styleMask:(NSUInteger)aMask
|
||||||
|
{
|
||||||
|
if ([self drawsContentsIntoWindowFrame]) {
|
||||||
|
return aRect;
|
||||||
|
}
|
||||||
|
if ([super respondsToSelector:@selector(contentRectForFrameRect:styleMask:)]) {
|
||||||
|
return [super contentRectForFrameRect:aRect styleMask:aMask];
|
||||||
|
} else {
|
||||||
|
return [NSWindow contentRectForFrameRect:aRect styleMask:aMask];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSRect)frameRectForContentRect:(NSRect)aRect
|
||||||
|
{
|
||||||
|
if ([self drawsContentsIntoWindowFrame]) {
|
||||||
|
return aRect;
|
||||||
|
}
|
||||||
|
return [super frameRectForContentRect:aRect];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSRect)frameRectForContentRect:(NSRect)aRect styleMask:(NSUInteger)aMask
|
||||||
|
{
|
||||||
|
if ([self drawsContentsIntoWindowFrame]) {
|
||||||
|
return aRect;
|
||||||
|
}
|
||||||
|
if ([super respondsToSelector:@selector(frameRectForContentRect:styleMask:)]) {
|
||||||
|
return [super frameRectForContentRect:aRect styleMask:aMask];
|
||||||
|
} else {
|
||||||
|
return [NSWindow frameRectForContentRect:aRect styleMask:aMask];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setContentView:(NSView*)aView
|
||||||
|
{
|
||||||
|
[super setContentView:aView];
|
||||||
|
|
||||||
|
// Now move the contentView to the bottommost layer so that it's guaranteed
|
||||||
|
// to be under the window buttons.
|
||||||
|
NSView* frameView = [aView superview];
|
||||||
|
[aView removeFromSuperview];
|
||||||
|
if ([frameView respondsToSelector:@selector(_addKnownSubview:positioned:relativeTo:)]) {
|
||||||
|
// 10.10 prints a warning when we call addSubview on the frame view, so we
|
||||||
|
// silence the warning by calling a private method instead.
|
||||||
|
[frameView _addKnownSubview:aView positioned:NSWindowBelow relativeTo:nil];
|
||||||
|
} else {
|
||||||
|
[frameView addSubview:aView positioned:NSWindowBelow relativeTo:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Stores the complete height of titlebar + toolbar.
|
// Stores the complete height of titlebar + toolbar.
|
||||||
- (void)setUnifiedToolbarHeight:(CGFloat)aHeight
|
- (void)setUnifiedToolbarHeight:(CGFloat)aHeight
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -478,6 +478,7 @@ STUB(gtk_widget_unparent)
|
||||||
STUB(gtk_window_deiconify)
|
STUB(gtk_window_deiconify)
|
||||||
STUB(gtk_window_fullscreen)
|
STUB(gtk_window_fullscreen)
|
||||||
STUB(gtk_window_get_group)
|
STUB(gtk_window_get_group)
|
||||||
|
STUB(gtk_window_get_modal)
|
||||||
STUB(gtk_window_get_transient_for)
|
STUB(gtk_window_get_transient_for)
|
||||||
STUB(gtk_window_get_type)
|
STUB(gtk_window_get_type)
|
||||||
STUB(gtk_window_get_type_hint)
|
STUB(gtk_window_get_type_hint)
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,11 @@ NS_IMETHODIMP nsColorPicker::Open(nsIColorPickerShownCallback *aColorPickerShown
|
||||||
GtkWidget* color_chooser = gtk_color_chooser_dialog_new(title, parent_window);
|
GtkWidget* color_chooser = gtk_color_chooser_dialog_new(title, parent_window);
|
||||||
|
|
||||||
if (parent_window) {
|
if (parent_window) {
|
||||||
gtk_window_set_destroy_with_parent(GTK_WINDOW(color_chooser), TRUE);
|
GtkWindow *window = GTK_WINDOW(color_chooser);
|
||||||
|
gtk_window_set_destroy_with_parent(window, TRUE);
|
||||||
|
if (gtk_window_get_modal(parent_window)) {
|
||||||
|
gtk_window_set_modal(window, TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(color_chooser), FALSE);
|
gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(color_chooser), FALSE);
|
||||||
|
|
@ -117,6 +121,9 @@ NS_IMETHODIMP nsColorPicker::Open(nsIColorPickerShownCallback *aColorPickerShown
|
||||||
GtkWindow *window = GTK_WINDOW(color_chooser);
|
GtkWindow *window = GTK_WINDOW(color_chooser);
|
||||||
gtk_window_set_transient_for(window, parent_window);
|
gtk_window_set_transient_for(window, parent_window);
|
||||||
gtk_window_set_destroy_with_parent(window, TRUE);
|
gtk_window_set_destroy_with_parent(window, TRUE);
|
||||||
|
if (gtk_window_get_modal(parent_window)) {
|
||||||
|
gtk_window_set_modal(window, TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GdkColor color_gdk = convertToGdkColor(color);
|
GdkColor color_gdk = convertToGdkColor(color);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue