mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-04-02 12:32:55 +00:00
Bug 436064, support multiple documents with a tab navigation bar, r=gavin
This commit is contained in:
parent
a995c17e77
commit
660f2575ba
@ -319,7 +319,6 @@ var BrowserUI = {
|
|||||||
this._edit.focus();
|
this._edit.focus();
|
||||||
bookmark.hidden = true;
|
bookmark.hidden = true;
|
||||||
urllist.hidden = true;
|
urllist.hidden = true;
|
||||||
this.openDefaultHistory();
|
|
||||||
}
|
}
|
||||||
else if (aMode == PANELMODE_BOOKMARK) {
|
else if (aMode == PANELMODE_BOOKMARK) {
|
||||||
toolbar.setAttribute("mode", "view");
|
toolbar.setAttribute("mode", "view");
|
||||||
@ -412,6 +411,7 @@ var BrowserUI = {
|
|||||||
// URL textbox events
|
// URL textbox events
|
||||||
case "click":
|
case "click":
|
||||||
this._showMode(PANELMODE_EDIT);
|
this._showMode(PANELMODE_EDIT);
|
||||||
|
this.openDefaultHistory();
|
||||||
break;
|
break;
|
||||||
case "input":
|
case "input":
|
||||||
if (this._edit.value) {
|
if (this._edit.value) {
|
||||||
|
@ -5,3 +5,7 @@ deckbrowser {
|
|||||||
#urlbar-edit {
|
#urlbar-edit {
|
||||||
-moz-binding: url("chrome://browser/content/urlbar.xml#autocomplete-aligned");
|
-moz-binding: url("chrome://browser/content/urlbar.xml#autocomplete-aligned");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
richlistitem[type="documenttab"] {
|
||||||
|
-moz-binding: url("chrome://browser/content/deckbrowser.xml#documenttab");
|
||||||
|
}
|
||||||
|
@ -65,7 +65,8 @@ var Browser = {
|
|||||||
_content : null,
|
_content : null,
|
||||||
|
|
||||||
_titleChanged : function(aEvent) {
|
_titleChanged : function(aEvent) {
|
||||||
if (aEvent.target != this.content.browser.contentDocument)
|
var browser = this.content.browser;
|
||||||
|
if (!browser || aEvent.target != browser.contentDocument)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
document.title = "Fennec - " + aEvent.target.title;
|
document.title = "Fennec - " + aEvent.target.title;
|
||||||
@ -94,13 +95,16 @@ var Browser = {
|
|||||||
styleSheets.loadAndRegisterSheet(styleURI, styleSheets.AGENT_SHEET);
|
styleSheets.loadAndRegisterSheet(styleURI, styleSheets.AGENT_SHEET);
|
||||||
|
|
||||||
this._content = document.getElementById("content");
|
this._content = document.getElementById("content");
|
||||||
|
this._content.progressListenerCreator = function (content, browser) {
|
||||||
|
return new ProgressController(content, browser);
|
||||||
|
};
|
||||||
|
|
||||||
|
this._content.newTab(true);
|
||||||
this._content.addEventListener("DOMTitleChanged", this, true);
|
this._content.addEventListener("DOMTitleChanged", this, true);
|
||||||
this._content.addEventListener("overpan", this, false);
|
this._content.addEventListener("overpan", this, false);
|
||||||
this._content.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver.onUpdatePageReport, false);
|
this._content.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver.onUpdatePageReport, false);
|
||||||
BrowserUI.init();
|
BrowserUI.init();
|
||||||
|
|
||||||
this._progressController = new ProgressController(this.content);
|
|
||||||
|
|
||||||
this._spatialNavigation = new SpatialNavigation(this.content);
|
this._spatialNavigation = new SpatialNavigation(this.content);
|
||||||
|
|
||||||
this.setupGeolocationPrompt();
|
this.setupGeolocationPrompt();
|
||||||
@ -148,7 +152,13 @@ var Browser = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setupGeolocationPrompt: function() {
|
setupGeolocationPrompt: function() {
|
||||||
var geolocationService = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationService);
|
try {
|
||||||
|
var geolocationService = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationService);
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
geolocationService.prompt = function(request) {
|
geolocationService.prompt = function(request) {
|
||||||
|
|
||||||
var notificationBox = Browser.getNotificationBox();
|
var notificationBox = Browser.getNotificationBox();
|
||||||
@ -218,6 +228,8 @@ var Browser = {
|
|||||||
case "cmd_fullscreen":
|
case "cmd_fullscreen":
|
||||||
case "cmd_addons":
|
case "cmd_addons":
|
||||||
case "cmd_downloads":
|
case "cmd_downloads":
|
||||||
|
case "cmd_newTab":
|
||||||
|
case "cmd_closeTab":
|
||||||
isSupported = true;
|
isSupported = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -237,6 +249,7 @@ var Browser = {
|
|||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case "cmd_menu":
|
case "cmd_menu":
|
||||||
|
this.content.tabListVisible = !this.content.tabListVisible;
|
||||||
controls.collapsed = !controls.collapsed;
|
controls.collapsed = !controls.collapsed;
|
||||||
break;
|
break;
|
||||||
case "cmd_fullscreen":
|
case "cmd_fullscreen":
|
||||||
@ -270,6 +283,11 @@ var Browser = {
|
|||||||
case "cmd_downloads":
|
case "cmd_downloads":
|
||||||
Cc["@mozilla.org/download-manager-ui;1"].getService(Ci.nsIDownloadManagerUI).show(window);
|
Cc["@mozilla.org/download-manager-ui;1"].getService(Ci.nsIDownloadManagerUI).show(window);
|
||||||
break;
|
break;
|
||||||
|
case "cmd_newTab":
|
||||||
|
this.newTab();
|
||||||
|
break;
|
||||||
|
case "cmd_closeTab":
|
||||||
|
this.content.removeTab(this.content.browser);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -277,6 +295,10 @@ var Browser = {
|
|||||||
return document.getElementById("notifications");
|
return document.getElementById("notifications");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
newTab: function() {
|
||||||
|
this.content.newTab(true);
|
||||||
|
BrowserUI._showMode(PANELMODE_EDIT);
|
||||||
|
},
|
||||||
|
|
||||||
findState: FINDSTATE_FIND,
|
findState: FINDSTATE_FIND,
|
||||||
openFind: function(aState) {
|
openFind: function(aState) {
|
||||||
@ -305,9 +327,9 @@ var Browser = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function ProgressController(aTabBrowser) {
|
function ProgressController(aTabBrowser, aBrowser) {
|
||||||
this._tabbrowser = aTabBrowser;
|
this._tabbrowser = aTabBrowser;
|
||||||
this.init(aTabBrowser.browser);
|
this.init(aBrowser);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgressController.prototype = {
|
ProgressController.prototype = {
|
||||||
@ -315,7 +337,6 @@ ProgressController.prototype = {
|
|||||||
|
|
||||||
init : function(aBrowser) {
|
init : function(aBrowser) {
|
||||||
this._browser = aBrowser;
|
this._browser = aBrowser;
|
||||||
this._browser.addProgressListener(this, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
|
|
||||||
|
|
||||||
// FIXME: until we can get proper canvas repainting hooked up, update the canvas every 300ms
|
// FIXME: until we can get proper canvas repainting hooked up, update the canvas every 300ms
|
||||||
var tabbrowser = this._tabbrowser;
|
var tabbrowser = this._tabbrowser;
|
||||||
@ -341,6 +362,7 @@ ProgressController.prototype = {
|
|||||||
if (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT) {
|
if (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT) {
|
||||||
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
|
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
|
||||||
aWebProgress.DOMWindow.focus();
|
aWebProgress.DOMWindow.focus();
|
||||||
|
this._tabbrowser.updateBrowser(this._browser, true);
|
||||||
this._tabbrowser.updateCanvasState(true);
|
this._tabbrowser.updateCanvasState(true);
|
||||||
//aWebProgress.DOMWindow.scrollbars.visible = false;
|
//aWebProgress.DOMWindow.scrollbars.visible = false;
|
||||||
}
|
}
|
||||||
@ -388,6 +410,7 @@ ProgressController.prototype = {
|
|||||||
|
|
||||||
if (aWebProgress.DOMWindow == this._browser.contentWindow) {
|
if (aWebProgress.DOMWindow == this._browser.contentWindow) {
|
||||||
BrowserUI.setURI();
|
BrowserUI.setURI();
|
||||||
|
this._tabbrowser.updateBrowser(this._browser, false);
|
||||||
this._tabbrowser.updateCanvasState();
|
this._tabbrowser.updateCanvasState();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -74,6 +74,9 @@
|
|||||||
<command id="cmd_search" label="&search.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
<command id="cmd_search" label="&search.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||||
<command id="cmd_go" label="&go.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
<command id="cmd_go" label="&go.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||||
|
|
||||||
|
<command id="cmd_newTab" label="&newtab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||||
|
<command id="cmd_closeTab" label="&closetab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||||
|
|
||||||
<!-- bookmarking -->
|
<!-- bookmarking -->
|
||||||
<command id="cmd_star" label="&star.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
<command id="cmd_star" label="&star.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||||
<command id="cmd_bookmarks" label="&bookmarks.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
<command id="cmd_bookmarks" label="&bookmarks.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
|
||||||
@ -102,6 +105,8 @@
|
|||||||
</commandset>
|
</commandset>
|
||||||
|
|
||||||
<keyset id="mainKeyset">
|
<keyset id="mainKeyset">
|
||||||
|
<key id="key_menu" keycode="T" modifiers="accel" command="cmd_newTab"/>
|
||||||
|
|
||||||
<!-- basic navigation -->
|
<!-- basic navigation -->
|
||||||
<key id="key_back" keycode="VK_LEFT" command="cmd_back" modifiers="control"/>
|
<key id="key_back" keycode="VK_LEFT" command="cmd_back" modifiers="control"/>
|
||||||
<key id="key_forward" keycode="VK_RIGHT" command="cmd_forward" modifiers="control"/>
|
<key id="key_forward" keycode="VK_RIGHT" command="cmd_forward" modifiers="control"/>
|
||||||
@ -200,7 +205,8 @@
|
|||||||
<hbox id="browser-container" flex="1">
|
<hbox id="browser-container" flex="1">
|
||||||
<vbox id="browser" flex="1">
|
<vbox id="browser" flex="1">
|
||||||
<notificationbox id="notifications" flex="1">
|
<notificationbox id="notifications" flex="1">
|
||||||
<deckbrowser id="content" autocompletepopup="popup_autocomplete_content" flex="1"/>
|
<deckbrowser id="content" autocompletepopup="popup_autocomplete_content" flex="1"
|
||||||
|
onnewtab="Browser.newTab()"/>
|
||||||
</notificationbox>
|
</notificationbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
<vbox id="browser-controls" collapsed="true">
|
<vbox id="browser-controls" collapsed="true">
|
||||||
|
@ -9,21 +9,26 @@
|
|||||||
|
|
||||||
<binding id="deckbrowser">
|
<binding id="deckbrowser">
|
||||||
<content>
|
<content>
|
||||||
<xul:deck flex="1">
|
<xul:vbox class="tab-list-container" collapsed="true">
|
||||||
|
<xul:richlistbox anonid="tab-list" class="tab-list"
|
||||||
|
onselect="this.parentNode.parentNode.selectTab(this.selectedItem)"/>
|
||||||
|
<xul:button class="newtab-button" label="+" xbl:inherits="oncommand=onnewtab"/>
|
||||||
|
</xul:vbox>
|
||||||
|
<xul:deck flex="1" selectedIndex="0">
|
||||||
<xul:stack anonid="cstack" flex="1" style="overflow: hidden;">
|
<xul:stack anonid="cstack" flex="1" style="overflow: hidden;">
|
||||||
<html:canvas anonid="ccanvas"
|
<html:canvas anonid="ccanvas"
|
||||||
moz-opaque="true"
|
moz-opaque="true"
|
||||||
style="-moz-stack-sizing: ignore;"/>
|
style="-moz-stack-sizing: ignore;"/>
|
||||||
</xul:stack>
|
</xul:stack>
|
||||||
<xul:browser anonid="browser"
|
<xul:deck anonid="display-list" flex="1"/>
|
||||||
class="deckbrowser-browser"
|
|
||||||
type="content-primary"
|
|
||||||
xbl:inherits="contextmenu,autocompletepopup"
|
|
||||||
style="overflow: hidden; visibility: hidden;"/>
|
|
||||||
</xul:deck>
|
</xul:deck>
|
||||||
</content>
|
</content>
|
||||||
|
|
||||||
<implementation>
|
<resources>
|
||||||
|
<stylesheet src="chrome://global/content/deckbrowser.css"/>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
<implementation implements="nsIObserver">
|
||||||
<constructor>
|
<constructor>
|
||||||
this._zoomLevel = 1;
|
this._zoomLevel = 1;
|
||||||
|
|
||||||
@ -38,6 +43,12 @@
|
|||||||
// this._stack.addEventListener("dblclick", this.stackEventHandler, true);
|
// this._stack.addEventListener("dblclick", this.stackEventHandler, true);
|
||||||
this._stack.addEventListener("DOMMouseScroll", this.stackEventHandler, true);
|
this._stack.addEventListener("DOMMouseScroll", this.stackEventHandler, true);
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
var obs = Components.classes["@mozilla.org/observer-service;1"].
|
||||||
|
getService(Components.interfaces.nsIObserverService);
|
||||||
|
obs.addObserver(function(subject, topic, data) self.destroyEarliestBrowser(),
|
||||||
|
"memory-pressure", false);
|
||||||
|
|
||||||
this._dragStartTimeout = -1;
|
this._dragStartTimeout = -1;
|
||||||
</constructor>
|
</constructor>
|
||||||
|
|
||||||
@ -65,10 +76,29 @@
|
|||||||
|
|
||||||
<property name="browser" readonly="true">
|
<property name="browser" readonly="true">
|
||||||
<getter>
|
<getter>
|
||||||
return document.getAnonymousElementByAttribute(this, "anonid", "browser");
|
<![CDATA[
|
||||||
|
return this.getBrowserForDisplay(this.displayList.selectedPanel);
|
||||||
|
]]>
|
||||||
</getter>
|
</getter>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
|
<property name="displayList" readonly="true">
|
||||||
|
<getter>
|
||||||
|
return document.getAnonymousElementByAttribute(this, "anonid", "display-list");
|
||||||
|
</getter>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="tabList" readonly="true">
|
||||||
|
<getter>
|
||||||
|
return document.getAnonymousElementByAttribute(this, "anonid", "tab-list");
|
||||||
|
</getter>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="tabListVisible" onget="return !this.tabList.parentNode.collapsed"
|
||||||
|
onset="this.tabList.parentNode.collapsed = !val; return val;"/>
|
||||||
|
|
||||||
|
<field name="progressListenerCreator"/>
|
||||||
|
|
||||||
<method name="updateCanvasState">
|
<method name="updateCanvasState">
|
||||||
<parameter name="aNewDoc"/>
|
<parameter name="aNewDoc"/>
|
||||||
<body><![CDATA[
|
<body><![CDATA[
|
||||||
@ -98,6 +128,297 @@
|
|||||||
]]></body>
|
]]></body>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
<field name="currentTab"/>
|
||||||
|
|
||||||
|
<method name="getDisplayForTab">
|
||||||
|
<parameter name="tab"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
var tabList = this.tabList.childNodes;
|
||||||
|
for (var t = 0; t < tabList.length; t++) {
|
||||||
|
if (tab == tabList[t])
|
||||||
|
return this.displayList.childNodes[t];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
]]>
|
||||||
|
</body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="getTabForDisplay">
|
||||||
|
<parameter name="display"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
var displayList = this.displayList.childNodes;
|
||||||
|
for (var t = 0; t < displayList.length; t++) {
|
||||||
|
if (display == displayList[t])
|
||||||
|
return this.tabList.childNodes[t];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
]]>
|
||||||
|
</body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="getBrowserForDisplay">
|
||||||
|
<parameter name="display"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
if (!display)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var browser = display.firstChild;
|
||||||
|
if (browser && browser.localName == "browser")
|
||||||
|
return browser;
|
||||||
|
|
||||||
|
browser = display.lastChild;
|
||||||
|
return (browser && browser.localName == "browser") ? browser : null;
|
||||||
|
]]>
|
||||||
|
</body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="updateBrowser">
|
||||||
|
<parameter name="browser"/>
|
||||||
|
<parameter name="done"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
var display = browser.parentNode;
|
||||||
|
var domWin = browser.contentWindow;
|
||||||
|
display.url = domWin.location.toString();
|
||||||
|
|
||||||
|
if (!done || domWin.location == "about:blank")
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.restoreBrowserState(display);
|
||||||
|
|
||||||
|
var tab = this.getTabForDisplay(display);
|
||||||
|
if (tab) {
|
||||||
|
tab.updateTab(browser);
|
||||||
|
|
||||||
|
var canvas = display.firstChild;
|
||||||
|
if (canvas.localName == "canvas")
|
||||||
|
display.removeChild(canvas);
|
||||||
|
}
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="selectTab">
|
||||||
|
<parameter name="tab"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
var currentTab = this.currentTab;
|
||||||
|
this.currentTab = tab;
|
||||||
|
|
||||||
|
if (currentTab) {
|
||||||
|
var currentDisplay = this.getDisplayForTab(currentTab);
|
||||||
|
var currentBrowser = this.getBrowserForDisplay(currentDisplay);
|
||||||
|
if (currentBrowser) {
|
||||||
|
currentDisplay.url = currentBrowser.contentWindow.location.toString();
|
||||||
|
currentBrowser.setAttribute("type", "content");
|
||||||
|
currentTab.updateTab(currentBrowser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var display = this.getDisplayForTab(tab);
|
||||||
|
var browser = this.getBrowserForDisplay(display);
|
||||||
|
if (!browser) {
|
||||||
|
browser = this.createBrowser(true, tab, display);
|
||||||
|
browser.loadURI(display.url, null, null, false);
|
||||||
|
}
|
||||||
|
display.lastAccess = Date.now();
|
||||||
|
|
||||||
|
browser.setAttribute("type", "content-primary");
|
||||||
|
this.displayList.selectedPanel = display;
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="newTab">
|
||||||
|
<parameter name="makeFront"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
var browser = this.createBrowser(makeFront, null, null);
|
||||||
|
return browser ? this.getTabForDisplay(browser.parentNode) : null;
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="removeTab">
|
||||||
|
<parameter name="tab"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
if (!tab)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var display = this.getDisplayForTab(tab);
|
||||||
|
if (display)
|
||||||
|
display.removeChild(display);
|
||||||
|
tab.parentNode.removeChild(tab);
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="createBrowser">
|
||||||
|
<parameter name="makeFront"/>
|
||||||
|
<parameter name="tab"/>
|
||||||
|
<parameter name="display"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||||
|
|
||||||
|
var browser = document.createElementNS(XUL_NS, "browser");
|
||||||
|
browser.className = "deckbrowser-browser";
|
||||||
|
browser.setAttribute("style", "overflow: hidden");
|
||||||
|
browser.setAttribute("contextmenu", this.getAttribute("contextmenu"));
|
||||||
|
browser.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup"));
|
||||||
|
browser.flex = 1;
|
||||||
|
|
||||||
|
if (makeFront)
|
||||||
|
browser.setAttribute("type", "content-primary");
|
||||||
|
else
|
||||||
|
browser.setAttribute("type", "content");
|
||||||
|
|
||||||
|
var nextDisplay;
|
||||||
|
var displayList = this.displayList;
|
||||||
|
if (tab) {
|
||||||
|
var nextTab = tab.nextSibling;
|
||||||
|
if (nextTab)
|
||||||
|
nextDisplay = this.getDisplayForTab(nextTab);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!display) {
|
||||||
|
display = document.createElementNS(XUL_NS, "deck");
|
||||||
|
displayList.insertBefore(display, nextDisplay);
|
||||||
|
}
|
||||||
|
display.appendChild(browser);
|
||||||
|
display.selectedIndex = 0;
|
||||||
|
|
||||||
|
if (this.progressListenerCreator) {
|
||||||
|
var listener = this.progressListenerCreator(this, browser);
|
||||||
|
browser.addProgressListener(listener);
|
||||||
|
display.progressListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tab) {
|
||||||
|
tab = document.createElementNS(XUL_NS, "richlistitem");
|
||||||
|
tab.setAttribute("type", "documenttab");
|
||||||
|
this.tabList.appendChild(tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tab == this.tabList.selectedItem) {
|
||||||
|
// already selected, but need to update the selected panel
|
||||||
|
display.lastAccess = Date.now();
|
||||||
|
displayList.selectedPanel = display;
|
||||||
|
}
|
||||||
|
else if (makeFront) {
|
||||||
|
this.tabList.selectedItem = tab;
|
||||||
|
}
|
||||||
|
|
||||||
|
return browser;
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="destroyBrowser">
|
||||||
|
<parameter name="browser"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
if (!browser || browser == this.browser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var display = browser.parentNode;
|
||||||
|
this.saveBrowserState(display);
|
||||||
|
|
||||||
|
var domWin = browser.contentWindow;
|
||||||
|
|
||||||
|
var tab = this.getTabForDisplay(display);
|
||||||
|
if (tab)
|
||||||
|
tab.markInvalid();
|
||||||
|
|
||||||
|
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||||
|
var canvas = document.createElementNS(XHTML_NS, "canvas");
|
||||||
|
canvas.setAttribute("width", domWin.innerWidth);
|
||||||
|
canvas.setAttribute("height", domWin.innerHeight);
|
||||||
|
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.drawWindow(domWin, 0, 0, domWin.innerWidth, domWin.innerHeight, "rgba(0,0,0,0)");
|
||||||
|
display.insertBefore(canvas, display.firstChild);
|
||||||
|
|
||||||
|
display.lastAccess = Date.now();
|
||||||
|
display.progressListener = null;
|
||||||
|
display.removeChild(browser);
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="destroyEarliestBrowser">
|
||||||
|
<body><![CDATA[
|
||||||
|
var earliestBrowser = null;
|
||||||
|
var earliest = Date.now();
|
||||||
|
var displayList = this.displayList.childNodes;
|
||||||
|
for (var t = 0; t < displayList.length; t++) {
|
||||||
|
var display = displayList[t];
|
||||||
|
var browser = this.getBrowserForDisplay(display);
|
||||||
|
if (browser &&
|
||||||
|
display != this.displayList.selectedItem &&
|
||||||
|
display.lastAccess < earliest) {
|
||||||
|
earliestBrowser = browser;
|
||||||
|
earliest = display.lastAccess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (earliestBrowser)
|
||||||
|
this.destroyBrowser(earliestBrowser);
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="saveBrowserState">
|
||||||
|
<parameter name="display"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
var state = { };
|
||||||
|
|
||||||
|
var browser = this.getBrowserForDisplay(display);
|
||||||
|
var doc = browser.contentDocument;
|
||||||
|
if (doc instanceof HTMLDocument) {
|
||||||
|
var tags = ["input", "textarea", "select"];
|
||||||
|
|
||||||
|
for (var t = 0; t < tags.length; t++) {
|
||||||
|
var elements = doc.getElementsByTagName(tags[t]);
|
||||||
|
for (var e = 0; e < elements.length; e++) {
|
||||||
|
var element = elements[e];
|
||||||
|
var id;
|
||||||
|
if (element.id)
|
||||||
|
id = "#" + element.id;
|
||||||
|
else if (element.name)
|
||||||
|
id = "$" + element.name;
|
||||||
|
|
||||||
|
if (id)
|
||||||
|
state[id] = element.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state._scrollX = window.scrollX;
|
||||||
|
state._scrollY = window.scrollY;
|
||||||
|
|
||||||
|
display.state = state;
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
|
<method name="restoreBrowserState">
|
||||||
|
<parameter name="display"/>
|
||||||
|
<body><![CDATA[
|
||||||
|
var state = display.state;
|
||||||
|
if (!state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var browser = this.getBrowserForDisplay(display);
|
||||||
|
var doc = browser.contentDocument;
|
||||||
|
for (item in state) {
|
||||||
|
var elem = null;
|
||||||
|
if (item.charAt(0) == "#") {
|
||||||
|
elem = doc.getElementById(item.substring(1));
|
||||||
|
}
|
||||||
|
else if (item.charAt(0) == "$") {
|
||||||
|
var list = doc.getElementsByName(item.substring(1));
|
||||||
|
if (list.length)
|
||||||
|
elem = list[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elem)
|
||||||
|
elem.value = state[item];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.browser.contentWindow.scrollTo(state._scrollX, state._scrollY);
|
||||||
|
]]></body>
|
||||||
|
</method>
|
||||||
|
|
||||||
<method name="_browserToCanvas">
|
<method name="_browserToCanvas">
|
||||||
<body><![CDATA[
|
<body><![CDATA[
|
||||||
// FIXME: canvas needs to know it's actual width/height
|
// FIXME: canvas needs to know it's actual width/height
|
||||||
@ -179,7 +500,8 @@
|
|||||||
var canvasRect = this._canvas.getBoundingClientRect();
|
var canvasRect = this._canvas.getBoundingClientRect();
|
||||||
var canvasWidth = canvasRect.right - canvasRect.left;
|
var canvasWidth = canvasRect.right - canvasRect.left;
|
||||||
|
|
||||||
this._zoomLevel = canvasWidth / contentWidth;
|
if (contentWidth)
|
||||||
|
this._zoomLevel = canvasWidth / contentWidth;
|
||||||
]]></body>
|
]]></body>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
@ -597,4 +919,56 @@
|
|||||||
</implementation>
|
</implementation>
|
||||||
</binding>
|
</binding>
|
||||||
|
|
||||||
|
<binding id="documenttab"
|
||||||
|
extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
|
||||||
|
<content>
|
||||||
|
<xul:stack anonid="page" class="documenttab-container" flex="1">
|
||||||
|
<html:canvas anonid="canvas" class="documenttab-canvas" width="80" height="60"/>
|
||||||
|
<xul:vbox align="start">
|
||||||
|
<xul:image anonid="close" class="documenttab-close"/>
|
||||||
|
</xul:vbox>
|
||||||
|
</xul:stack>
|
||||||
|
</content>
|
||||||
|
<implementation>
|
||||||
|
<method name="updateTab">
|
||||||
|
<parameter name="browser"/>
|
||||||
|
<body>
|
||||||
|
<![CDATA[
|
||||||
|
let canvas = document.getAnonymousElementByAttribute(this, "anonid", "canvas");
|
||||||
|
|
||||||
|
let domWin = browser.contentWindow;
|
||||||
|
let width = domWin.innerWidth;
|
||||||
|
let height = domWin.innerHeight;
|
||||||
|
|
||||||
|
let ctx = canvas.getContext("2d");
|
||||||
|
ctx.clearRect(0, 0, 80, 60);
|
||||||
|
ctx.restore(); // XXXndeakin remove this
|
||||||
|
ctx.save();
|
||||||
|
ctx.scale(80 / width, 60 / height);
|
||||||
|
ctx.drawWindow(domWin, 0, 0, width, height, "rgba(0,0,0,0)");
|
||||||
|
ctx.restore();
|
||||||
|
]]>
|
||||||
|
</body>
|
||||||
|
</method>
|
||||||
|
<method name="markInvalid">
|
||||||
|
<parameter name="browser"/>
|
||||||
|
<body>
|
||||||
|
<![CDATA[
|
||||||
|
let canvas = document.getAnonymousElementByAttribute(this, "anonid", "canvas");
|
||||||
|
let ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
ctx.strokeStyle = "red";
|
||||||
|
ctx.moveTo(63, 43);
|
||||||
|
ctx.lineTo(78, 58);
|
||||||
|
ctx.moveTo(78, 43);
|
||||||
|
ctx.lineTo(63, 58);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.restore();
|
||||||
|
]]>
|
||||||
|
</body>
|
||||||
|
</method>
|
||||||
|
</implementation>
|
||||||
|
</binding>
|
||||||
|
|
||||||
</bindings>
|
</bindings>
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
<!ENTITY bookmarks.label "Bookmarks">
|
<!ENTITY bookmarks.label "Bookmarks">
|
||||||
<!ENTITY bookmarks.tooltip "View bookmarks">
|
<!ENTITY bookmarks.tooltip "View bookmarks">
|
||||||
|
|
||||||
|
<!ENTITY newtab.label "New Tab">
|
||||||
|
<!ENTITY closetab.label "Close Tab">
|
||||||
|
|
||||||
<!ENTITY cut.label "Cut">
|
<!ENTITY cut.label "Cut">
|
||||||
<!ENTITY copy.label "Copy">
|
<!ENTITY copy.label "Copy">
|
||||||
<!ENTITY copylink.label "Copy Link Location">
|
<!ENTITY copylink.label "Copy Link Location">
|
||||||
|
@ -246,6 +246,37 @@ toolbarbutton.browser-control-button {
|
|||||||
_moz-box-align: start;
|
_moz-box-align: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* tab list */
|
||||||
|
|
||||||
|
.tab-list-container {
|
||||||
|
background-color: rgb(123,125,123);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-list {
|
||||||
|
-moz-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 4px;
|
||||||
|
background-color: rgb(123,125,123);
|
||||||
|
}
|
||||||
|
|
||||||
|
richlistitem[type="documenttab"] {
|
||||||
|
-moz-appearance: none;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
-moz-border-radius: 5px;
|
||||||
|
background: none;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
richlistitem[type="documenttab"][selected="true"] {
|
||||||
|
border: 1px solid white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newtab-button {
|
||||||
|
-moz-appearance: none;
|
||||||
|
background-color: rgba(207,207,207,0.9);
|
||||||
|
font-size: 24pt;
|
||||||
|
}
|
||||||
|
|
||||||
/* autocomplete */
|
/* autocomplete */
|
||||||
|
|
||||||
#popup_autocomplete {
|
#popup_autocomplete {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user