зеркало из https://github.com/mozilla/pjs.git
Bug 437957 - Animate zoom [r=mfinkle]
This commit is contained in:
Родитель
b04ad8c63d
Коммит
159ef84658
|
@ -364,6 +364,13 @@ pref("browser.ui.kinetic.swipeLength", 160);
|
|||
|
||||
// zooming
|
||||
pref("browser.ui.zoom.pageFitGranularity", 10); // don't zoom to fit by less than 1/10.
|
||||
pref("browser.ui.zoom.animationFps", 60);
|
||||
pref("browser.ui.zoom.animationDuration", 350); // ms duration of double-tap zoom animation
|
||||
|
||||
// pinch gesture
|
||||
pref("browser.ui.pinch.maxGrowth", 150); // max pinch distance growth
|
||||
pref("browser.ui.pinch.maxShrink", 200); // max pinch distance shrinkage
|
||||
pref("browser.ui.pinch.scalingFactor", 500); // scaling factor for above pinch limits
|
||||
|
||||
// Touch radius (area around the touch location to look for target elements):
|
||||
pref("browser.ui.touch.left", 8);
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
|
||||
/*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Mobile Browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Benjamin Stover <bstover@mozilla.com>
|
||||
* Matt Brubeck <mbrubeck@mozilla.com>
|
||||
* Jaakko Kiviluoto <jaakko.kiviluoto@digia.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cu = Components.utils;
|
||||
|
||||
/**
|
||||
* Responsible for zooming in to a given view rectangle
|
||||
* @param aBrowserView BrowserView instance
|
||||
* @param aZoomRect Optional. Zoom rectangle to be configured
|
||||
*/
|
||||
function AnimatedZoom(aBrowserView) {
|
||||
this.bv = aBrowserView;
|
||||
|
||||
// Render a snapshot of the viewport contents around the visible rect
|
||||
let [w, h] = this.bv.getViewportDimensions();
|
||||
let viewportRect = new Rect(0, 0, w, h);
|
||||
this.zoomFrom = this.bv.getVisibleRect().translateInside(viewportRect);
|
||||
|
||||
// try to cover twice the size of the current visible rect
|
||||
this.snapshotRect = this.bv.getVisibleRect().inflate(2);
|
||||
|
||||
// sanitize the snapshot rectangle to fit inside viewport
|
||||
this.snapshotRect.translateInside(viewportRect).restrictTo(viewportRect).expandToIntegers();
|
||||
this.snapshot = this._createCanvas(this.snapshotRect.width, this.snapshotRect.height);
|
||||
let snapshotCtx = this.snapshot.getContext("2d");
|
||||
snapshotCtx.clearRect(0, 0, this.snapshotRect.width, this.snapshotRect.height);
|
||||
this.bv.renderToCanvas(this.snapshot, this.snapshotRect.width, this.snapshotRect.height, this.snapshotRect.clone());
|
||||
|
||||
// stop live rendering during zooming
|
||||
this.bv.pauseRendering();
|
||||
|
||||
// hide ui elements to avoid undefined states after zoom
|
||||
Browser.hideTitlebar();
|
||||
Browser.hideSidebars();
|
||||
|
||||
let clientVis = Browser.browserViewToClientRect(this.bv.getCriticalRect());
|
||||
let viewBuffer = Elements.viewBuffer;
|
||||
viewBuffer.left = clientVis.left;
|
||||
viewBuffer.top = clientVis.top;
|
||||
viewBuffer.width = this.zoomFrom.width;
|
||||
viewBuffer.height = this.zoomFrom.height;
|
||||
viewBuffer.style.display = "block";
|
||||
|
||||
// configure defaults for the canvas' drawing context
|
||||
let ctx = viewBuffer.getContext("2d");
|
||||
|
||||
// disable smoothing and use the fastest composition operation
|
||||
ctx.mozImageSmoothingEnabled = false;
|
||||
ctx.globalCompositeOperation = 'copy';
|
||||
|
||||
// set background fill pattern
|
||||
let backgroundImage = new Image();
|
||||
backgroundImage.src = "chrome://browser/content/checkerboard.png";
|
||||
ctx.fillStyle = ctx.createPattern(backgroundImage, 'repeat');
|
||||
|
||||
// fill the canvas with current data
|
||||
this.updateTo(this.zoomFrom);
|
||||
}
|
||||
|
||||
/** Creating a canvas element of width and height. */
|
||||
AnimatedZoom.prototype._createCanvas = function(width, height) {
|
||||
let canvas = document.createElementNS(kXHTMLNamespaceURI, "canvas");
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
canvas.mozOpaque = true;
|
||||
return canvas;
|
||||
}
|
||||
|
||||
/** Updates the zoom to new rect. */
|
||||
AnimatedZoom.prototype.updateTo = function(nextRect) {
|
||||
this.zoomRect = nextRect;
|
||||
|
||||
// prepare to draw to the zoom canvas
|
||||
let canvasRect = new Rect(0, 0, Elements.viewBuffer.width, Elements.viewBuffer.height);
|
||||
let ctx = Elements.viewBuffer.getContext("2d");
|
||||
ctx.save();
|
||||
|
||||
// srcRect = area inside this.snapshot to copy from
|
||||
let srcRect = nextRect.intersect(this.snapshotRect);
|
||||
if (srcRect.isEmpty())
|
||||
return;
|
||||
|
||||
// destRect = respective area inside canvas to paint to. The dimensions of
|
||||
// destRect within canvas equals those of srcRect within nextRect.
|
||||
let s = canvasRect.width / nextRect.width;
|
||||
let destRect = srcRect.clone().translate(-nextRect.x, -nextRect.y).scale(s, s);
|
||||
|
||||
// adjust from viewport coordinates to snapshot canvas coordinates
|
||||
srcRect.translate(-this.snapshotRect.left, -this.snapshotRect.top);
|
||||
|
||||
// fill background and draw the (possibly scaled) image
|
||||
destRect.restrictTo(canvasRect).expandToIntegers();
|
||||
ctx.drawImage(this.snapshot,
|
||||
Math.floor(srcRect.left), Math.floor(srcRect.top),
|
||||
Math.floor(srcRect.width), Math.floor(srcRect.height),
|
||||
Math.floor(destRect.left), Math.floor(destRect.top),
|
||||
Math.floor(destRect.width), Math.floor(destRect.height));
|
||||
|
||||
// clip the over leftover area and fill it with checkerboard
|
||||
let unknowns = canvasRect.subtract(destRect);
|
||||
if (unknowns.length > 0) {
|
||||
ctx.beginPath();
|
||||
unknowns.forEach(function(r) { ctx.rect(r.x, r.y, r.width, r.height); });
|
||||
ctx.clip();
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
/** Starts an animated zoom to zoomRect. */
|
||||
AnimatedZoom.prototype.animateTo = function(aZoomRect) {
|
||||
if (this.timer)
|
||||
return false;
|
||||
|
||||
this.zoomTo = aZoomRect;
|
||||
|
||||
// start animation timer
|
||||
this.counter = 0;
|
||||
this.inc = 1.0 / gPrefService.getIntPref("browser.ui.zoom.animationDuration");
|
||||
this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
this.interval = 1000 / gPrefService.getIntPref("browser.ui.zoom.animationFps");
|
||||
this.timer.initWithCallback(Util.bind(this._callback, this), this.interval, this.timer.TYPE_REPEATING_PRECISE);
|
||||
|
||||
// force first update to be according to FPS even though first callback would take longer
|
||||
this.lastTime = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Callback for the animation. */
|
||||
AnimatedZoom.prototype._callback = function() {
|
||||
try {
|
||||
if (this.counter < 1) {
|
||||
// increase animation position according to elapsed time
|
||||
let now = Date.now();
|
||||
if (this.lastTime == 0)
|
||||
this.lastTime = now - this.interval; // fix lastTime if not yet set (first frame)
|
||||
this.counter += this.inc * (now - this.lastTime);
|
||||
this.lastTime = now;
|
||||
|
||||
// update scaled image to interpolated rectangle
|
||||
let rect = this.zoomFrom.blend(this.zoomTo, Math.min(this.counter, 1));
|
||||
this.updateTo(rect);
|
||||
}
|
||||
else {
|
||||
// last cycle already rendered final scaled image, now clean up
|
||||
this.finish();
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
Util.dumpLn("Error while zooming. Please report error at:", e.getSource());
|
||||
this.finish();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/** Stop animation, zoom to point, and clean up. */
|
||||
AnimatedZoom.prototype.finish = function() {
|
||||
try {
|
||||
// resume live rendering
|
||||
this.bv.resumeRendering(true);
|
||||
|
||||
// if we actually zoomed somewhere, clean up the UI to normal
|
||||
if (this.zoomRect)
|
||||
Browser.setVisibleRect(this.zoomRect);
|
||||
}
|
||||
finally {
|
||||
if (this.timer) {
|
||||
this.timer.cancel();
|
||||
this.timer = null;
|
||||
}
|
||||
this.snapshot = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -258,6 +258,12 @@ BrowserView.prototype = {
|
|||
return this._visibleRectFactory();
|
||||
},
|
||||
|
||||
getCriticalRect: function getCriticalRect() {
|
||||
let bvs = this._browserViewportState;
|
||||
let vr = this.getVisibleRect();
|
||||
return BrowserView.Util.visibleRectToCriticalRect(vr, bvs);
|
||||
},
|
||||
|
||||
/**
|
||||
* @return [width, height]
|
||||
*/
|
||||
|
|
|
@ -128,6 +128,9 @@ function InputHandler(browserViewContainer) {
|
|||
window.addEventListener("mouseup", this, true);
|
||||
window.addEventListener("mousemove", this, true);
|
||||
window.addEventListener("click", this, true);
|
||||
window.addEventListener("MozMagnifyGestureStart", this, true);
|
||||
window.addEventListener("MozMagnifyGestureUpdate", this, true);
|
||||
window.addEventListener("MozMagnifyGesture", this, true);
|
||||
|
||||
/* these handle key strokes in the browser view (where page content appears) */
|
||||
browserViewContainer.addEventListener("keypress", this, false);
|
||||
|
@ -135,10 +138,11 @@ function InputHandler(browserViewContainer) {
|
|||
browserViewContainer.addEventListener("keydown", this, false);
|
||||
browserViewContainer.addEventListener("DOMMouseScroll", this, true);
|
||||
browserViewContainer.addEventListener("MozMousePixelScroll", this, true);
|
||||
browserViewContainer.addEventListener("contextmenu", this, false);
|
||||
browserViewContainer.addEventListener("contextmenu", this, true);
|
||||
|
||||
this.addModule(new MouseModule(this, browserViewContainer));
|
||||
this.addModule(new KeyModule(this, browserViewContainer));
|
||||
this.addModule(new GestureModule(this, browserViewContainer));
|
||||
this.addModule(new ScrollwheelModule(this, browserViewContainer));
|
||||
}
|
||||
|
||||
|
@ -381,6 +385,12 @@ MouseModule.prototype = {
|
|||
this.cancelPending();
|
||||
}
|
||||
break;
|
||||
case "MozMagnifyGestureStart":
|
||||
case "MozMagnifyGesture":
|
||||
// disallow kinetic panning after gesture
|
||||
if (this._dragData.dragging)
|
||||
this._doDragStop(0, 0, true);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -660,7 +670,8 @@ MouseModule.prototype = {
|
|||
*/
|
||||
_doDoubleClick: function _doDoubleClick() {
|
||||
let mouseUp1 = this._downUpEvents[1].event;
|
||||
let mouseUp2 = this._downUpEvents[3].event;
|
||||
// sometimes the second press event is not dispatched at all
|
||||
let mouseUp2 = this._downUpEvents[Math.min(3, this._downUpEvents.length - 1)].event;
|
||||
this._cleanClickBuffer(4);
|
||||
this._clicker.doubleClick(mouseUp1.clientX, mouseUp1.clientY,
|
||||
mouseUp2.clientX, mouseUp2.clientY);
|
||||
|
@ -1197,3 +1208,144 @@ ScrollwheelModule.prototype = {
|
|||
/* We don't have much state to reset if we lose event focus */
|
||||
cancelPending: function cancelPending() {}
|
||||
};
|
||||
|
||||
|
||||
// Simple gestures support
|
||||
//
|
||||
// As per bug #412486, web content must not be allowed to receive any
|
||||
// simple gesture events. Multi-touch gesture APIs are in their
|
||||
// infancy and we do NOT want to be forced into supporting an API that
|
||||
// will probably have to change in the future. (The current Mac OS X
|
||||
// API is undocumented and was reverse-engineered.) Until support is
|
||||
// implemented in the event dispatcher to keep these events as
|
||||
// chrome-only, we must listen for the simple gesture events during
|
||||
// the capturing phase and call stopPropagation on every event.
|
||||
|
||||
function GestureModule(owner, browserViewContainer) {
|
||||
this._owner = owner;
|
||||
this._browserViewContainer = browserViewContainer;
|
||||
}
|
||||
|
||||
GestureModule.prototype = {
|
||||
|
||||
/**
|
||||
* Dispatch events based on the type of mouse gesture event. For now, make
|
||||
* sure to stop propagation of every gesture event so that web content cannot
|
||||
* receive gesture events.
|
||||
*
|
||||
* @param evInfo Event information structure
|
||||
*/
|
||||
handleEvent: function handleEvent(evInfo) {
|
||||
try {
|
||||
let consume = false;
|
||||
switch (evInfo.event.type) {
|
||||
case "MozMagnifyGestureStart":
|
||||
consume = true;
|
||||
this._pinchStart(evInfo.event);
|
||||
break;
|
||||
|
||||
case "MozMagnifyGestureUpdate":
|
||||
consume = true;
|
||||
if (this._ignoreNextUpdate)
|
||||
this._ignoreNextUpdate = false;
|
||||
else
|
||||
this._pinchUpdate(evInfo.event);
|
||||
break;
|
||||
|
||||
case "MozMagnifyGesture":
|
||||
consume = true;
|
||||
this._pinchEnd(evInfo.event);
|
||||
break;
|
||||
|
||||
case "contextmenu":
|
||||
// prevent context menu while pinching
|
||||
if (this._pinchZoom)
|
||||
consume = true;
|
||||
break;
|
||||
}
|
||||
if (consume) {
|
||||
// prevent sending of event to content
|
||||
evInfo.event.stopPropagation();
|
||||
evInfo.event.preventDefault();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
Util.dumpLn("Error while handling gesture event", evInfo.event.type,
|
||||
"\nPlease report error at:", e.getSource());
|
||||
}
|
||||
},
|
||||
|
||||
cancelPending: function cancelPending() {
|
||||
// terminate pinch zoom if ongoing
|
||||
if (this._pinchZoom) {
|
||||
this._pinchZoom.finish();
|
||||
this._pinchZoom = null;
|
||||
}
|
||||
},
|
||||
|
||||
_pinchStart: function _pinchStart(aEvent) {
|
||||
let bv = Browser._browserView;
|
||||
// start gesture if it's not taking place already, or over a XUL element
|
||||
if (this._pinchZoom || (aEvent.target instanceof XULElement) || !bv.allowZoom)
|
||||
return;
|
||||
|
||||
// grab events during pinch
|
||||
this._owner.grab(this);
|
||||
|
||||
// hide element highlight
|
||||
document.getElementById("tile-container").customClicker.panBegin();
|
||||
|
||||
// create the AnimatedZoom object for fast arbitrary zooming
|
||||
this._pinchZoom = new AnimatedZoom(bv);
|
||||
|
||||
// start from current zoom level
|
||||
this._pinchZoomLevel = bv.getZoomLevel();
|
||||
this._pinchDelta = 0;
|
||||
this._ignoreNextUpdate = true; // first update gives useless, huge delta
|
||||
|
||||
// cache gesture limit values
|
||||
this._maxGrowth = gPrefService.getIntPref("browser.ui.pinch.maxGrowth");
|
||||
this._maxShrink = gPrefService.getIntPref("browser.ui.pinch.maxShrink");
|
||||
this._scalingFactor = gPrefService.getIntPref("browser.ui.pinch.scalingFactor");
|
||||
|
||||
// save the initial gesture start point as reference
|
||||
[this._pinchStartX, this._pinchStartY] =
|
||||
Browser.transformClientToBrowser(aEvent.clientX, aEvent.clientY);
|
||||
},
|
||||
|
||||
_pinchUpdate: function _pinchUpdate(aEvent) {
|
||||
if (!this._pinchZoom || !aEvent.delta)
|
||||
return;
|
||||
|
||||
// Accumulate pinch delta. Changes smaller than 1 are just jitter.
|
||||
this._pinchDelta += aEvent.delta;
|
||||
|
||||
// decrease the pinchDelta min/max values to limit zooming out/in speed
|
||||
let delta = Math.max(-this._maxShrink, Math.min(this._maxGrowth, this._pinchDelta));
|
||||
this._pinchZoomLevel *= (1 + delta / this._scalingFactor);
|
||||
this._pinchZoomLevel = Browser._browserView.clampZoomLevel(this._pinchZoomLevel);
|
||||
this._pinchDelta = 0;
|
||||
|
||||
// get current pinch position to calculate opposite vector for zoom point
|
||||
let [pX, pY] =
|
||||
Browser.transformClientToBrowser(aEvent.clientX, aEvent.clientY);
|
||||
|
||||
// redraw zoom canvas according to new zoom rect
|
||||
let rect = Browser._getZoomRectForPoint(2 * this._pinchStartX - pX,
|
||||
2 * this._pinchStartY - pY,
|
||||
this._pinchZoomLevel);
|
||||
this._pinchZoom.updateTo(rect);
|
||||
},
|
||||
|
||||
_pinchEnd: function _pinchEnd(aEvent) {
|
||||
// release grab
|
||||
this._owner.ungrab(this);
|
||||
|
||||
// stop ongoing animated zoom
|
||||
if (this._pinchZoom) {
|
||||
// zoom to current level for real
|
||||
this._pinchZoom.finish();
|
||||
this._pinchZoom = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -591,4 +591,33 @@ Rect.prototype = {
|
|||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Blends two rectangles together.
|
||||
* @param rect Rectangle to blend this one with
|
||||
* @param scalar Ratio from 0 (returns a clone of this rect) to 1 (clone of rect).
|
||||
* @return New blended rectangle.
|
||||
*/
|
||||
blend: function blend(rect, scalar) {
|
||||
return new Rect(
|
||||
this.left + (rect.left - this.left ) * scalar,
|
||||
this.top + (rect.top - this.top ) * scalar,
|
||||
this.width + (rect.width - this.width ) * scalar,
|
||||
this.height + (rect.height - this.height) * scalar);
|
||||
},
|
||||
|
||||
/**
|
||||
* Grows or shrinks the rectangle while keeping the center point.
|
||||
* Accepts single multipler, or separate for both axes.
|
||||
*/
|
||||
inflate: function inflate(xscl, yscl) {
|
||||
let xAdj = (this.width * xscl - this.width) / 2;
|
||||
let s = (arguments.length > 1) ? yscl : xscl;
|
||||
let yAdj = (this.height * s - this.height) / 2;
|
||||
this.left -= xAdj;
|
||||
this.right += xAdj;
|
||||
this.top -= yAdj;
|
||||
this.bottom += yAdj;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1621,7 +1621,7 @@ var FormHelper = {
|
|||
}
|
||||
}
|
||||
|
||||
Browser.setVisibleRect(zoomRect);
|
||||
Browser.animatedZoomTo(zoomRect);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
* Roy Frostig <rfrostig@mozilla.com>
|
||||
* Ben Combee <bcombee@mozilla.com>
|
||||
* Matt Brubeck <mbrubeck@mozilla.com>
|
||||
* Benjamin Stover <bstover@mozilla.com>
|
||||
* Miika Jarvinen <mjarvin@gmail.com>
|
||||
* Jaakko Kiviluoto <jaakko.kiviluoto@digia.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -1071,7 +1074,7 @@ var Browser = {
|
|||
zoomLevel = Math.max(zoomLevel, bv.getPageZoomLevel());
|
||||
|
||||
let center = this.getVisibleRect().center().map(bv.viewportToBrowser);
|
||||
this.setVisibleRect(this._getZoomRectForPoint(center.x, center.y, zoomLevel));
|
||||
this.animatedZoomTo(this._getZoomRectForPoint(center.x, center.y, zoomLevel));
|
||||
},
|
||||
|
||||
/** Rect should be in viewport coordinates. */
|
||||
|
@ -1123,6 +1126,11 @@ var Browser = {
|
|||
return result.translateInside(bv._browserViewportState.viewportRect);
|
||||
},
|
||||
|
||||
animatedZoomTo: function animatedZoomTo(rect) {
|
||||
let zoom = new AnimatedZoom(this._browserView);
|
||||
zoom.animateTo(rect);
|
||||
},
|
||||
|
||||
setVisibleRect: function setVisibleRect(rect) {
|
||||
let bv = this._browserView;
|
||||
let vis = bv.getVisibleRect();
|
||||
|
@ -1172,19 +1180,19 @@ var Browser = {
|
|||
if (!zoomRect && bv.isDefaultZoom())
|
||||
zoomRect = this._getZoomRectForPoint(x, y, bv.getZoomLevel() * 2);
|
||||
|
||||
if (zoomRect)
|
||||
this.setVisibleRect(zoomRect);
|
||||
if (zoomRect && bv.allowZoom)
|
||||
this.animatedZoomTo(zoomRect);
|
||||
|
||||
return zoomRect;
|
||||
},
|
||||
|
||||
zoomFromPoint: function zoomFromPoint(cX, cY) {
|
||||
let bv = this._browserView;
|
||||
if (!bv.isDefaultZoom()) {
|
||||
if (!bv.isDefaultZoom() && bv.allowZoom) {
|
||||
let zoomLevel = bv.getDefaultZoomLevel();
|
||||
let [x, y] = this.transformClientToBrowser(cX, cY);
|
||||
let zoomRect = this._getZoomRectForPoint(x, y, zoomLevel);
|
||||
this.setVisibleRect(zoomRect);
|
||||
this.animatedZoomTo(zoomRect);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -2704,9 +2712,6 @@ var ImagePreloader = {
|
|||
function rendererFactory(aBrowser, aCanvas) {
|
||||
let wrapper = {};
|
||||
|
||||
if (!aCanvas.parentNode)
|
||||
throw "Canvas Must have a parent node";
|
||||
|
||||
if (aBrowser.contentWindow) {
|
||||
let ctx = aCanvas.getContext("2d");
|
||||
let draw = function(browser, aLeft, aTop, aWidth, aHeight, aColor, aFlags) {
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
<script type="application/javascript" src="chrome://browser/content/InputHandler.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/TileManager.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/BrowserView.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/AnimatedZoom.js"/>
|
||||
|
||||
<stringbundleset id="stringbundleset">
|
||||
<stringbundle id="bundle_browser" src="chrome://browser/locale/browser.properties"/>
|
||||
|
|
|
@ -57,5 +57,6 @@ chrome.jar:
|
|||
content/prompt/promptPassword.xul (content/prompt/promptPassword.xul)
|
||||
content/prompt/select.xul (content/prompt/select.xul)
|
||||
content/prompt/prompt.js (content/prompt/prompt.js)
|
||||
content/AnimatedZoom.js (content/AnimatedZoom.js)
|
||||
|
||||
% override chrome://global/content/config.xul chrome://browser/content/config.xul
|
||||
|
|
Загрузка…
Ссылка в новой задаче