gecko/mobile/chrome/content/foo.xul
2009-07-17 17:14:49 -07:00

470 lines
15 KiB
XML

<window
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
onload="onAlmostLoad();"
style="background-color:white;"
width="800"
height="480"
onresize="onResize();"
onkeypress="onKeyPress(event);">
<script type="application/x-javascript" src="WidgetStack.js"/>
<script type="application/x-javascript" src="TileManager.js"/>
<script type="application/x-javascript;version=1.8" src="BrowserView.js"/>
<script type="application/x-javascript;version=1.8">
<![CDATA[
// We do not endorse the use of globals, but this is just a closed lab
// environment. What could possibly go wrong? ...
let bv = null;
let scrollbox = null;
let leftbar = null;
let rightbar = null;
let topbar = null;
function debug() {
let w = {};
let h = {};
scrollbox.getScrolledSize(w, h);
let container = document.getElementById("tile_container");
let [x, y] = getScrollboxPosition();
let [w, h] = [w.value, h.value];
if (bv) {
dump('----------------------DEBUG!-------------------------\n');
dump(bv._browserViewportState.toString() + endl);
dump(endl);
let cr = bv._tileManager._criticalRect;
dump('criticalRect from BV: ' + (cr ? cr.toString() : null) + endl);
dump('visibleRect from BV : ' + bv._visibleRect.toString() + endl);
dump('visibleRect from foo: ' + scrollboxToViewportRect(getVisibleRect()) + endl);
dump(endl);
dump('container width,height from BV: ' + bv._container.style.width + ', '
+ bv._container.style.height + endl);
dump('container width,height via DOM: ' + container.style.width + ', '
+ container.style.height + endl);
dump(endl);
dump('scrollbox position : ' + x + ', ' + y + endl);
dump('scrollbox scrolledsize: ' + w + ', ' + h + endl);
dump(endl);
dump('tilecache capacity: ' + bv._tileManager._tileCache.getCapacity() + endl);
dump('tilecache size : ' + bv._tileManager._tileCache.size + endl);
dump('tilecache numFree : ' + bv._tileManager._tileCache.numFree + endl);
dump('tilecache iBound : ' + bv._tileManager._tileCache.iBound + endl);
dump('tilecache jBound : ' + bv._tileManager._tileCache.jBound + endl);
dump('tilecache _lru : ' + bv._tileManager._tileCache._lru + endl);
dump('-----------------------------------------------------\n');
}
}
function debugTile(i, j) {
let tc = bv._tileManager._tileCache;
let t = tc.getTile(i, j);
dump('------ DEBUGGING TILE (' + i + ',' + j + ') --------\n');
dump('in bounds: ' + tc.inBounds(i, j) + endl);
dump('occupied : ' + tc._isOccupied(i, j) + endl);
if (t)
{
dump('toString : ' + t.toString(true) + endl);
dump('free : ' + t.free + endl);
dump('dirtyRect: ' + t._dirtyTileCanvasRect + endl);
let len = tc._tilePool.length;
for (let k = 0; k < len; ++k)
if (tc._tilePool[k] === t)
dump('found in tilePool at index ' + k + endl);
}
dump('------------------------------------\n');
}
function onKeyPress(e) {
const a = 97; // debug all critical tiles
const c = 99; // set tilecache capacity
const d = 100; // debug dump
const f = 102; // run noop() through forEachIntersectingRect (for timing)
const i = 105; // toggle info click mode
const l = 108; // restart lazy crawl
const m = 109; // fix mouseout
const t = 116; // debug given list of tiles separated by space
switch (e.charCode) {
case d:
debug();
break;
case l:
bv._tileManager.restartLazyCrawl(bv._tileManager._criticalRect);
break;
case c:
let cap = parseInt(window.prompt('new capacity'));
bv._tileManager._tileCache.setCapacity(cap);
break;
case f:
let noop = function noop() { for (let i = 0; i < 10; ++i); };
bv._tileManager._tileCache.forEachIntersectingRect(bv._tileManager._criticalRect,
false, noop, window);
break;
case t:
let ijstrs = window.prompt('row,col plz').split(' ');
for each (let ijstr in ijstrs) {
let [i, j] = ijstr.split(',').map(function (x) parseInt(x));
debugTile(i, j);
}
break;
case a:
let cr = bv._tileManager._criticalRect;
dump('>>>>>> critical rect is ' + (cr ? cr.toString() : cr) + endl);
if (cr) {
let starti = cr.left >> kTileExponentWidth;
let endi = cr.right >> kTileExponentWidth;
let startj = cr.top >> kTileExponentHeight;
let endj = cr.bottom >> kTileExponentHeight;
for (var jj = startj; jj <= endj; ++jj)
for (var ii = starti; ii <= endi; ++ii)
debugTile(ii, jj);
}
break;
case i:
window.infoMode = !window.infoMode;
break;
case m:
onMouseUp();
break;
default:
break;
}
}
function onResize(e) {
if (bv) {
bv.beginBatchOperation();
bv.setVisibleRect(scrollboxToViewportRect(getVisibleRect()));
bv.zoomToPage();
bv.commitBatchOperation();
}
}
function onMouseDown(e) {
if (window.infoMode) {
let [basex, basey] = getScrollboxPosition();
let [x, y] = scrollboxToViewportXY(basex + e.clientX, basey + e.clientY);
let i = x >> kTileExponentWidth;
let j = y >> kTileExponentHeight;
debugTile(i, j);
}
window._isDragging = true;
window._dragStart = {x: e.clientX, y: e.clientY};
bv.pauseRendering();
}
function onMouseUp() {
window._isDragging = false;
bv.resumeRendering();
}
function onMouseMove(e) {
if (window._isDragging) {
let x = {};
let y = {};
let w = {};
let h = {};
scrollbox.getPosition(x, y);
scrollbox.getScrolledSize(w, h);
let dx = window._dragStart.x - e.clientX;
let dy = window._dragStart.y - e.clientY;
// XXX if max(x, 0) > scrollwidth we shouldn't do anything (same for y/height)
let newX = Math.max(x.value + dx, 0);
let newY = Math.max(y.value + dy, 0);
if (newX < w.value || newY < h.value) {
// clip dx and dy to prevent us from going below 0
dx = Math.max(dx, -x.value);
dy = Math.max(dy, -y.value);
let oldx = x.value;
let oldy = y.value;
bv.onBeforeVisibleMove(dx, dy);
updateBars(oldx, oldy, dx, dy);
scrollbox.scrollBy(dx, dy);
let [newx, newy] = getScrollboxPosition();
let realdx = newx - oldx;
let realdy = newy - oldy;
updateBars(oldx, oldy, realdx, realdy);
bv.onAfterVisibleMove(realdx, realdy);
}
window._dragStart = {x: e.clientX, y: e.clientY};
}
}
function onAlmostLoad() {
window._isDragging = false;
window.infoMode = false;
window.setTimeout(onLoad, 1500);
}
function onLoad() {
// ----------------------------------------------------
scrollbox = document.getElementById("scrollbox")
.boxObject
.QueryInterface(Components.interfaces.nsIScrollBoxObject);
leftbar = document.getElementById("left_sidebar");
rightbar = document.getElementById("right_sidebar");
topbar = document.getElementById("top_urlbar");
// ----------------------------------------------------
let initX = Math.round(leftbar.getBoundingClientRect().right);
dump('scrolling to ' + initX + endl);
scrollbox.scrollTo(initX, 0);
let [x, y] = getScrollboxPosition();
dump(' scrolled to ' + x + ',' + y + endl);
let container = document.getElementById("tile_container");
container.addEventListener("mousedown", onMouseDown, true);
container.addEventListener("mouseup", onMouseUp, true);
container.addEventListener("mousemove", onMouseMove, true);
bv = new BrowserView(container, scrollboxToViewportRect(getVisibleRect()));
let browser = document.getElementById("googlenews");
bv.setBrowser(browser, false);
}
function updateBars(x, y, dx, dy) {
return;
// shouldn't update margin if it doesn't need to be changed
let sidebars = document.getElementsByClassName("sidebar");
for (let i = 0; i < sidebars.length; i++) {
let sidebar = sidebars[i];
sidebar.style.margin = (y + dy) + "px 0px 0px 0px";
}
let urlbar = document.getElementById("top_urlbar");
urlbar.style.margin = "0px 0px 0px " + (x + dx) + "px";
}
function viewportToScrollboxXY(x, y) {
return scrollboxToViewportXY(x, y, -1);
}
function scrollboxToViewportXY(x, y) {
if (!x) x = 0;
if (!y) y = 0;
// shield your eyes!
let direction = (arguments.length >= 3) ? arguments[2] : 1;
let leftbarcr = leftbar.getBoundingClientRect();
let rightbarcr = rightbar.getBoundingClientRect();
let topbarcr = topbar.getBoundingClientRect();
let xtrans = direction * (-leftbarcr.width);
let ytrans = direction * (-topbarcr.height);
x += xtrans;
y += ytrans;
return [x, y];
}
function scrollboxToBrowserXY(browserView, x, y) {
[x, y] = scrollboxToViewportXY(x, y);
return [browserView.viewportToBrowser(x),
browserView.viewportToBrowser(y)];
}
function scrollboxToViewportRect(rect) {
let leftbarcr = leftbar.getBoundingClientRect();
let topbarcr = topbar.getBoundingClientRect();
let xtrans = -leftbarcr.width;
let ytrans = -topbarcr.height;
rect.translate(xtrans, ytrans);
return rect;
}
function getScrollboxPosition() {
let x = {};
let y = {};
scrollbox.getPosition(x, y);
return [x.value, y.value];
}
function getContentScrollValues(browser) {
let cwu = getBrowserDOMWindowUtils(browser);
let scrollX = {};
let scrollY = {};
cwu.getScrollXY(false, scrollX, scrollY);
return [scrollX.value, scrollY.value];
}
function getBrowserDOMWindowUtils(browser) {
return browser.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
}
function getBrowserClientRect(browser, el) {
let [scrollX, scrollY] = getContentScrollValues(browser);
let r = el.getBoundingClientRect();
return new wsRect(r.left + scrollX,
r.top + scrollY,
r.width, r.height);
}
function scrollToElement(browser, el) {
var elRect = getPagePosition(browser, el);
bv.browserToViewportRect(elRect);
elRect.round();
this.scrollTo(elRect.x, elRect.y);
}
function zoomToElement(aElement) {
const margin = 15;
let elRect = getBrowserClientRect(browser, aElement);
let elWidth = elRect.width;
let vrWidth = bv.visibleRect.width;
/* Try to set zoom-level such that once zoomed element is as wide
* as the visible rect */
let zoomLevel = vrtWidth / (elWidth + (2 * margin));
bv.beginBatchOperation();
bv.setZoomLevel(zoomLevel);
/* If zoomLevel ends up clamped to less than asked for, calculate
* how many more screen pixels will fit horizontally in addition to
* element's width. This ensures that more of the webpage is
* showing instead of the navbar. Bug 480595. */
let xpadding = Math.max(margin, vrWidth - bv.browserToViewport(elWidth));
// XXX TODO these arguments are wrong, we still have to transform the coordinates
// from viewport to scrollbox before sending them to scrollTo
this.scrollTo(Math.floor(Math.max(bv.browserToViewport(elRect.x) - xpadding, 0)),
Math.floor(Math.max(bv.browserToViewport(elRect.y) - margin, 0)));
bv.commitBatchOperation();
}
function zoomFromElement(browser, aElement) {
let elRect = getBrowserClientRect(browser, aElement);
bv.beginBatchOperation();
// pan to the element
// don't bother with x since we're zooming all the way out
bv.zoomToPage();
// XXX have this center the element on the page
// XXX TODO these arguments are wrong, we still have to transform the coordinates
// from viewport to scrollbox before sending them to scrollTo
this.scrollTo(0, Math.floor(Math.max(0, bv.browserToViewport(elRect.y))));
bv.commitBatchOperation();
}
/**
* Retrieve the content element for a given point in client coordinates
* (relative to the top left corner of the chrome window).
*/
function elementFromPoint(browser, browserView, x, y) {
[x, y] = scrollboxToBrowserXY(browserView, x, y);
let cwu = getBrowserDOMWindowUtils(browser);
return cwu.elementFromPoint(x, y,
true, /* ignore root scroll frame*/
false); /* don't flush layout */
}
/* ensures that a given content element is visible */
function ensureElementIsVisible(browser, aElement) {
let elRect = getBrowserClientRect(browser, aElement);
bv.browserToViewportRect(elRect);
let curRect = bv.visibleRect;
let newx = curRect.x;
let newy = curRect.y;
if (elRect.x < curRect.x || elRect.width > curRect.width) {
newx = elRect.x;
} else if (elRect.x + elRect.width > curRect.x + curRect.width) {
newx = elRect.x - curRect.width + elRect.width;
}
if (elRect.y < curRect.y || elRect.height > curRect.height) {
newy = elRect.y;
} else if (elRect.y + elRect.height > curRect.y + curRect.height) {
newy = elRect.y - curRect.height + elRect.height;
}
// XXX TODO these arguments are wrong, we still have to transform the coordinates
// from viewport to scrollbox before sending them to scrollTo
this.scrollTo(newx, newy);
}
// this is a mehful way of getting the visible rect in scrollbox coordinates
// that we use in this here lab environment and hopefully nowhere in real fennec
function getVisibleRect() {
let w = window.innerWidth;
let h = window.innerHeight;
let [x, y] = getScrollboxPosition();
return new wsRect(x, y, w, h);
}
]]>
</script>
<scrollbox id="scrollbox" style="-moz-box-orient: vertical; overflow: scroll;" flex="1">
<hbox id="top_urlbar" style="background-color: pink"><textbox flex="1"/></hbox>
<hbox style="position: relative">
<vbox id="left_sidebar" class="sidebar" style="background-color: red"><button label="left sidebar"/></vbox>
<box>
<html:div id="tile_container" style="position: relative; width: 800px; height: 480px; overflow: -moz-hidden-unscrollable;"/>
</box>
<vbox id="right_sidebar" class="sidebar" style="background-color: blue"><button label="right sidebar"/></vbox>
</hbox>
</scrollbox>
<box>
<html:div style="position: relative; overflow: hidden; max-width: 0px; max-height: 0px; visibility: hidden;">
<html:div id="browsers" style="position: absolute;">
<!-- <browser id="googlenews" src="http://www.webhamster.com/" type="content" style="width: 1024px; height: 614px"/> -->
<browser id="googlenews" src="http://slashdot.org/" type="content" style="width: 1024px; height: 614px"/>
</html:div>
</html:div>
</box>
</window>