From df3721ca7adbdd597906a1cc07177aa9c253a774 Mon Sep 17 00:00:00 2001 From: Gavin Sharp Date: Fri, 11 Jul 2008 18:22:38 -0400 Subject: [PATCH] Bug 436059: initial 'zoom to element' support, r=stuart --- mobile/chrome/content/deckbrowser.xml | 287 ++++++++++++++++++-------- 1 file changed, 197 insertions(+), 90 deletions(-) diff --git a/mobile/chrome/content/deckbrowser.xml b/mobile/chrome/content/deckbrowser.xml index adc6ed78869..ae304498102 100644 --- a/mobile/chrome/content/deckbrowser.xml +++ b/mobile/chrome/content/deckbrowser.xml @@ -37,20 +37,16 @@ this._stack.addEventListener("dblclick", this.stackEventHandler, true); this._stack.addEventListener("DOMMouseScroll", this.stackEventHandler, true); - this._scrollStartTimeout = -1; + this._dragStartTimeout = -1; ({ dragging: false, - offX: 0, - offY: 0, + dragX: 0, + dragY: 0, sX: 0, sY: 0, - scrollableWidth: 0, - scrollableHeight: 0, - canvasH: 0, - canvasW: 0, pageX: 0, pageY: 0 }) @@ -76,6 +72,7 @@ if (aLocationChanged) { this.dragData.pageX = 0; this.dragData.pageY = 0; + this._zoomLevel = 1; } if (this._updateTimeout) @@ -104,11 +101,10 @@ ctx.clearRect(0,0,w,h); - //dump("x, y: " + this.dragData.pageX + "," + this.dragData.pageY + "\n"); ctx.save(); ctx.scale(this._zoomLevel, this._zoomLevel); - ctx.drawWindow(this.browser.contentWindow, - -this.dragData.pageX / this._zoomLevel, -this.dragData.pageY / this._zoomLevel, + ctx.drawWindow(this.browser.contentWindow, + this.dragData.pageX, this.dragData.pageY, w / this._zoomLevel, h / this._zoomLevel, "white"); ctx.restore(); @@ -117,11 +113,10 @@ @@ -149,81 +144,197 @@ ]]> + /** + * Retrieve the content element for a given point (relative to the top + * left corner of the browser window). + */ + + + + + + + + + + + + + + + + - + + + var cdoc = this.browser.contentDocument; + + // These might not exist yet + var body = cdoc.body || {}; + var html = cdoc.documentElement || {}; + + if (!(body.scrollWidth || html.scrollWidth)) + throw "Both body and documentElement have no scrollWidth?"; + + return [Math.max(body.scrollWidth, html.scrollWidth), + Math.max(body.scrollHeight, html.scrollHeight)]; + + + + + + + + /** + * Given a set of page coordinates, constrain them such that they + * fit within the rect defined by [0,0] and [x,y], where x and y are + * the maximum values that can be used for the canvas' .top and .left + * such that it is still within the scrollable area of the page, taking + * into account the current zoomLevel. + */ + + + + + + + + + + + + + + 10 || Math.abs(this.deckbrowser.dragData.sY - aEvent.screenY) > 10)) { - clearTimeout(this.deckbrowser._scrollStartTimeout); + clearTimeout(this.deckbrowser._dragStartTimeout); this.deckbrowser._dragStartTimer(); } else { return false; } } - var dx = aEvent.screenX - this.deckbrowser.dragData.sX; - var dy = aEvent.screenY - this.deckbrowser.dragData.sY; + var dx = this.deckbrowser.dragData.sX - aEvent.screenX; + var dy = this.deckbrowser.dragData.sY - aEvent.screenY; - this.deckbrowser._doPan(dx, dy); + this.deckbrowser._moveCanvas(dx, dy); if (Date.now() - this.deckbrowser.dragData.lastMouseEvent < 75) { // FIXME: make this a constant //dump("dropping event\n"); @@ -323,26 +429,27 @@ this.deckbrowser.dragData.lastMouseEvent = Date.now(); aEvent.preventDefault(); - return true; + return true; }, - + DOMMouseScroll: function seh_DOMMouseScroll(aEvent) { this.deckbrowser.zoom(aEvent.detail); }, - + dblclick: function seh_dblclick(aEvent) { - //dump("Zooming...\n"); - var x = aEvent.clientX; - var y = aEvent.clientY; + var target = aEvent.originalTarget; + if (this.deckbrowser._zoomed) { this.deckbrowser._zoomLevel = 1; + var dragData = this.deckbrowser.dragData; + dragData.pageX = dragData.pageY = 0; + this.deckbrowser._browserToCanvas(); this.deckbrowser._zoomed = false; } else { - this.deckbrowser._zoomLevel = 2; + var element = this.deckbrowser.elementFromPoint(aEvent.clientX, aEvent.clientY); + this.deckbrowser.zoomToElement(element); this.deckbrowser._zoomed = true; } - - this.deckbrowser._browserToCanvas(); } }); ]]>