Bug 386228 - "Unify back and forward tab history and provide only one drop-down button (IE7 style)" [p=zeniko@gmail.com (Simon Bünzli) ui-r=beltzner r=gavin a=blocking-firefox3+]

This commit is contained in:
reed@reedloden.com 2008-01-28 03:30:24 -08:00
Родитель 7765204bf0
Коммит 5e2f9684a2
5 изменённых файлов: 184 добавлений и 6 удалений

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

@ -0,0 +1,80 @@
<?xml version="1.0"?>
# -*- Mode: HTML -*-
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org browser.
#
# The Initial Developer of the Original Code is
# Simon Bünzli <zeniko@gmail.com>
# Portions created by the Initial Developer are Copyright (C) 2007 - 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
<!DOCTYPE bindings SYSTEM "chrome://global/locale/global.dtd">
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl"
>
<binding id="unified-back-forward-button-wrapper" display="xul:menu"
extends="chrome://global/content/bindings/toolbarbutton.xml#menu">
<content>
<children includes="toolbarbutton|observes|template|menupopup|tooltip"/>
<xul:dropmarker type="menu-button"
class="toolbarbutton-menubutton-dropmarker"
chromedir="&locale.dir;"
xbl:inherits="align,dir,pack,orient,disabled,toolbarmode,buttonstyle"
/>
</content>
<implementation>
<constructor><![CDATA[
this._updateUnifiedState();
]]></constructor>
<method name="_updateUnifiedState">
<body><![CDATA[
var canGoBack = !document.getElementById("Browser:Back").hasAttribute("disabled");
var canGoForward = !document.getElementById("Browser:Forward").hasAttribute("disabled");
if (canGoBack || canGoForward)
this.removeAttribute("disabled");
else
this.setAttribute("disabled", "true");
]]></body>
</method>
</implementation>
<handlers>
<!-- observing state changes of the child buttons -->
<handler event="broadcast" action="this._updateUnifiedState();"/>
</handlers>
</binding>
</bindings>

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

@ -23,6 +23,17 @@ toolbar[printpreview="true"] {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup"); -moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup");
} }
/* ::::: Unified Back-/Forward Button ::::: */
#unified-back-forward-button {
-moz-binding: url("chrome://browser/content/bindings.xml#unified-back-forward-button-wrapper");
}
#unified-back-forward-button > toolbarbutton > dropmarker {
display: none; /* we provide our own */
}
.unified-nav-current {
font-weight: bold;
}
menuitem.spell-suggestion { menuitem.spell-suggestion {
font-weight: bold; font-weight: bold;
} }

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

@ -181,6 +181,45 @@ function UpdateBackForwardCommands(aWebNavigation)
} }
} }
var UnifiedBackForwardButton = {
unify: function() {
var backButton = document.getElementById("back-button");
if (!backButton || !backButton.nextSibling || backButton.nextSibling.id != "forward-button")
return; // back and forward buttons aren't adjacent
var wrapper = document.createElement("toolbaritem");
wrapper.id = "unified-back-forward-button";
wrapper.className = "chromeclass-toolbar-additional";
wrapper.setAttribute("context", "backMenu");
var toolbar = backButton.parentNode;
toolbar.insertBefore(wrapper, backButton);
var forwardButton = backButton.nextSibling;
wrapper.appendChild(backButton);
wrapper.appendChild(forwardButton);
var popup = backButton.getElementsByTagName("menupopup")[0].cloneNode(true);
wrapper.appendChild(popup);
this._unified = true;
},
separate: function() {
if (!this._unified)
return;
var wrapper = document.getElementById("unified-back-forward-button");
var toolbar = wrapper.parentNode;
toolbar.insertBefore(wrapper.firstChild, wrapper); // Back button
toolbar.insertBefore(wrapper.firstChild, wrapper); // Forward button
toolbar.removeChild(wrapper);
this._unified = false;
}
};
#ifdef XP_MACOSX #ifdef XP_MACOSX
/** /**
* Click-and-Hold implementation for the Back and Forward buttons * Click-and-Hold implementation for the Back and Forward buttons
@ -920,6 +959,7 @@ function delayedStartup()
sidebar.setAttribute("src", sidebarBox.getAttribute("src")); sidebar.setAttribute("src", sidebarBox.getAttribute("src"));
} }
UnifiedBackForwardButton.unify();
UpdateUrlbarSearchSplitterState(); UpdateUrlbarSearchSplitterState();
try { try {
@ -1444,12 +1484,14 @@ function BrowserHandleShiftBackspace()
function BrowserBackMenu(event) function BrowserBackMenu(event)
{ {
return FillHistoryMenu(event.target, "back"); var menuType = UnifiedBackForwardButton._unified ? "unified" : "back";
return FillHistoryMenu(event.target, menuType);
} }
function BrowserForwardMenu(event) function BrowserForwardMenu(event)
{ {
return FillHistoryMenu(event.target, "forward"); var menuType = UnifiedBackForwardButton._unified ? "unified" : "forward";
return FillHistoryMenu(event.target, menuType);
} }
function BrowserStop() function BrowserStop()
@ -2934,6 +2976,7 @@ function FillHistoryMenu(aParent, aMenu)
var webNav = getWebNavigation(); var webNav = getWebNavigation();
var sessionHistory = webNav.sessionHistory; var sessionHistory = webNav.sessionHistory;
var bundle_browser = document.getElementById("bundle_browser");
var count = sessionHistory.count; var count = sessionHistory.count;
var index = sessionHistory.index; var index = sessionHistory.index;
@ -2950,7 +2993,8 @@ function FillHistoryMenu(aParent, aMenu)
{ {
entry = sessionHistory.getEntryAtIndex(j, false); entry = sessionHistory.getEntryAtIndex(j, false);
if (entry) if (entry)
createMenuItem(aParent, j, entry.title); createMenuItem(aParent, j, entry.title || entry.URI.spec,
bundle_browser.getString("tabHistory.goBack"));
} }
break; break;
case "forward": case "forward":
@ -2960,9 +3004,39 @@ function FillHistoryMenu(aParent, aMenu)
{ {
entry = sessionHistory.getEntryAtIndex(j, false); entry = sessionHistory.getEntryAtIndex(j, false);
if (entry) if (entry)
createMenuItem(aParent, j, entry.title); createMenuItem(aParent, j, entry.title || entry.URI.spec,
bundle_browser.getString("tabHistory.goForward"));
} }
break; break;
case "unified":
if (count <= 1) // don't display the popup for a single item
return false;
var half_length = Math.floor(MAX_HISTORY_MENU_ITEMS / 2);
var start = Math.max(index - half_length, 0);
end = Math.min(start == 0 ? MAX_HISTORY_MENU_ITEMS : index + half_length + 1, count);
if (end == count)
start = Math.max(count - MAX_HISTORY_MENU_ITEMS, 0);
var tooltips = [
bundle_browser.getString("tabHistory.goBack"),
bundle_browser.getString("tabHistory.current"),
bundle_browser.getString("tabHistory.goForward")
];
var classNames = ["unified-nav-back", "unified-nav-current", "unified-nav-forward"];
for (var j = end - 1; j >= start; j--) {
entry = sessionHistory.getEntryAtIndex(j, false);
var tooltip = tooltips[j < index ? 0 : j == index ? 1 : 2];
var className = classNames[j < index ? 0 : j == index ? 1 : 2];
var item = createMenuItem(aParent, j, entry.title || entry.URI.spec, tooltip, className);
if (j == index) { // mark the current history item
item.setAttribute("type", "radio");
item.setAttribute("checked", "true");
}
}
break;
} }
return true; return true;
@ -2984,12 +3058,16 @@ function addToUrlbarHistory(aUrlToAdd)
} }
} }
function createMenuItem( aParent, aIndex, aLabel) function createMenuItem(aParent, aIndex, aLabel, aTooltipText, aClassName)
{ {
var menuitem = document.createElement( "menuitem" ); var menuitem = document.createElement( "menuitem" );
menuitem.setAttribute( "label", aLabel ); menuitem.setAttribute( "label", aLabel );
menuitem.setAttribute( "index", aIndex ); menuitem.setAttribute( "index", aIndex );
aParent.appendChild( menuitem ); if (aTooltipText)
menuitem.setAttribute("tooltiptext", aTooltipText);
if (aClassName)
menuitem.className = aClassName;
return aParent.appendChild(menuitem);
} }
function deleteHistoryItems(aParent) function deleteHistoryItems(aParent)
@ -3088,6 +3166,8 @@ function BrowserCustomizeToolbar()
var cmd = document.getElementById("cmd_CustomizeToolbars"); var cmd = document.getElementById("cmd_CustomizeToolbars");
cmd.setAttribute("disabled", "true"); cmd.setAttribute("disabled", "true");
UnifiedBackForwardButton.separate();
var splitter = document.getElementById("urlbar-search-splitter"); var splitter = document.getElementById("urlbar-search-splitter");
if (splitter) if (splitter)
splitter.parentNode.removeChild(splitter); splitter.parentNode.removeChild(splitter);
@ -3130,6 +3210,7 @@ function BrowserToolboxCustomizeDone(aToolboxChanged)
#endif #endif
} }
UnifiedBackForwardButton.unify();
UpdateUrlbarSearchSplitterState(); UpdateUrlbarSearchSplitterState();
// Update the urlbar // Update the urlbar

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

@ -13,6 +13,7 @@ browser.jar:
* content/browser/aboutDialog.xul (content/aboutDialog.xul) * content/browser/aboutDialog.xul (content/aboutDialog.xul)
* content/browser/aboutDialog.js (content/aboutDialog.js) * content/browser/aboutDialog.js (content/aboutDialog.js)
content/browser/aboutDialog.css (content/aboutDialog.css) content/browser/aboutDialog.css (content/aboutDialog.css)
* content/browser/bindings.xml (content/bindings.xml)
* content/browser/browser.css (content/browser.css) * content/browser/browser.css (content/browser.css)
* content/browser/browser.js (content/browser.js) * content/browser/browser.js (content/browser.js)
* content/browser/browser.xul (content/browser.xul) * content/browser/browser.xul (content/browser.xul)

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

@ -81,6 +81,11 @@ feedHasFeedsNew=Subscribe to this page…
menuOpenAllInTabs.label=Open All in Tabs menuOpenAllInTabs.label=Open All in Tabs
menuOpenAllInTabs.accesskey=o menuOpenAllInTabs.accesskey=o
# Unified Back-/Forward Popup
tabHistory.current=Stay on this page
tabHistory.goBack=Go back to this page
tabHistory.goForward=Go forward to this page
# Block autorefresh # Block autorefresh
refreshBlocked.goButton=Allow refreshBlocked.goButton=Allow
refreshBlocked.goButton.accesskey=A refreshBlocked.goButton.accesskey=A