Bug 895581 Double tap should zoom content instead of selecting text.r=mbrubeck

This commit is contained in:
Allison Naaktgeboren 2013-11-18 23:13:05 -08:00
parent 5205e58f56
commit b5d0411402
3 changed files with 100 additions and 16 deletions

View File

@ -114,6 +114,7 @@ function getOverflowContentBoundingRect(aElement) {
*/
let Content = {
_debugEvents: false,
_isZoomedIn: false,
get formAssistant() {
delete this.formAssistant;
@ -133,6 +134,7 @@ let Content = {
addEventListener("touchstart", this, false);
addEventListener("click", this, true);
addEventListener("dblclick", this, true);
addEventListener("keydown", this);
addEventListener("keyup", this);
@ -180,6 +182,15 @@ let Content = {
this.formAssistant.open(aEvent.target, aEvent);
break;
case "dblclick":
// XXX Once gesture listners are used(Bug 933236), apzc will notify us
if (aEvent.mozInputSource == Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH) {
let selection = content.getSelection();
selection.removeAllRanges();
this._onZoomToTappedContent(aEvent.target);
}
break;
case "click":
// Workaround for bug 925457: we sometimes don't recognize the
// correct tap target or are unable to identify if it's editable.
@ -363,6 +374,75 @@ let Content = {
}
},
_onZoomToTappedContent: function (aElement) {
if (!aElement || this._isZoomedIn) {
this._zoomOut();
return;
}
while (aElement && !this._shouldZoomToElement(aElement)) {
aElement = aElement.parentNode;
}
if (!aElement) {
this._zoomOut();
} else {
this._zoomToElement(aElement);
}
},
/******************************************************
* Zoom utilities
*/
_zoomOut: function() {
let rect = getBoundingContentRect(content.document.documentElement);
let utils = Util.getWindowUtils(content);
let viewId = utils.getViewId(content.document.documentElement);
let presShellId = {};
utils.getPresShellId(presShellId);
let zoomData = [rect.x,
rect.y,
rect.width,
rect.height,
presShellId.value,
viewId].join(",");
Services.obs.notifyObservers(null, "Metro:ZoomToRect", zoomData);
this._isZoomedIn = false;
},
_zoomToElement: function(aElement) {
let rect = getBoundingContentRect(aElement);
let utils = Util.getWindowUtils(content);
let viewId = utils.getViewId(content.document.documentElement);
let presShellId = {};
utils.getPresShellId(presShellId);
let zoomData = [rect.x,
rect.y,
rect.width,
rect.height,
presShellId.value,
viewId].join(",");
Services.obs.notifyObservers(null, "Metro:ZoomToRect", zoomData);
this._isZoomedIn = true;
},
_shouldZoomToElement: function(aElement) {
let win = aElement.ownerDocument.defaultView;
if (win.getComputedStyle(aElement, null).display == "inline") {
return false;
}
else if (aElement instanceof Ci.nsIDOMHTMLLIElement) {
return false;
}
else if (aElement instanceof Ci.nsIDOMHTMLQuoteElement) {
return false;
}
else {
return true;
}
},
/******************************************************
* General utilities

View File

@ -93,7 +93,6 @@ var TouchModule = {
// capture phase events
window.addEventListener("CancelTouchSequence", this, true);
window.addEventListener("dblclick", this, true);
window.addEventListener("keydown", this, true);
window.addEventListener("MozMouseHittest", this, true);
@ -144,20 +143,6 @@ var TouchModule = {
case "touchend":
this._onTouchEnd(aEvent);
break;
case "dblclick":
// XXX This will get picked up somewhere below us for "double tap to zoom"
// once we get omtc and the apzc. Currently though dblclick is delivered to
// content and triggers selection of text, so fire up the SelectionHelperUI
// once selection is present.
if (!InputSourceHelper.isPrecise &&
!SelectionHelperUI.isActive &&
!FindHelperUI.isActive) {
setTimeout(function () {
SelectionHelperUI.attachEditSession(Browser.selectedTab.browser,
aEvent.clientX, aEvent.clientY);
}, 50);
}
break;
case "keydown":
this._handleKeyDown(aEvent);
break;

View File

@ -278,6 +278,7 @@ MetroWidget::Destroy()
nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1", &rv);
if (NS_SUCCEEDED(rv)) {
observerService->RemoveObserver(this, "apzc-scroll-offset-changed");
observerService->RemoveObserver(this, "Metro:ZoomToRect");
}
}
@ -966,6 +967,7 @@ CompositorParent* MetroWidget::NewCompositorParent(int aSurfaceWidth, int aSurfa
nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1", &rv);
if (NS_SUCCEEDED(rv)) {
observerService->AddObserver(this, "apzc-scroll-offset-changed", false);
observerService->AddObserver(this, "Metro:ZoomToRect", false);
}
}
@ -1561,5 +1563,22 @@ MetroWidget::Observe(nsISupports *subject, const char *topic, const PRUnichar *d
mController->UpdateScrollOffset(ScrollableLayerGuid(mRootLayerTreeId, presShellId, scrollId),
scrollOffset);
}
return NS_OK;
else if (!strcmp(topic, "Metro:ZoomToRect")) {
CSSRect rect = CSSRect();
uint64_t viewId = 0;
int32_t presShellId = 0;
int reScan = swscanf(data, L"%f,%f,%f,%f,%d,%llu",
&rect.x, &rect.y, &rect.width, &rect.height,
&presShellId, &viewId);
if(reScan != 6) {
NS_WARNING("Malformed Metro:ZoomToRect message");
}
ScrollableLayerGuid guid = ScrollableLayerGuid(mRootLayerTreeId, presShellId, viewId);
APZController::sAPZC->ZoomToRect(guid, rect);
}
else {
return NS_OK;
}
}