Bug 783687 - Use custom event in the chat box to update the titlebar. r=jaws
authorShane Caraveo <mixedpuppy@gmail.com>
Tue, 25 Sep 2012 14:38:58 -0700
changeset 108192 987f0423f403b837cabcf872aba7742eb20af2ce
parent 108191 20b1b4fd678e4166d25b6cf98431f7ae87056af5
child 108193 e4be135eff48ba0d22309e8926b91ba290e6c423
push id15433
push userryanvm@gmail.com
push dateWed, 26 Sep 2012 22:56:47 +0000
treeherdermozilla-inbound@d0d8848ffd07 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs783687
milestone18.0a1
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
Bug 783687 - Use custom event in the chat box to update the titlebar. r=jaws
browser/base/content/socialchat.xml
browser/themes/gnomestripe/browser.css
browser/themes/pinstripe/browser.css
browser/themes/winstripe/browser.css
--- a/browser/base/content/socialchat.xml
+++ b/browser/base/content/socialchat.xml
@@ -2,17 +2,17 @@
 
 <bindings id="socialChatBindings"
     xmlns="http://www.mozilla.org/xbl"
     xmlns:xbl="http://www.mozilla.org/xbl"
     xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <binding id="chatbox">
     <content orient="vertical" mousethrough="never">
-      <xul:hbox class="chat-titlebar" xbl:inherits="minimized,selected"
+      <xul:hbox class="chat-titlebar" xbl:inherits="minimized,selected,activity"
                 onclick="document.getBindingParent(this).toggle();" align="baseline">
         <xul:image class="chat-status-icon" xbl:inherits="src=image"/>
         <xul:label class="chat-title" flex="1" xbl:inherits="value=label,crop"/>
         <xul:toolbarbutton class="chat-close-button chat-toolbarbutton"
                            oncommand="document.getBindingParent(this).close();"/>
       </xul:hbox>
       <xul:iframe anonid="iframe" class="chat-frame" flex="1"
                   xbl:inherits="src,origin,collapsed=minimized" type="content"/>
@@ -73,37 +73,52 @@
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="focus" phase="capturing">
         this.parentNode.selectedChat = this;
       </handler>
-      <handler event="load"><![CDATA[
+      <handler event="DOMContentLoaded"><![CDATA[
         this.isActive = !this.minimized;
         if (this._callback) this._callback(this.iframe.contentWindow);
+        let chatbox = this;
+        function chatActivity() {
+          chatbox.setAttribute("activity", true);
+          chatbox.parentNode.updateTitlebar(chatbox);
+        };
+        let iframeWindow = this.iframe.contentWindow;
+        iframeWindow.addEventListener("socialChatActivity", chatActivity);
+        iframeWindow.addEventListener("unload", function unload() {
+          iframeWindow.removeEventListener("unload", unload);
+          iframeWindow.removeEventListener("socialChatActivity", chatActivity);
+        });
       ]]></handler>
-      <handler event="DOMTitleChanged" action="this.setAttribute('label', this.iframe.contentDocument.title);"/>
+      <handler event="DOMTitleChanged"><![CDATA[
+        this.setAttribute('label', this.iframe.contentDocument.title);
+        this.parentNode.updateTitlebar(this);
+      ]]></handler>
       <handler event="DOMLinkAdded"><![CDATA[
         // much of this logic is from DOMLinkHandler in browser.js
         // this sets the presence icon for a chat user, we simply use favicon style updating
         let link = event.originalTarget;
         let rel = link.rel && link.rel.toLowerCase();
         if (!link || !link.ownerDocument || !rel || !link.href)
           return;
         if (link.rel.indexOf("icon") < 0)
           return;
 
         let uri = DOMLinkHandler.getLinkIconURI(link);
         if (!uri)
           return;
 
         // we made it this far, use it
         this.setAttribute('image', uri.spec);
+        this.parentNode.updateTitlebar(this);
       ]]></handler>
     </handlers>
   </binding>
 
   <binding id="chatbar">
     <content>
       <xul:hbox align="end" pack="end" anonid="innerbox" class="chatbar-innerbox" mousethrough="always" flex="1">
         <xul:toolbarbutton anonid="nub" class="chatbar-button" type="menu" collapsed="true" mousethrough="never">
@@ -119,32 +134,37 @@
       <field name="innerbox" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "innerbox");
       </field>
 
       <field name="menupopup" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "nubMenu");
       </field>
 
+      <field name="nub" readonly="true">
+        document.getAnonymousElementByAttribute(this, "anonid", "nub");
+      </field>
+
       <property name="emptyWidth">
         <getter>
           return document.getAnonymousElementByAttribute(this, "anonid", "spacer").boxObject.width;
         </getter>
       </property>
 
       <property name="selectedChat">
         <getter><![CDATA[
           return this._selectedChat;
         ]]></getter>
         <setter><![CDATA[
           if (this._selectedChat)
             this._selectedChat.removeAttribute("selected");
           this._selectedChat = val;
           if (val) {
             this._selectedChat.setAttribute("selected", "true");
+            this._selectedChat.removeAttribute("activity");
           }
         ]]></setter>
       </property>
 
       <field name="menuitemMap">new WeakMap()</field>
       <field name="chatboxForURL">new Map();</field>
 
       <property name="firstCollapsedChild">
@@ -191,16 +211,31 @@
           }
           if (!this.firstCollapsedChild) {
             window.removeEventListener("resize", this);
             this.menupopup.parentNode.collapsed = true;
           }
         ]]></body>
       </method>
 
+      <method name="updateTitlebar">
+        <parameter name="aChatbox"/>
+        <body><![CDATA[
+          if (aChatbox.collapsed) {
+            let menuitem = this.menuitemMap.get(aChatbox);
+            if (aChatbox.getAttribute("activity")) {
+              menuitem.setAttribute("activity", true);
+              this.nub.setAttribute("activity", true);
+            }
+            menuitem.setAttribute("label", aChatbox.getAttribute("label"));
+            menuitem.setAttribute("image", aChatbox.getAttribute("image"));
+          }
+        ]]></body>
+      </method>
+
       <method name="handleEvent">
         <parameter name="aEvent"/>
         <body><![CDATA[
           if (aEvent.type == "resize") {
             this.resize();
           }
         ]]></body>
       </method>
@@ -220,17 +255,19 @@
 
       <method name="collapseChat">
         <parameter name="aChatbox"/>
         <body><![CDATA[
           aChatbox.viewWidth = aChatbox.getBoundingClientRect().width;
           aChatbox.collapsed = true;
           aChatbox.isActive = false;
           let menu = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
+          menu.setAttribute("class", "menuitem-iconic");
           menu.setAttribute("label", aChatbox.iframe.contentDocument.title);
+          menu.setAttribute("image", aChatbox.getAttribute("image"));
           menu.chat = aChatbox;
           this.menuitemMap.set(aChatbox, menu);
           this.menupopup.appendChild(menu);
           this.menupopup.parentNode.collapsed = false;
         ]]></body>
       </method>
 
       <method name="showChat">
@@ -291,16 +328,19 @@
           this.insertBefore(cb, this.firstChild);
           cb.init(aProvider, aURL, aCallback);
           this.chatboxForURL.set(aURL, Cu.getWeakReference(cb));
         ]]></body>
       </method>
 
     </implementation>
     <handlers>
+      <handler event="popupshown"><![CDATA[
+        this.nub.removeAttribute("activity");
+      ]]></handler>
       <handler event="overflow"><![CDATA[
         // make sure we're not getting an overflow from content
         if (event.originalTarget != this.innerbox)
           return;
 
         let hasHidden = this.firstCollapsedChild;
         let child = this.firstRemovableChild;
         if (child)
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -2775,16 +2775,20 @@ html|*#gcli-output-frame {
 .chat-titlebar[minimized="true"] {
   border-bottom: none;
 }
 
 .chat-titlebar[selected] {
   background-color: #f0f0f0;
 }
 
+.chat-titlebar[activity] {
+  background-color: #ceeaff;
+}
+
 .chat-frame {
   padding: 0;
   margin: 0;
   overflow: hidden;
 }
 
 .chatbar-button {
   background-color: #d9d9d9;
@@ -2804,16 +2808,24 @@ html|*#gcli-output-frame {
   box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
 }
 
 .chatbar-button > .toolbarbutton-text,
 .chatbar-button > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
+.chatbar-button[activity] {
+  background-color: #ceeaff;
+}
+
+.chatbar-button > menupopup > menuitem[activity] {
+  font-weight: bold;
+}
+
 .chatbar-innerbox {
   background: transparent;
   margin: -285px -1px 0 -1px;
   overflow: hidden;
 }
 
 chatbar {
   -moz-margin-end: 20px;
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -3457,16 +3457,20 @@ html|*#gcli-output-frame {
   border-bottom: 1px solid #404040;
   cursor: pointer;
 }
 
 .chat-titlebar[minimized="true"] {
   border-bottom: none;
 }
 
+.chat-titlebar[activity] {
+  background-color: #ceeaff;
+}
+
 .chat-titlebar[selected] {
   background-color: #f0f0f0;
 }
 
 .chat-frame {
   padding: 0;
   margin: 0;
   overflow: hidden;
@@ -3490,16 +3494,24 @@ html|*#gcli-output-frame {
   box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
 }
 
 .chatbar-button > .toolbarbutton-text,
 .chatbar-button > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
+.chatbar-button[activity] {
+  background-color: #ceeaff;
+}
+
+.chatbar-button > menupopup > menuitem[activity] {
+  font-weight: bold;
+}
+
 .chatbar-innerbox {
   background: transparent;
   margin: -285px -1px 0 -1px;
   overflow: hidden;
 }
 
 chatbar {
   -moz-margin-end: 20px;
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -3479,16 +3479,20 @@ html|*#gcli-output-frame {
 .chat-titlebar[minimized="true"] {
   border-bottom: none;
 }
 
 .chat-titlebar[selected] {
   background-color: #dae3f0;
 }
 
+.chat-titlebar[activity] {
+  background-color: #ceeaff;
+}
+
 .chat-frame {
   padding: 0;
   margin: 0;
   overflow: hidden;
 }
 
 .chatbar-button {
   /* XXX get a real image for this */
@@ -3517,16 +3521,24 @@ html|*#gcli-output-frame {
   box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
 }
 
 .chatbar-button > .toolbarbutton-text,
 .chatbar-button > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
+.chatbar-button[activity] {
+  background-color: #ceeaff;
+}
+
+.chatbar-button > menupopup > menuitem[activity] {
+  font-weight: bold;
+}
+
 .chatbar-innerbox {
   background: transparent;
   margin: -285px -1px 0 -1px;
   overflow: hidden;
 }
 
 chatbar {
   -moz-margin-end: 20px;