Bug 597286, part 8: Create new longtap event and use it to bring up context menus [r=mbrubeck]

This commit is contained in:
Benjamin Stover 2010-09-22 15:12:41 -07:00
parent cab4c0015e
commit 2817ccff66
4 changed files with 53 additions and 20 deletions

View File

@ -46,7 +46,7 @@
const kDoubleClickInterval = 400;
// Amount of time to wait before tap becomes long tap
const kLongTapWait = 700;
const kLongTapWait = 500;
// If a tap lasts longer than this duration in ms, treat it as a single-tap
// immediately instead of waiting for a possible double tap.
@ -581,7 +581,7 @@ MouseModule.prototype = {
let ev = this._downUpEvents[0];
let event = document.createEvent("Events");
event.initEvent("LongTap", true, false);
event.initEvent("TapLong", true, false);
event.clientX = ev.clientX;
event.clientY = ev.clientY;
ev.target.dispatchEvent(event);

View File

@ -417,7 +417,6 @@ var BrowserUI = {
messageManager.addMessageListener("Browser:Highlight", this);
messageManager.addMessageListener("Browser:OpenURI", this);
messageManager.addMessageListener("Browser:ContextMenu", ContextHelper);
messageManager.addMessageListener("Browser:SaveAs:Return", this);
// listening mousedown for automatically dismiss some popups (e.g. larry)
@ -2369,11 +2368,7 @@ var ContextHelper = {
return this._popup = document.getElementById("context-popup");
},
showPopup: function ch_showPopup(aData) {
this.receiveMessage(aData);
},
receiveMessage: function ch_receiveMessage(aMessage) {
showPopup: function ch_showPopup(aMessage) {
this.popupState = aMessage.json;
this.popupState.target = aMessage.target;
@ -2398,7 +2393,7 @@ var ContextHelper = {
if (!first) {
this.popupState = null;
return;
return false;
}
// Allow the first and last *non-hidden* elements to be selected in CSS.
@ -2413,6 +2408,7 @@ var ContextHelper = {
this.sizeToContent();
BrowserUI.pushPopup(this, [this._popup]);
return true;
},
hide: function ch_hide() {

View File

@ -1269,7 +1269,22 @@ const ContentTouchHandler = {
document.addEventListener("TapUp", this, false);
document.addEventListener("TapSingle", this, false);
document.addEventListener("TapDouble", this, false);
document.addEventListener("TapLong", this, false);
document.addEventListener("PanBegin", this, false);
document.addEventListener("PopupChanged", this._popupChanged.bind(this), false);
// Context menus have the following flow:
// [parent] mousedown -> TapDown -> Browser:MouseDown
// [child] Browser:MouseDown -> contextmenu -> Browser:ContextMenu
// [parent] Browser:ContextMenu -> ...* -> TapLong
//
// * = Here some time will elapse. Although we get the context menu we need
// ASAP, we do not act on the context menu until we receive a LongTap.
// This is so we can show the context menu as soon as we know it is
// a long tap, without waiting for child process.
//
messageManager.addMessageListener("Browser:ContextMenu", this);
},
handleEvent: function handleEvent(ev) {
@ -1292,12 +1307,24 @@ const ContentTouchHandler = {
case "TapDouble":
this.tapDouble(ev.clientX1, ev.clientY1, ev.clientX2, ev.clientY2);
break;
case "TapLong":
this.tapLong();
break;
case "PanBegin":
this.panBegin();
break;
}
},
receiveMessage: function receiveMessage(aMessage) {
this._contextMenu = { name: aMessage.name, json: aMessage.json, target: aMessage.target };
},
_popupChanged: function _popupChanged() {
TapHighlightHelper.hide(200);
this._contextMenu = null;
},
/**
* Check if the event concern the browser content
*/
@ -1329,15 +1356,19 @@ const ContentTouchHandler = {
tapUp: function tapUp(aX, aY) {
TapHighlightHelper.hide(200);
this._contextMenu = null;
},
panBegin: function panBegin() {
TapHighlightHelper.hide(0);
this._contextMenu = null;
this._dispatchMouseEvent("Browser:MouseCancel");
},
tapSingle: function tapSingle(aX, aY, aModifiers) {
TapHighlightHelper.hide(200);
this._contextMenu = null;
// Cancel the mouse click if we are showing a context menu
if (!ContextHelper.popupState)
@ -1347,6 +1378,8 @@ const ContentTouchHandler = {
tapDouble: function tapDouble(aX1, aY1, aX2, aY2) {
TapHighlightHelper.hide();
this._contextMenu = null;
this._dispatchMouseEvent("Browser:MouseCancel");
@ -1360,6 +1393,16 @@ const ContentTouchHandler = {
this._dispatchMouseEvent("Browser:ZoomToPoint", aX1, aY1);
},
tapLong: function tapLong() {
if (this._contextMenu) {
TapHighlightHelper.hide();
if (ContextHelper.showPopup(this._contextMenu))
// Stop all input sequences
ih.cancelPending();
this._contextMenu = null;
}
},
toString: function toString() {
return "[ContentTouchHandler] { }";
}

View File

@ -315,7 +315,6 @@ function Content() {
this._progressController.start();
this._formAssistant = new FormAssistant();
this._contextTimeout = new Util.Timeout();
}
Content.prototype = {
@ -375,9 +374,7 @@ Content.prototype = {
}
break;
case "Browser:MouseDown":
this._contextTimeout.clear();
case "Browser:MouseDown": {
let element = elementFromPoint(x, y);
if (!element)
return;
@ -387,12 +384,11 @@ Content.prototype = {
sendAsyncMessage("Browser:Highlight", { rects: rects });
}
this._contextTimeout.once(500, function() {
let event = content.document.createEvent("PopupEvents");
event.initEvent("contextmenu", true, true);
element.dispatchEvent(event);
});
let event = content.document.createEvent("PopupEvents");
event.initEvent("contextmenu", true, true);
element.dispatchEvent(event);
break;
}
case "Browser:MouseUp": {
let element = elementFromPoint(x, y);
@ -410,7 +406,6 @@ Content.prototype = {
}
case "Browser:MouseCancel":
this._contextTimeout.clear();
break;
case "Browser:SaveAs":
@ -497,7 +492,6 @@ Content.prototype = {
},
startLoading: function startLoading() {
this._contextTimeout.clear();
this._loading = true;
},