gecko/mobile/chrome/content/deckbrowser.xml

342 lines
12 KiB
XML
Raw Normal View History

<?xml version="1.0"?>
<!DOCTYPE bindings PUBLIC "-//MOZILLA//DTD XBL V1.0//EN" "http://www.mozilla.org/xbl">
<bindings
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="deckpage">
<content>
<xul:stack anonid="page" class="deckpage-container" flex="1">
<html:canvas anonid="canvas" class="deckpage-canvas"/>
<xul:vbox align="start">
<xul:image anonid="close" class="deckpage-close"/>
</xul:vbox>
</xul:stack>
</content>
</binding>
<binding id="deckbrowser">
<content>
<xul:stack flex="1">
<xul:deck anonid="container" class="deckbrowser-container" flex="1">
</xul:deck>
<xul:scrollbox anonid="renderspace" class="deckbrowser-renderspace" style="visibility: hidden" flex="1">
<html:canvas anonid="canvas"/>
</xul:scrollbox>
</xul:stack>
<xul:vbox anonid="tabspace" class="deckbrowser-tabspace" collapsed="true" align="center" flex="1">
<xul:description anonid="title" class="deckbrowser-title" crop="end"/>
<xul:description anonid="uri" class="deckbrowser-uri" crop="center"/>
<xul:hbox anonid="tabs" class="deckbrowser-tabs" flex="1" style="overflow-x: auto">
</xul:hbox>
</xul:vbox>
</content>
<implementation>
<constructor>
</constructor>
<field name="_container" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "container");
</field>
<field name="_tabspace" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "tabspace");
</field>
<field name="_renderspace" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "renderspace");
</field>
<field name="_browsers">
null
</field>
<property name="browser" readonly="true">
<getter>
return this._container.selectedPanel;
</getter>
</property>
<property name="browsers" readonly="true">
<getter>
<![CDATA[
if (!this._browsers) {
var browsers = [];
for (var i = 0; i < this._container.childNodes.length; i++)
browsers.push(this._container.childNodes[i]);
this._browsers = browsers;
}
return this._browsers;
]]>
</getter>
</property>
<method name="addBrowser">
<parameter name="aURI"/>
<parameter name="aReferrer"/>
<parameter name="aPostData"/>
<parameter name="aFixUp"/>
<body>
<![CDATA[
var b = document.createElement("browser");
b.setAttribute("class", "deckbrowser-browser");
b.setAttribute("flex", "1");
b.setAttribute("type", "content-targetable");
if (this.hasAttribute("autocompletepopup"))
b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
if (this.hasAttribute("contentcontextmenu"))
b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu"));
this._container.appendChild(b);
this._container.selectedPanel = b;
this._browsers = null;
if (aURI != "about:blank") {
b.stop();
b.loadURI(aURI, aReferrer, aPostData, aFixup);
}
// Broadcast creation
var event = document.createEvent("Event");
event.initEvent("TabOpen", true, false);
b.dispatchEvent(event);
return b;
]]>
</body>
</method>
<method name="removeBrowser">
<parameter name="aBrowser"/>
<body>
<![CDATA[
this._browsers = null;
if (!aBrowser)
aBrowser = this.browser;
var count = this._container.childNodes.length;
if (count == 1) {
var self = this;
setTimeout(function() { self.addBrowser("about:blank"); }, 0);
}
var currentIndex = this._container.selectedIndex;
var index = -1;
for (var i = 0; i<count; i++) {
if (this._container.childNodes[i] == aBrowser)
index = i;
}
// Broadcast removal
var event = document.createEvent("Event");
event.initEvent("TabClose", true, false);
aBrowser.dispatchEvent(event);
this._container.removeChild(aBrowser);
// Select the new tab
var newIndex = -1;
if (currentIndex > index)
newIndex = currentIndex - 1;
else if (currentIndex < index)
newIndex = currentIndex;
else {
newIndex = (index == count - 1) ? index - 1 : index;
}
this._container.selectedIndex = newIndex;
]]>
</body>
</method>
<method name="show">
<parameter name="aBrowser"/>
<body>
<![CDATA[
if (aBrowser.constructor.name == "Number")
aBrowser = this.browsers[aBrowser];
this._container.selectedPanel = aBrowser;
var event = document.createEvent("Event");
event.initEvent("TabSelect", true, false);
aBrowser.dispatchEvent(event);
]]>
</body>
</method>
<method name="select">
<body>
<![CDATA[
var tabs = document.getAnonymousElementByAttribute(this, "anonid", "tabs");
while (tabs.childNodes.length > 0)
tabs.removeChild(tabs.childNodes[0]);
var browsers = this.browsers;
for (var i=0; i<browsers.length; i++) {
var domWin = browsers[i].contentWindow;
var viewW = domWin.innerWidth;
var viewH = domWin.innerHeight;
var canvasW = this.boxObject.width / 1.5;
var canvasH = (viewH / viewW) * canvasW;
var deckpage = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "deckpage");
tabs.appendChild(deckpage);
var canvas = document.getAnonymousElementByAttribute(deckpage, "anonid", "canvas");
canvas.setAttribute("width", canvasW);
canvas.setAttribute("height", canvasH);
canvas.setAttribute("left", "10");
canvas.setAttribute("top", "10");
let self = this;
let target = browsers[i];
var page = document.getAnonymousElementByAttribute(deckpage, "anonid", "page");
function _selectTab(aEvent) {
self.show(target);
self._tabspace.collapsed = true;
self._container.collapsed = false;
}
page.addEventListener("click", _selectTab, false);
var close = document.getAnonymousElementByAttribute(deckpage, "anonid", "close");
function _closeTab(aEvent) {
self.removeBrowser(target);
self._tabspace.collapsed = true;
self._container.collapsed = false;
};
close.addEventListener("click", _closeTab, false);
let title = document.getAnonymousElementByAttribute(this, "anonid", "title");
let uri = document.getAnonymousElementByAttribute(this, "anonid", "uri");
function _hoverTab(aEvent) {
title.value = target.contentDocument.title;
uri.value = target.currentURI.spec;
};
page.addEventListener("mouseover", _hoverTab, false);
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvasW, canvasH);
ctx.save();
ctx.scale(canvasW/viewW, canvasH/viewH);
ctx.drawWindow(domWin, 0, 0, viewW, viewH, "rgba(0,0,0,0)");
ctx.restore();
}
this._container.collapsed = true;
this._renderspace.collapse = true;
this._tabspace.collapsed = false;
]]>
</body>
</method>
<field name="_updateTimer">
null
</field>
<method name="_updateCanvas">
<parameter name="aOffsetX"/>
<parameter name="aOffsetY"/>
<body>
<![CDATA[
var posX = aOffsetX;
var posY = aOffsetY;
var canvas = document.getAnonymousElementByAttribute(this, "anonid", "canvas");
var domWin = this.browser.contentWindow;
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
var stime = Date.now();
ctx.save();
ctx.translate(posX, posY);
ctx.drawWindow(domWin, posX, posY, domWin.innerWidth, domWin.innerHeight, "rgba(0,0,0,0)");
ctx.restore();
var etime = Date.now();
dump("drawWindow: " + (etime - stime) + " ms\n");
]]>
</body>
</method>
<method name="startPan">
<parameter name="aEvent"/>
<body>
<![CDATA[
var canvas = document.getAnonymousElementByAttribute(this, "anonid", "canvas");
var domWin = this.browser.contentWindow;
var canvasW = domWin.innerWidth + domWin.scrollMaxX;
var canvasH = domWin.innerHeight + domWin.scrollMaxY;
canvas.width = canvasW;
canvas.height = canvasH;
this._updateCanvas(domWin.scrollX, domWin.scrollY);
this._updateTimer = null;
// Must uncollapse the scroller before scrolling it into position.
// It fails to scroll otherwise.
this._container.style.visibility = "hidden";
this._renderspace.style.visibility = "visible";
var domWin = this.browser.contentWindow;
var scroller = this._renderspace.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
scroller.scrollTo(domWin.scrollX, domWin.scrollY);
]]>
</body>
</method>
<method name="doPan">
<parameter name="aEvent"/>
<parameter name="aDeltaX"/>
<parameter name="aDeltaY"/>
<body>
<![CDATA[
var scroller = this._renderspace.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
scroller.scrollBy(aDeltaX, aDeltaY);
var sx = {}; var sy = {};
scroller.getPosition(sx, sy);
if (this._updateTimer) {
clearTimeout(this._updateTimer);
this._updateTimer = null;
}
var self = this;
this._updateTimer = setTimeout(function() { self._updateCanvas(sx.value, sy.value); }, 250);
]]>
</body>
</method>
<method name="endPan">
<parameter name="aEvent"/>
<body>
<![CDATA[
if (this._updateTimer) {
clearTimeout(this._updateTimer);
this._updateTimer = null;
}
var scroller = this._renderspace.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
var sx = {}; var sy = {};
scroller.getPosition(sx, sy);
var domWin = this.browser.contentWindow;
domWin.scrollTo(sx.value, sy.value);
scroller.scrollTo(0, 0);
this._renderspace.style.visibility = "hidden";
this._container.style.visibility = "visible";
]]>
</body>
</method>
</implementation>
<handlers>
</handlers>
</binding>
</bindings>