author | Raymond Lee <raymond@raysquare.com> |
Fri, 10 Sep 2010 22:40:27 +0800 | |
changeset 52383 | a6b04551c72aff25bbdef2845a69fd51390c513f |
parent 52382 | a6fd7402dfe65ae5ac12c3c89105260040a69f25 |
child 52384 | 65161587c8b4bc9563a7a000384559b853dc2411 |
push id | 1 |
push user | root |
push date | Tue, 26 Apr 2011 22:38:44 +0000 |
treeherder | mozilla-beta@bfdb6e623a36 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 587341 |
milestone | 2.0b6pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/base/content/browser-tabview.js +++ b/browser/base/content/browser-tabview.js @@ -145,18 +145,21 @@ let TabView = { while (popup.firstChild && popup.firstChild != separator) popup.removeChild(popup.firstChild); let self = this; this._initFrame(function() { let activeGroup = tab.tabItem.parent; let groupItems = self._window.GroupItems.groupItems; - groupItems.forEach(function(groupItem) { - if (groupItem.getTitle().length > 0 && + groupItems.forEach(function(groupItem) { + // if group has title, it's not hidden and there is no active group or + // the active group id doesn't match the group id, a group menu item + // would be added. + if (groupItem.getTitle().length > 0 && !groupItem.hidden && (!activeGroup || activeGroup.id != groupItem.id)) { let menuItem = self._createGroupMenuItem(groupItem); popup.insertBefore(menuItem, separator); isEmpty = false; } }); separator.hidden = isEmpty; });
--- a/browser/base/content/tabview/groupitems.js +++ b/browser/base/content/tabview/groupitems.js @@ -72,16 +72,17 @@ function GroupItem(listOfEls, options) { this.defaultSize = new Point(TabItems.tabWidth * 1.5, TabItems.tabHeight * 1.5); this.isAGroupItem = true; this.id = options.id || GroupItems.getNextID(); this._isStacked = false; this._stackAngles = [0]; this.expanded = null; this.locked = (options.locked ? Utils.copy(options.locked) : {}); this.topChild = null; + this.hidden = false; this.keepProportional = false; // Variable: _activeTab // The <TabItem> for the groupItem's active tab. this._activeTab = null; // Variables: xDensity, yDensity @@ -264,16 +265,19 @@ function GroupItem(listOfEls, options) { // ___ locking if (this.locked.bounds) $container.css({cursor: 'default'}); if (this.locked.close) $close.hide(); + // ___ Undo Close + this.$undoContainer = null; + // ___ Superclass initialization this._init($container[0]); if (this.$debug) this.$debug.css({zIndex: -1000}); // ___ Children Array.prototype.forEach.call(listOfEls, function(el) { @@ -536,39 +540,166 @@ GroupItem.prototype = Utils.extend(new I // ---------- // Function: close // Closes the groupItem, removing (but not closing) all of its children. close: function GroupItem_close() { this.removeAll(); GroupItems.unregister(this); this._sendToSubscribers("close"); this.removeTrenches(); - iQ(this.container).fadeOut(function() { - iQ(this).remove(); - Items.unsquish(); + + iQ(this.container).animate({ + opacity: 0, + "-moz-transform": "scale(.3)", + }, { + duration: 170, + complete: function() { + iQ(this).remove(); + Items.unsquish(); + } }); Storage.deleteGroupItem(gWindow, this.id); }, // ---------- // Function: closeAll // Closes the groupItem and all of its children. closeAll: function GroupItem_closeAll() { - var self = this; - if (this._children.length) { - var toClose = this._children.concat(); + if (this._children.length > 0) { + this._children.forEach(function(child) { + iQ(child.container).hide(); + }); + + iQ(this.container).animate({ + opacity: 0, + "-moz-transform": "scale(.3)", + }, { + duration: 170, + complete: function() { + iQ(this).hide(); + } + }); + + this._createUndoButton(); + } else { + if (!this.locked.close) + this.close(); + } + }, + + // ---------- + // Function: _createUndoButton + // Makes the affordance for undo a close group action + _createUndoButton: function() { + let self = this; + this.$undoContainer = iQ("<div/>") + .addClass("undo") + .attr("type", "button") + .text("Undo Close Group") + .appendTo("body"); + let undoClose = iQ("<span/>") + .addClass("close") + .appendTo(this.$undoContainer); + + this.$undoContainer.css({ + left: this.bounds.left + this.bounds.width/2 - iQ(self.$undoContainer).width()/2, + top: this.bounds.top + this.bounds.height/2 - iQ(self.$undoContainer).height()/2, + "-moz-transform": "scale(.1)", + opacity: 0 + }); + this.hidden = true; + + setTimeout(function() { + self.$undoContainer.animate({ + "-moz-transform": "scale(1)", + "opacity": 1 + }, { + easing: "tabviewBounce", + duration: 170, + complete: function() { + self._sendToSubscribers("groupHidden", { groupItemId: self.id }); + } + }); + }, 50); + + let remove = function() { + // close all children + let toClose = self._children.concat(); toClose.forEach(function(child) { child.removeSubscriber(self, "close"); child.close(); }); - } + + // remove all children + self.removeAll(); + GroupItems.unregister(self); + self._sendToSubscribers("close"); + self.removeTrenches(); + + iQ(self.container).remove(); + self.$undoContainer.remove(); + self.$undoContainer = null; + Items.unsquish(); + + Storage.deleteGroupItem(gWindow, self.id); + }; + + this.$undoContainer.click(function(e) { + // Only do this for clicks on this actual element. + if (e.target.nodeName != self.$undoContainer[0].nodeName) + return; + + self.$undoContainer.fadeOut(function() { + iQ(this).remove(); + self.hidden = false; + self.$undoContainer = null; - if (!this.locked.close) - this.close(); + iQ(self.container).show().animate({ + "-moz-transform": "scale(1)", + "opacity": 1 + }, { + duration: 170, + complete: function() { + self._children.forEach(function(child) { + iQ(child.container).show(); + }); + } + }); + + self._sendToSubscribers("groupShown", { groupItemId: self.id }); + }); + }); + + undoClose.click(function() { + self.$undoContainer.fadeOut(remove); + }); + + // After 15 seconds, fade away. + const WAIT = 15000; + const FADE = 300; + + let fadeaway = function() { + if (self.$undoContainer) + self.$undoContainer.animate({ + color: "transparent", + opacity: 0 + }, { + duration: FADE, + complete: remove + }); + }; + + let timeoutId = setTimeout(fadeaway, WAIT); + // Cancel the fadeaway if you move the mouse over the undo + // button, and restart the countdown once you move out of it. + this.$undoContainer.mouseover(function() clearTimeout(timeoutId)); + this.$undoContainer.mouseout(function() { + timeoutId = setTimeout(fadeaway, WAIT); + }); }, // ---------- // Function: add // Adds an item to the groupItem. // Parameters: // // a - The item to add. Can be an <Item>, a DOM element or an iQ object. @@ -1589,24 +1720,23 @@ let GroupItems = { // Returns the active groupItem. Active means its tabs are // shown in the tab bar when not in the TabView interface. getActiveGroupItem: function GroupItems_getActiveGroupItem() { return this._activeGroupItem; }, // ---------- // Function: setActiveGroupItem - // Sets the active groupItem, thereby showing only the relevent tabs, and + // Sets the active groupItem, thereby showing only the relevant tabs and // setting the groupItem which will receive new tabs. // // Paramaters: // groupItem - the active <GroupItem> or <null> if no groupItem is active // (which means we have an orphaned tab selected) setActiveGroupItem: function GroupItems_setActiveGroupItem(groupItem) { - if (this._activeGroupItem) iQ(this._activeGroupItem.container).removeClass('activeGroupItem'); if (groupItem !== null) { if (groupItem) iQ(groupItem.container).addClass('activeGroupItem'); // if a groupItem is active, we surely are not in an orphaned tab. this.setActiveOrphanTab(null); @@ -1691,54 +1821,60 @@ let GroupItems = { var tabItem = null; if (reverse) groupItems = groupItems.reverse(); if (!activeGroupItem) { if (groupItems.length > 0) { groupItems.some(function(groupItem) { - var child = groupItem.getChild(0); - if (child) { - tabItem = child; - return true; + if (!groupItem.hidden) { + var child = groupItem.getChild(0); + if (child) { + tabItem = child; + return true; + } } return false; }); } } else { var currentIndex; groupItems.some(function(groupItem, index) { - if (groupItem == activeGroupItem) { + if (!groupItem.hidden && groupItem == activeGroupItem) { currentIndex = index; return true; } return false; }); var firstGroupItems = groupItems.slice(currentIndex + 1); firstGroupItems.some(function(groupItem) { - var child = groupItem.getChild(0); - if (child) { - tabItem = child; - return true; + if (!groupItem.hidden) { + var child = groupItem.getChild(0); + if (child) { + tabItem = child; + return true; + } } return false; }); if (!tabItem) { var orphanedTabs = GroupItems.getOrphanedTabs(); if (orphanedTabs.length > 0) tabItem = orphanedTabs[0]; } if (!tabItem) { var secondGroupItems = groupItems.slice(0, currentIndex); secondGroupItems.some(function(groupItem) { - var child = groupItem.getChild(0); - if (child) { - tabItem = child; - return true; + if (!groupItem.hidden) { + var child = groupItem.getChild(0); + if (child) { + tabItem = child; + return true; + } } return false; }); } } return tabItem; }, @@ -1813,10 +1949,30 @@ let GroupItems = { // to begin with let newTabGroupTitle = "New Tabs"; this.groupItems.forEach(function(groupItem) { if (groupItem.getTitle() == newTabGroupTitle && groupItem.locked.title) { groupItem.removeAll(); groupItem.close(); } }); + }, + + // ---------- + // Function: removeHiddenGroups + // Removes all hidden groups' data and its browser tabs. + removeHiddenGroups: function GroupItems_removeHiddenGroups() { + iQ(".undo").remove(); + + // ToDo: encapsulate this in the group item. bug 594863 + this.groupItems.forEach(function(groupItem) { + if (groupItem.hidden) { + let toClose = groupItem._children.concat(); + toClose.forEach(function(child) { + child.removeSubscriber(groupItem, "close"); + child.close(); + }); + + Storage.deleteGroupItem(gWindow, groupItem.id); + } + }); } };
--- a/browser/base/content/tabview/tabitems.js +++ b/browser/base/content/tabview/tabitems.js @@ -44,17 +44,16 @@ // ########## // Class: TabItem // An <Item> that represents a tab. Also implements the <Subscribable> interface. // // Parameters: // tab - a xul:tab function TabItem(tab) { - Utils.assert(tab, "tab"); this.tab = tab; // register this as the tab's tabItem this.tab.tabItem = this; // ___ set up div var $div = iQ('<div>') @@ -501,16 +500,20 @@ TabItem.prototype = Utils.extend(new Ite // ---------- // Function: zoomIn // Allows you to select the tab and zoom in on it, thereby bringing you // to the tab in Firefox to interact with. // Parameters: // isNewBlankTab - boolean indicates whether it is a newly opened blank tab. zoomIn: function TabItem_zoomIn(isNewBlankTab) { + // don't allow zoom in if its group is hidden + if (this.parent && this.parent.hidden) + return; + var self = this; var $tabEl = iQ(this.container); var childHitResult = { shouldZoom: true }; if (this.parent) childHitResult = this.parent.childHit(this); if (childHitResult.shouldZoom) { // Zoom in!
--- a/browser/base/content/tabview/tabview.css +++ b/browser/base/content/tabview/tabview.css @@ -97,16 +97,25 @@ body { .appTabTray { position: absolute; } /* Other Items ----------------------------------*/ +.undo { + position: absolute; +} + +.undo .close { + display: inline-block; + position: relative; +} + .info-item { position: absolute; } /* Trenches ----------------------------------*/ .guideTrench,
--- a/browser/base/content/tabview/ui.js +++ b/browser/base/content/tabview/ui.js @@ -209,18 +209,20 @@ let UI = { iQ(window).resize(function() { self._resize(); }); // ___ setup observer to save canvas images var observer = { observe : function(subject, topic, data) { if (topic == "quit-application-requested") { - if (self._isTabViewVisible()) + if (self._isTabViewVisible()) { + GroupItems.removeHiddenGroups(); TabItems.saveAll(true); + } self._save(); } } }; Services.obs.addObserver(observer, "quit-application-requested", false); // ___ Done this._frameInitalized = true; @@ -348,16 +350,17 @@ let UI = { // ---------- // Function: hideTabView // Hides TabView and shows the main browser UI. hideTabView: function UI_hideTabView() { if (!this._isTabViewVisible()) return; + GroupItems.removeHiddenGroups(); TabItems.pausePainting(); this._reorderTabsOnHide.forEach(function(groupItem) { groupItem.reorderTabsBasedOnTabItemOrder(); }); this._reorderTabsOnHide = []; #ifdef XP_WIN @@ -567,17 +570,18 @@ let UI = { event.stopPropagation(); event.preventDefault(); } return; } function getClosestTabBy(norm) { var centers = - [[item.bounds.center(), item] for each(item in TabItems.getItems())]; + [[item.bounds.center(), item] + for each(item in TabItems.getItems()) if (!item.parent || !item.parent.hidden)]; var myCenter = self.getActiveTab().bounds.center(); var matches = centers .filter(function(item){return norm(item[0], myCenter)}) .sort(function(a,b){ return myCenter.distance(a[0]) - myCenter.distance(b[0]); }); if (matches.length > 0) return matches[0][1];
--- a/browser/base/content/test/tabview/Makefile.in +++ b/browser/base/content/test/tabview/Makefile.in @@ -46,12 +46,13 @@ include $(topsrcdir)/config/rules.mk _BROWSER_FILES = \ browser_tabview_launch.js \ browser_tabview_dragdrop.js \ browser_tabview_group.js \ browser_tabview_search.js \ browser_tabview_snapping.js \ browser_tabview_bug591706.js \ browser_tabview_apptabs.js \ + browser_tabview_undo_group.js \ $(NULL) libs:: $(_BROWSER_FILES) $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
--- a/browser/base/content/test/tabview/browser_tabview_bug591706.js +++ b/browser/base/content/test/tabview/browser_tabview_bug591706.js @@ -75,34 +75,43 @@ function onTabViewWindowLoaded() { isnot(firstTab.linkedBrowser.contentWindow.location, secondTab.linkedBrowser.contentWindow.location, "The two tabs must have different locations"); // Add the first tab to the group *programmatically*, without specifying a dropPos group.add(firstTabItem); is(group.getChildren().length, 2, "Two tabs in the group"); is(group.getChildren()[0].tab.linkedBrowser.contentWindow.location, secondTab.linkedBrowser.contentWindow.location, "The second tab was there first"); is(group.getChildren()[1].tab.linkedBrowser.contentWindow.location, firstTab.linkedBrowser.contentWindow.location, "The first tab was just added and went to the end of the line"); + group.addSubscriber(group, "close", function() { + group.removeSubscriber(group, "close"); + + ok(group.isEmpty(), "The group is empty again"); + + is(contentWindow.GroupItems.getActiveGroupItem(), null, "The active group is gone"); + contentWindow.GroupItems.setActiveGroupItem(currentGroup); + isnot(contentWindow.GroupItems.getActiveGroupItem(), null, "There is an active group"); + is(gBrowser.tabs.length, 1, "There is only one tab left"); + is(gBrowser.visibleTabs.length, 1, "There is also only one visible tab"); + + let onTabViewHidden = function() { + window.removeEventListener("tabviewhidden", onTabViewHidden, false); + finish(); + }; + window.addEventListener("tabviewhidden", onTabViewHidden, false); + gBrowser.selectedTab = originalTab; + + TabView.hide(); + }); + // Get rid of the group and its children group.closeAll(); - ok(group.isEmpty(), "The group is empty again"); - - is(contentWindow.GroupItems.getActiveGroupItem(), null, "The active group is gone"); - contentWindow.GroupItems.setActiveGroupItem(currentGroup); - isnot(contentWindow.GroupItems.getActiveGroupItem(), null, "There is an active group"); - is(gBrowser.tabs.length, 1, "There is only one tab left"); - is(gBrowser.visibleTabs.length, 1, "There is also only one visible tab"); - - let onTabViewHidden = function() { - window.removeEventListener("tabviewhidden", onTabViewHidden, false); - finish(); - }; - window.addEventListener("tabviewhidden", onTabViewHidden, false); - gBrowser.selectedTab = originalTab; - - TabView.hide(); + // close undo group + let closeButton = group.$undoContainer.find(".close"); + EventUtils.sendMouseEvent( + { type: "click" }, closeButton[0], contentWindow); } function simulateDragDrop(srcElement, offsetX, offsetY, contentWindow) { // enter drag mode let dataTransfer; EventUtils.synthesizeMouse( srcElement, 1, 1, { type: "mousedown" }, contentWindow);
--- a/browser/base/content/test/tabview/browser_tabview_dragdrop.js +++ b/browser/base/content/test/tabview/browser_tabview_dragdrop.js @@ -109,17 +109,21 @@ function addTest(contentWindow, groupOne is(groupOne.getChildren().length, --groupOneTabItemCount, "The number of children in group one is decreased by 1"); is(groupTwo.getChildren().length, ++groupTwoTabItemCount, "The number of children in group two is increased by 1"); let onTabViewHidden = function() { window.removeEventListener("tabviewhidden", onTabViewHidden, false); - groupTwo.closeAll(); + groupTwo.closeAll(); + // close undo group + let closeButton = groupTwo.$undoContainer.find(".close"); + EventUtils.sendMouseEvent( + { type: "click" }, closeButton[0], contentWindow); }; groupTwo.addSubscriber(groupTwo, "close", function() { groupTwo.removeSubscriber(groupTwo, "close"); finish(); }); window.addEventListener("tabviewhidden", onTabViewHidden, false); gBrowser.selectedTab = originalTab; }
new file mode 100644 --- /dev/null +++ b/browser/base/content/test/tabview/browser_tabview_undo_group.js @@ -0,0 +1,168 @@ +/* ***** 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 tabview undo group test. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Raymond Lee <raymond@appcoast.com> + * + * 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 ***** */ + +function test() { + waitForExplicitFinish(); + + window.addEventListener("tabviewshown", onTabViewWindowLoaded, false); + TabView.toggle(); +} + +function onTabViewWindowLoaded() { + window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false); + ok(TabView.isVisible(), "Tab View is visible"); + + let contentWindow = document.getElementById("tab-view").contentWindow; + + // create a group item + let box = new contentWindow.Rect(20, 400, 300, 300); + let groupItem = new contentWindow.GroupItem([], { bounds: box }); + + // create a tab item in the new group + let onTabViewHidden = function() { + window.removeEventListener("tabviewhidden", onTabViewHidden, false); + + ok(!TabView.isVisible(), "Tab View is hidden because we just opened a tab"); + // show tab view + TabView.toggle(); + }; + let onTabViewShown = function() { + window.removeEventListener("tabviewshown", onTabViewShown, false); + + is(groupItem.getChildren().length, 1, "The new group has a tab item"); + // start the tests + testUndoGroup(contentWindow, groupItem); + }; + window.addEventListener("tabviewhidden", onTabViewHidden, false); + window.addEventListener("tabviewshown", onTabViewShown, false); + + // click on the + button + let newTabButton = groupItem.container.getElementsByClassName("newTabButton"); + ok(newTabButton[0], "New tab button exists"); + + EventUtils.sendMouseEvent({ type: "click" }, newTabButton[0], contentWindow); +} + +function testUndoGroup(contentWindow, groupItem) { + groupItem.addSubscriber(groupItem, "groupHidden", function() { + groupItem.removeSubscriber(groupItem, "groupHidden"); + + // check the data of the group + let theGroupItem = contentWindow.GroupItems.groupItem(groupItem.id); + ok(theGroupItem, "The group item still exists"); + is(theGroupItem.getChildren().length, 1, + "The tab item in the group still exists"); + + // check the visibility of the group element and undo element + is(theGroupItem.container.style.display, "none", + "The group element is hidden"); + ok(theGroupItem.$undoContainer, "Undo container is avaliable"); + + EventUtils.sendMouseEvent( + { type: "click" }, theGroupItem.$undoContainer[0], contentWindow); + }); + + groupItem.addSubscriber(groupItem, "groupShown", function() { + groupItem.removeSubscriber(groupItem, "groupShown"); + + // check the data of the group + let theGroupItem = contentWindow.GroupItems.groupItem(groupItem.id); + ok(theGroupItem, "The group item still exists"); + is(theGroupItem.getChildren().length, 1, + "The tab item in the group still exists"); + + // check the visibility of the group element and undo element + is(theGroupItem.container.style.display, "", "The group element is visible"); + ok(!theGroupItem.$undoContainer, "Undo container is not avaliable"); + + // start the next test + testCloseUndoGroup(contentWindow, groupItem); + }); + + let closeButton = groupItem.container.getElementsByClassName("close"); + ok(closeButton, "Group item close button exists"); + EventUtils.sendMouseEvent({ type: "click" }, closeButton[0], contentWindow); +} + +function testCloseUndoGroup(contentWindow, groupItem) { + groupItem.addSubscriber(groupItem, "groupHidden", function() { + groupItem.removeSubscriber(groupItem, "groupHidden"); + + // check the data of the group + let theGroupItem = contentWindow.GroupItems.groupItem(groupItem.id); + ok(theGroupItem, "The group item still exists"); + is(theGroupItem.getChildren().length, 1, + "The tab item in the group still exists"); + + // check the visibility of the group element and undo element + is(theGroupItem.container.style.display, "none", + "The group element is hidden"); + ok(theGroupItem.$undoContainer, "Undo container is avaliable"); + + // click on close + let closeButton = theGroupItem.$undoContainer.find(".close"); + EventUtils.sendMouseEvent( + { type: "click" }, closeButton[0], contentWindow); + }); + + groupItem.addSubscriber(groupItem, "close", function() { + groupItem.removeSubscriber(groupItem, "close"); + + let theGroupItem = contentWindow.GroupItems.groupItem(groupItem.id); + ok(!theGroupItem, "The group item doesn't exists"); + + let endGame = function() { + window.removeEventListener("tabviewhidden", endGame, false); + ok(!TabView.isVisible(), "Tab View is hidden"); + finish(); + }; + window.addEventListener("tabviewhidden", endGame, false); + + // after the last selected tabitem is closed, there would be not active + // tabitem on the UI so we set the active tabitem before toggling the + // visibility of tabview + let tabItems = contentWindow.TabItems.getItems(); + ok(tabItems[0], "A tab item exists"); + contentWindow.UI.setActiveTab(tabItems[0]); + + TabView.toggle(); + }); + + let closeButton = groupItem.container.getElementsByClassName("close"); + ok(closeButton, "Group item close button exists"); + EventUtils.sendMouseEvent({ type: "click" }, closeButton[0], contentWindow); +}
--- a/browser/themes/gnomestripe/browser/tabview/tabview.css +++ b/browser/themes/gnomestripe/browser/tabview/tabview.css @@ -189,16 +189,45 @@ body { } .appTabIcon { width: 16px; height: 16px; cursor: pointer; } +.undo { + background-color: #A0A0A0; + width: 150px; + height: 30px; + line-height: 30px; + -moz-box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,.24); + text-shadow: 0px -1px 0px rgba(255,255,255,.2); + color: rgba( 0,0,0, .8); + border-radius: 0.4em; + text-align: center; + border: none; + cursor: pointer; +} + +.undo:hover { + background-color: #949494; +} + +.undo .close { + top: 4px; + left: 4px; + opacity: 0.5; +} + +.undo .close:hover{ + opacity: 1.0; +} + + /* InfoItems ----------------------------------*/ .info-item { cursor: move; border: 1px solid rgba(230,230,230,1); background-color: rgba(248,248,248,1); border-radius: 0.4em;
--- a/browser/themes/pinstripe/browser/tabview/tabview.css +++ b/browser/themes/pinstripe/browser/tabview/tabview.css @@ -196,16 +196,44 @@ body { } .appTabIcon { width: 16px; height: 16px; cursor: pointer; } +.undo { + background-color: #A0A0A0; + width: 150px; + height: 30px; + line-height: 30px; + -moz-box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,.24); + text-shadow: 0px -1px 0px rgba(255,255,255,.2); + color: rgba( 0,0,0, .8); + border-radius: 0.4em; + text-align: center; + border: none; + cursor: pointer; +} + +.undo:hover { + background-color: #949494; +} + +.undo .close { + top: 4px; + left: 4px; + opacity: 0.5; +} + +.undo .close:hover{ + opacity: 1.0; +} + /* InfoItems ----------------------------------*/ .info-item { cursor: move; border: 1px solid rgba(230,230,230,1); background-color: rgba(248,248,248,1); border-radius: 0.4em;
--- a/browser/themes/winstripe/browser/tabview/tabview.css +++ b/browser/themes/winstripe/browser/tabview/tabview.css @@ -201,16 +201,44 @@ body { } .appTabIcon { width: 16px; height: 16px; cursor: pointer; } +.undo { + background-color: #A0A0A0; + width: 150px; + height: 30px; + line-height: 30px; + -moz-box-shadow: 0px 1px 0px rgba(255,255,255,.5), 0px -1px 0px rgba(0,0,0,.24); + text-shadow: 0px -1px 0px rgba(255,255,255,.2); + color: rgba( 0,0,0, .8); + border-radius: 0.4em; + text-align: center; + border: none; + cursor: pointer; +} + +.undo:hover { + background-color: #949494; +} + +.undo .close { + top: 4px; + left: 4px; + opacity: 0.5; +} + +.undo .close:hover{ + opacity: 1.0; +} + /* InfoItems ----------------------------------*/ .info-item { cursor: move; border: 1px solid rgba(230,230,230,1); background-color: rgba(248,248,248,1); border-radius: 0.4em;