Bug 457326: refactor deckbrowser layout to better support canvas sized relative to the viewport (and other minor cleanup), r=mfinkle

This commit is contained in:
Gavin Sharp 2008-09-29 09:53:49 -04:00
Родитель 8f186479ae
Коммит 6b9fe265b9
4 изменённых файлов: 114 добавлений и 84 удалений

Просмотреть файл

@ -41,9 +41,12 @@ pref("general.useragent.extra.mobile", "@APP_UA_NAME@/@APP_VERSION@");
pref("browser.chromeURL", "chrome://browser/content/");
pref("browser.startup.homepage", "http://www.mozilla.org/");
pref("browser.ui.cursor", false);
pref("browser.ui.cursor", true);
pref("browser.ui.panning.kinetic", true);
pref("javascript.options.showInConsole", true);
pref("browser.dom.window.dump.enabled", true);
/* cache prefs */
pref("browser.cache.disk.enable", false);
pref("browser.cache.disk.capacity", 0);

Просмотреть файл

@ -52,6 +52,24 @@ const UIMODE_PANEL = 7;
const kMaxEngines = 4;
const kDefaultFavIconURL = "chrome://browser/skin/images/default-favicon.png";
[
["gContentBox", "contentBox"],
].forEach(function (elementGlobal) {
var [name, id] = elementGlobal;
window.__defineGetter__(name, function () {
var element = document.getElementById(id);
if (!element)
return null;
delete window[name];
return window[name] = element;
});
window.__defineSetter__(name, function (val) {
delete window[name];
return window[name] = val;
});
});
var BrowserUI = {
_panel : null,
_caption : null,
@ -61,6 +79,19 @@ var BrowserUI = {
_favicon : null,
_faviconAdded : false,
_setContentPosition : function (aProp, aValue) {
if (aProp == "left") {
gContentBox.style.marginLeft = aValue + "px";
gContentBox.style.marginRight = -aValue + "px";
} else if (aProp == "top") {
gContentBox.style.marginTop = aValue + "px";
gContentBox.style.marginBottom = -aValue + "px";
}
},
get _contentTop() {
return parseInt(gContentBox.style.marginTop);
},
_titleChanged : function(aDocument) {
var browser = Browser.currentBrowser;
if (browser && aDocument != browser.contentDocument)
@ -94,18 +125,17 @@ var BrowserUI = {
this._favicon.src = browser.mIconURL || kDefaultFavIconURL;
let toolbar = document.getElementById("toolbar-main");
let browserBox = document.getElementById("browser");
if (Browser.content.currentTab.chromeTop) {
// Browser box was panned, so let's reset it
browserBox.top = Browser.content.currentTab.chromeTop;
browserBox.left = 0;
toolbar.top = browserBox.top - toolbar.boxObject.height;
// content box was panned, so let's reset it
this._setContentPosition("top", Browser.content.currentTab.chromeTop);
this._setContentPosition("left", 0);
toolbar.top = this._contentTop - toolbar.boxObject.height;
}
else {
// Must be initial conditions
toolbar.top = 0;
browserBox.top = toolbar.boxObject.height;
browserBox.left = 0;
this._setContentPosition("top", toolbar.boxObject.height);
this._setContentPosition("left", 0);
}
this.show(UIMODE_NONE);
@ -186,21 +216,20 @@ var BrowserUI = {
_scrollToolbar : function bui_scrollToolbar(aEvent) {
var [scrollWidth, ] = Browser.content._contentAreaDimensions;
var [canvasW, ] = Browser.content._effectiveCanvasDimensions;
var [viewportW, ] = Browser.content._effectiveViewportDimensions;
var pannedUI = false;
if (this._dragData.dragging && Browser.content.scrollY == 0) {
let toolbar = document.getElementById("toolbar-main");
let browser = document.getElementById("browser");
let dy = this._dragData.lastY - aEvent.screenY;
this._dragData.dragY += dy;
// NOTE: We should only be scrolling the toolbar if the sidebars are not
// visible (browser.left == 0)
// visible (gContentBox.style.marginLeft == "0px")
let sidebarVisible = gContentBox.style.marginLeft != "0px";
let newTop = null;
if (dy > 0 && (toolbar.top > -toolbar.boxObject.height && browser.left == 0)) {
if (dy > 0 && (toolbar.top > -toolbar.boxObject.height && !sidebarVisible)) {
// Scroll the toolbar up unless it is already scrolled up
newTop = this._dragData.sTop - dy;
@ -212,7 +241,7 @@ var BrowserUI = {
Browser.content.dragData.sX = aEvent.screenX;
Browser.content.dragData.sY = aEvent.screenY;
}
else if (dy < 0 && (toolbar.top < 0 && browser.left == 0)) {
else if (dy < 0 && (toolbar.top < 0 && !sidebarVisible)) {
// Scroll the toolbar down unless it is already down
newTop = this._dragData.sTop - dy;
@ -225,21 +254,20 @@ var BrowserUI = {
// getting to the deckbrowser.
if (newTop != null) {
toolbar.top = newTop;
browser.top = newTop + toolbar.boxObject.height;
this._setContentPosition("top", newTop + toolbar.boxObject.height);
// Cache the current top so we can use it when switching tabs
Browser.content.currentTab.chromeTop = browser.top;
Browser.content.currentTab.chromeTop = this._contentTop;
pannedUI = true;
}
}
if (this._dragData.dragging && (Browser.content.scrollX == 0 || (Browser.content.scrollX + canvasW) == scrollWidth)) {
if (this._dragData.dragging && (Browser.content.scrollX == 0 || (Browser.content.scrollX + viewportW) == scrollWidth)) {
let tabbar = document.getElementById("tab-list-container");
let sidebar = document.getElementById("browser-controls");
let panelUI = document.getElementById("panel-container");
let toolbar = document.getElementById("toolbar-main");
let browser = document.getElementById("browser");
let dx = this._dragData.lastX - aEvent.screenX;
this._dragData.dragX += dx;
@ -249,7 +277,7 @@ var BrowserUI = {
let tabbarW = tabbar.boxObject.width;
let sidebarW = sidebar.boxObject.width;
let browserW = browser.boxObject.width;
let contentW = gContentBox.boxObject.width;
// Limit the panning
if (newLeft > 0)
@ -269,11 +297,11 @@ var BrowserUI = {
if (newLeft + tabbarW != 0)
toolbar.top = 0;
else
toolbar.top = browser.top - toolbar.boxObject.height;
browser.left = newLeft + tabbarW;
sidebar.left = newLeft + tabbarW + browserW;
panelUI.left = newLeft + tabbarW + browserW + sidebarW;
toolbar.top = this._contentTop - toolbar.boxObject.height;
this._setContentPosition("left", newLeft + tabbarW);
sidebar.left = newLeft + tabbarW + contentW;
panelUI.left = newLeft + tabbarW + contentW + sidebarW;
// Set the UI mode based on where we ended up
if (newLeft > -(tabbarW - tabbarW / 3) && newLeft <= 0)
@ -281,7 +309,7 @@ var BrowserUI = {
else if (newLeft >= -(tabbarW + sidebarW) && newLeft < -(tabbarW + sidebarW / 3))
this.mode = UIMODE_CONTROLS;
else
this.mode = (browser.top == 0 ? UIMODE_NONE : UIMODE_URLVIEW);
this.mode = (gContentBox.style.marginTop == "0px" ? UIMODE_NONE : UIMODE_URLVIEW);
pannedUI = true;
}
@ -304,7 +332,6 @@ var BrowserUI = {
_showToolbar : function(aShow) {
var toolbar = document.getElementById("toolbar-main");
var browser = document.getElementById("browser");
if (aShow) {
// Always show the toolbar, either by floating or panning
@ -315,12 +342,12 @@ var BrowserUI = {
else if (toolbar.top < 0) {
// Partially showing, so show it completely
toolbar.top = 0;
browser.top = toolbar.boxObject.height;
this._setContentPosition("top", toolbar.boxObject.height);
}
}
else {
// If we are floating the toolbar, then hide it again
if (browser.top == 0) {
if (gContentBox.style.marginTop == "0px") {
toolbar.top = -toolbar.boxObject.height;
}
}
@ -347,11 +374,10 @@ var BrowserUI = {
let sidebar = document.getElementById("browser-controls");
let panelUI = document.getElementById("panel-container");
let toolbar = document.getElementById("toolbar-main");
let browser = document.getElementById("browser");
let tabbarW = tabbar.boxObject.width;
let sidebarW = sidebar.boxObject.width;
let browserW = browser.boxObject.width;
let contentW = gContentBox.boxObject.width;
let newLeft = -tabbarW;
switch (aMode) {
@ -359,7 +385,7 @@ var BrowserUI = {
Shortcuts.deinit();
break;
case UIMODE_PANEL:
newLeft = -browserW;
newLeft = -contentW;
this._initPanel();
break;
case UIMODE_CONTROLS:
@ -378,10 +404,10 @@ var BrowserUI = {
newToolbarLeft += tabbarW + sidebarW;
toolbar.left = newToolbarLeft;
browser.left = newLeft + tabbarW;
sidebar.left = newLeft + tabbarW + browserW;
panelUI.left = newLeft + tabbarW + browserW + sidebarW;
panelUI.width = browserW;
this._setContentPosition("left", newLeft + tabbarW);
sidebar.left = newLeft + tabbarW + contentW;
panelUI.left = newLeft + tabbarW + contentW + sidebarW;
panelUI.width = contentW;
},
_initPanel : function() {
@ -405,10 +431,6 @@ var BrowserUI = {
var toolbar = document.getElementById("toolbar-main");
var toolbarH = toolbar.boxObject.height;
var browser = document.getElementById("browser");
browser.width = containerW;
browser.height = containerH;
var sidebar = document.getElementById("browser-controls");
var panelUI = document.getElementById("panel-container");
var tabbar = document.getElementById("tab-list-container");
@ -470,8 +492,7 @@ var BrowserUI = {
this._faviconAdded = false;
}
else if (aState == TOOLBARSTATE_LOADED) {
var container = document.getElementById("browser");
container.top = toolbar.boxObject.height;
this._setContentPosition("top", toolbar.boxObject.height);
toolbar.setAttribute("mode", "view");

Просмотреть файл

@ -189,9 +189,11 @@
</popupset>
<stack id="browser-container" flex="1" style="overflow: hidden;">
<vbox id="browser" style="-moz-stack-sizing: ignore; width: 800px; height: 480px;" top="60">
<vbox id="contentBox" style="-moz-stack-sizing: ignore; margin-top: 60px; margin: 0;">
<notificationbox id="notifications" flex="1">
<deckbrowser id="content" autocompletepopup="popup_autocomplete_content" flex="1"
<deckbrowser id="content"
autocompletepopup="popup_autocomplete_content"
flex="1"
onnewtab="CommandUpdater.doCommand('cmd_newTab');"/>
</notificationbox>
</vbox>

Просмотреть файл

@ -10,10 +10,12 @@
<binding id="deckbrowser">
<content>
<xul:deck flex="1" selectedIndex="0">
<xul:stack anonid="cstack" flex="1" style="overflow: hidden;">
<html:canvas anonid="ccanvas"
moz-opaque="true"
style="-moz-stack-sizing: ignore;"/>
<xul:stack flex="1">
<html:div anonid="viewport" style="-moz-stack-sizing: ignore; overflow: hidden;">
<html:canvas anonid="ccanvas"
moz-opaque="true"
style="height: 100%; width: 100%;"/>
</html:div>
</xul:stack>
<xul:deck anonid="display-list" flex="1"/>
</xul:deck>
@ -27,21 +29,21 @@
<constructor><![CDATA[
this._zoomLevel = 1;
// panning
this._stack.addEventListener("mousedown", this.stackEventHandler, true);
// need mouseup handled on the window to catch mouseups on e.g. the toolbar
window.addEventListener("mouseup", this.stackEventHandler, true);
this._stack.addEventListener("mousemove", this.stackEventHandler, true);
var prefsvc = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch2);
this._allowKinetic = prefsvc.getBoolPref("browser.ui.panning.kinetic");
// panning
this._viewport.addEventListener("mousedown", this.stackEventHandler, true);
// need mouseup handled on the window to catch mouseups on e.g. the toolbar
window.addEventListener("mouseup", this.stackEventHandler, true);
this._viewport.addEventListener("mousemove", this.stackEventHandler, true);
// zoom
// FIXME: dblclicks don't work on the device
// this._stack.addEventListener("dblclick", this.stackEventHandler, true);
this._stack.addEventListener("DOMMouseScroll", this.stackEventHandler, true);
// this._viewport.addEventListener("dblclick", this.stackEventHandler, true);
this._viewport.addEventListener("DOMMouseScroll", this.stackEventHandler, true);
var self = this;
var obs = Components.classes["@mozilla.org/observer-service;1"].
@ -54,7 +56,21 @@
this.PAN_EVENTS_TO_TRACK = 2;
this._panEventTracker = new Array(this.PAN_EVENTS_TO_TRACK);
this._panEventTrackerIndex = 0;
]]></constructor>
]]></constructor>
<property name="viewportDimensions" readonly="true">
<getter><![CDATA[
var rect = this._viewport.getBoundingClientRect();
return [rect.width, rect.height];
]]></getter>
</property>
<property name="_effectiveViewportDimensions" readonly="true">
<getter><![CDATA[
var [w, h] = this.viewportDimensions;
return [this._screenToPage(w), this._screenToPage(h)];
]]></getter>
</property>
<property name="dragData" readonly="true">
<getter>
@ -77,8 +93,8 @@
</getter>
</property>
<field name="_stack">
document.getAnonymousElementByAttribute(this, "anonid", "cstack");
<field name="_viewport">
document.getAnonymousElementByAttribute(this, "anonid", "viewport");
</field>
<field name="_canvas">
@ -119,17 +135,12 @@
<method name="updateCanvasState">
<body><![CDATA[
this._updateViewState();
// clear the whole canvas and redraw
// Clear the whole canvas
// XXX is this really necessary given zoomToPage's redraw?
var ctx = this._canvas.getContext("2d");
ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
this._browserToCanvas();
]]></body>
</method>
<method name="_updateViewState">
<body><![CDATA[
// Reset the pan data.
// Reset pan data
this.dragData.pageX = 0;
this.dragData.pageY = 0;
@ -650,11 +661,11 @@
// Adjust the zoomLevel to fit the page contents in our window
// width
var [contentWidth, ] = this._contentAreaDimensions;
var canvasRect = this._canvas.getBoundingClientRect();
var canvasWidth = canvasRect.right - canvasRect.left;
var [viewportW, ] = this.viewportDimensions;
if (contentWidth)
this._zoomLevel = canvasWidth / contentWidth;
this._zoomLevel = viewportW / contentWidth;
this._browserToCanvas();
]]></body>
</method>
@ -786,13 +797,6 @@
</getter>
</property>
<property name="_effectiveCanvasDimensions" readonly="true">
<getter><![CDATA[
return [this._screenToPage(this._canvas.width),
this._screenToPage(this._canvas.height)];
]]></getter>
</property>
<property name="scrollX" readonly="true">
<getter><![CDATA[
return this.dragData.pageX - this._screenToPage(this.dragData.dragX);
@ -817,25 +821,25 @@
<parameter name="aY"/>
<body><![CDATA[
var [contentAreaWidth, contentAreaHeight] = this._contentAreaDimensions;
var [canvasW, canvasH] = this._effectiveCanvasDimensions;
var [viewportW, viewportH] = this._effectiveViewportDimensions;
var offscreenWidth = contentAreaWidth - canvasW;
var offscreenWidth = contentAreaWidth - viewportW;
if (offscreenWidth <= 0) {
// Content is narrower than viewport, no need to pan horizontally
aX = 0;
} else {
// min of 0, max of contentAreaWidth - canvasW
// min of 0, max of contentAreaWidth - viewportW
var newPageX = Math.min(this.dragData.pageX + aX, offscreenWidth);
newPageX = Math.max(newPageX, 0);
aX = newPageX - this.dragData.pageX;
}
var offscreenHeight = contentAreaHeight - canvasH;
var offscreenHeight = contentAreaHeight - viewportH;
if (offscreenHeight <= 0) {
// Content is shorter than viewport, no need to pan vertically
aY = 0;
} else {
// min of 0, max of contentAreaHeight - canvasH
// min of 0, max of contentAreaHeight - viewportH
var newPageY = Math.min(this.dragData.pageY + aY, offscreenHeight);
newPageY = Math.max(newPageY, 0);
aY = newPageY - this.dragData.pageY;
@ -1039,11 +1043,11 @@
this.dragData.pageX -= this._screenToPage(this.dragData.dragX);
this.dragData.pageY -= this._screenToPage(this.dragData.dragY);
// relocate the canvas to 0x0 in the window
// reset the drag data
this.dragData.dragX = 0;
this.dragData.dragY = 0;
// update canvas position and draw the canvas at the new location
// update the canvas and move it to the right position
this._browserToCanvas();
this._updateCanvasPosition();
]]></body>