Bug 511107 - Need a centralized way to assign lightweight themes to XUL windows. r=enn,mconnor,rflint
authorDão Gottwald <dao@mozilla.com>
Thu, 03 Sep 2009 22:19:50 +0200
changeset 32218 e75c771c6ab8ce2288cc584a97bd95c3fa248bcb
parent 32217 ec44dfe85a0d2a24aeaf6a7581ae0719f0a64223
child 32219 81c827ddc262c9130fad583adc07f87bf5081a3d
push id8922
push userdgottwald@mozilla.com
push dateThu, 03 Sep 2009 20:20:24 +0000
treeherdermozilla-central@e75c771c6ab8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersenn, mconnor, rflint
bugs511107
milestone1.9.3a1pre
Bug 511107 - Need a centralized way to assign lightweight themes to XUL windows. r=enn,mconnor,rflint
browser/base/content/browser.css
browser/base/content/browser.xul
browser/themes/gnomestripe/browser/browser.css
browser/themes/pinstripe/browser/browser.css
browser/themes/winstripe/browser/browser.css
toolkit/content/LightweightThemeConsumer.jsm
toolkit/content/Makefile.in
toolkit/content/widgets/dialog.xml
toolkit/content/widgets/general.xml
toolkit/content/widgets/wizard.xml
toolkit/content/xul.css
toolkit/themes/gnomestripe/global/global.css
toolkit/themes/gnomestripe/global/notification.css
toolkit/themes/pinstripe/global/findBar.css
toolkit/themes/pinstripe/global/global.css
toolkit/themes/pinstripe/global/globalBindings.xml
toolkit/themes/pinstripe/global/notification.css
toolkit/themes/winstripe/global/global.css
toolkit/themes/winstripe/global/notification.css
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -12,16 +12,26 @@ tabbrowser {
 toolbar[printpreview="true"] {
   -moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
 }
 
 toolbarpaletteitem[place="palette"] > toolbaritem > hbox[type="places"] {
   display: none;
 }
 
+#main-window[lwtheme="true"] {
+  background-repeat: no-repeat;
+  background-position: top right;
+}
+
+#browser-bottombox[lwthemefooter="true"] {
+  background-repeat: no-repeat;
+  background-position: bottom left;
+}
+
 /* ::::: location bar ::::: */
 #urlbar {
   -moz-binding: url(chrome://browser/content/urlbarBindings.xml#urlbar);
 }
 
 #wrapper-urlbar-container #urlbar {
   -moz-user-input: disabled;
   cursor: -moz-grab;
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -75,16 +75,18 @@
         titlemodifier_privatebrowsing="&mainWindow.titlePrivateBrowsingSuffix;"
 #else
         title_privatebrowsing="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@ &mainWindow.titlePrivateBrowsingSuffix;"
         titlemodifier="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@"
         titlemodifier_normal="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@"
         titlemodifier_privatebrowsing="&mainWindow.titlemodifier;@PRE_RELEASE_SUFFIX@ &mainWindow.titlePrivateBrowsingSuffix;"
 #endif
         titlemenuseparator="&mainWindow.titlemodifiermenuseparator;"
+        lightweightthemes="true"
+        lightweightthemesfooter="browser-bottombox"
         windowtype="navigator:browser"
         screenX="4" screenY="4"
         browsingmode="normal"
         toggletoolbar="true"
         persist="screenX screenY width height sizemode"> 
 
 # All JS files which are not content (only) dependent that browser.xul
 # wishes to include *must* go into the global-scripts.inc file
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -65,16 +65,26 @@
 }
 
 #navigator-toolbox[inFullscreen="true"],
 #navigator-toolbox[inFullscreen="true"] > #nav-bar {
   border-top: none;
   padding-top: 0;
 }
 
+#main-window[lwtheme="true"] #urlbar:not([focused="true"]),
+#main-window[lwtheme="true"] #searchbar > textbox:not([focused="true"]),
+#main-window[lwtheme="true"] .tabbrowser-tab:not([selected="true"]) {
+  opacity: .85;
+}
+
+#main-window[lwtheme="true"] .tabbrowser-tab {
+  text-shadow: none;
+}
+
 /* Places toolbar */
 toolbarbutton.bookmark-item {
   margin: 0;
   min-width: 0;
   max-width: 13em;
   padding: 2px 3px;
 }
 
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -41,16 +41,89 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 @import url("chrome://global/skin/");
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
+#main-window[lwtheme="true"] #urlbar:not([focused="true"]),
+#main-window[lwtheme="true"] #searchbar > textbox:not([focused="true"]) {
+  opacity: .9;
+}
+
+#main-window[lwtheme="true"] > #navigator-toolbox toolbarbutton {
+  color: inherit !important;
+  text-shadow: inherit;
+}
+
+#main-window[lwtheme="true"] #PersonalToolbar,
+#main-window[lwtheme="true"] #nav-bar {
+  -moz-appearance: none !important;
+  background: none !important;
+  border-style: none !important;
+}
+
+#main-window[lwtheme="true"] .tabbrowser-strip,
+#main-window[lwtheme="true"] .tabbrowser-tabs {
+  background: none !important;
+}
+
+#main-window[lwtheme="true"] .tabbrowser-tab,
+#main-window[lwtheme="true"]:not([active="true"]) .tabbrowser-tab {
+  color: inherit;
+  text-shadow: inherit;
+}
+
+#main-window[lwtheme="true"] .tabbrowser-tab[selected="true"] {
+  background-color: transparent !important;
+}
+#main-window[lwtheme="true"] .tabbrowser-tab:not([selected="true"]):not(:hover) > .tab-text {
+  opacity: .8;
+}
+
+#main-window[lwtheme="true"] .tabbrowser-arrowscrollbox > .tabs-newtab-button {
+  width: auto;
+  -moz-box-flex: 1;
+  -moz-box-pack: start;
+  border-style: none;
+  background: none;
+}
+
+#main-window[lwthemetextcolor="bright"] .tabbrowser-tab {
+  -moz-border-left-colors: rgba(255,255,255,.1) rgba(255,255,255,.6) rgba(255,255,255,.2);
+  -moz-border-bottom-colors: rgba(255,255,255,.1) rgba(255,255,255,.6) rgba(255,255,255,.2);
+  -moz-border-right-colors: rgba(255,255,255,.1) rgba(255,255,255,.6) rgba(255,255,255,.2);
+}
+
+#main-window[lwthemetextcolor="bright"] .tabbrowser-tab[selected="true"] {
+  -moz-border-left-colors: rgba(255,255,255,.6) rgba(255,255,255,.2);
+  -moz-border-bottom-colors: rgba(255,255,255,.6) rgba(255,255,255,.2);
+  -moz-border-right-colors: rgba(255,255,255,.6) rgba(255,255,255,.2);
+}
+
+#main-window[lwthemetextcolor="dark"] .tabs-newtab-button,
+#main-window[lwthemetextcolor="dark"] .tabs-alltabs-button,
+#main-window[lwthemetextcolor="dark"] .tabs-container > .tabs-closebutton,
+#main-window[lwthemetextcolor="dark"] .tabbrowser-arrowscrollbox > .scrollbutton-up,
+#main-window[lwthemetextcolor="dark"] .tabbrowser-arrowscrollbox > .scrollbutton-down-stack > .scrollbutton-down,
+#main-window[lwthemetextcolor="dark"] .tabbrowser-tab:not([selected="true"]) {
+  -moz-box-shadow: inset 0 1px 0 rgba(50,50,50,.5);
+}
+
+#main-window[lwthemetextcolor="bright"] .tabs-newtab-button,
+#main-window[lwthemetextcolor="bright"] .tabs-alltabs-button,
+#main-window[lwthemetextcolor="bright"] .tabs-container > .tabs-closebutton,
+#main-window[lwthemetextcolor="bright"] .tabbrowser-arrowscrollbox > .scrollbutton-up,
+#main-window[lwthemetextcolor="bright"] .tabbrowser-arrowscrollbox > .scrollbutton-down-stack > .scrollbutton-down,
+#main-window[lwthemetextcolor="bright"] .tabbrowser-tab:not([selected="true"]) {
+  -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.6);
+}
+
 #main-window {
   -moz-appearance: none;
   background-color: #eeeeee;
 }
 
 #main-window[chromehidden~="toolbar"][chromehidden~="location"][chromehidden~="directories"] {
   border-top: 1px solid rgba(0,0,0,0.65);
 }
@@ -1271,16 +1344,17 @@ richlistitem[selected="true"][current="t
 
 #sidebar { 
   background-color: #d4dde5;
 }
 
 sidebarheader { 
   background-color: #d4dde5;
   padding: 2px;
+  text-shadow: none;
 }
 
 #sidebar-box {
   -moz-appearance: dialog;
   -moz-appearance: none;
 }
 
 #sidebar-splitter {
@@ -1416,24 +1490,24 @@ tabbrowser > tabbox {
   opacity: .6;
 }
 
 .tabbrowser-tab > .tab-text {
   margin-top: 3px;
   margin-bottom: 0;
   font: message-box;
   font-weight: bold;
-  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
 }
 
 .tabbrowser-tab,
 .tabbrowser-arrowscrollbox > .tabs-newtab-button {
   -moz-appearance: none;
   -moz-border-radius: 0 0 6px 6px;
   color: #222;
+  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
   margin: 0 0 1px;
   padding: 0 5px;
   border-style: none solid solid;
   border-width: 3px;
   -moz-border-right-colors: rgba(0, 0, 0, .08) rgba(0, 0, 0, .17) rgba(180, 180, 180, .29);
   -moz-border-bottom-colors: rgba(0, 0, 0, .08) rgba(0, 0, 0, .17) rgba(180, 180, 180, .29);
   -moz-border-left-colors: rgba(0, 0, 0, .08) rgba(0, 0, 0, .17) rgba(180, 180, 180, .29);
   -moz-background-clip: padding;
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -41,16 +41,29 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 @import url("chrome://global/skin/");
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
+#main-window[lwtheme="true"] #urlbar:not([focused="true"]),
+#main-window[lwtheme="true"] #searchbar > textbox:not([focused="true"]) {
+  opacity: .85;
+}
+
+#main-window[lwtheme="true"] .tabbrowser-tab[selected="true"] {
+  text-shadow: none;
+}
+
+#main-window[lwtheme="true"] .tabbrowser-tab:not([selected="true"]) {
+  color: inherit;
+}
+
 #menubar-items {
   -moz-box-orient: vertical; /* for flex hack */
 }
 
 #menubar-items > menubar {
   -moz-box-flex: 1; /* make menu items expand to fill toolbar height */
 }
 
new file mode 100644
--- /dev/null
+++ b/toolkit/content/LightweightThemeConsumer.jsm
@@ -0,0 +1,121 @@
+/* ***** 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 Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Dao Gottwald <dao@mozilla.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * 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 ***** */
+
+let EXPORTED_SYMBOLS = ["LightweightThemeConsumer"];
+
+function LightweightThemeConsumer(aDocument) {
+  this._doc = aDocument;
+  this._footerId = aDocument.documentElement.getAttribute("lightweightthemesfooter");
+
+  Components.classes["@mozilla.org/observer-service;1"]
+            .getService(Components.interfaces.nsIObserverService)
+            .addObserver(this, "lightweight-theme-changed", false);
+
+  var temp = {};
+  Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", temp);
+  this._update(temp.LightweightThemeManager.currentTheme);
+}
+
+LightweightThemeConsumer.prototype = {
+  observe: function (aSubject, aTopic, aData) {
+    if (aTopic != "lightweight-theme-changed")
+      return;
+
+    this._update(JSON.parse(aData));
+  },
+
+  destroy: function () {
+    Components.classes["@mozilla.org/observer-service;1"]
+              .getService(Components.interfaces.nsIObserverService)
+              .removeObserver(this, "lightweight-theme-changed");
+
+    this._doc = null;
+  },
+
+  _update: function (aData) {
+    if (!aData)
+      aData = { headerURL: "", footerURL: "", textColor: "", dominantColor: "" };
+
+    var root = this._doc.documentElement;
+    var active = !!aData.headerURL;
+
+    if (active) {
+      root.style.color = aData.textColor || "black";
+      let [r, g, b] = _parseRGB(this._doc.defaultView.getComputedStyle(root, "").color);
+      let brightness = (r + g + b) / 3;
+      root.setAttribute("lwthemetextcolor", brightness <= 127 ? "dark" : "bright");
+      root.setAttribute("lwtheme", "true");
+    } else {
+      root.style.color = "";
+      root.removeAttribute("lwthemetextcolor");
+      root.removeAttribute("lwtheme");
+    }
+
+    _setImage(root, active, aData.headerURL);
+    if (this._footerId) {
+      let footer = this._doc.getElementById(this._footerId);
+      _setImage(footer, active, aData.footerURL);
+      if (active && aData.footerURL)
+        footer.setAttribute("lwthemefooter", "true");
+      else
+        footer.removeAttribute("lwthemefooter");
+    }
+
+    if (root.hasAttribute("activetitlebarcolor")) {
+      if (!root.hasAttribute("originalactivetitlebarcolor")) {
+        root.setAttribute("originalactivetitlebarcolor",
+                          root.getAttribute("activetitlebarcolor"));
+        root.setAttribute("originalinactivetitlebarcolor",
+                          root.getAttribute("inactivetitlebarcolor"));
+      }
+      root.setAttribute("activetitlebarcolor", aData.dominantColor
+                          || root.getAttribute("originalactivetitlebarcolor"));
+      root.setAttribute("inactivetitlebarcolor", aData.dominantColor
+                          || root.getAttribute("originalinactivetitlebarcolor"));
+    }
+  }
+}
+
+function _setImage(aElement, aActive, aURL) {
+  aElement.style.backgroundImage =
+    (aActive && aURL) ? 'url("' + aURL.replace('"', '\\"', "g") + '")' : "";
+}
+
+function _parseRGB(aColorString) {
+  var rgb = aColorString.match(/^rgba?\((\d+), (\d+), (\d+)/);
+  rgb.shift();
+  return rgb.map(function (x) parseInt(x));
+}
--- a/toolkit/content/Makefile.in
+++ b/toolkit/content/Makefile.in
@@ -75,14 +75,15 @@ DEFINES += -DSOURCE_REPO="$(SOURCE_REPO)
 endif
 
 ifdef ENABLE_TESTS
 DIRS += tests
 endif
 
 EXTRA_JS_MODULES = \
   debug.js \
+  LightweightThemeConsumer.jsm \
   WindowDraggingUtils.jsm \
   $(NULL)
 
 EXTRA_PP_JS_MODULES = debug.js
 
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/content/widgets/dialog.xml
+++ b/toolkit/content/widgets/dialog.xml
@@ -1,22 +1,19 @@
 <?xml version="1.0"?>
 
 <bindings id="dialogBindings"
           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="dialog-base">
+  
+  <binding id="dialog" extends="chrome://global/content/bindings/general.xml#root-element">
     <resources>
       <stylesheet src="chrome://global/skin/dialog.css"/>
     </resources>
-  </binding>
-  
-  <binding id="dialog" extends="chrome://global/content/bindings/dialog.xml#dialog-base">
     <content>
       <xul:vbox class="box-inherit dialog-content-box" flex="1">
         <children/>
       </xul:vbox>
           
       <xul:hbox class="dialog-button-box" anonid="buttons"
                 xbl:inherits="pack=buttonpack,align=buttonalign,dir=buttondir,orient=buttonorient"
 #ifdef XP_UNIX
@@ -416,16 +413,19 @@
         if (btn)
           btn.setAttribute("default", event.originalTarget == btn || !(event.originalTarget instanceof Components.interfaces.nsIDOMXULButtonElement));
       </handler>
 #endif
     </handlers>
 
   </binding>
 
-  <binding id="dialogheader" extends="chrome://global/content/bindings/dialog.xml#dialog-base">
+  <binding id="dialogheader">
+    <resources>
+      <stylesheet src="chrome://global/skin/dialog.css"/>
+    </resources>
     <content>
       <xul:label class="dialogheader-title" xbl:inherits="value=title,crop" crop="right" flex="1"/>
       <xul:label class="dialogheader-description" xbl:inherits="value=description"/>
     </content>
   </binding>
 
 </bindings>
--- a/toolkit/content/widgets/general.xml
+++ b/toolkit/content/widgets/general.xml
@@ -55,16 +55,35 @@
 
   <binding id="control-item" extends="chrome://global/content/bindings/general.xml#basetext">
     <implementation>
       <property name="value"      onset="this.setAttribute('value', val); return val;"
                                   onget="return this.getAttribute('value');"/>
     </implementation>
   </binding>
 
+  <binding id="root-element">
+    <implementation>
+      <field name="_lightweightTheme">null</field>
+      <constructor><![CDATA[
+        if (this.hasAttribute("lightweightthemes")) {
+          let temp = {};
+          Components.utils.import("resource://gre/modules/LightweightThemeConsumer.jsm", temp);
+          this._lightweightTheme = new temp.LightweightThemeConsumer(this.ownerDocument);
+        }
+      ]]></constructor>
+      <destructor><![CDATA[
+        if (this._lightweightTheme) {
+          this._lightweightTheme.destroy();
+          this._lightweightTheme = null;
+        }
+      ]]></destructor>
+    </implementation>
+  </binding>
+
   <!--
     Inline Editable UI Element
     - This binding forms the basis of the inline edit treecell and the inline edit
     - buttons. 
     - TODO: investigate creating extensions to the wrapper widgets (tree, toolbar)
     -       to make them provide some object implementing an interface similar to
     -       tree's so we can build in some of the ILE behavior (such as going
     -       in and out of the mode, asking isEditable etc) so as to remove some of
--- a/toolkit/content/widgets/wizard.xml
+++ b/toolkit/content/widgets/wizard.xml
@@ -11,17 +11,20 @@
    xmlns:xbl="http://www.mozilla.org/xbl">
 
   <binding id="wizard-base">
     <resources>
       <stylesheet src="chrome://global/skin/wizard.css"/>
     </resources>
   </binding>
   
-  <binding id="wizard" extends="chrome://global/content/bindings/wizard.xml#wizard-base">
+  <binding id="wizard" extends="chrome://global/content/bindings/general.xml#root-window">
+    <resources>
+      <stylesheet src="chrome://global/skin/wizard.css"/>
+    </resources>
     <content>
       <xul:hbox class="wizard-header" anonid="Header"/>
       
       <xul:deck class="wizard-page-box" flex="1" anonid="Deck">
         <children includes="wizardpage"/>
       </xul:deck>
       <children/>
       
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -14,16 +14,17 @@
   -moz-user-focus: ignore;
   -moz-user-select: -moz-none;
   display: -moz-box;
   -moz-box-sizing: border-box;
 }
 
 :root {
   text-rendering: optimizeLegibility;
+  -moz-binding: url("chrome://global/content/bindings/general.xml#root-element");
 }
 
 :root:-moz-locale-dir(rtl) {
   direction: rtl;
 }
 
 /* hide the content and destroy the frame */
 [hidden="true"] {
@@ -983,34 +984,36 @@ stringbundleset {
 
 stringbundle {
   -moz-binding: url("chrome://global/content/bindings/stringbundle.xml#stringbundle");
   visibility: collapse;
 }
 
 /********** dialog **********/
 
-dialog {
+dialog,
+dialog:root /* ovverride :root from above */ {
   -moz-binding: url("chrome://global/content/bindings/dialog.xml#dialog");
   -moz-box-orient: vertical;
 }
 
 dialogheader {
   -moz-binding: url("chrome://global/content/bindings/dialog.xml#dialogheader");
 }
 
 /********* page ************/
 
 page {
   -moz-box-orient: vertical;
 }
 
 /********** wizard **********/
 
-wizard {
+wizard,
+wizard:root /* ovverride :root from above */ {
   -moz-binding: url("chrome://global/content/bindings/wizard.xml#wizard");
   -moz-box-orient: vertical;
   width: 40em;
   height: 30em;
 }
 
 wizardpage {
   -moz-binding: url("chrome://global/content/bindings/wizard.xml#wizardpage");
@@ -1023,17 +1026,18 @@ wizardpage {
 }
 
 .wizard-buttons {
   -moz-binding: url("chrome://global/content/bindings/wizard.xml#wizard-buttons");
 }
 
 /********** preferences ********/
 
-prefwindow {
+prefwindow,
+prefwindow:root /* ovverride :root from above */ {
   -moz-binding: url("chrome://global/content/bindings/preferences.xml#prefwindow");  
   -moz-box-orient: vertical;
 }
 
 prefpane {
   -moz-binding: url("chrome://global/content/bindings/preferences.xml#prefpane");  
   -moz-box-orient: vertical;
 }
--- a/toolkit/themes/gnomestripe/global/global.css
+++ b/toolkit/themes/gnomestripe/global/global.css
@@ -183,16 +183,46 @@ sidebarheader > label {
 
 toolbar[mode="text"] .toolbarbutton-text {
   padding: 0 !important;
   margin: 3px 5px !important;
 }
 
 /* ::::: miscellaneous formatting ::::: */
 
+:root[lwtheme="true"],
+[lwthemefooter="true"],
+:root[lwtheme="true"] toolbar,
+:root[lwtheme="true"] statusbarpanel {
+  -moz-appearance: none;
+}
+
+:root[lwtheme="true"] sidebarheader {
+  background: none;
+}
+
+:root[lwthemetextcolor="dark"] {
+  text-shadow: 1px 1px 2px white;
+}
+
+:root[lwthemetextcolor="bright"] {
+  text-shadow: 1px 1px 2px black;
+}
+
+:root[lwtheme="true"] menubar > menu,
+:root[lwtheme="true"] toolbarbutton {
+  text-shadow: none;
+}
+
+:root[lwtheme="true"] menubar > menu:not([open="true"]),
+:root[lwtheme="true"] toolbarbutton:not(:hover):not([checked="true"]):not([open="true"]):not([disabled="true"]) {
+  color: inherit;
+  text-shadow: inherit;
+}
+
 .inset {
   border: 1px solid ThreeDShadow;
   border-right-color: ThreeDHighlight;
   border-bottom-color: ThreeDHighlight;
   margin: 0 5px 5px;
 }
   
 .outset {
--- a/toolkit/themes/gnomestripe/global/notification.css
+++ b/toolkit/themes/gnomestripe/global/notification.css
@@ -1,13 +1,14 @@
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
 notification {
   background-color: InfoBackground;
   color: InfoText;
+  text-shadow: none;
 }
 
 notification[type="info"] {
   background-color: -moz-Dialog;
   color: -moz-DialogText;
 }
 
 notification[type="critical"] {
--- a/toolkit/themes/pinstripe/global/findBar.css
+++ b/toolkit/themes/pinstripe/global/findBar.css
@@ -37,16 +37,17 @@ findbar {
 .findbar-highlight {
   margin: 0 4px;
   padding: 1px 3px;
   -moz-appearance: none;
   -moz-border-radius: 100%;
   border: @roundButtonBorder@;
   background: @roundButtonBackground@;
   -moz-box-shadow: @roundButtonShadow@;
+  color: buttontext;
 }
 
 .findbar-container > toolbarbutton:focus {
   position: relative;
   -moz-box-shadow: @focusRingShadow@, @roundButtonShadow@;
 }
 
 .findbar-container > toolbarbutton > .toolbarbutton-text {
--- a/toolkit/themes/pinstripe/global/global.css
+++ b/toolkit/themes/pinstripe/global/global.css
@@ -159,16 +159,51 @@ statusbarpanel {
 }
 
 .statusbarpanel-iconic {
   padding: 0px;
 }    
 
 /* ::::: miscellaneous formatting ::::: */
 
+:root[lwtheme="true"],
+[lwthemefooter="true"], {
+  -moz-appearance: none;
+}
+
+:root[lwthemetextcolor="dark"] {
+  text-shadow: 1px 1px 2px white;
+}
+
+:root[lwthemetextcolor="bright"] {
+  text-shadow: 1px 1px 2px black;
+}
+
+:root[lwtheme="true"] toolbar,
+:root[lwtheme="true"] findbar,
+:root[lwtheme="true"] statusbar {
+  -moz-appearance: none;
+  background: none;
+  border-style: none;
+}
+
+:root[lwtheme="true"] splitter {
+  background: none;
+}
+
+:root[lwtheme="true"] statusbar {
+  text-shadow: inherit;
+}
+
+:root[lwtheme="true"] .findbar-container > label,
+:root[lwtheme="true"] .findbar-find-status {
+  color: inherit;
+  text-shadow: inherit;
+}
+
 .inset {
   border: 1px solid ThreeDShadow;
   border-right-color: ThreeDHighlight;
   border-bottom-color: ThreeDHighlight;
   margin: 0 5px 5px;
 }
   
 .outset {
--- a/toolkit/themes/pinstripe/global/globalBindings.xml
+++ b/toolkit/themes/pinstripe/global/globalBindings.xml
@@ -1,17 +1,18 @@
 <?xml version="1.0"?>
 
 <!DOCTYPE bindings SYSTEM "chrome://global/locale/preferences.dtd">
 
 <bindings id="globalBindings"
           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="unifiedWindow">
+  <binding id="unifiedWindow"
+           extends="chrome://global/content/bindings/general.xml#root-window">
     <content activetitlebarcolor="#C9C9C9" inactivetitlebarcolor="#E4E4E4"/>
   </binding>
 
   <binding id="unifiedDialog"
            extends="chrome://global/content/bindings/dialog.xml#dialog">
     <content activetitlebarcolor="#C9C9C9" inactivetitlebarcolor="#E4E4E4">
       <xul:vbox class="box-inherit dialog-content-box" flex="1">
         <children/>
--- a/toolkit/themes/pinstripe/global/notification.css
+++ b/toolkit/themes/pinstripe/global/notification.css
@@ -1,12 +1,13 @@
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
 notification {
   padding: 3px 3px 4px;
+  text-shadow: none;
 }
 
 notification[type="info"] {
   color: rgba(255,255,255,0.95);
   background: url("chrome://global/skin/notification/info-bar-background.png") #404040 repeat-x top left;
   border-top: 1px solid #707070;
   border-bottom: 1px solid #2a2a2a;
 }
--- a/toolkit/themes/winstripe/global/global.css
+++ b/toolkit/themes/winstripe/global/global.css
@@ -183,16 +183,57 @@ sidebarheader > label {
 
 toolbar[mode="text"] .toolbarbutton-text {
   padding: 0 !important;
   margin: 3px 5px !important;
 }
 
 /* ::::: miscellaneous formatting ::::: */
 
+:root[lwtheme="true"],
+[lwthemefooter="true"] {
+  -moz-appearance: none;
+}
+
+:root[lwthemetextcolor="dark"] {
+  text-shadow: 1px 1px 2px white;
+}
+
+:root[lwthemetextcolor="bright"] {
+  text-shadow: 1px 1px 2px black;
+}
+
+:root[lwtheme="true"] toolbox,
+:root[lwtheme="true"] toolbar,
+:root[lwtheme="true"] statusbar,
+:root[lwtheme="true"] sidebarheader,
+:root[lwtheme="true"] .tabbrowser-tabs {
+  -moz-appearance: none;
+  background: none;
+  border-style: none;
+}
+
+:root[lwtheme="true"] splitter {
+  background: none;
+}
+
+:root[lwtheme="true"] toolbarbutton {
+  text-shadow: none;
+}
+
+:root[lwtheme="true"] menubar > menu {
+  -moz-appearance: none;
+  color: inherit;
+}
+
+:root[lwtheme="true"] toolbarbutton:not(:hover):not([checked="true"]):not([open="true"]):not([disabled="true"]) {
+  color: inherit;
+  text-shadow: inherit;
+}
+
 .inset {
   border: 1px solid ThreeDShadow;
   border-right-color: ThreeDHighlight;
   border-bottom-color: ThreeDHighlight;
   margin: 0 5px 5px;
 }
   
 .outset {
--- a/toolkit/themes/winstripe/global/notification.css
+++ b/toolkit/themes/winstripe/global/notification.css
@@ -1,13 +1,14 @@
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
 notification {
   background-color: InfoBackground;
   color: InfoText;
+  text-shadow: none;
 }
 
 notification[type="info"] {
   background-color: -moz-Dialog;
   color: -moz-DialogText;
 }
 
 notification[type="critical"] {