diff --git a/mobile/chrome/content/InputHandler.js b/mobile/chrome/content/InputHandler.js index 51cd01aa1b81..6bb6025817a0 100644 --- a/mobile/chrome/content/InputHandler.js +++ b/mobile/chrome/content/InputHandler.js @@ -374,6 +374,14 @@ InputHandler.EventInfo.prototype = { * dragMove(dx, dy, scroller) * Signals an input attempt to drag by dx, dy. * + * Optionally, a custom dragger may define a boolean property + * + * allowRealtimeDownUp + * + * that, when true, will prevent the mousedown and mouseup events corresponding + * to the beginning and end of a drag from being swallowed (propagation stopped + * and default prevented) by the MouseModule. + * * Between mousedown and mouseup, MouseModule incrementally drags and updates * the dragger accordingly, and also determines whether a [double-]click occured * (based on whether the input moves have moved outside of a certain drag disk @@ -473,8 +481,10 @@ MouseModule.prototype = { : null; this._clicker = (targetClicker) ? targetClicker.customClicker : null; - evInfo.event.stopPropagation(); - evInfo.event.preventDefault(); + if (this._dragger && !this._dragger.allowRealtimeDownUp) { + evInfo.event.stopPropagation(); + evInfo.event.preventDefault(); + } this._owner.grab(this); @@ -497,19 +507,21 @@ MouseModule.prototype = { _onMouseUp: function _onMouseUp(evInfo) { let dragData = this._dragData; - evInfo.event.stopPropagation(); - evInfo.event.preventDefault(); + if (this._dragger && !this._dragger.allowRealtimeDownUp) { + evInfo.event.stopPropagation(); + evInfo.event.preventDefault(); - // we are swallowing mousedown and mouseup, so we should swallow their - // potential corresponding click, too - this._owner.suppressNextClick(); + // we have swallowed mousedown and mouseup, so we should swallow their + // potential corresponding click, too + this._owner.suppressNextClick(); + } let [sX, sY] = [evInfo.event.screenX, evInfo.event.screenY]; let movedOutOfRadius = dragData.isPointOutsideRadius(sX, sY); - if (dragData.dragging) - this._doDragStop(sX, sY); + if (dragData.dragging) // XXX same check as this._dragger but we + this._doDragStop(sX, sY); // are using both, no good reason this._recordEvent(evInfo); @@ -558,6 +570,10 @@ MouseModule.prototype = { this._owner.startListening(); }, + _skipAllDownUpEvents: function _skipAllDownUpEvents() { + this._downUpDispatchedIndex = this._downUpEvents.length; + }, + /** * Helper function to _redispatchDownUpEvents() that sends a single DOM mouse * event to the Fennec global chrome window. @@ -662,12 +678,17 @@ MouseModule.prototype = { */ _doClick: function _doClick(movedOutOfRadius) { let commitToClicker = this._clicker && !movedOutOfRadius; + let needToRedispatch = this._dragger && !this._dragger.allowRealtimeDownUp && !movedOutOfRadius; if (commitToClicker) { this._commitAnotherClick(); // commit this click to the doubleclick timewait buffer } - this._redispatchDownUpEvents(); + if (needToRedispatch) { + this._redispatchDownUpEvents(); + } else { + this._skipAllDownUpEvents(); + } if (!commitToClicker) { this._cleanClickBuffer(); // clean the click buffer ourselves, since there was no clicker diff --git a/mobile/chrome/content/browser-ui.js b/mobile/chrome/content/browser-ui.js index c08c3b1832f3..0f2fa2784fe4 100644 --- a/mobile/chrome/content/browser-ui.js +++ b/mobile/chrome/content/browser-ui.js @@ -884,7 +884,7 @@ var SelectHelper = { this._list.setAttribute("multiple", this._control.multiple ? "true" : "false"); let firstSelected = null; - + let optionIndex = 0; let children = this._control.children; for (let i=0; i visibleItemsCount) { diff --git a/mobile/chrome/content/browser.js b/mobile/chrome/content/browser.js index 9947daefc0a4..3d977fc9a9fe 100644 --- a/mobile/chrome/content/browser.js +++ b/mobile/chrome/content/browser.js @@ -353,6 +353,7 @@ var Browser = { let controlsScrollbox = this.controlsScrollbox = document.getElementById("scrollbox"); this.controlsScrollboxScroller = controlsScrollbox.boxObject.QueryInterface(Ci.nsIScrollBoxObject); controlsScrollbox.customDragger = { + allowRealtimeDownUp: true, dragStart: function dragStart(cx, cy, target, scroller) {}, dragStop: function dragStop(dx, dy, scroller) { return false; }, dragMove: function dragMove(dx, dy, scroller) { return false; } @@ -1241,6 +1242,8 @@ var Browser = { }; Browser.MainDragger = function MainDragger(browserView) { + this.allowRealtimeDownUp = true; + this.scrollingOuterX = true; this.bv = browserView; this.floatedWhileDragging = false; @@ -1847,7 +1850,7 @@ const gPopupBlockerObserver = { gPrefService.setBoolPref("privacy.popups.showBrowserMessage", !showMessage); Browser.getNotificationBox().removeCurrentNotification(); }, - + showPopupsForSite: function showPopupsForSite() { let uri = Browser.selectedBrowser.currentURI; let pageReport = Browser.selectedBrowser.pageReport; @@ -1863,10 +1866,10 @@ const gPopupBlockerObserver = { if (popupURIspec == "" || popupURIspec == "about:blank" || popupURIspec == uri.spec) continue; - + let popupFeatures = pageReport[i].popupWindowFeatures; let popupName = pageReport[i].popupWindowName; - + Browser.addTab(popupURIspec, false); } }