Bug 1027631 - Send touch caret tap event. r=ehsan

This commit is contained in:
Morris Tseng 2014-10-07 02:28:00 -04:00
parent 05409ccb0a
commit 43772ef2d4
5 changed files with 75 additions and 2 deletions

View File

@ -333,6 +333,7 @@ var shell = {
this.contentBrowser.addEventListener('mozbrowserloadstart', this, true);
this.contentBrowser.addEventListener('mozbrowserselectionchange', this, true);
this.contentBrowser.addEventListener('mozbrowserscrollviewchange', this, true);
this.contentBrowser.addEventListener('mozbrowsertouchcarettap', this, true);
CustomEventManager.init();
WebappsHelper.init();
@ -361,6 +362,7 @@ var shell = {
this.contentBrowser.removeEventListener('mozbrowserloadstart', this, true);
this.contentBrowser.removeEventListener('mozbrowserselectionchange', this, true);
this.contentBrowser.removeEventListener('mozbrowserscrollviewchange', this, true);
this.contentBrowser.removeEventListener('mozbrowsertouchcarettap', this, true);
ppmm.removeMessageListener("content-handler", this);
UserAgentOverrides.uninit();
@ -508,6 +510,12 @@ var shell = {
detail: evt.detail,
});
break;
case 'mozbrowsertouchcarettap':
this.sendChromeEvent({
type: 'touchcarettap',
detail: evt.detail,
});
break;
case 'mozbrowserselectionchange':
// The mozbrowserselectionchange event, may have crossed the chrome-content boundary.
// This event always dispatch to shell.js. But the offset we got from this event is

View File

@ -226,6 +226,12 @@ BrowserElementChild.prototype = {
/* useCapture = */ false,
/* wantsUntrusted = */ false);
addEventListener('touchcarettap',
this._touchCaretTapHandler.bind(this),
/* useCapture = */ false,
/* wantsUntrusted = */ false);
// This listens to unload events from our message manager, but /not/ from
// the |content| window. That's because the window's unload event doesn't
// bubble, and we're not using a capturing listener. If we'd used
@ -631,6 +637,11 @@ BrowserElementChild.prototype = {
sendAsyncMsg('metachange', meta);
},
_touchCaretTapHandler: function(e) {
e.stopPropagation();
sendAsyncMsg('touchcarettap');
},
_ScrollViewChangeHandler: function(e) {
e.stopPropagation();
let detail = {

View File

@ -258,7 +258,8 @@ BrowserElementParent.prototype = {
"visibilitychange": this._childVisibilityChange,
"got-set-input-method-active": this._gotDOMRequestResult,
"selectionchange": this._handleSelectionChange,
"scrollviewchange": this._handleScrollViewChange
"scrollviewchange": this._handleScrollViewChange,
"touchcarettap": this._handleTouchCaretTap
};
let mmSecuritySensitiveCalls = {
@ -505,6 +506,12 @@ BrowserElementParent.prototype = {
this._frameElement.dispatchEvent(evt);
},
_handleTouchCaretTap: function(data) {
let evt = this._createEvent("touchcarettap", data.json,
/* cancelable = */ false);
this._frameElement.dispatchEvent(evt);
},
_createEvent: function(evtName, detail, cancelable) {
// This will have to change if we ever want to send a CustomEvent with null
// detail. For now, it's OK.

View File

@ -30,6 +30,7 @@
#include "nsView.h"
#include "nsDOMTokenList.h"
#include "nsCaret.h"
#include "mozilla/dom/CustomEvent.h"
using namespace mozilla;
@ -58,7 +59,8 @@ TouchCaret::TouchCaret(nsIPresShell* aPresShell)
: mState(TOUCHCARET_NONE),
mActiveTouchId(-1),
mCaretCenterToDownPointOffsetY(0),
mVisible(false)
mVisible(false),
mIsValidTap(false)
{
TOUCHCARET_LOG("Constructor, PresShell=%p", aPresShell);
MOZ_ASSERT(NS_IsMainThread());
@ -601,6 +603,7 @@ TouchCaret::HandleMouseMoveEvent(WidgetMouseEvent* aEvent)
movePoint = contentBoundary.ClampPoint(movePoint);
MoveCaret(movePoint);
mIsValidTap = false;
status = nsEventStatus_eConsumeNoDefault;
}
break;
@ -638,6 +641,7 @@ TouchCaret::HandleTouchMoveEvent(WidgetTouchEvent* aEvent)
movePoint = contentBoundary.ClampPoint(movePoint);
MoveCaret(movePoint);
mIsValidTap = false;
status = nsEventStatus_eConsumeNoDefault;
}
break;
@ -848,6 +852,35 @@ TouchCaret::HandleTouchDownEvent(WidgetTouchEvent* aEvent)
return status;
}
void
TouchCaret::DispatchTapEvent()
{
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
if (!presShell) {
return;
}
nsCOMPtr<nsIDocument> doc = presShell->GetDocument();
if (!doc) {
return;
}
ErrorResult res;
nsRefPtr<Event> domEvent =
doc->CreateEvent(NS_LITERAL_STRING("CustomEvent"), res);
if (res.Failed()) {
return;
}
CustomEvent* customEvent = static_cast<CustomEvent*>(domEvent.get());
customEvent->InitCustomEvent(NS_LITERAL_STRING("touchcarettap"),
true, false, nullptr);
customEvent->SetTrusted(true);
customEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
bool ret;
doc->DispatchEvent(domEvent, &ret);
}
void
TouchCaret::SetState(TouchCaretState aState)
{
@ -879,5 +912,12 @@ TouchCaret::SetState(TouchCaretState aState)
if (mState == TOUCHCARET_NONE) {
mActiveTouchId = -1;
mCaretCenterToDownPointOffsetY = 0;
if (mIsValidTap) {
DispatchTapEvent();
mIsValidTap = false;
}
} else if (mState == TOUCHCARET_TOUCHDRAG_ACTIVE ||
mState == TOUCHCARET_MOUSEDRAG_ACTIVE) {
mIsValidTap = true;
}
}

View File

@ -209,6 +209,11 @@ private:
*/
void SetState(TouchCaretState aState);
/**
* Dispatch touch caret tap event to chrome.
*/
void DispatchTapEvent();
/**
* Current state we're dealing with.
*/
@ -249,6 +254,8 @@ private:
// Touch caret visibility
bool mVisible;
// Use for detecting single tap on touch caret.
bool mIsValidTap;
// Touch caret timer
nsCOMPtr<nsITimer> mTouchCaretExpirationTimer;