author | Morris Tseng <mtseng@mozilla.com> |
Tue, 07 Oct 2014 02:28:00 -0400 | |
changeset 209648 | 5d276cd3759b7a1abdba67badd95d986c8a47d23 |
parent 209647 | 52b5b862e170fb0231402eb5484f0dcbdb5659b9 |
child 209649 | ea71dddb40aa31514c686c0de5c7616f40a0a64f |
push id | 27619 |
push user | kwierso@gmail.com |
push date | Thu, 09 Oct 2014 23:42:28 +0000 |
treeherder | mozilla-central@c0a98d9b9a33 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | ehsan |
bugs | 1067231 |
milestone | 35.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -328,16 +328,17 @@ var shell = { window.addEventListener('MozApplicationManifest', this); window.addEventListener('mozfullscreenchange', this); window.addEventListener('MozAfterPaint', this); window.addEventListener('sizemodechange', this); window.addEventListener('unload', this); 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(); UserAgentOverrides.init(); IndexedDBPromptHelper.init(); CaptivePortalLoginHelper.init(); this.contentBrowser.src = homeURL; @@ -356,16 +357,17 @@ var shell = { window.removeEventListener('keypress', this, true); window.removeEventListener('keyup', this, true); window.removeEventListener('MozApplicationManifest', this); window.removeEventListener('mozfullscreenchange', this); window.removeEventListener('sizemodechange', this); 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(); IndexedDBPromptHelper.uninit(); }, // If this key event actually represents a hardware button, filter it here // and send a mozChromeEvent with detail.type set to xxx-button-press or @@ -503,16 +505,22 @@ var shell = { this.notifyContentStart(); break; case 'mozbrowserscrollviewchange': this.sendChromeEvent({ type: 'scrollviewchange', 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 // based on tab's coordinate. So get the actual offsets between shell and evt.target. let elt = evt.target; let win = elt.ownerDocument.defaultView; let offsetX = win.mozInnerScreenX - window.mozInnerScreenX; let offsetY = win.mozInnerScreenY - window.mozInnerScreenY;
--- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -221,16 +221,22 @@ BrowserElementChild.prototype = { /* useCapture = */ false, /* wantsUntrusted = */ false); addEventListener('scrollviewchange', this._ScrollViewChangeHandler.bind(this), /* 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 // useCapture == true, we /would/ hear unload events from the window, which // is not what we want! addEventListener('unload', this._unloadHandler.bind(this), /* useCapture = */ false, @@ -626,16 +632,21 @@ BrowserElementChild.prototype = { if (lang) { meta.lang = lang; } sendAsyncMsg('metachange', meta); }, + _touchCaretTapHandler: function(e) { + e.stopPropagation(); + sendAsyncMsg('touchcarettap'); + }, + _ScrollViewChangeHandler: function(e) { e.stopPropagation(); let detail = { state: e.state, scrollX: e.scrollX, scrollY: e.scrollY, }; sendAsyncMsg('scrollviewchange', detail);
--- a/dom/browser-element/BrowserElementParent.jsm +++ b/dom/browser-element/BrowserElementParent.jsm @@ -253,17 +253,18 @@ BrowserElementParent.prototype = { "got-can-go-forward": this._gotDOMRequestResult, "fullscreen-origin-change": this._remoteFullscreenOriginChange, "rollback-fullscreen": this._remoteFrameFullscreenReverted, "exit-fullscreen": this._exitFullscreen, "got-visible": this._gotDOMRequestResult, "visibilitychange": this._childVisibilityChange, "got-set-input-method-active": this._gotDOMRequestResult, "selectionchange": this._handleSelectionChange, - "scrollviewchange": this._handleScrollViewChange + "scrollviewchange": this._handleScrollViewChange, + "touchcarettap": this._handleTouchCaretTap }; let mmSecuritySensitiveCalls = { "showmodalprompt": this._handleShowModalPrompt, "contextmenu": this._fireCtxMenuEvent, "securitychange": this._fireEventFromMsg, "locationchange": this._fireEventFromMsg, "iconchange": this._fireEventFromMsg, @@ -500,16 +501,22 @@ BrowserElementParent.prototype = { }, _handleScrollViewChange: function(data) { let evt = this._createEvent("scrollviewchange", data.json, /* cancelable = */ false); 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. if (detail !== undefined && detail !== null) { detail = Cu.cloneInto(detail, this._window); return new this._window.CustomEvent('mozbrowser' + evtName, { bubbles: true, cancelable: cancelable,
--- a/layout/base/TouchCaret.cpp +++ b/layout/base/TouchCaret.cpp @@ -25,16 +25,17 @@ #include "mozilla/Preferences.h" #include "mozilla/BasicEvents.h" #include "nsIDOMWindow.h" #include "nsQueryContentEventResult.h" #include "nsIInterfaceRequestorUtils.h" #include "nsView.h" #include "nsDOMTokenList.h" #include "nsCaret.h" +#include "mozilla/dom/CustomEvent.h" using namespace mozilla; // To enable all the TOUCHCARET_LOG print statements, change the 0 to 1 in the // following #define. #define ENABLE_TOUCHCARET_LOG 0 #if ENABLE_TOUCHCARET_LOG @@ -53,17 +54,18 @@ NS_IMPL_ISUPPORTS(TouchCaret, nsISelecti /*static*/ int32_t TouchCaret::sTouchCaretInflateSize = 0; /*static*/ int32_t TouchCaret::sTouchCaretExpirationTime = 0; 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()); static bool addedTouchCaretPref = false; if (!addedTouchCaretPref) { Preferences::AddIntVarCache(&sTouchCaretInflateSize, "touchcaret.inflatesize.threshold"); @@ -596,16 +598,17 @@ TouchCaret::HandleMouseMoveEvent(WidgetM case TOUCHCARET_MOUSEDRAG_ACTIVE: { nsPoint movePoint = GetEventPosition(aEvent); movePoint.y += mCaretCenterToDownPointOffsetY; nsRect contentBoundary = GetContentBoundary(); movePoint = contentBoundary.ClampPoint(movePoint); MoveCaret(movePoint); + mIsValidTap = false; status = nsEventStatus_eConsumeNoDefault; } break; case TOUCHCARET_TOUCHDRAG_ACTIVE: case TOUCHCARET_TOUCHDRAG_INACTIVE: // Consume mouse event in touch sequence. status = nsEventStatus_eConsumeNoDefault; @@ -633,16 +636,17 @@ TouchCaret::HandleTouchMoveEvent(WidgetT case TOUCHCARET_TOUCHDRAG_ACTIVE: { nsPoint movePoint = GetEventPosition(aEvent, mActiveTouchId); movePoint.y += mCaretCenterToDownPointOffsetY; nsRect contentBoundary = GetContentBoundary(); movePoint = contentBoundary.ClampPoint(movePoint); MoveCaret(movePoint); + mIsValidTap = false; status = nsEventStatus_eConsumeNoDefault; } break; case TOUCHCARET_TOUCHDRAG_INACTIVE: // Consume NS_TOUCH_MOVE event in TOUCHCARET_TOUCHDRAG_INACTIVE state. status = nsEventStatus_eConsumeNoDefault; break; @@ -844,16 +848,45 @@ TouchCaret::HandleTouchDownEvent(WidgetT mTouchesId.AppendElement(aEvent->touches[i]->mIdentifier); } } 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) { TOUCHCARET_LOG("state changed from %d to %d", mState, aState); if (mState == TOUCHCARET_NONE) { MOZ_ASSERT(aState != TOUCHCARET_TOUCHDRAG_INACTIVE, "mState: NONE => TOUCHDRAG_INACTIVE isn't allowed!"); } @@ -874,10 +907,17 @@ TouchCaret::SetState(TouchCaretState aSt "TOUCHDRAG_INACTIVE allowed next state: NONE!"); } mState = 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; } }
--- a/layout/base/TouchCaret.h +++ b/layout/base/TouchCaret.h @@ -205,16 +205,21 @@ private: }; /** * Do actual state transition and reset substates. */ void SetState(TouchCaretState aState); /** + * Dispatch touch caret tap event to chrome. + */ + void DispatchTapEvent(); + + /** * Current state we're dealing with. */ TouchCaretState mState; /** * Array containing all active touch IDs. When a touch happens, it gets added * to this array, even if we choose not to handle it. When it ends, we remove * it. We need to maintain this array in order to detect the end of the @@ -244,16 +249,18 @@ private: { return sTouchCaretExpirationTime; } nsWeakPtr mPresShell; // Touch caret visibility bool mVisible; + // Use for detecting single tap on touch caret. + bool mIsValidTap; // Touch caret timer nsCOMPtr<nsITimer> mTouchCaretExpirationTimer; // Preference static int32_t sTouchCaretInflateSize; static int32_t sTouchCaretExpirationTime; // The auto scroll timer's interval in miliseconds.