зеркало из https://github.com/mozilla/gecko-dev.git
merge with stuart
This commit is contained in:
Коммит
f1e7faff4e
|
@ -17,11 +17,12 @@
|
|||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roy Frostig <rfrostig@mozilla.com>
|
||||
* Stuart Parmenter <stuart@mozilla.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
|
||||
|
@ -39,13 +40,9 @@
|
|||
|
||||
let Ci = Components.interfaces;
|
||||
|
||||
// --- REMOVE ---
|
||||
let noop = function() {};
|
||||
let endl = '\n';
|
||||
// --------------
|
||||
|
||||
function BrowserView(container, visibleRect) {
|
||||
bindAll(this);
|
||||
Util.bindAll(this);
|
||||
this.init(container, visibleRect);
|
||||
}
|
||||
|
||||
|
@ -133,41 +130,43 @@ function BrowserView(container, visibleRect) {
|
|||
*
|
||||
* Maintaining per-browser state is a little bit of a hack involving attaching
|
||||
* an object as the obfuscated dynamic JS property of the browser object, that
|
||||
* hopefully no one but us will touch. See getViewportStateFromBrowser() for
|
||||
* the property name.
|
||||
* hopefully no one but us will touch. See BrowserView.Util.getViewportStateFromBrowser()
|
||||
* for the property name.
|
||||
*/
|
||||
BrowserView.prototype = (
|
||||
function() {
|
||||
const kBrowserViewZoomLevelMin = 0.2;
|
||||
const kBrowserViewZoomLevelMax = 4.0;
|
||||
const kBrowserViewZoomLevelPrecision = 10000;
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Privates
|
||||
//
|
||||
|
||||
const kZoomLevelMin = 0.2;
|
||||
const kZoomLevelMax = 4.0;
|
||||
const kZoomLevelPrecision = 10000;
|
||||
// -----------------------------------------------------------
|
||||
// Util/convenience functions.
|
||||
//
|
||||
// These are mostly for use by BrowserView itself, but if you find them handy anywhere
|
||||
// else, feel free.
|
||||
//
|
||||
|
||||
function visibleRectToCriticalRect(visibleRect, browserViewportState) {
|
||||
BrowserView.Util = {
|
||||
visibleRectToCriticalRect: function visibleRectToCriticalRect(visibleRect, browserViewportState) {
|
||||
return visibleRect.intersect(browserViewportState.viewportRect);
|
||||
}
|
||||
},
|
||||
|
||||
function clampZoomLevel(zl) {
|
||||
let bounded = Math.min(Math.max(kZoomLevelMin, zl), kZoomLevelMax);
|
||||
return Math.round(bounded * kZoomLevelPrecision) / kZoomLevelPrecision;
|
||||
}
|
||||
clampZoomLevel: function clampZoomLevel(zl) {
|
||||
let bounded = Math.min(Math.max(kBrowserViewZoomLevelMin, zl), kBrowserViewZoomLevelMax);
|
||||
return Math.round(bounded * kBrowserViewZoomLevelPrecision) / kBrowserViewZoomLevelPrecision;
|
||||
},
|
||||
|
||||
function pageZoomLevel(visibleRect, browserW, browserH) {
|
||||
return clampZoomLevel(visibleRect.width / browserW);
|
||||
}
|
||||
pageZoomLevel: function pageZoomLevel(visibleRect, browserW, browserH) {
|
||||
return BrowserView.Util.clampZoomLevel(visibleRect.width / browserW);
|
||||
},
|
||||
|
||||
function seenBrowser(browser) {
|
||||
seenBrowser: function seenBrowser(browser) {
|
||||
return !!(browser.__BrowserView__vps);
|
||||
}
|
||||
},
|
||||
|
||||
function initBrowserState(browser, visibleRect) {
|
||||
let [browserW, browserH] = getBrowserDimensions(browser);
|
||||
initBrowserState: function initBrowserState(browser, visibleRect) {
|
||||
let [browserW, browserH] = BrowserView.Util.getBrowserDimensions(browser);
|
||||
|
||||
let zoomLevel = pageZoomLevel(visibleRect, browserW, browserH);
|
||||
let zoomLevel = BrowserView.Util.pageZoomLevel(visibleRect, browserW, browserH);
|
||||
let viewportRect = (new wsRect(0, 0, browserW, browserH)).scale(zoomLevel, zoomLevel);
|
||||
|
||||
dump('--- initing browser to ---' + endl);
|
||||
|
@ -177,13 +176,13 @@ function() {
|
|||
zoomLevel);
|
||||
dump(browser.__BrowserView__vps.toString() + endl);
|
||||
dump('--------------------------' + endl);
|
||||
}
|
||||
},
|
||||
|
||||
function getViewportStateFromBrowser(browser) {
|
||||
getViewportStateFromBrowser: function getViewportStateFromBrowser(browser) {
|
||||
return browser.__BrowserView__vps;
|
||||
}
|
||||
},
|
||||
|
||||
function getBrowserDimensions(browser) {
|
||||
getBrowserDimensions: function getBrowserDimensions(browser) {
|
||||
let cdoc = browser.contentDocument;
|
||||
|
||||
// These might not exist yet depending on page load state
|
||||
|
@ -193,52 +192,50 @@ function() {
|
|||
let h = Math.max(body.scrollHeight || 0, html.scrollHeight);
|
||||
|
||||
return [w, h];
|
||||
}
|
||||
},
|
||||
|
||||
function getContentScrollValues(browser) {
|
||||
let cwu = getBrowserDOMWindowUtils(browser);
|
||||
getContentScrollValues: function getContentScrollValues(browser) {
|
||||
let cwu = BrowserView.Util.getBrowserDOMWindowUtils(browser);
|
||||
let scrollX = {};
|
||||
let scrollY = {};
|
||||
cwu.getScrollXY(false, scrollX, scrollY);
|
||||
|
||||
return [scrollX.value, scrollY.value];
|
||||
}
|
||||
},
|
||||
|
||||
function getBrowserDOMWindowUtils(browser) {
|
||||
getBrowserDOMWindowUtils: function getBrowserDOMWindowUtils(browser) {
|
||||
return browser.contentWindow
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
}
|
||||
},
|
||||
|
||||
function getNewBatchOperationState() {
|
||||
getNewBatchOperationState: function getNewBatchOperationState() {
|
||||
return {
|
||||
viewportSizeChanged: false,
|
||||
dirtyAll: false
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
function clampViewportWH(width, height, visibleRect) {
|
||||
clampViewportWH: function clampViewportWH(width, height, visibleRect) {
|
||||
let minW = visibleRect.width;
|
||||
let minH = visibleRect.height;
|
||||
return [Math.max(width, minW), Math.max(height, minH)];
|
||||
}
|
||||
},
|
||||
|
||||
function initContainer(container, visibleRect) {
|
||||
initContainer: function initContainer(container, visibleRect) {
|
||||
container.style.width = visibleRect.width + 'px';
|
||||
container.style.height = visibleRect.height + 'px';
|
||||
container.style.overflow = '-moz-hidden-unscrollable';
|
||||
}
|
||||
},
|
||||
|
||||
function resizeContainerToViewport(container, viewportRect) {
|
||||
resizeContainerToViewport: function resizeContainerToViewport(container, viewportRect) {
|
||||
container.style.width = viewportRect.width + 'px';
|
||||
container.style.height = viewportRect.height + 'px';
|
||||
}
|
||||
|
||||
// --- Change of coordinates functions --- //
|
||||
};
|
||||
|
||||
|
||||
// The following returned object becomes BrowserView.prototype
|
||||
return {
|
||||
BrowserView.prototype = {
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Public instance methods
|
||||
|
@ -247,7 +244,9 @@ function() {
|
|||
init: function init(container, visibleRect) {
|
||||
this._batchOps = [];
|
||||
this._container = container;
|
||||
this._browser = null;
|
||||
this._browserViewportState = null;
|
||||
this._contentWindow = null;
|
||||
this._renderMode = 0;
|
||||
this._tileManager = new TileManager(this._appendTile, this._removeTile, this);
|
||||
this.setVisibleRect(visibleRect);
|
||||
|
@ -296,7 +295,7 @@ function() {
|
|||
if (!bvs)
|
||||
return;
|
||||
|
||||
//[width, height] = clampViewportWH(width, height, vis);
|
||||
//[width, height] = BrowserView.Util.clampViewportWH(width, height, vis);
|
||||
bvs.viewportRect.right = width;
|
||||
bvs.viewportRect.bottom = height;
|
||||
|
||||
|
@ -336,7 +335,7 @@ function() {
|
|||
},
|
||||
|
||||
beginBatchOperation: function beginBatchOperation() {
|
||||
this._batchOps.push(getNewBatchOperationState());
|
||||
this._batchOps.push(BrowserView.Util.getNewBatchOperationState());
|
||||
this.pauseRendering();
|
||||
},
|
||||
|
||||
|
@ -410,7 +409,7 @@ function() {
|
|||
let vs = this._browserViewportState;
|
||||
let vr = this._visibleRect;
|
||||
|
||||
let destCR = visibleRectToCriticalRect(vr.clone().translate(dx, dy), vs);
|
||||
let destCR = BrowserView.Util.visibleRectToCriticalRect(vr.clone().translate(dx, dy), vs);
|
||||
|
||||
this._tileManager.beginCriticalMove(destCR);
|
||||
},
|
||||
|
@ -427,7 +426,7 @@ function() {
|
|||
vs.visibleX = vr.left;
|
||||
vs.visibleY = vr.top;
|
||||
|
||||
let cr = visibleRectToCriticalRect(vr, vs);
|
||||
let cr = BrowserView.Util.visibleRectToCriticalRect(vr, vs);
|
||||
|
||||
this._tileManager.endCriticalMove(cr, this.isRendering());
|
||||
},
|
||||
|
@ -453,6 +452,7 @@ function() {
|
|||
|
||||
this._restoreBrowser(browser);
|
||||
|
||||
if (browser) {
|
||||
browser.setAttribute("type", "content-primary");
|
||||
|
||||
this.beginBatchOperation();
|
||||
|
@ -472,6 +472,7 @@ function() {
|
|||
this._viewportChanged(browserChanged, browserChanged);
|
||||
|
||||
this.commitBatchOperation();
|
||||
}
|
||||
},
|
||||
|
||||
handleMozAfterPaint: function handleMozAfterPaint(ev) {
|
||||
|
@ -479,7 +480,7 @@ function() {
|
|||
let tm = this._tileManager;
|
||||
let vs = this._browserViewportState;
|
||||
|
||||
let [scrollX, scrollY] = getContentScrollValues(browser);
|
||||
let [scrollX, scrollY] = BrowserView.Util.getContentScrollValues(browser);
|
||||
let clientRects = ev.clientRects;
|
||||
|
||||
// !!! --- RESIZE HACK BEGIN -----
|
||||
|
@ -506,12 +507,12 @@ function() {
|
|||
// remove this. this is where we make 'lazy' calculations
|
||||
// that hint at a browser size change and fake the size change
|
||||
// event dispach
|
||||
if (r.right > hack.maxSeenW) {
|
||||
hack.maxSeenW = r.right;
|
||||
if (r.right > hack.maxW) {
|
||||
hack.maxW = rect.right;
|
||||
hackSizeChanged = true;
|
||||
}
|
||||
if (r.bottom > hack.maxSeenH) {
|
||||
hack.maxSeenH = r.bottom;
|
||||
if (r.bottom > hack.maxH) {
|
||||
hack.maxH = rect.bottom;
|
||||
hackSizeChanged = true;
|
||||
}
|
||||
// !!! --- RESIZE HACK END -------
|
||||
|
@ -534,8 +535,7 @@ function() {
|
|||
},
|
||||
// !!! --- RESIZE HACK END -------
|
||||
|
||||
handleMozAfterSizeChange: function handleMozAfterSizeChange(ev) {
|
||||
dump("win\n");
|
||||
handleMozAfterSizeChange: function handleMozAfterPaint(ev) {
|
||||
// !!! --- RESIZE HACK BEGIN -----
|
||||
// get the correct properties off of the event, these are wrong because
|
||||
// we're using a MouseEvent since it has an X and Y prop of some sort and
|
||||
|
@ -543,9 +543,6 @@ function() {
|
|||
let w = ev.screenX;
|
||||
let h = ev.screenY;
|
||||
// !!! --- RESIZE HACK END -------
|
||||
|
||||
debugger;
|
||||
|
||||
this.setViewportDimensions(this.browserToViewport(w), this.browserToViewport(h));
|
||||
},
|
||||
|
||||
|
@ -555,8 +552,8 @@ function() {
|
|||
if (!browser)
|
||||
return;
|
||||
|
||||
let [w, h] = getBrowserDimensions(browser);
|
||||
this.setZoomLevel(pageZoomLevel(this._visibleRect, w, h));
|
||||
let [w, h] = BrowserView.Util.getBrowserDimensions(browser);
|
||||
this.setZoomLevel(BrowserView.Util.pageZoomLevel(this._visibleRect, w, h));
|
||||
},
|
||||
|
||||
zoom: function zoom(aDirection) {
|
||||
|
@ -609,19 +606,23 @@ function() {
|
|||
//
|
||||
|
||||
_restoreBrowser: function _restoreBrowser(browser) {
|
||||
let bvs = null;
|
||||
|
||||
if (browser) {
|
||||
let vr = this._visibleRect;
|
||||
|
||||
if (!seenBrowser(browser))
|
||||
initBrowserState(browser, vr);
|
||||
if (!BrowserView.Util.seenBrowser(browser))
|
||||
BrowserView.Util.initBrowserState(browser, vr);
|
||||
|
||||
let bvs = getViewportStateFromBrowser(browser);
|
||||
bvs = BrowserView.Util.getViewportStateFromBrowser(browser);
|
||||
|
||||
this._contentWindow = browser.contentWindow;
|
||||
this._browser = browser;
|
||||
this._browserViewportState = bvs;
|
||||
vr.left = bvs.visibleX;
|
||||
vr.top = bvs.visibleY;
|
||||
this._tileManager.setBrowser(browser);
|
||||
}
|
||||
|
||||
this._browser = browser;
|
||||
this._contentWindow = (browser) ? browser.contentWindow : null;
|
||||
this._browserViewportState = bvs;
|
||||
},
|
||||
|
||||
_viewportChanged: function _viewportChanged(viewportSizeChanged, dirtyAll) {
|
||||
|
@ -650,16 +651,16 @@ function() {
|
|||
if (dirtyAll) {
|
||||
// We're about to mark the entire viewport dirty, so we can clear any
|
||||
// queued afterPaint events that will cause redundant draws
|
||||
getBrowserDOMWindowUtils(this._browser).clearMozAfterPaintEvents();
|
||||
BrowserView.Util.getBrowserDOMWindowUtils(this._browser).clearMozAfterPaintEvents();
|
||||
}
|
||||
*/
|
||||
// !!! --- RESIZE HACK END -------
|
||||
|
||||
if (bvs) {
|
||||
resizeContainerToViewport(this._container, bvs.viewportRect);
|
||||
BrowserView.Util.resizeContainerToViewport(this._container, bvs.viewportRect);
|
||||
|
||||
this._tileManager.viewportChangeHandler(bvs.viewportRect,
|
||||
visibleRectToCriticalRect(vis, bvs),
|
||||
BrowserView.Util.visibleRectToCriticalRect(vis, bvs),
|
||||
viewportSizeChanged,
|
||||
dirtyAll);
|
||||
}
|
||||
|
@ -671,7 +672,11 @@ function() {
|
|||
canvas.style.position = "absolute";
|
||||
canvas.style.left = tile.x + "px";
|
||||
canvas.style.top = tile.y + "px";
|
||||
// XXX better for the jit
|
||||
|
||||
// XXX The above causes a trace abort, and this function is called back in the tight
|
||||
// render-heavy loop in TileManager, so even though what we do below isn't so proper
|
||||
// and takes longer on the Platform/C++ emd, it's better than causing a trace abort
|
||||
// in our tight loop. :/
|
||||
//canvas.setAttribute("style", "position: absolute; left: " + tile.boundRect.left + "px; " + "top: " + tile.boundRect.top + "px;");
|
||||
|
||||
this._container.appendChild(canvas);
|
||||
|
@ -687,16 +692,20 @@ function() {
|
|||
//dump('-- ' + tile.toString(true) + endl);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
)();
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Helper structures
|
||||
//
|
||||
|
||||
/**
|
||||
* A BrowserViewportState maintains viewport state information that is unique to each
|
||||
* browser. It does not hold *all* viewport state maintained by BrowserView. For
|
||||
* instance, it does not maintain width and height of the visible rectangle (but it
|
||||
* does keep the top and left coordinates (cf visibleX, visibleY)), since those are not
|
||||
* characteristic of the current browser in view.
|
||||
*/
|
||||
BrowserView.BrowserViewportState = function(viewportRect,
|
||||
visibleX,
|
||||
visibleY,
|
||||
|
|
|
@ -193,7 +193,7 @@ CanvasBrowser.prototype = {
|
|||
// or a flush operation on the queue. XXX need tochanged justone to
|
||||
// be based on time taken..ie do as many paints as we can <200ms
|
||||
// returns true if q is cleared
|
||||
flushRegion: function flushRegion(viewingBoundsOnly) {
|
||||
/* flushRegion: function flushRegion(viewingBoundsOnly) {
|
||||
let rgn = this._rgnPage;
|
||||
|
||||
let drawls = [];
|
||||
|
@ -291,7 +291,7 @@ CanvasBrowser.prototype = {
|
|||
// region ends up in a funny state unless it's reset
|
||||
this._rgnPage.setToRect(0,0,0,0);
|
||||
},
|
||||
|
||||
*/
|
||||
startLoading: function startLoading() {
|
||||
this._maxRight = 0;
|
||||
this._maxBottom = 0;
|
||||
|
@ -300,13 +300,15 @@ CanvasBrowser.prototype = {
|
|||
},
|
||||
|
||||
endLoading: function endLoading() {
|
||||
dump("*** done loading\n");
|
||||
|
||||
this._pageLoading = false;
|
||||
this._lazyWidthChanged = false;
|
||||
this._lazyHeightChanged = false;
|
||||
this.zoomToPage();
|
||||
// flush the region, to reduce startPanning delay
|
||||
// and to avoid getting a black border in tab thumbnail
|
||||
this.flushRegion();
|
||||
this._criticalRegionPaint();
|
||||
|
||||
if (this._drawTimeout) {
|
||||
clearTimeout(this._drawTimeout);
|
||||
|
@ -317,58 +319,53 @@ CanvasBrowser.prototype = {
|
|||
// flush outstanding dirty rects,
|
||||
// switch to unoptimized painting mode during panning
|
||||
startPanning: function startPanning() {
|
||||
this.flushRegion();
|
||||
this._criticalRegionPaint();
|
||||
|
||||
// do not delay paints as that causes displaced painting bugs
|
||||
this._isPanning = true;
|
||||
},
|
||||
|
||||
endPanning: function endPanning() {
|
||||
this.flushRegion();
|
||||
this._criticalRegionPaint();
|
||||
|
||||
this._isPanning = false;
|
||||
},
|
||||
|
||||
viewportHandler: function viewportHandler(bounds, boundsSizeChanged) {
|
||||
// This is the callback fired by WidgetStack whenever the viewport
|
||||
// changes somehow.
|
||||
viewportHandler: function viewportHandler(viewportBoundsRect,
|
||||
viewportInnerBoundsRect,
|
||||
viewportVisibleRect,
|
||||
boundsSizeChanged) {
|
||||
this._isPanning = false;
|
||||
let pageBounds = bounds.clone();
|
||||
let visibleBounds = ws.viewportVisibleRect;
|
||||
|
||||
this._viewportRect = viewportBoundsRect;
|
||||
this._canvasCoordsInViewport = [viewportInnerBoundsRect.x, viewportInnerBoundsRect.y];
|
||||
this._visibleRect = viewportVisibleRect;
|
||||
|
||||
// do not floor top/left, or the blit below will be off
|
||||
pageBounds.top = this._screenToPage(pageBounds.top);
|
||||
pageBounds.left = this._screenToPage(pageBounds.left);
|
||||
pageBounds.bottom = Math.ceil(this._screenToPage(pageBounds.bottom));
|
||||
pageBounds.right = Math.ceil(this._screenToPage(pageBounds.right));
|
||||
//pageBounds.top = this._screenToPage(pageBounds.top);
|
||||
//pageBounds.left = this._screenToPage(pageBounds.left);
|
||||
//pageBounds.bottom = Math.ceil(this._screenToPage(pageBounds.bottom));
|
||||
//pageBounds.right = Math.ceil(this._screenToPage(pageBounds.right));
|
||||
|
||||
visibleBounds.top = Math.max(0, this._screenToPage(visibleBounds.top));
|
||||
visibleBounds.left = Math.max(0, this._screenToPage(visibleBounds.left));
|
||||
visibleBounds.bottom = Math.ceil(this._screenToPage(visibleBounds.bottom));
|
||||
visibleBounds.right = Math.ceil(this._screenToPage(visibleBounds.right));
|
||||
//visibleBounds.top = Math.max(0, this._screenToPage(visibleBounds.top));
|
||||
//visibleBounds.left = Math.max(0, this._screenToPage(visibleBounds.left));
|
||||
//visibleBounds.bottom = Math.ceil(this._screenToPage(visibleBounds.bottom));
|
||||
//visibleBounds.right = Math.ceil(this._screenToPage(visibleBounds.right));
|
||||
|
||||
// if the page is being panned, flush the queue, so things blit correctly
|
||||
// this avoids incorrect offsets due to a change in _pageBounds.x/y
|
||||
// should probably check that (visibleBounds|pageBounds).(x|y) actually changed
|
||||
if (boundsSizeChanged) {
|
||||
this.clearRegion();
|
||||
|
||||
// since we are going to repaint the whole browser
|
||||
// any outstanding paint events will cause redundant draws
|
||||
this.contentDOMWindowUtils.clearMozAfterPaintEvents();
|
||||
} else
|
||||
this.flushRegion();
|
||||
this._redrawRects([this._viewportRect.clone()]);
|
||||
|
||||
this._visibleBounds = visibleBounds;
|
||||
this._pageBounds = pageBounds;
|
||||
|
||||
let dx = this._screenX - bounds.x;
|
||||
let dy = this._screenY - bounds.y;
|
||||
this._screenX = bounds.x;
|
||||
this._screenY = bounds.y;
|
||||
|
||||
if (boundsSizeChanged) {
|
||||
this._redrawRects([pageBounds]);
|
||||
return;
|
||||
} else {
|
||||
this._criticalRegionPaint();
|
||||
}
|
||||
|
||||
/*
|
||||
// deal with repainting
|
||||
// we don't need to do anything if the source and destination are the same
|
||||
if (!dx && !dy) {
|
||||
|
@ -495,8 +492,10 @@ CanvasBrowser.prototype = {
|
|||
let contentW = self._maxRight;
|
||||
let [canvasW, ] = self.canvasDimensions;
|
||||
|
||||
if (contentW > canvasW)
|
||||
this.zoomLevel = canvasW / contentW;
|
||||
if (contentW > canvasW) {
|
||||
this._safeSetSoomLevel(canvasW / contentW); // XXX using 'this' instead of 'self'. This shouldn't work?
|
||||
Browser.updateViewportSize();
|
||||
}
|
||||
|
||||
self._lazyWidthChanged = false;
|
||||
} else if (self._lazyHeightChanged) {
|
||||
|
@ -533,7 +532,7 @@ CanvasBrowser.prototype = {
|
|||
if (flushNow) {
|
||||
resizeAndPaint(this);
|
||||
}
|
||||
},
|
||||
},*/
|
||||
|
||||
_clampZoomLevel: function _clampZoomLevel(aZoomLevel) {
|
||||
const min = 0.2;
|
||||
|
@ -542,8 +541,12 @@ CanvasBrowser.prototype = {
|
|||
return Math.min(Math.max(min, aZoomLevel), max);
|
||||
},
|
||||
|
||||
_safeSetZoomLevel: function _safeSetZoomLevel(zl) {
|
||||
this._zoomLevel = this._clampZoomLevel(zl);
|
||||
},
|
||||
|
||||
set zoomLevel(val) {
|
||||
this._zoomLevel = this._clampZoomLevel(val);
|
||||
this._safeSetZoomLevel(val);
|
||||
Browser.updateViewportSize();
|
||||
},
|
||||
|
||||
|
@ -588,7 +591,7 @@ CanvasBrowser.prototype = {
|
|||
|
||||
let elRect = this._getPagePosition(aElement);
|
||||
let elWidth = elRect.width;
|
||||
let visibleViewportWidth = this._pageToScreen(this._visibleBounds.width);
|
||||
let visibleViewportWidth = this._visibleRect.width;
|
||||
/* Try to set zoom-level such that once zoomed element is as wide
|
||||
* as the visible viewport */
|
||||
let zoomLevel = visibleViewportWidth / (elWidth + (2 * margin));
|
||||
|
@ -648,12 +651,15 @@ CanvasBrowser.prototype = {
|
|||
let [scrollX, scrollY] = this.contentScrollValues;
|
||||
let r = aElement.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
width: r.width,
|
||||
height: r.height,
|
||||
x: r.left + scrollX,
|
||||
y: r.top + scrollY
|
||||
};
|
||||
return new wsRect(r.left + scrollX,
|
||||
r.top + scrollY,
|
||||
r.width, r.height);
|
||||
//return {
|
||||
// width: r.width,
|
||||
// height: r.height,
|
||||
// x: r.left + scrollX,
|
||||
// y: r.top + scrollY
|
||||
//};
|
||||
},
|
||||
|
||||
/* Given a set of client coordinates (relative to the app window),
|
||||
|
@ -664,9 +670,10 @@ CanvasBrowser.prototype = {
|
|||
// Need to adjust for the deckbrowser not being at 0,0
|
||||
// (e.g. due to other browser UI)
|
||||
|
||||
let [canvasX, canvasY] = this._canvasCoordsInViewport;
|
||||
let canvasRect = this._canvas.getBoundingClientRect();
|
||||
let clickOffsetX = this._screenToPage(aClientX - canvasRect.left) + this._pageBounds.x;
|
||||
let clickOffsetY = this._screenToPage(aClientY - canvasRect.top) + this._pageBounds.y;
|
||||
let clickOffsetX = this._screenToPage(aClientX - canvasRect.left + canvasX);
|
||||
let clickOffsetY = this._screenToPage(aClientY - canvasRect.top + canvasY);
|
||||
|
||||
// Take scroll offset into account to return coordinates relative to the viewport
|
||||
let [scrollX, scrollY] = this.contentScrollValues;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Roy Frostig <rfrostig@mozilla.com>
|
||||
* Stuart Parmenter <stuart@mozilla.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
|
||||
|
@ -40,30 +41,11 @@
|
|||
const kXHTMLNamespaceURI = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
// base-2 exponent for width, height of a single tile.
|
||||
const kTileExponentWidth = 6;
|
||||
const kTileExponentHeight = 6;
|
||||
const kTileExponentWidth = 7;
|
||||
const kTileExponentHeight = 7;
|
||||
const kTileWidth = Math.pow(2, kTileExponentWidth); // 2^7 = 128
|
||||
const kTileHeight = Math.pow(2, kTileExponentHeight); // 2^7 = 128
|
||||
const kLazyRoundTimeCap = 500; // millis
|
||||
|
||||
|
||||
function bind(f, thisObj) {
|
||||
return function() {
|
||||
return f.apply(thisObj, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
function bindSome(instance, methodNames) {
|
||||
for each (let methodName in methodNames)
|
||||
if (methodName in instance)
|
||||
instance[methodName] = bind(instance[methodName], instance);
|
||||
}
|
||||
|
||||
function bindAll(instance) {
|
||||
for (let key in instance)
|
||||
if (instance[key] instanceof Function)
|
||||
instance[key] = bind(instance[key], instance);
|
||||
}
|
||||
const kTileLazyRoundTimeCap = 500; // millis
|
||||
|
||||
|
||||
/**
|
||||
|
@ -95,10 +77,6 @@ function TileManager(appendTile, removeTile, browserView) {
|
|||
// in the sense that it must be rendered as soon as it becomes dirty
|
||||
this._criticalRect = null;
|
||||
|
||||
// Current <browser> DOM element, holding the content we wish to render.
|
||||
// This is null when no browser is attached
|
||||
this._browser = null;
|
||||
|
||||
// if we have an outstanding paint timeout, its value is stored here
|
||||
// for cancelling when we end page loads
|
||||
//this._drawTimeout = 0;
|
||||
|
@ -122,8 +100,6 @@ function TileManager(appendTile, removeTile, browserView) {
|
|||
|
||||
TileManager.prototype = {
|
||||
|
||||
setBrowser: function setBrowser(b) { this._browser = b; },
|
||||
|
||||
// This is the callback fired by our client whenever the viewport
|
||||
// changed somehow (or didn't change but someone asked it to update).
|
||||
viewportChangeHandler: function viewportChangeHandler(viewportRect,
|
||||
|
@ -133,7 +109,7 @@ TileManager.prototype = {
|
|||
// !!! --- DEBUG BEGIN -----
|
||||
dump("***vphandler***\n");
|
||||
dump(viewportRect.toString() + "\n");
|
||||
dump((criticalRect ? criticalRect.toString() : "null") + "\n");
|
||||
dump(criticalRect.toString() + "\n");
|
||||
dump(boundsSizeChanged + "\n");
|
||||
dump(dirtyAll + "\n***************\n");
|
||||
// !!! --- DEBUG END -------
|
||||
|
@ -180,7 +156,6 @@ TileManager.prototype = {
|
|||
},
|
||||
|
||||
beginCriticalMove: function beginCriticalMove(destCriticalRect) {
|
||||
let start = Date.now();
|
||||
function appendNonDirtyTile(tile) {
|
||||
if (!tile.isDirty())
|
||||
this._appendTileSafe(tile);
|
||||
|
@ -188,18 +163,9 @@ TileManager.prototype = {
|
|||
|
||||
if (destCriticalRect)
|
||||
this._tileCache.forEachIntersectingRect(destCriticalRect, false, appendNonDirtyTile, this);
|
||||
let end = Date.now();
|
||||
dump("start: " + (end-start) + "\n")
|
||||
},
|
||||
|
||||
beginCriticalMove2: function beginCriticalMove(destCriticalRect) {
|
||||
/*
|
||||
function appendNonDirtyTile(tile) {
|
||||
if (!tile.isDirty())
|
||||
this._appendTileSafe(tile);
|
||||
}
|
||||
*/
|
||||
|
||||
beginCriticalMoveUnrolled: function beginCriticalMoveUnrolled(destCriticalRect) {
|
||||
let start = Date.now();
|
||||
|
||||
if (destCriticalRect) {
|
||||
|
@ -228,9 +194,7 @@ TileManager.prototype = {
|
|||
|
||||
for (var j = startj; j <= endj; ++j) {
|
||||
for (var i = starti; i <= endi; ++i) {
|
||||
|
||||
// 'this' for getTile needs to be tc
|
||||
|
||||
//tile = this.getTile(i, j, create, evictGuard);
|
||||
//if (!tc.inBounds(i, j)) {
|
||||
if (0 <= i && 0 <= j && i <= tc.iBound && j <= tc.jBound) {
|
||||
|
@ -271,27 +235,22 @@ TileManager.prototype = {
|
|||
}
|
||||
|
||||
let end = Date.now();
|
||||
dump("start: " + (end-start) + "\n")
|
||||
dump("start: " + (end-start) + "\n");
|
||||
},
|
||||
|
||||
endCriticalMove: function endCriticalMove(destCriticalRect, doCriticalPaint) {
|
||||
let start = Date.now();
|
||||
|
||||
let tc = this._tileCache;
|
||||
let cr = this._criticalRect;
|
||||
|
||||
let dcr = destCriticalRect;
|
||||
|
||||
let dcr = destCriticalRect; // XXX help the closure upval analyser with a local let
|
||||
let f = function releaseOldTile(tile) {
|
||||
// release old tile
|
||||
if (!tile.boundRect.intersects(dcr))
|
||||
tc.releaseTile(tile);
|
||||
}
|
||||
};
|
||||
|
||||
if (cr)
|
||||
tc.forEachIntersectingRect(cr, false, f, this);
|
||||
|
||||
if (dcr)
|
||||
this._holdRect(destCriticalRect);
|
||||
|
||||
if (cr)
|
||||
|
@ -299,13 +258,8 @@ TileManager.prototype = {
|
|||
else
|
||||
this._criticalRect = cr = destCriticalRect;
|
||||
|
||||
let crpstart = Date.now();
|
||||
if (doCriticalPaint)
|
||||
this.criticalRectPaint();
|
||||
dump(" crp: " + (Date.now() - crpstart) + "\n");
|
||||
|
||||
let end = Date.now();
|
||||
dump("end: " + (end - start) + "\n");
|
||||
},
|
||||
|
||||
restartLazyCrawl: function restartLazyCrawl(startRectOrQueue) {
|
||||
|
@ -351,7 +305,7 @@ TileManager.prototype = {
|
|||
|
||||
_renderTile: function _renderTile(tile) {
|
||||
if (tile.isDirty())
|
||||
tile.render(this._browser, this._browserView);
|
||||
tile.render(this._browserView);
|
||||
},
|
||||
|
||||
_appendTileSafe: function _appendTileSafe(tile) {
|
||||
|
@ -406,7 +360,7 @@ TileManager.prototype = {
|
|||
let start = Date.now();
|
||||
let comeAgain = true;
|
||||
|
||||
while ((Date.now() - start) <= kLazyRoundTimeCap) {
|
||||
while ((Date.now() - start) <= kTileLazyRoundTimeCap) {
|
||||
let tile = self._crawler.next();
|
||||
|
||||
if (!tile) {
|
||||
|
@ -594,7 +548,6 @@ TileManager.TileCache.prototype = {
|
|||
|
||||
} else {
|
||||
// assert: nTiles == capacity
|
||||
dump("\nevicting\n");
|
||||
tile = this._evictTile(evictionGuard);
|
||||
if (tile)
|
||||
this._reassignTile(tile, i, j);
|
||||
|
@ -750,7 +703,7 @@ TileManager.Tile = function Tile(i, j) {
|
|||
this._canvas.setAttribute("width", String(kTileWidth));
|
||||
this._canvas.setAttribute("height", String(kTileHeight));
|
||||
this._canvas.setAttribute("moz-opaque", "true");
|
||||
this._canvas.style.border = "1px solid red";
|
||||
//this._canvas.style.border = "1px solid red";
|
||||
|
||||
this.init(i, j); // defines more properties, cf below
|
||||
};
|
||||
|
@ -846,7 +799,7 @@ TileManager.Tile.prototype = {
|
|||
* to render, as this will cause the entire tile to re-render in the
|
||||
* case that it is not dirty.
|
||||
*/
|
||||
render: function render(browser, browserView) {
|
||||
render: function render(browserView) {
|
||||
if (!this.isDirty())
|
||||
this.markDirty();
|
||||
|
||||
|
@ -856,20 +809,17 @@ TileManager.Tile.prototype = {
|
|||
let y = rect.top - this.boundRect.top;
|
||||
|
||||
browserView.viewportToBrowserRect(rect);
|
||||
//rect.round(); // snap outward to get whole "pixel" (in browser coords)
|
||||
|
||||
let sourceContent = browserView._contentWindow;
|
||||
let ctx = this._canvas.getContext("2d");
|
||||
ctx.save();
|
||||
|
||||
browserView.browserToViewportCanvasContext(ctx);
|
||||
|
||||
ctx.translate(x, y);
|
||||
|
||||
let cw = browserView._contentWindow;
|
||||
//let cw = browser.contentWindow;
|
||||
ctx.drawWindow(cw,
|
||||
ctx.drawWindow(sourceContent,
|
||||
rect.left, rect.top,
|
||||
rect.right - rect.left, rect.bottom - rect.top,
|
||||
rect.width, rect.height,
|
||||
"grey",
|
||||
(ctx.DRAWWINDOW_DO_NOT_FLUSH | ctx.DRAWWINDOW_DRAW_CARET));
|
||||
|
||||
|
@ -924,7 +874,7 @@ TileManager.CrawlIterator = function CrawlIterator(tileCache, startRect) {
|
|||
// filters the tiles we've already reused once from being considered victims
|
||||
// for reuse when we ask the tile cache to create a new tile
|
||||
let visited = this._visited;
|
||||
this._notVisited = function(tile) { return !visited[tile]; };
|
||||
this._notVisited = function(tile) { return !visited[tile.toString()]; };
|
||||
|
||||
// a generator that generates tile indices corresponding to tiles intersecting
|
||||
// the boundary of an expanding rectangle
|
||||
|
@ -1011,7 +961,7 @@ TileManager.CrawlIterator.prototype = {
|
|||
}
|
||||
|
||||
if (tile) {
|
||||
this._visited[tile] = true;
|
||||
this._visited[tile.toString()] = true;
|
||||
} else {
|
||||
this.becomeQueue();
|
||||
return this.next();
|
||||
|
|
Загрузка…
Ссылка в новой задаче