mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
470 lines
15 KiB
XML
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>
|