Merge the last PGO-green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Sat, 25 Aug 2012 11:42:21 -0400
changeset 103411 e874475efe15461988861e6172417b7b09fd7b62
parent 103410 ead893fc780c8e4c1fa43a4c688d75e725709448 (current diff)
parent 103381 54fdedb218f858cda41f4c45d91dc8ee46d998e5 (diff)
child 103412 36f85f213ee28ce22a753c963d971408674cbfb1
child 103466 bc23ba35391382a3de4dd325ad6baaaa88292ec3
push id13981
push userryanvm@gmail.com
push dateSat, 25 Aug 2012 19:48:18 +0000
treeherdermozilla-inbound@779bdf71cde5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone17.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
Merge the last PGO-green inbound changeset to m-c.
browser/config/tooltool-manifests/macosx32/clang.manifest
browser/config/tooltool-manifests/macosx64/clang.manifest
browser/themes/pinstripe/social/panelarrow-down.png
browser/themes/pinstripe/social/panelarrow-horiz.png
browser/themes/pinstripe/social/panelarrow-up.png
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -794,18 +794,17 @@ Accessible::ChildAtPoint(int32_t aX, int
   NS_ENSURE_TRUE(frame, nullptr);
 
   nsPresContext *presContext = frame->PresContext();
 
   nsRect screenRect = frame->GetScreenRectInAppUnits();
   nsPoint offset(presContext->DevPixelsToAppUnits(aX) - screenRect.x,
                  presContext->DevPixelsToAppUnits(aY) - screenRect.y);
 
-  nsIPresShell* presShell = presContext->PresShell();
-  nsIFrame *foundFrame = presShell->GetFrameForPoint(frame, offset);
+  nsIFrame *foundFrame = nsLayoutUtils::GetFrameForPoint(frame, offset);
 
   nsIContent* content = nullptr;
   if (!foundFrame || !(content = foundFrame->GetContent()))
     return fallbackAnswer;
 
   // Get accessible for the node with the point or the first accessible in
   // the DOM parent chain.
   DocAccessible* contentDocAcc = GetAccService()->
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -36,16 +36,17 @@ let SocialUI = {
         // Exceptions here sometimes don't get reported properly, report them
         // manually :(
         try {
           this.updateToggleCommand();
           SocialShareButton.updateButtonHiddenState();
           SocialToolbar.updateButtonHiddenState();
           SocialSidebar.updateSidebar();
           SocialChatBar.update();
+          SocialFlyout.unload();
         } catch (e) {
           Components.utils.reportError(e);
           throw e;
         }
         break;
       case "social:ambient-notification-changed":
         SocialToolbar.updateButton();
         break;
@@ -174,16 +175,126 @@ let SocialChatBar = {
       this.chatbar.newChat(aProvider, aURL, aCallback);
   },
   update: function() {
     if (!this.canShow)
       this.chatbar.removeAll();
   }
 }
 
+function sizeSocialPanelToContent(iframe) {
+  // FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
+  // Need to handle dynamic sizing
+  let doc = iframe.contentDocument;
+  if (!doc) {
+    return;
+  }
+  // "notif" is an implementation detail that we should get rid of
+  // eventually
+  let body = doc.getElementById("notif") || doc.body;
+  if (!body || !body.firstChild) {
+    return;
+  }
+
+  let [height, width] = [body.firstChild.offsetHeight || 300, 330];
+  iframe.style.width = width + "px";
+  iframe.style.height = height + "px";
+}
+
+let SocialFlyout = {
+  get panel() {
+    return document.getElementById("social-flyout-panel");
+  },
+
+  dispatchPanelEvent: function(name) {
+    let doc = this.panel.firstChild.contentDocument;
+    let evt = doc.createEvent("CustomEvent");
+    evt.initCustomEvent(name, true, true, {});
+    doc.documentElement.dispatchEvent(evt);
+  },
+
+  _createFrame: function() {
+    let panel = this.panel;
+    if (!Social.provider || panel.firstChild)
+      return;
+    // create and initialize the panel for this window
+    let iframe = document.createElement("iframe");
+    iframe.setAttribute("type", "content");
+    iframe.setAttribute("flex", "1");
+    iframe.setAttribute("origin", Social.provider.origin);
+    panel.appendChild(iframe);
+  },
+
+  unload: function() {
+    let panel = this.panel;
+    if (!panel.firstChild)
+      return
+    panel.removeChild(panel.firstChild);
+  },
+
+  onShown: function(aEvent) {
+    let iframe = this.panel.firstChild;
+    iframe.docShell.isActive = true;
+    iframe.docShell.isAppTab = true;
+    if (iframe.contentDocument.readyState == "complete") {
+      this.dispatchPanelEvent("socialFrameShow");
+    } else {
+      // first time load, wait for load and dispatch after load
+      iframe.addEventListener("load", function panelBrowserOnload(e) {
+        iframe.removeEventListener("load", panelBrowserOnload, true);
+        setTimeout(function() {
+          SocialFlyout.dispatchPanelEvent("socialFrameShow");
+        }, 0);
+      }, true);
+    }
+  },
+
+  onHidden: function(aEvent) {
+    this.panel.firstChild.docShell.isActive = false;
+    this.dispatchPanelEvent("socialFrameHide");
+  },
+
+  open: function(aURL, yOffset, aCallback) {
+    if (!Social.provider)
+      return;
+    let panel = this.panel;
+    if (!panel.firstChild)
+      this._createFrame();
+    panel.hidden = false;
+    let iframe = panel.firstChild;
+
+    let src = iframe.getAttribute("src");
+    if (src != aURL) {
+      iframe.addEventListener("load", function documentLoaded() {
+        iframe.removeEventListener("load", documentLoaded, true);
+        sizeSocialPanelToContent(iframe);
+        if (aCallback) {
+          try {
+            aCallback(iframe.contentWindow);
+          } catch(e) {
+            Cu.reportError(e);
+          }
+        }
+      }, true);
+      iframe.setAttribute("src", aURL);
+    }
+    else if (aCallback) {
+      try {
+        aCallback(iframe.contentWindow);
+      } catch(e) {
+        Cu.reportError(e);
+      }
+    }
+
+    sizeSocialPanelToContent(iframe);
+    let anchor = document.getElementById("social-sidebar-browser");
+    panel.openPopup(anchor, "start_before", 0, yOffset, false, false);
+  }
+}
+
 let SocialShareButton = {
   // Called once, after window load, when the Social.provider object is initialized
   init: function SSB_init() {
     this.updateButtonHiddenState();
     this.updateProfileInfo();
   },
 
   updateProfileInfo: function SSB_updateProfileInfo() {
@@ -331,16 +442,18 @@ var SocialToolbar = {
   },
 
   updateButton: function SocialToolbar_updateButton() {
     this.updateButtonHiddenState();
     let provider = Social.provider;
     let iconNames = Object.keys(provider.ambientNotificationIcons);
     let iconBox = document.getElementById("social-status-iconbox");
     let notifBox = document.getElementById("social-notification-box");
+    let panel = document.getElementById("social-notification-panel");
+    panel.hidden = false;
     let notificationFrames = document.createDocumentFragment();
     let iconContainers = document.createDocumentFragment();
 
     for each(let name in iconNames) {
       let icon = provider.ambientNotificationIcons[name];
 
       let notificationFrameId = "social-status-" + icon.name;
       let notificationFrame = document.getElementById(notificationFrameId);
@@ -390,69 +503,50 @@ var SocialToolbar = {
   },
 
   showAmbientPopup: function SocialToolbar_showAmbientPopup(iconContainer) {
     let iconImage = iconContainer.firstChild;
     let panel = document.getElementById("social-notification-panel");
     let notifBox = document.getElementById("social-notification-box");
     let notificationFrame = document.getElementById(iconImage.getAttribute("notificationFrameId"));
 
-    panel.hidden = false;
-
-    function sizePanelToContent() {
-      // FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
-      // Need to handle dynamic sizing
-      let doc = notificationFrame.contentDocument;
-      if (!doc) {
-        return;
-      }
-      // "notif" is an implementation detail that we should get rid of
-      // eventually
-      let body = doc.getElementById("notif") || doc.body;
-      if (!body || !body.firstChild) {
-        return;
-      }
-
-      // Clear dimensions on all browsers so the panel size will
-      // only use the selected browser.
-      let frameIter = notifBox.firstElementChild;
-      while (frameIter) {
-        frameIter.hidden = (frameIter != notificationFrame);
-        frameIter = frameIter.nextElementSibling;
-      }
-
-      let [height, width] = [body.firstChild.offsetHeight || 300, 330];
-      notificationFrame.style.width = width + "px";
-      notificationFrame.style.height = height + "px";
+    // Clear dimensions on all browsers so the panel size will
+    // only use the selected browser.
+    let frameIter = notifBox.firstElementChild;
+    while (frameIter) {
+      frameIter.collapsed = (frameIter != notificationFrame);
+      frameIter = frameIter.nextElementSibling;
     }
 
-    sizePanelToContent();
-
     function dispatchPanelEvent(name) {
       let evt = notificationFrame.contentDocument.createEvent("CustomEvent");
       evt.initCustomEvent(name, true, true, {});
       notificationFrame.contentDocument.documentElement.dispatchEvent(evt);
     }
 
-    panel.addEventListener("popuphiding", function onpopuphiding() {
-      panel.removeEventListener("popuphiding", onpopuphiding);
+    panel.addEventListener("popuphidden", function onpopuphiding() {
+      panel.removeEventListener("popuphidden", onpopuphiding);
       SocialToolbar.button.removeAttribute("open");
+      notificationFrame.docShell.isActive = false;
       dispatchPanelEvent("socialFrameHide");
     });
 
     panel.addEventListener("popupshown", function onpopupshown() {
       panel.removeEventListener("popupshown", onpopupshown);
       SocialToolbar.button.setAttribute("open", "true");
+      notificationFrame.docShell.isActive = true;
       notificationFrame.docShell.isAppTab = true;
       if (notificationFrame.contentDocument.readyState == "complete") {
+        sizeSocialPanelToContent(notificationFrame);
         dispatchPanelEvent("socialFrameShow");
       } else {
         // first time load, wait for load and dispatch after load
         notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
           notificationFrame.removeEventListener("load", panelBrowserOnload, true);
+          sizeSocialPanelToContent(notificationFrame);
           setTimeout(function() {
             dispatchPanelEvent("socialFrameShow");
           }, 0);
         }, true);
       }
     });
 
     panel.openPopup(iconImage, "bottomcenter topleft", 0, 0, false, false);
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -266,16 +266,23 @@
                 command="Social:UnsharePage"/>
 #endif
       </hbox>
     </panel>
 
     <panel id="social-notification-panel" type="arrow" hidden="true" noautofocus="true">
       <box id="social-notification-box" flex="1"></box>
     </panel>
+    <panel id="social-flyout-panel"
+           onpopupshown="SocialFlyout.onShown()"
+           onpopuphidden="SocialFlyout.onHidden()"
+           type="arrow"
+           hidden="true"
+           noautofocus="true"
+           position="topcenter topright"/>
 
     <menupopup id="inspector-node-popup">
       <menuitem id="inspectorHTMLCopyInner"
                 label="&inspectorHTMLCopyInner.label;"
                 accesskey="&inspectorHTMLCopyInner.accesskey;"
                 command="Inspector:CopyInner"/>
       <menuitem id="inspectorHTMLCopyOuter"
                 label="&inspectorHTMLCopyOuter.label;"
@@ -1063,16 +1070,17 @@
     <splitter id="social-sidebar-splitter"
               class="chromeclass-extrachrome sidebar-splitter"
               observes="socialSidebarBroadcaster"/>
     <vbox id="social-sidebar-box"
           class="chromeclass-extrachrome"
           observes="socialSidebarBroadcaster">
       <browser id="social-sidebar-browser"
                type="content"
+               disableglobalhistory="true"
                flex="1"
                style="min-width: 14em; width: 18em; max-width: 36em;"/>
     </vbox>
     <vbox id="browser-border-end" hidden="true" layer="true"/>
   </hbox>
 
   <hbox id="full-screen-warning-container" hidden="true" fadeout="true">
     <hbox style="width: 100%;" pack="center"> <!-- Inner hbox needed due to bug 579776. -->
--- a/browser/base/content/socialchat.xml
+++ b/browser/base/content/socialchat.xml
@@ -20,16 +20,43 @@
                   xbl:inherits="src,origin,collapsed=minimized" type="content"/>
     </content>
 
     <implementation implements="nsIDOMEventListener">
       <field name="iframe" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "iframe");
       </field>
 
+      <property name="minimized">
+        <getter>
+          return this.getAttribute("minimized") == "true";
+        </getter>
+        <setter>
+          this.isActive = !val;
+          if (val)
+            this.setAttribute("minimized", "true");
+          else
+            this.removeAttribute("minimized");
+        </setter>
+      </property>
+
+      <property name="isActive">
+        <getter>
+          return this.iframe.docShell.isActive;
+        </getter>
+        <setter>
+          this.iframe.docShell.isActive = !!val;
+
+          // let the chat frame know if it is being shown or hidden
+          let evt = this.iframe.contentDocument.createEvent("CustomEvent");
+          evt.initCustomEvent(val ? "socialFrameHide" : "socialFrameShow", true, true, {});
+          this.iframe.contentDocument.documentElement.dispatchEvent(evt);
+        </setter>
+      </property>
+
       <method name="init">
         <parameter name="aProvider"/>
         <parameter name="aURL"/>
         <parameter name="aCallback"/>
         <body><![CDATA[
           this._callback = aCallback;
           this.setAttribute("origin", aProvider.origin);
           this.setAttribute("src", aURL);
@@ -39,37 +66,29 @@
       <method name="close">
         <body><![CDATA[
           this.parentNode.remove(this);
         ]]></body>
       </method>
 
       <method name="toggle">
         <body><![CDATA[
-          let type;
-          if (this.getAttribute("minimized") == "true") {
-            this.removeAttribute("minimized");
-            type = "socialFrameShow";
-          } else {
-            this.setAttribute("minimized", "true");
-            type = "socialFrameHide";
-          }
-          // let the chat frame know if it is being shown or hidden
-          let evt = this.iframe.contentDocument.createEvent("CustomEvent");
-          evt.initCustomEvent(type, true, true, {});
-          this.iframe.contentDocument.documentElement.dispatchEvent(evt);
+          this.minimized = !this.minimized;
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="focus" phase="capturing">
         this.parentNode.selectedChat = this;
       </handler>
-      <handler event="DOMContentLoaded" action="if (this._callback) this._callback(this.iframe.contentWindow);"/>
+      <handler event="load"><![CDATA[
+        this.isActive = !this.minimized;
+        if (this._callback) this._callback(this.iframe.contentWindow);
+      ]]></handler>
       <handler event="DOMTitleChanged" action="this.setAttribute('label', this.iframe.contentDocument.title);"/>
       <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;
@@ -187,32 +206,34 @@
             this.showChat(newChat);
         ]]></body>
       </method>
 
       <method name="collapseChat">
         <parameter name="aChatbox"/>
         <body><![CDATA[
           aChatbox.collapsed = true;
+          aChatbox.isActive = false;
           let menu = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
           menu.setAttribute("label", aChatbox.iframe.contentDocument.title);
           menu.chat = aChatbox;
           this.menuitemMap.set(aChatbox, menu);
           this.menupopup.appendChild(menu);
           this.menupopup.parentNode.collapsed = false;
         ]]></body>
       </method>
 
       <method name="showChat">
         <parameter name="aChatbox"/>
         <body><![CDATA[
           let menuitem = this.menuitemMap.get(aChatbox);
           this.menuitemMap.delete(aChatbox);
           this.menupopup.removeChild(menuitem);
           aChatbox.collapsed = false;
+          aChatbox.isActive = !aChatbox.minimized;
         ]]></body>
       </method>
 
       <method name="remove">
         <parameter name="aChatbox"/>
         <body><![CDATA[
           if (this.selectedChat == aChatbox) {
             this.selectedChat = aChatbox.previousSibling ? aChatbox.previousSibling : aChatbox.nextSibling
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -59,19 +59,16 @@ endif
 # 480169)
 
 # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638.
 
 # browser_bug321000.js is disabled because newline handling is shaky (bug 592528)
 
 # browser_pageInfo.js + feed_tab.html is disabled for leaking (bug 767896)
 
-# browser_social_shareButton.js is disabled for not properly
-#   tearing down the social providers (bug 780010).
-
 _BROWSER_FILES = \
                  head.js \
                  browser_typeAheadFind.js \
                  browser_keywordSearch.js \
                  browser_allTabsPanel.js \
                  browser_alltabslistener.js \
                  browser_bug304198.js \
                  title_test.svg \
@@ -258,23 +255,26 @@ endif
                  browser_minimize.js \
                  browser_aboutSyncProgress.js \
                  browser_middleMouse_inherit.js \
                  redirect_bug623155.sjs \
                  browser_tabDrop.js \
                  browser_lastAccessedTab.js \
                  browser_bug734076.js \
                  browser_social_toolbar.js \
+                 browser_social_shareButton.js \
                  browser_social_sidebar.js \
+                 browser_social_flyout.js \
                  browser_social_mozSocial_API.js \
                  browser_social_isVisible.js \
                  browser_social_chatwindow.js \
                  social_panel.html \
                  social_sidebar.html \
                  social_chat.html \
+                 social_flyout.html \
                  social_window.html \
                  social_worker.js \
                  $(NULL)
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 _BROWSER_FILES += \
 		browser_bug462289.js \
 		$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_social_flyout.js
@@ -0,0 +1,48 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function test() {
+  waitForExplicitFinish();
+
+  let manifest = { // normal provider
+    name: "provider 1",
+    origin: "https://example.com",
+    sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html",
+    workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js",
+    iconURL: "chrome://branding/content/icon48.png"
+  };
+  runSocialTestWithProvider(manifest, function (finishcb) {
+    runSocialTests(tests, undefined, undefined, finishcb);
+  });
+}
+
+var tests = {
+  testOpenCloseFlyout: function(next) {
+    let panel = document.getElementById("social-flyout-panel");
+    let port = Social.provider.port;
+    ok(port, "provider has a port");
+    port.onmessage = function (e) {
+      let topic = e.data.topic;
+      switch (topic) {
+        case "got-sidebar-message":
+          port.postMessage({topic: "test-flyout-open"});
+          break;
+        case "got-flyout-visibility":
+          if (e.data.result == "hidden") {
+            ok(true, "flyout visibility is 'hidden'");
+            next();
+          } else if (e.data.result == "shown") {
+            ok(true, "flyout visibility is 'shown");
+            panel.hidePopup();
+          }
+          break;
+        case "got-flyout-message":
+          ok(e.data.result == "ok", "got flyout message");
+          break;
+      }
+    }
+    port.postMessage({topic: "test-init"});
+  }
+}
+
--- a/browser/base/content/test/browser_social_mozSocial_API.js
+++ b/browser/base/content/test/browser_social_mozSocial_API.js
@@ -37,16 +37,18 @@ var tests = {
 
     let port = Social.provider.port;
     ok(port, "provider has a port");
     port.onmessage = function (e) {
       let topic = e.data.topic;
       switch (topic) {
         case "got-panel-message":
           ok(true, "got panel message");
+          // Check the panel isn't in our history.
+          ensureSocialUrlNotRemembered(e.data.location);
           break;
         case "got-social-panel-visibility":
           if (e.data.result == "shown") {
             ok(true, "panel shown");
             let panel = document.getElementById("social-notification-panel");
             panel.hidePopup();
           } else if (e.data.result == "hidden") {
             ok(true, "panel hidden");
@@ -89,16 +91,18 @@ var tests = {
     ok(port, "provider has a port");
     port.postMessage({topic: "test-service-window"});
     port.onmessage = function (e) {
       let topic = e.data.topic;
       switch (topic) {
         case "got-service-window-message":
           // The sidebar message will always come first, since it loads by default
           ok(true, "got service window message");
+          // the service window URL should not be stored in history.
+          ensureSocialUrlNotRemembered(e.data.location);
           port.postMessage({topic: "test-close-service-window"});
           break;
         case "got-service-window-closed-message":
           ok(true, "got service window closed message");
           next();
           break;
       }
     }
--- a/browser/base/content/test/browser_social_shareButton.js
+++ b/browser/base/content/test/browser_social_shareButton.js
@@ -1,17 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 let prefName = "social.enabled",
-    shareButton,
-    sharePopup,
-    okButton,
-    undoButton,
     gFinishCB;
 
 function test() {
   waitForExplicitFinish();
 
   // Need to load a non-empty page for the social share button to appear
   let tab = gBrowser.selectedTab = gBrowser.addTab("about:", {skipAnimation: true});
   tab.linkedBrowser.addEventListener("load", function tabLoad(event) {
@@ -41,54 +37,69 @@ function tabLoaded() {
   });
 }
 
 function testInitial(finishcb) {
   ok(Social.provider, "Social provider is active");
   ok(Social.provider.enabled, "Social provider is enabled");
   ok(Social.provider.port, "Social provider has a port to its FrameWorker");
 
-  shareButton = SocialShareButton.shareButton;
-  sharePopup = SocialShareButton.sharePopup;
+  let {shareButton, sharePopup} = SocialShareButton;
   ok(shareButton, "share button exists");
   ok(sharePopup, "share popup exists");
 
-  okButton = document.getElementById("editSharePopupOkButton");
-  undoButton = document.getElementById("editSharePopupUndoButton");
-
-  is(shareButton.hidden, false, "share button should be visible");
+  let okButton = document.getElementById("editSharePopupOkButton");
+  let undoButton = document.getElementById("editSharePopupUndoButton");
 
-  // Test clicking the share button
-  shareButton.addEventListener("click", function listener() {
-    shareButton.removeEventListener("click", listener);
-    is(shareButton.hasAttribute("shared"), true, "Share button should have 'shared' attribute after share button is clicked");
-    executeSoon(testSecondClick.bind(window, testPopupOKButton));
-  });
-  EventUtils.synthesizeMouseAtCenter(shareButton, {});
+  // ensure the worker initialization and handshakes are all done and we
+  // have a profile.
+  waitForCondition(function() Social.provider.profile, function() {
+    is(shareButton.hidden, false, "share button should be visible");
+    // check dom values
+    let profile = Social.provider.profile;
+    let portrait = document.getElementById("socialUserPortrait").getAttribute("src");
+    is(profile.portrait, portrait, "portrait is set");
+    let displayName = document.getElementById("socialUserDisplayName");
+    is(displayName.label, profile.displayName, "display name is set");
+    ok(!document.getElementById("editSharePopupHeader").hidden, "user profile is visible");
+  
+    // Test clicking the share button
+    shareButton.addEventListener("click", function listener() {
+      shareButton.removeEventListener("click", listener);
+      is(shareButton.hasAttribute("shared"), true, "Share button should have 'shared' attribute after share button is clicked");
+      executeSoon(testSecondClick.bind(window, testPopupOKButton));
+    });
+    EventUtils.synthesizeMouseAtCenter(shareButton, {});
+  }, "provider didn't provide a profile");
 }
 
 function testSecondClick(nextTest) {
+  let {shareButton, sharePopup} = SocialShareButton;
   sharePopup.addEventListener("popupshown", function listener() {
     sharePopup.removeEventListener("popupshown", listener);
     ok(true, "popup was shown after second click");
     executeSoon(nextTest);
   });
   EventUtils.synthesizeMouseAtCenter(shareButton, {});
 }
 
 function testPopupOKButton() {
+  let {shareButton, sharePopup} = SocialShareButton;
+  let okButton = document.getElementById("editSharePopupOkButton");
   sharePopup.addEventListener("popuphidden", function listener() {
     sharePopup.removeEventListener("popuphidden", listener);
     is(shareButton.hasAttribute("shared"), true, "Share button should still have 'shared' attribute after OK button is clicked");
     executeSoon(testSecondClick.bind(window, testPopupUndoButton));
   });
   EventUtils.synthesizeMouseAtCenter(okButton, {});
 }
 
 function testPopupUndoButton() {
+  let {shareButton, sharePopup} = SocialShareButton;
+  let undoButton = document.getElementById("editSharePopupUndoButton");
   sharePopup.addEventListener("popuphidden", function listener() {
     sharePopup.removeEventListener("popuphidden", listener);
     is(shareButton.hasAttribute("shared"), false, "Share button should not have 'shared' attribute after Undo button is clicked");
     executeSoon(testShortcut);
   });
   EventUtils.synthesizeMouseAtCenter(undoButton, {});
 }
 
@@ -97,28 +108,31 @@ function testShortcut() {
   keyTarget.addEventListener("keyup", function listener() {
     keyTarget.removeEventListener("keyup", listener);
     executeSoon(checkShortcutWorked.bind(window, keyTarget));
   });
   EventUtils.synthesizeKey("l", {accelKey: true, shiftKey: true}, keyTarget);
 }
 
 function checkShortcutWorked(keyTarget) {
+  let {sharePopup, shareButton} = SocialShareButton;
   is(shareButton.hasAttribute("shared"), true, "Share button should be in the 'shared' state after keyboard shortcut is used");
 
   // Test a second invocation of the shortcut
   sharePopup.addEventListener("popupshown", function listener() {
     sharePopup.removeEventListener("popupshown", listener);
     ok(true, "popup was shown after second use of keyboard shortcut");
     executeSoon(checkOKButton);
   });
   EventUtils.synthesizeKey("l", {accelKey: true, shiftKey: true}, keyTarget);
 }
 
 function checkOKButton() {
+  let okButton = document.getElementById("editSharePopupOkButton");
+  let undoButton = document.getElementById("editSharePopupUndoButton");
   is(document.activeElement, okButton, "ok button should be focused by default");
 
   // This rest of particular test doesn't really apply on Mac, since buttons
   // aren't focusable by default.
   if (navigator.platform.indexOf("Mac") != -1) {
     executeSoon(testCloseBySpace);
     return;
   }
@@ -151,22 +165,24 @@ function checkNextInTabOrder(element, ne
   // Register a cleanup function to remove the listener in case this test fails
   registerCleanupFunction(function () {
     element.removeEventListener("focus", listener);
   });
   EventUtils.synthesizeKey("VK_TAB", {});
 }
 
 function testCloseBySpace() {
-  is(document.activeElement.id, okButton.id, "testCloseBySpace, the ok button should be focused");
+  let sharePopup = SocialShareButton.sharePopup;
+  is(document.activeElement.id, "editSharePopupOkButton", "testCloseBySpace, the ok button should be focused");
   sharePopup.addEventListener("popuphidden", function listener() {
     sharePopup.removeEventListener("popuphidden", listener);
     ok(true, "space closed the share popup");
     executeSoon(testDisable);
   });
   EventUtils.synthesizeKey("VK_SPACE", {});
 }
 
 function testDisable() {
+  let shareButton = SocialShareButton.shareButton;
   Services.prefs.setBoolPref(prefName, false);
   is(shareButton.hidden, true, "Share button should be hidden when pref is disabled");
   gFinishCB();
 }
--- a/browser/base/content/test/head.js
+++ b/browser/base/content/test/head.js
@@ -83,19 +83,37 @@ function waitForCondition(condition, nex
     if (condition()) {
       moveOn();
     }
     tries++;
   }, 100);
   var moveOn = function() { clearInterval(interval); nextTest(); };
 }
 
+// Check that a specified (string) URL hasn't been "remembered" (ie, is not
+// in history, will not appear in about:newtab or auto-complete, etc.)
+function ensureSocialUrlNotRemembered(url) {
+  let gh = Cc["@mozilla.org/browser/global-history;2"]
+           .getService(Ci.nsIGlobalHistory2);
+  let uri = Services.io.newURI(url, null, null);
+  ok(!gh.isVisited(uri), "social URL " + url + " should not be in global history");
+}
+
 function runSocialTestWithProvider(manifest, callback) {
   let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
 
+  // Check that none of the provider's content ends up in history.
+  registerCleanupFunction(function () {
+    for (let what of ['sidebarURL', 'workerURL', 'iconURL']) {
+      if (manifest[what]) {
+        ensureSocialUrlNotRemembered(manifest[what]);
+      }
+    }
+  });
+
   info("runSocialTestWithProvider: " + manifest.toSource());
 
   let oldProvider;
   SocialService.addProvider(manifest, function(provider) {
     info("runSocialTestWithProvider: provider added");
     oldProvider = Social.provider;
     Social.provider = provider;
 
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/social_flyout.html
@@ -0,0 +1,22 @@
+<html>
+  <head>
+    <meta charset="utf-8">
+    <script>
+      function pingWorker() {
+        var port = navigator.mozSocial.getWorker().port;
+        port.postMessage({topic: "flyout-message", result: "ok"});
+      }
+      window.addEventListener("socialFrameShow", function(e) {
+        var port = navigator.mozSocial.getWorker().port;
+        port.postMessage({topic: "flyout-visibility", result: "shown"});
+      }, false);
+      window.addEventListener("socialFrameHide", function(e) {
+        var port = navigator.mozSocial.getWorker().port;
+        port.postMessage({topic: "flyout-visibility", result: "hidden"});
+      }, false);
+    </script>
+  </head>
+  <body onload="pingWorker();">
+    <p>This is a test social flyout panel.</p>
+  </body>
+</html>
--- a/browser/base/content/test/social_panel.html
+++ b/browser/base/content/test/social_panel.html
@@ -1,15 +1,17 @@
 <html>
   <head>
     <meta charset="utf-8">
     <script>
       function pingWorker() {
         var port = navigator.mozSocial.getWorker().port;
-        port.postMessage({topic: "panel-message", result: "ok"});
+        port.postMessage({topic: "panel-message",
+                          result: "ok",
+                          location: window.location.href});
       }
       window.addEventListener("socialFrameShow", function(e) {
         var port = navigator.mozSocial.getWorker().port;
         port.postMessage({topic: "status-panel-visibility", result: "shown"});
       }, false);
       window.addEventListener("socialFrameHide", function(e) {
         var port = navigator.mozSocial.getWorker().port;
         port.postMessage({topic: "status-panel-visibility", result: "hidden"});
--- a/browser/base/content/test/social_sidebar.html
+++ b/browser/base/content/test/social_sidebar.html
@@ -3,16 +3,19 @@
     <meta charset="utf-8">
     <script>
       var win;
       function pingWorker() {
         var port = navigator.mozSocial.getWorker().port;
         port.onmessage = function(e) {
           var topic = e.data.topic;
           switch (topic) {
+            case "test-flyout-open":
+              navigator.mozSocial.openPanel("social_flyout.html");
+              break;
             case "test-chatbox-open":
               navigator.mozSocial.openChatWindow("social_chat.html", function(chatwin) {
                 port.postMessage({topic: "chatbox-opened", result: chatwin ? "ok" : "failed"});
               });
               break;
             case "test-service-window":
               win = navigator.mozSocial.openServiceWindow("social_window.html", "test-service-window", "width=300,height=300");
               break;
--- a/browser/base/content/test/social_window.html
+++ b/browser/base/content/test/social_window.html
@@ -1,14 +1,17 @@
 <html>
   <head>
     <meta charset="utf-8">
     <script>
       function pingWorker() {
         var port = navigator.mozSocial.getWorker().port;
-        port.postMessage({topic: "service-window-message", result: "ok"});
+        port.postMessage({topic: "service-window-message",
+                          location: window.location.href,
+                          result: "ok"
+                         });
       }
     </script>
   </head>
   <body onload="pingWorker();">
     <p>This is a test social service window.</p>
   </body>
 </html>
--- a/browser/base/content/test/social_worker.js
+++ b/browser/base/content/test/social_worker.js
@@ -13,17 +13,18 @@ onconnect = function(e) {
         testPort = port;
         break;
       case "sidebar-message":
         sidebarPort = port;
         if (testPort && event.data.result == "ok")
           testPort.postMessage({topic:"got-sidebar-message"});
         break;
       case "service-window-message":
-        testPort.postMessage({topic:"got-service-window-message"});
+        testPort.postMessage({topic:"got-service-window-message",
+                              location: event.data.location});
         break;
       case "service-window-closed-message":
         testPort.postMessage({topic:"got-service-window-closed-message"});
         break;
       case "test-service-window":
         sidebarPort.postMessage({topic:"test-service-window"});
         break;
       case "test-service-window-twice":
@@ -32,35 +33,49 @@ onconnect = function(e) {
       case "test-service-window-twice-result":
         testPort.postMessage({topic: "test-service-window-twice-result", result: event.data.result })
         break;
       case "test-close-service-window":
         sidebarPort.postMessage({topic:"test-close-service-window"});
         break;
       case "panel-message":
         if (testPort && event.data.result == "ok")
-          testPort.postMessage({topic:"got-panel-message"});
+          testPort.postMessage({topic:"got-panel-message",
+                                location: event.data.location
+                               });
         break;
       case "status-panel-visibility":
         testPort.postMessage({topic:"got-social-panel-visibility", result: event.data.result });
         break;
       case "test-chatbox-open":
         sidebarPort.postMessage({topic:"test-chatbox-open"});
         break;
       case "chatbox-message":
         testPort.postMessage({topic:"got-chatbox-message", result: event.data.result});
         break;
       case "chatbox-visibility":
         testPort.postMessage({topic:"got-chatbox-visibility", result: event.data.result});
         break;
+      case "test-flyout-open":
+        sidebarPort.postMessage({topic:"test-flyout-open"});
+        break;
+      case "flyout-message":
+        testPort.postMessage({topic:"got-flyout-message", result: event.data.result});
+        break;
+      case "flyout-visibility":
+        testPort.postMessage({topic:"got-flyout-visibility", result: event.data.result});
+        break;
       case "social.initialize":
         // This is the workerAPI port, respond and set up a notification icon.
         port.postMessage({topic: "social.initialize-response"});
         let profile = {
-          userName: "foo"
+          portrait: "https://example.com/portrait.jpg",
+          userName: "trickster",
+          displayName: "Kuma Lisa",
+          profileURL: "http://en.wikipedia.org/wiki/Kuma_Lisa"
         };
         port.postMessage({topic: "social.user-profile", data: profile});
         let icon = {
           name: "testIcon",
           iconURL: "chrome://branding/content/icon48.png",
           contentPanel: "https://example.com/browser/browser/base/content/test/social_panel.html",
           counter: 1
         };
--- a/browser/components/thumbnails/PageThumbs.jsm
+++ b/browser/components/thumbnails/PageThumbs.jsm
@@ -480,17 +480,17 @@ let PageThumbsWorker = {
   _callbacks: [],
 
   /**
    * Get the worker, spawning it if necessary.
    * Code of the worker is in companion file PageThumbsWorker.js
    */
   get _worker() {
     delete this._worker;
-    this._worker = new ChromeWorker("resource://gre/modules/PageThumbsWorker.js");
+    this._worker = new ChromeWorker("resource:///modules/PageThumbsWorker.js");
     this._worker.addEventListener("message", this);
     return this._worker;
   },
 
   /**
    * Post a message to the dedicated thread, registering a callback
    * to be executed once the reply has been received.
    *
--- a/browser/components/thumbnails/PageThumbsWorker.js
+++ b/browser/components/thumbnails/PageThumbsWorker.js
@@ -14,16 +14,19 @@
 importScripts("resource://gre/modules/osfile.jsm");
 
 let PageThumbsWorker = {
   handleMessage: function Worker_handleMessage(aEvent) {
     let msg = aEvent.data;
     let data = {result: null, data: null};
 
     switch (msg.type) {
+      case "removeFile":
+        data.result = this.removeFile(msg);
+        break;
       case "removeFiles":
         data.result = this.removeFiles(msg);
         break;
       case "getFilesInDirectory":
         data.result = this.getFilesInDirectory(msg);
         break;
       default:
         data.result = false;
@@ -43,16 +46,25 @@ let PageThumbsWorker = {
         entries.push(entry.name);
       }
     }
 
     iter.close();
     return entries;
   },
 
+  removeFile: function Worker_removeFile(msg) {
+    try {
+      OS.File.remove(msg.path);
+      return true;
+    } catch (e) {
+      return false;
+    }
+  },
+
   removeFiles: function Worker_removeFiles(msg) {
     for (let file of msg.paths) {
       try {
         OS.File.remove(file);
       } catch (e) {
         // We couldn't remove the file for some reason.
         // Let's just continue with the next one.
       }
--- a/browser/components/thumbnails/test/browser_thumbnails_storage.js
+++ b/browser/components/thumbnails/test/browser_thumbnails_storage.js
@@ -14,42 +14,52 @@ XPCOMUtils.defineLazyGetter(this, "Sanit
 
 /**
  * These tests ensure that the thumbnail storage is working as intended.
  * Newly captured thumbnails should be saved as files and they should as well
  * be removed when the user sanitizes their history.
  */
 function runTests() {
   yield clearHistory();
-
-  // create a thumbnail
-  yield addTab(URL);
-  yield whenFileExists();
-  gBrowser.removeTab(gBrowser.selectedTab);
+  yield createThumbnail();
 
-  // clear all browser history
-  yield clearHistory();
-
-  // create a thumbnail
-  yield addTab(URL);
-  yield whenFileExists();
-  gBrowser.removeTab(gBrowser.selectedTab);
-
-  // make sure copy() updates an existing file
+  // Make sure Storage.copy() updates an existing file.
   PageThumbsStorage.copy(URL, URL_COPY);
   let copy = PageThumbsStorage.getFileForURL(URL_COPY);
   let mtime = copy.lastModifiedTime -= 60;
 
   PageThumbsStorage.copy(URL, URL_COPY);
   isnot(PageThumbsStorage.getFileForURL(URL_COPY).lastModifiedTime, mtime,
         "thumbnail file was updated");
 
-  // clear last 10 mins of history
+  let file = PageThumbsStorage.getFileForURL(URL);
+  let fileCopy = PageThumbsStorage.getFileForURL(URL_COPY);
+
+  // Clear the browser history. Retry until the files are gone because Windows
+  // locks them sometimes.
+  while (file.exists() || fileCopy.exists()) {
+    yield clearHistory();
+  }
+
+  yield createThumbnail();
+
+  // Clear the last 10 minutes of browsing history.
   yield clearHistory(true);
-  ok(!copy.exists(), "copy of thumbnail has been removed");
+
+  // Retry until the file is gone because Windows locks it sometimes.
+  while (file.exists()) {
+    // Re-add our URL to the history so that history observer's onDeleteURI()
+    // is called again.
+    let time = Date.now() * 1000;
+    let trans = Ci.nsINavHistoryService.TRANSITION_LINK;
+    PlacesUtils.history.addVisit(makeURI(URL), time, null, trans, false, 0);
+
+    // Try again...
+    yield clearHistory(true);
+  }
 }
 
 function clearHistory(aUseRange) {
   let s = new Sanitizer();
   s.prefDomain = "privacy.cpd.";
 
   let prefs = gPrefService.getBranch(s.prefDomain);
   prefs.setBoolPref("history", true);
@@ -60,30 +70,38 @@ function clearHistory(aUseRange) {
   prefs.setBoolPref("offlineApps", false);
   prefs.setBoolPref("passwords", false);
   prefs.setBoolPref("sessions", false);
   prefs.setBoolPref("siteSettings", false);
 
   if (aUseRange) {
     let usec = Date.now() * 1000;
     s.range = [usec - 10 * 60 * 1000 * 1000, usec];
+    s.ignoreTimespan = false;
   }
 
   s.sanitize();
   s.range = null;
+  s.ignoreTimespan = true;
 
-  executeSoon(function () {
-    if (PageThumbsStorage.getFileForURL(URL).exists())
-      clearHistory(aUseRange);
-    else
+  executeSoon(next);
+}
+
+function createThumbnail() {
+  addTab(URL, function () {
+    whenFileExists(function () {
+      gBrowser.removeTab(gBrowser.selectedTab);
       next();
+    });
   });
 }
 
-function whenFileExists() {
-  let callback = whenFileExists;
-
+function whenFileExists(aCallback) {
+  let callback;
   let file = PageThumbsStorage.getFileForURL(URL);
-  if (file.exists() && file.fileSize)
-    callback = next;
+  if (file.exists() && file.fileSize) {
+    callback = aCallback;
+  } else {
+    callback = function () whenFileExists(aCallback);
+  }
 
   executeSoon(callback);
 }
--- a/browser/components/thumbnails/test/head.js
+++ b/browser/components/thumbnails/test/head.js
@@ -52,20 +52,21 @@ let TestRunner = {
  */
 function next() {
   TestRunner.next();
 }
 
 /**
  * Creates a new tab with the given URI.
  * @param aURI The URI that's loaded in the tab.
+ * @param aCallback The function to call when the tab has loaded.
  */
-function addTab(aURI) {
+function addTab(aURI, aCallback) {
   let tab = gBrowser.selectedTab = gBrowser.addTab(aURI);
-  whenLoaded(tab.linkedBrowser);
+  whenLoaded(tab.linkedBrowser, aCallback);
 }
 
 /**
  * Loads a new URI into the currently selected tab.
  * @param aURI The URI to load.
  */
 function navigateTo(aURI) {
   let browser = gBrowser.selectedTab.linkedBrowser;
deleted file mode 100644
--- a/browser/config/tooltool-manifests/macosx32/clang.manifest
+++ /dev/null
@@ -1,17 +0,0 @@
-[
-{
-"clang_version": "r161022"
-},
-{
-"size": 47,
-"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
-"algorithm": "sha512",
-"filename": "setup.sh"
-},
-{
-"size": 54405078,
-"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9",
-"algorithm": "sha512",
-"filename": "clang.tar.bz2"
-}
-]
deleted file mode 100644
--- a/browser/config/tooltool-manifests/macosx64/clang.manifest
+++ /dev/null
@@ -1,17 +0,0 @@
-[
-{
-"clang_version": "r161022"
-},
-{
-"size": 47,
-"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
-"algorithm": "sha512",
-"filename": "setup.sh"
-},
-{
-"size": 54405078,
-"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9",
-"algorithm": "sha512",
-"filename": "clang.tar.bz2"
-}
-]
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -378,16 +378,25 @@ social.pageShared.label=Page shared
 
 # LOCALIZATION NOTE (social.enable.label): %S = Social networking provider
 social.enable.label=%S integration
 social.enable.accesskey=n
 
 # LOCALIZATION NOTE (social.enabled.message): %1$S is the name of the social provider, %2$S is brandShortName (e.g. Firefox)
 social.activated.message=%1$S integration with %2$S has been activated.
 
+# LOCALIZATION NOTE (social.error.message): %1$S is brandShortName (e.g. Firefox), %2$S is the name of the social provider
+social.error.message=%1$S is unable to connect with %2$S right now.
+social.error.tryAgain.label=Try Again
+social.error.tryAgain.accesskey=T
+social.error.ok.label=OK
+social.error.ok.accesskey=O
+social.error.closeSidebar.label=Close This Sidebar
+social.error.closeSidebar.accesskey=C
+
 # Identity notifications popups
 identity.termsOfService = Terms of Service
 identity.privacyPolicy = Privacy Policy
 identity.chooseIdentity.description = Sign in to %S
 identity.chooseIdentity.label = Use an existing email
 identity.newIdentity.label = Use a different email
 identity.newIdentity.accessKey = e
 identity.newIdentity.email.placeholder = Email
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -2736,24 +2736,16 @@ stack[anonid=browserStack][responsivemod
   cursor: pointer;
   min-width: 0;
   margin: 0 6px;
 }
 #social-statusarea-username:hover {
   text-decoration: underline;
 }
 
-#social-notification-panel {
-  min-height: 100px;
-  min-width: 100px;
-  max-height: 600px;
-  max-width: 400px;
-}
-
-
 .chat-status-icon {
   max-height: 16px;
   max-width: 16px;
   padding: 0;
 }
 
 .chat-toolbarbutton {
   -moz-appearance: none;
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -3425,58 +3425,16 @@ stack[anonid=browserStack][responsivemod
 }
 
 #social-statusarea-username:hover {
   text-decoration: underline;
 }
 
 /* === end of social toolbar provider menu === */
 
-/* === start of social toolbar panels === */
-
-#social-notification-panel {
-  min-height: 100px;
-  min-width: 240px;
-  max-height: 600px;
-  max-width: 400px;
-}
-
-#social-notification-panel .panel-arrowcontent {
-  margin: -4px 0 0 0;
-  padding: 0;
-  border-radius: 0px;
-  background: white;
-}
-
-#social-notification-panel .panel-arrow[side="top"] {
-  list-style-image: url("chrome://browser/skin/social/panelarrow-up.png");
-  margin-top: -4px;
-  margin-bottom: 3px;
-  height: 21px;
-}
-
-#social-notification-panel .panel-arrow[side="bottom"] {
-  list-style-image: url("chrome://browser/skin/social/panelarrow-down.png");
-  margin-top: -5px;
-}
-
-#social-notification-panel .panel-arrow[side="left"] {
-  list-style-image: url("chrome://browser/skin/social/panelarrow-horiz.png");
-  margin-right: -1px;
-  -moz-transform: scaleX(-1);
-}
-
-#social-notification-panel .panel-arrow[side="right"] {
-  list-style-image: url("chrome://browser/skin/social/panelarrow-horiz.png");
-  margin-left: -1px;
-}
-
-/* === end of social toolbar panels === */
-
-
 .chat-status-icon {
   max-height: 16px;
   max-width: 16px;
   padding: 0;
 }
 
 .chat-toolbarbutton {
   -moz-appearance: none;
--- a/browser/themes/pinstripe/jar.mn
+++ b/browser/themes/pinstripe/jar.mn
@@ -105,19 +105,16 @@ browser.jar:
   skin/classic/browser/preferences/Options-sync.png         (preferences/Options-sync.png)
 #endif
   skin/classic/browser/preferences/saveFile.png             (preferences/saveFile.png)
 * skin/classic/browser/preferences/preferences.css          (preferences/preferences.css)
   skin/classic/browser/preferences/in-content/preferences.css (preferences/in-content/preferences.css)
   skin/classic/browser/preferences/applications.css         (preferences/applications.css)
   skin/classic/browser/preferences/aboutPermissions.css     (preferences/aboutPermissions.css)
   skin/classic/browser/social/social.png                    (social/social.png)
-  skin/classic/browser/social/panelarrow-down.png           (social/panelarrow-down.png)
-  skin/classic/browser/social/panelarrow-horiz.png          (social/panelarrow-horiz.png)
-  skin/classic/browser/social/panelarrow-up.png             (social/panelarrow-up.png)
   skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon.png             (tabbrowser/alltabs-box-bkgnd-icon.png)
   skin/classic/browser/tabbrowser/newtab.png                             (tabbrowser/newtab.png)
   skin/classic/browser/tabbrowser/connecting.png                         (tabbrowser/connecting.png)
   skin/classic/browser/tabbrowser/loading.png                            (tabbrowser/loading.png)
   skin/classic/browser/tabbrowser/tab-arrow-left.png                     (tabbrowser/tab-arrow-left.png)
   skin/classic/browser/tabbrowser/tab-arrow-right.png                    (tabbrowser/tab-arrow-right.png)
   skin/classic/browser/tabbrowser/tabbar-bottom-bg-active.png            (tabbrowser/tabbar-bottom-bg-active.png)
   skin/classic/browser/tabbrowser/tabbar-bottom-bg-inactive.png          (tabbrowser/tabbar-bottom-bg-inactive.png)
deleted file mode 100644
index 0224ebdf153bec5d7125f88bb9494d6d36dfbeae..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index ed59312c14252fe9c7f37e902285d652cbb09359..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 451b83b3b9bfde3ffba768feba91566bea92210d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -3439,24 +3439,16 @@ stack[anonid=browserStack][responsivemod
   cursor: pointer;
   min-width: 0;
   margin: 0 6px;
 }
 #social-statusarea-username:hover {
   text-decoration: underline;
 }
 
-#social-notification-panel {
-  min-height: 100px;
-  min-width: 100px;
-  max-height: 600px;
-  max-width: 400px;
-}
-
-
 .chat-status-icon {
   max-height: 16px;
   max-width: 16px;
   padding: 0;
 }
 
 .chat-toolbarbutton {
   -moz-appearance: none;
--- a/config/system-headers
+++ b/config/system-headers
@@ -399,17 +399,16 @@ libgnomevfs/gnome-vfs-file-info.h
 libgnomevfs/gnome-vfs.h
 libgnomevfs/gnome-vfs-init.h
 libgnomevfs/gnome-vfs-mime.h
 libgnomevfs/gnome-vfs-mime-handlers.h
 libgnomevfs/gnome-vfs-mime-utils.h
 libgnomevfs/gnome-vfs-ops.h
 libgnomevfs/gnome-vfs-standard-callbacks.h
 lib$routines.h
-libnotify/notify.h
 limits
 limits.h
 link.h
 linux/kernel.h
 linux/limits.h
 linux/rtc.h
 linux/version.h
 list
--- a/configure.in
+++ b/configure.in
@@ -69,17 +69,16 @@ WINDRES_VERSION=2.14.90
 W32API_VERSION=3.14
 GNOMEVFS_VERSION=2.0
 GNOMEUI_VERSION=2.2.0
 GCONF_VERSION=1.2.1
 GIO_VERSION=2.18
 STARTUP_NOTIFICATION_VERSION=0.8
 DBUS_VERSION=0.60
 SQLITE_VERSION=3.7.13
-LIBNOTIFY_VERSION=0.4
 
 MSMANIFEST_TOOL=
 
 dnl Set various checks
 dnl ========================================================
 MISSING_X=
 AC_PROG_AWK
 
@@ -4924,61 +4923,22 @@ then
         AC_DEFINE(MOZ_ENABLE_LIBPROXY)
     fi
 fi
 AC_SUBST(MOZ_ENABLE_LIBPROXY)
 AC_SUBST(MOZ_LIBPROXY_CFLAGS)
 AC_SUBST(MOZ_LIBPROXY_LIBS)
 
 dnl ========================================================
-dnl = libnotify support
+dnl = GNOME component (mozgnome)
 dnl ========================================================
 
 if test "$MOZ_ENABLE_GTK2"
 then
-    MOZ_ENABLE_LIBNOTIFY=1
-
-    MOZ_ARG_DISABLE_BOOL(libnotify,
-    [  --disable-libnotify     Disable libnotify support ],
-    MOZ_ENABLE_LIBNOTIFY=,
-    MOZ_ENABLE_LIBNOTIFY=1)
-
-    if test "$MOZ_ENABLE_LIBNOTIFY"
-    then
-        AC_DEFINE(MOZ_ENABLE_LIBNOTIFY)
-    fi
-fi
-
-if test -z "$SKIP_LIBRARY_CHECKS"
-then
-    if test "$MOZ_ENABLE_GTK2"
-    then
-        if test "$MOZ_ENABLE_LIBNOTIFY"
-        then
-            PKG_CHECK_MODULES(MOZ_LIBNOTIFY, libnotify >= $LIBNOTIFY_VERSION)
-        fi
-    fi
-fi
-AC_SUBST(MOZ_ENABLE_LIBNOTIFY)
-AC_SUBST(MOZ_LIBNOTIFY_CFLAGS)
-AC_SUBST(MOZ_LIBNOTIFY_LIBS)
-
-dnl ========================================================
-dnl = GNOME component (mozgnome)
-dnl ========================================================
-
-# The GNOME component is built if one of
-# gnome-vfs, gio, gconf or libnotify is available.
-if test "$MOZ_ENABLE_GCONF" -o \
-   "$MOZ_ENABLE_GNOMEVFS" -o \
-   "$MOZ_ENABLE_GIO" -o \
-   "$MOZ_ENABLE_LIBNOTIFY"; then
     MOZ_ENABLE_GNOME_COMPONENT=1
-else
-    MOZ_ENABLE_GNOME_COMPONENT=
 fi
 AC_SUBST(MOZ_ENABLE_GNOME_COMPONENT)
 
 dnl ========================================================
 dnl = libgnomeui support module
 dnl ========================================================
 
 if test "$MOZ_ENABLE_GTK2"
--- a/dom/activities/interfaces/nsIActivityProxy.idl
+++ b/dom/activities/interfaces/nsIActivityProxy.idl
@@ -1,18 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIDOMMozActivity;
 interface nsIDOMMozActivityOptions;
+interface nsIDOMWindow;
 
 /**
   * Implemented by @mozilla.org/dom/activities/proxy;1
   */
-[scriptable, uuid(2241faf9-6219-4bc0-95f3-18651ac8a18b)]
+[scriptable, uuid(3f9e0695-f466-4111-a8fa-ed5c0751c42b)]
 interface nsIActivityProxy : nsISupports
 {
-    void startActivity(in nsIDOMMozActivity activity, in nsIDOMMozActivityOptions options);
+    void startActivity(in nsIDOMMozActivity activity,
+                       in nsIDOMMozActivityOptions options,
+                       in nsIDOMWindow window);
     void cleanup();
 };
--- a/dom/activities/src/Activity.cpp
+++ b/dom/activities/src/Activity.cpp
@@ -62,17 +62,17 @@ Activity::Initialize(nsISupports* aOwner
   }
 
   // Instantiate a JS proxy that will do the child <-> parent communication
   // with the JS implementation of the backend.
   nsresult rv;
   mProxy = do_CreateInstance("@mozilla.org/dom/activities/proxy;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  mProxy->StartActivity(this, options);
+  mProxy->StartActivity(this, options, window);
   return NS_OK;
 }
 
 Activity::~Activity()
 {
   if (mProxy) {
     mProxy->Cleanup();
   }
--- a/dom/activities/src/ActivityProxy.js
+++ b/dom/activities/src/ActivityProxy.js
@@ -1,46 +1,48 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
- 
+
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
- 
+
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
   return Cc["@mozilla.org/childprocessmessagemanager;1"]
            .getService(Ci.nsIFrameMessageManager)
            .QueryInterface(Ci.nsISyncMessageSender);
 });
 
 function debug(aMsg) {
   //dump("-- ActivityProxy " + Date.now() + " : " + aMsg + "\n");
 }
 
 /**
   * nsIActivityProxy implementation
   * We keep a reference to the C++ Activity object, and
-  * communicate with the Message Manager to know when to 
+  * communicate with the Message Manager to know when to
   * fire events on it.
   */
 function ActivityProxy() {
   debug("ActivityProxy");
   this.activity = null;
 }
 
 ActivityProxy.prototype = {
-  startActivity: function actProxy_startActivity(aActivity, aOptions) {
+  startActivity: function actProxy_startActivity(aActivity, aOptions, aWindow) {
     debug("startActivity");
 
+    this.window = aWindow;
     this.activity = aActivity;
     this.id = Cc["@mozilla.org/uuid-generator;1"]
                 .getService(Ci.nsIUUIDGenerator)
                 .generateUUID().toString();
     cpmm.sendAsyncMessage("Activity:Start", { id: this.id, options: aOptions });
 
     cpmm.addMessageListener("Activity:FireSuccess", this);
     cpmm.addMessageListener("Activity:FireError", this);
@@ -51,17 +53,18 @@ ActivityProxy.prototype = {
     let msg = aMessage.json;
     if (msg.id != this.id)
       return;
     debug("msg=" + JSON.stringify(msg));
 
     switch(aMessage.name) {
       case "Activity:FireSuccess":
         debug("FireSuccess");
-        Services.DOMRequest.fireSuccess(this.activity, msg.result);
+        Services.DOMRequest.fireSuccess(this.activity,
+                                        ObjectWrapper.wrap(msg.result, this.window));
         break;
       case "Activity:FireError":
         debug("FireError");
         Services.DOMRequest.fireError(this.activity, msg.error);
         break;
     }
   },
 
--- a/dom/activities/src/ActivityWrapper.js
+++ b/dom/activities/src/ActivityWrapper.js
@@ -4,40 +4,41 @@
 
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
 function debug(aMsg) {
   //dump("-- ActivityWrapper.js " + Date.now() + " : " + aMsg + "\n");
 }
 
 /**
   * nsISystemMessagesWrapper implementation. Will return a
   * nsIDOMMozActivityRequestHandler
   */
 function ActivityWrapper() {
   debug("ActivityWrapper");
 }
 
 ActivityWrapper.prototype = {
-  wrapMessage: function wrapMessage(aMessage) {
+  wrapMessage: function wrapMessage(aMessage, aWindow) {
     debug("Wrapping " + JSON.stringify(aMessage));
     let handler = Cc["@mozilla.org/dom/activities/request-handler;1"]
                     .createInstance(Ci.nsIDOMMozActivityRequestHandler);
     handler.wrappedJSObject._id = aMessage.id;
 
     // options is an nsIDOMActivityOptions object.
     var options = handler.wrappedJSObject._options;
     options.wrappedJSObject._name = aMessage.payload.name;
-    options.wrappedJSObject._data = aMessage.payload.data;
+    options.wrappedJSObject._data = ObjectWrapper.wrap(aMessage.payload.data, aWindow);
 
     return handler;
   },
 
   classID: Components.ID("{5430d6f9-32d6-4924-ba39-6b6d1b093cd6}"),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessagesWrapper])
 }
 
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -97,16 +97,17 @@ UnwrapDOMObject(JSObject* obj, DOMObject
 
 #ifdef DEBUG
   if (IsDOMClass(js::GetObjectClass(obj))) {
     MOZ_ASSERT(slot == eRegularDOMObject);
   } else {
     MOZ_ASSERT(js::IsObjectProxyClass(js::GetObjectClass(obj)) ||
                js::IsFunctionProxyClass(js::GetObjectClass(obj)));
     MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
+    MOZ_ASSERT(IsNewProxyBinding(js::GetProxyHandler(obj)));
     MOZ_ASSERT(slot == eProxyDOMObject);
   }
 #endif
 
   JS::Value val = js::GetReservedSlot(obj, slot);
   // XXXbz/khuey worker code tries to unwrap interface objects (which have
   // nothing here).  That needs to stop.
   // XXX We don't null-check UnwrapObject's result; aren't we going to crash
@@ -124,31 +125,32 @@ GetDOMClass(JSObject* obj)
 {
   js::Class* clasp = js::GetObjectClass(obj);
   if (IsDOMClass(clasp)) {
     return &DOMJSClass::FromJSClass(clasp)->mClass;
   }
 
   js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
   MOZ_ASSERT(handler->family() == ProxyFamily());
+  MOZ_ASSERT(IsNewProxyBinding(handler));
   return &static_cast<DOMProxyHandler*>(handler)->mClass;
 }
 
 inline DOMObjectSlot
 GetDOMClass(JSObject* obj, const DOMClass*& result)
 {
   js::Class* clasp = js::GetObjectClass(obj);
   if (IsDOMClass(clasp)) {
     result = &DOMJSClass::FromJSClass(clasp)->mClass;
     return eRegularDOMObject;
   }
 
   if (js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) {
     js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
-    if (handler->family() == ProxyFamily()) {
+    if (handler->family() == ProxyFamily() && IsNewProxyBinding(handler)) {
       result = &static_cast<DOMProxyHandler*>(handler)->mClass;
       return eProxyDOMObject;
     }
   }
 
   return eNonDOMObject;
 }
 
@@ -166,17 +168,18 @@ UnwrapDOMObjectToISupports(JSObject* obj
 }
 
 inline bool
 IsDOMObject(JSObject* obj)
 {
   js::Class* clasp = js::GetObjectClass(obj);
   return IsDOMClass(clasp) ||
          ((js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) &&
-          js::GetProxyHandler(obj)->family() == ProxyFamily());
+          (js::GetProxyHandler(obj)->family() == ProxyFamily() &&
+           IsNewProxyBinding(js::GetProxyHandler(obj))));
 }
 
 // Some callers don't want to set an exception when unwrappin fails
 // (for example, overload resolution uses unwrapping to tell what sort
 // of thing it's looking at).
 // U must be something that a T* can be assigned to (e.g. T* or an nsRefPtr<T>).
 template <prototypes::ID PrototypeID, class T, typename U>
 inline nsresult
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -77,16 +77,26 @@ DOMInterfaces = {
     ],
     'resultNotAddRefed': [ 'canvas' ],
     'binaryNames': {
         'mozImageSmoothingEnabled': 'imageSmoothingEnabled',
         'mozFillRule': 'fillRule'
     }
 }],
 
+'CSS2Properties': {
+  'nativeType': 'nsDOMCSSDeclaration',
+  'prefable': True,
+},
+
+'CSSStyleDeclaration': {
+  'nativeType': 'nsICSSDeclaration',
+  'prefable': True
+},
+
 'Document': [
 {
     'nativeType': 'nsIDocument',
 },
 {
     'workers': True,
     'nativeType': 'JSObject',
     'headerFile': 'jsapi.h',
@@ -368,16 +378,18 @@ def addExternalHTMLElement(element):
    addExternalIface(element, nativeType=nativeElement,
                     headerFile=nativeElement + '.h')
 
 addExternalHTMLElement('HTMLCanvasElement')
 addExternalHTMLElement('HTMLImageElement')
 addExternalHTMLElement('HTMLVideoElement')
 addExternalIface('CanvasGradient', headerFile='nsIDOMCanvasRenderingContext2D.h')
 addExternalIface('CanvasPattern', headerFile='nsIDOMCanvasRenderingContext2D.h')
+addExternalIface('CSSRule')
+addExternalIface('CSSValue')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('ImageData', nativeType='mozilla::dom::ImageData')
 addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h')
 addExternalIface('WebGLActiveInfo', nativeType='mozilla::WebGLActiveInfo',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLBuffer', nativeType='mozilla::WebGLBuffer',
                  headerFile='WebGLContext.h')
 addExternalIface('WebGLContextAttributes', nativeType='JSObject',
--- a/dom/bindings/DOMJSProxyHandler.cpp
+++ b/dom/bindings/DOMJSProxyHandler.cpp
@@ -33,16 +33,27 @@ DefineStaticJSVals(JSContext* cx)
   JSAutoRequest ar(cx);
 
   return InternJSString(cx, s_length_id, "length");
 }
 
 
 int HandlerFamily;
 
+// Store the information for the specialized ICs.
+struct SetListBaseInformation
+{
+  SetListBaseInformation() {
+    js::SetListBaseInformation((void*) &HandlerFamily, js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO);
+  }
+};
+
+SetListBaseInformation gSetListBaseInformation;
+
+
 bool
 DefineConstructor(JSContext* cx, JSObject* obj, DefineInterface aDefine, nsresult* aResult)
 {
   bool enabled;
   bool defined = aDefine(cx, obj, &enabled);
   MOZ_ASSERT(!defined || enabled,
              "We defined a constructor but the new bindings are disabled?");
   *aResult = defined ? NS_OK : NS_ERROR_FAILURE;
--- a/dom/bindings/DOMJSProxyHandler.h
+++ b/dom/bindings/DOMJSProxyHandler.h
@@ -19,21 +19,21 @@ namespace mozilla {
 namespace dom {
 
 enum {
   JSPROXYSLOT_EXPANDO = 0
 };
 
 template<typename T> struct Prefable;
 
-class DOMProxyHandler : public js::BaseProxyHandler
+class DOMProxyHandler : public DOMBaseProxyHandler
 {
 public:
   DOMProxyHandler(const DOMClass& aClass)
-    : js::BaseProxyHandler(ProxyFamily()),
+    : DOMBaseProxyHandler(true),
       mClass(aClass)
   {
   }
 
   bool getPropertyDescriptor(JSContext* cx, JSObject* proxy, jsid id, bool set,
                              JSPropertyDescriptor* desc);
   bool defineProperty(JSContext* cx, JSObject* proxy, jsid id,
                       JSPropertyDescriptor* desc);
--- a/dom/bindings/ErrorResult.h
+++ b/dom/bindings/ErrorResult.h
@@ -7,16 +7,17 @@
 /**
  * A struct for tracking exceptions that need to be thrown to JS.
  */
 
 #ifndef mozilla_ErrorResult_h
 #define mozilla_ErrorResult_h
 
 #include "nscore.h"
+#include "mozilla/Assertions.h"
 
 namespace mozilla {
 
 class ErrorResult {
 public:
   ErrorResult() {
     mResult = NS_OK;
   }
new file mode 100644
--- /dev/null
+++ b/dom/bindings/GenerateCSS2PropertiesWebIDL.py
@@ -0,0 +1,22 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import sys
+import string
+
+propList = eval(sys.stdin.read())
+props = ""
+for [prop, pref] in propList:
+    pref = '[Pref=%s] ' % pref if pref is not "" else ""
+    if not prop.startswith("Moz"):
+        prop = prop[0].lower() + prop[1:]
+    # Unfortunately, even some of the getters here are fallible
+    # (e.g. on nsComputedDOMStyle).
+    props += "  %sattribute DOMString %s;\n" % (pref, prop)
+
+idlFile = open(sys.argv[1], "r");
+idlTemplate = idlFile.read();
+idlFile.close();
+
+print string.Template(idlTemplate).substitute({ "props": props })
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -17,17 +17,17 @@ EXPORT_LIBRARY   = 1
 include $(topsrcdir)/config/config.mk
 
 # Need this to find all our DOM source files.
 include $(topsrcdir)/dom/dom-config.mk
 
 include $(topsrcdir)/dom/webidl/WebIDL.mk
 
 binding_include_path := mozilla/dom
-all_webidl_files = $(webidl_files)
+all_webidl_files = $(webidl_files) $(generated_webidl_files)
 # Set exported_binding_headers before adding the test IDL to the mix
 exported_binding_headers := $(subst .webidl,Binding.h,$(all_webidl_files))
 # Set linked_binding_cpp_files before adding the test IDL to the mix
 linked_binding_cpp_files := $(subst .webidl,Binding.cpp,$(all_webidl_files))
 
 all_webidl_files += $(test_webidl_files)
 
 binding_header_files := $(subst .webidl,Binding.h,$(all_webidl_files))
@@ -83,16 +83,26 @@ bindinggen_dependencies := \
   Bindings.conf \
   Configuration.py \
   Codegen.py \
   parser/WebIDL.py \
   ParserResults.pkl \
   $(GLOBAL_DEPS) \
   $(NULL)
 
+CSS2Properties.webidl: $(topsrcdir)/layout/style/nsCSSPropList.h \
+                       $(topsrcdir)/layout/style/nsCSSPropAliasList.h \
+                       $(webidl_base)/CSS2Properties.webidl.in \
+                       $(webidl_base)/CSS2PropertiesProps.h \
+                       $(srcdir)/GenerateCSS2PropertiesWebIDL.py \
+                       $(GLOBAL_DEPS)
+	$(CPP) -I$(topsrcdir)/layout/style $(webidl_base)/CSS2PropertiesProps.h | \
+	  PYTHONDONTWRITEBYTECODE=1 $(PYTHON) \
+	  $(srcdir)/GenerateCSS2PropertiesWebIDL.py $(webidl_base)/CSS2Properties.webidl.in > CSS2Properties.webidl
+
 $(webidl_files): %: $(webidl_base)/%
 	$(INSTALL) $(IFLAGS1) $(webidl_base)/$* .
 
 $(test_webidl_files): %: $(srcdir)/test/%
 	$(INSTALL) $(IFLAGS1) $(srcdir)/test/$* .
 
 $(binding_header_files): %Binding.h: $(bindinggen_dependencies) \
                                      %.webidl \
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -1315,17 +1315,18 @@ BluetoothDBusService::SetProperty(Blueto
   void* val;
   nsCString str;
   if (aValue.value().type() == BluetoothValue::Tuint32_t) {
     tmp_int = aValue.value().get_uint32_t();
     val = &tmp_int;
     type = DBUS_TYPE_UINT32;
   } else if (aValue.value().type() == BluetoothValue::TnsString) {
     str = NS_ConvertUTF16toUTF8(aValue.value().get_nsString());
-    val = (void*)str.get();
+    const char* tempStr = str.get();
+    val = &tempStr;
     type = DBUS_TYPE_STRING;
   } else if (aValue.value().type() == BluetoothValue::Tbool) {
     tmp_int = aValue.value().get_bool() ? 1 : 0;
     val = &(tmp_int);
     type = DBUS_TYPE_BOOLEAN;
   } else {
     NS_WARNING("Property type not handled!");
     dbus_message_unref(msg);
--- a/dom/messages/SystemMessageManager.js
+++ b/dom/messages/SystemMessageManager.js
@@ -55,17 +55,17 @@ SystemMessageManager.prototype = {
     debug("Dispatching " + JSON.stringify(aMessage) + "\n");
     let contractID = "@mozilla.org/dom/system-messages/wrapper/" + aType + ";1";
     let wrapped = false;
 
     if (contractID in Cc) {
       debug(contractID + " is registered, creating an instance");
       let wrapper = Cc[contractID].createInstance(Ci.nsISystemMessagesWrapper);
       if (wrapper) {
-        aMessage = wrapper.wrapMessage(aMessage);
+        aMessage = wrapper.wrapMessage(aMessage, this._window);
         wrapped = true;
         debug("wrapped = " + aMessage);
       }
     }
 
     aHandler.handleMessage(wrapped ? aMessage : ObjectWrapper.wrap(aMessage, this._window));
   },
 
--- a/dom/messages/interfaces/nsISystemMessagesInternal.idl
+++ b/dom/messages/interfaces/nsISystemMessagesInternal.idl
@@ -1,15 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "domstubs.idl"
 
 interface nsIURI;
+interface nsIDOMWindow;
 
 // Implemented by the contract id @mozilla.org/system-message-internal;1
 
 [scriptable, uuid(3a50fd6b-0263-45c1-b738-a002052ad31b)]
 interface nsISystemMessagesInternal : nsISupports
 {
   /*
    * Allow any internal user to broadcast a message of a given type.
@@ -24,17 +25,17 @@ interface nsISystemMessagesInternal : ns
    * Registration of a page that wants to be notified of a message type.
    * @param type          The message type.
    * @param pageURI       The URI of the page that will be opened.
    * @param manifestURI   The webapp's manifest URI.
    */
   void registerPage(in DOMString type, in nsIURI pageURI, in nsIURI manifestURI);
 };
 
-[scriptable, uuid(b43c74ec-1b64-49fb-b552-aadd9d827eec)]
+[scriptable, uuid(002f0e82-91f0-41de-ad43-569a2b9d12df)]
 interface nsISystemMessagesWrapper: nsISupports
 {
   /*
    * Wrap a message and gives back any kind of object.
    * @param message  The json blob to wrap.
    */
-  jsval wrapMessage(in jsval message);
+  jsval wrapMessage(in jsval message, in nsIDOMWindow window);
 };
--- a/dom/tests/mochitest/bugs/test_bug529328.html
+++ b/dom/tests/mochitest/bugs/test_bug529328.html
@@ -96,41 +96,31 @@ function testMediaList() {
   is(s.sheet.media.item(0), "a", "Wrong value for in bounds access (MediaList)");
   is(s.sheet.media.item(1), "b", "Wrong value for in bounds access (MediaList)");
   is(s.sheet.media.item(2), null, "Wrong value for out of bounds access (MediaList) (MediaList)");
 }
 
 function testCSSStyleDeclaration() {
   var s = document.createElement("span");
 
-  try {
-    is(s.style[-1], "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
-    todo(true, "Didn't throw");
-  } catch (e) {
-    todo(false, "Shouldn't throw");
-  }
-  is(s.style[0], "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
-  is(s.style[1], "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
-  is(s.style[2], "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
+  is(s.style[-1], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)");
+  is(s.style[0], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)");
+  is(s.style[1], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)");
+  is(s.style[2], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)");
   is(s.style.item(-1), "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
   is(s.style.item(0), "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
   is(s.style.item(1), "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
   is(s.style.item(2), "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
 
   s.setAttribute("style", "color: blue; z-index: 42;");
 
-  try {
-    is(s.style[-1], "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
-    todo(true, "Didn't throw");
-  } catch (e) {
-    todo(false, "Shouldn't throw");
-  }
+  is(s.style[-1], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)");
   is(s.style[0], "color", "Wrong value for in bounds access (CSSStyleDeclaration)");
   is(s.style[1], "z-index", "Wrong value for in bounds access (CSSStyleDeclaration)");
-  is(s.style[2], "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
+  is(s.style[2], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)");
   is(s.style.item(-1), "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
   is(s.style.item(0), "color", "Wrong value for in bounds access (CSSStyleDeclaration)");
   is(s.style.item(1), "z-index", "Wrong value for in bounds access (CSSStyleDeclaration)");
   is(s.style.item(2), "", "Wrong value for out of bounds access (CSSStyleDeclaration)");
 }
 
 testDOMTokenList();
 testDOMStringList();
new file mode 100644
--- /dev/null
+++ b/dom/webidl/CSS2Properties.webidl.in
@@ -0,0 +1,3 @@
+interface CSS2Properties : CSSStyleDeclaration {
+${props}
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/CSS2PropertiesProps.h
@@ -0,0 +1,34 @@
+/* A file meant as input to the preprocessor only */
+
+/* DO_PROP serves as an extra level of indirection to allow expansion
+   of CSS_PROP_DOMPROP_PREFIXED */
+
+[
+
+#define DO_PROP(method, pref) \
+  [ #method, pref ],
+#define CSS_PROP(name, id, method, flags, pref, parsevariant, kwtable, \
+		 stylestruct, stylestructofset, animtype) \
+  DO_PROP(method, pref)
+#define CSS_PROP_SHORTHAND(name, id, method, flags, pref) \
+  DO_PROP(method, pref)
+#define CSS_PROP_DOMPROP_PREFIXED(val) Moz##val
+#define CSS_PROP_LIST_EXCLUDE_INTERNAL
+
+#include "nsCSSPropList.h"
+
+#undef CSS_PROP_LIST_EXCLUDE_INTERNAL
+#undef CSS_PROP_DOMPROP_PREFIXED
+#undef CSS_PROP_SHORTHAND
+#undef CSS_PROP
+
+#define CSS_PROP_ALIAS(name, id, method, pref) \
+  DO_PROP(method, pref)
+
+#include "nsCSSPropAliasList.h"
+
+#undef CSS_PROP_ALIAS
+
+#undef DO_PROP
+
+]
new file mode 100644
--- /dev/null
+++ b/dom/webidl/CSSStyleDeclaration.webidl
@@ -0,0 +1,34 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * The origin of this IDL file is
+ * http://dev.w3.org/csswg/cssom/
+ */
+
+interface CSSRule;
+interface CSSValue;
+
+interface CSSStyleDeclaration {
+  [GetterInfallible]
+  attribute DOMString cssText;
+
+  [Infallible]
+  readonly attribute unsigned long length;
+  [Infallible]
+  getter DOMString item(unsigned long index);
+
+  DOMString getPropertyValue(DOMString property);
+  // Mozilla extension, sort of
+  CSSValue getPropertyCSSValue(DOMString property);
+  [Infallible]
+  DOMString getPropertyPriority(DOMString property);
+  // This would be nicer if it used a string default value of "".
+  // See bug 759622.
+  void setProperty(DOMString property, DOMString value, [TreatNullAs=EmptyString] optional DOMString priority);
+  DOMString removeProperty(DOMString property);
+
+  [Infallible]
+  readonly attribute CSSRule parentRule;
+};
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -1,16 +1,21 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 webidl_base = $(topsrcdir)/dom/webidl
 
+generated_webidl_files = \
+  CSS2Properties.webidl \
+  $(NULL)
+
 webidl_files = \
   CanvasRenderingContext2D.webidl \
+  CSSStyleDeclaration.webidl \
   Function.webidl \
   EventListener.webidl \
   EventTarget.webidl \
   Performance.webidl \
   PerformanceNavigation.webidl \
   PerformanceTiming.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \
--- a/js/src/config/system-headers
+++ b/js/src/config/system-headers
@@ -399,17 +399,16 @@ libgnomevfs/gnome-vfs-file-info.h
 libgnomevfs/gnome-vfs.h
 libgnomevfs/gnome-vfs-init.h
 libgnomevfs/gnome-vfs-mime.h
 libgnomevfs/gnome-vfs-mime-handlers.h
 libgnomevfs/gnome-vfs-mime-utils.h
 libgnomevfs/gnome-vfs-ops.h
 libgnomevfs/gnome-vfs-standard-callbacks.h
 lib$routines.h
-libnotify/notify.h
 limits
 limits.h
 link.h
 linux/kernel.h
 linux/limits.h
 linux/rtc.h
 linux/version.h
 list
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -2667,18 +2667,18 @@ ASTSerializer::expression(ParseNode *pn,
       {
         NodeVector elts(cx);
         if (!elts.reserve(pn->pn_count))
             return false;
 
         for (ParseNode *next = pn->pn_head; next; next = next->pn_next) {
             JS_ASSERT(pn->pn_pos.encloses(next->pn_pos));
 
-            if (next->isKind(PNK_COMMA)) {
-                elts.infallibleAppend(MagicValue(JS_SERIALIZE_NO_NODE));
+            if (next->isKind(PNK_COMMA) && next->pn_count == 0) {
+                elts.infallibleAppend(NullValue());
             } else {
                 Value expr;
                 if (!expression(next, &expr))
                     return false;
                 elts.infallibleAppend(expr);
             }
         }
 
@@ -3015,18 +3015,21 @@ ASTSerializer::arrayPattern(ParseNode *p
 {
     JS_ASSERT(pn->isKind(PNK_RB));
 
     NodeVector elts(cx);
     if (!elts.reserve(pn->pn_count))
         return false;
 
     for (ParseNode *next = pn->pn_head; next; next = next->pn_next) {
+        /* Comma expressions can't occur inside patterns, so no need to test pn_count. */
+        JS_ASSERT_IF(next->isKind(PNK_COMMA), next->pn_count == 0);
+
         if (next->isKind(PNK_COMMA)) {
-            elts.infallibleAppend(MagicValue(JS_SERIALIZE_NO_NODE));
+            elts.infallibleAppend(NullValue());
         } else {
             Value patt;
             if (!pattern(next, pkind, &patt))
                 return false;
             elts.infallibleAppend(patt);
         }
     }
 
--- a/js/src/tests/js1_8_5/extensions/reflect-parse.js
+++ b/js/src/tests/js1_8_5/extensions/reflect-parse.js
@@ -233,16 +233,19 @@ assertDecl("function f(a) { function a()
            funDecl(ident("f"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))])));
 assertDecl("function f(a,b,c) { function b() { } }",
            funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))])));
 assertDecl("function f(a,[x,y]) { function a() { } }",
            funDecl(ident("f"),
                    [ident("a"), arrPatt([ident("x"), ident("y")])],
                    blockStmt([funDecl(ident("a"), [], blockStmt([]))])));
 
+// Bug 632027: array holes should reflect as null
+assertExpr("[,]=[,]", aExpr("=", arrPatt([null]), arrExpr([null])));
+
 // Bug 591450: this test currently crashes because of a bug in jsparse
 // assertDecl("function f(a,[x,y],b,[w,z],c) { function b() { } }",
 //            funDecl(ident("f"),
 //                    [ident("a"), arrPatt([ident("x"), ident("y")]), ident("b"), arrPatt([ident("w"), ident("z")]), ident("c")],
 //                    blockStmt([funDecl(ident("b"), [], blockStmt([]))])));
 
 
 // expressions
@@ -315,29 +318,31 @@ assertExpr("(new Object(42))", newExpr(i
 assertExpr("(new Object(1,2,3))", newExpr(ident("Object"), [lit(1),lit(2),lit(3)]));
 assertExpr("(String())", callExpr(ident("String"), []));
 assertExpr("(String(42))", callExpr(ident("String"), [lit(42)]));
 assertExpr("(String(1,2,3))", callExpr(ident("String"), [lit(1),lit(2),lit(3)]));
 assertExpr("[]", arrExpr([]));
 assertExpr("[1]", arrExpr([lit(1)]));
 assertExpr("[1,2]", arrExpr([lit(1),lit(2)]));
 assertExpr("[1,2,3]", arrExpr([lit(1),lit(2),lit(3)]));
-assertExpr("[1,,2,3]", arrExpr([lit(1),,lit(2),lit(3)]));
-assertExpr("[1,,,2,3]", arrExpr([lit(1),,,lit(2),lit(3)]));
-assertExpr("[1,,,2,,3]", arrExpr([lit(1),,,lit(2),,lit(3)]));
-assertExpr("[1,,,2,,,3]", arrExpr([lit(1),,,lit(2),,,lit(3)]));
-assertExpr("[,1,2,3]", arrExpr([,lit(1),lit(2),lit(3)]));
-assertExpr("[,,1,2,3]", arrExpr([,,lit(1),lit(2),lit(3)]));
-assertExpr("[,,,1,2,3]", arrExpr([,,,lit(1),lit(2),lit(3)]));
-assertExpr("[,,,1,2,3,]", arrExpr([,,,lit(1),lit(2),lit(3),]));
-assertExpr("[,,,1,2,3,,]", arrExpr([,,,lit(1),lit(2),lit(3),,]));
-assertExpr("[,,,1,2,3,,,]", arrExpr([,,,lit(1),lit(2),lit(3),,,]));
-assertExpr("[,,,,,]", arrExpr([,,,,,]));
+assertExpr("[1,,2,3]", arrExpr([lit(1),null,lit(2),lit(3)]));
+assertExpr("[1,,,2,3]", arrExpr([lit(1),null,null,lit(2),lit(3)]));
+assertExpr("[1,,,2,,3]", arrExpr([lit(1),null,null,lit(2),null,lit(3)]));
+assertExpr("[1,,,2,,,3]", arrExpr([lit(1),null,null,lit(2),null,null,lit(3)]));
+assertExpr("[,1,2,3]", arrExpr([null,lit(1),lit(2),lit(3)]));
+assertExpr("[,,1,2,3]", arrExpr([null,null,lit(1),lit(2),lit(3)]));
+assertExpr("[,,,1,2,3]", arrExpr([null,null,null,lit(1),lit(2),lit(3)]));
+assertExpr("[,,,1,2,3,]", arrExpr([null,null,null,lit(1),lit(2),lit(3)]));
+assertExpr("[,,,1,2,3,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null]));
+assertExpr("[,,,1,2,3,,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null,null]));
+assertExpr("[,,,,,]", arrExpr([null,null,null,null,null]));
 assertExpr("[1, ...a, 2]", arrExpr([lit(1), spread(ident("a")), lit(2)]));
-assertExpr("[,, ...a,, ...b, 42]", arrExpr([,, spread(ident("a")),, spread(ident("b")), lit(42)]));
+assertExpr("[,, ...a,, ...b, 42]", arrExpr([null,null, spread(ident("a")),, spread(ident("b")), lit(42)]));
+assertExpr("[1,(2,3)]", arrExpr([lit(1),seqExpr([lit(2),lit(3)])]));
+assertExpr("[,(2,3)]", arrExpr([null,seqExpr([lit(2),lit(3)])]));
 assertExpr("({})", objExpr([]));
 assertExpr("({x:1})", objExpr([{ key: ident("x"), value: lit(1) }]));
 assertExpr("({x:1, y:2})", objExpr([{ key: ident("x"), value: lit(1) },
                                     { key: ident("y"), value: lit(2) } ]));
 assertExpr("({x:1, y:2, z:3})", objExpr([{ key: ident("x"), value: lit(1) },
                                          { key: ident("y"), value: lit(2) },
                                          { key: ident("z"), value: lit(3) } ]));
 assertExpr("({x:1, 'y':2, z:3})", objExpr([{ key: ident("x"), value: lit(1) },
--- a/js/xpconnect/src/dombindings.cpp
+++ b/js/xpconnect/src/dombindings.cpp
@@ -60,25 +60,16 @@ DefineStaticJSVals(JSContext *cx)
 
     return SET_JSID_TO_STRING(cx, prototype) &&
            SET_JSID_TO_STRING(cx, length) &&
            SET_JSID_TO_STRING(cx, iterator) &&
            DefinePropertyStaticJSVals(cx);
 }
 
 
-int HandlerFamily;
-
-struct SetListBaseInformation
-{
-    SetListBaseInformation() {
-        js::SetListBaseInformation((void*) &HandlerFamily, js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO);
-    }
-} gSetListBaseInformation;
-
 JSBool
 Throw(JSContext *cx, nsresult rv)
 {
     XPCThrower::Throw(rv, cx);
     return false;
 }
 
 template<class T>
--- a/js/xpconnect/src/dombindings.h
+++ b/js/xpconnect/src/dombindings.h
@@ -12,19 +12,19 @@
 #include "jsproxy.h"
 #include "xpcpublic.h"
 #include "nsString.h"
 
 namespace mozilla {
 namespace dom {
 namespace oldproxybindings {
 
-class ProxyHandler : public js::BaseProxyHandler {
+class ProxyHandler : public DOMBaseProxyHandler {
 protected:
-    ProxyHandler() : js::BaseProxyHandler(ProxyFamily())
+    ProxyHandler() : DOMBaseProxyHandler(false)
     {
     }
 
 public:
     virtual bool isInstanceOf(JSObject *prototype) = 0;
 };
 
 class NoType;
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -304,41 +304,59 @@ Throw(JSContext *cx, nsresult rv);
 nsCycleCollectionParticipant *
 xpc_JSCompartmentParticipant();
 
 namespace mozilla {
 namespace dom {
 
 extern int HandlerFamily;
 inline void* ProxyFamily() { return &HandlerFamily; }
+
+class DOMBaseProxyHandler : public js::BaseProxyHandler {
+protected:
+    DOMBaseProxyHandler(bool aNewDOMProxy) : js::BaseProxyHandler(ProxyFamily()),
+                                             mNewDOMProxy(aNewDOMProxy)
+    {
+    }
+
+public:
+    bool mNewDOMProxy;
+};
+
+inline bool IsNewProxyBinding(js::BaseProxyHandler* handler)
+{
+  MOZ_ASSERT(handler->family() == ProxyFamily());
+  return static_cast<DOMBaseProxyHandler*>(handler)->mNewDOMProxy;
+}
+
 inline bool IsDOMProxy(JSObject *obj)
 {
     return js::IsProxy(obj) &&
-           js::GetProxyHandler(obj)->family() == ProxyFamily();
+           js::GetProxyHandler(obj)->family() == ProxyFamily() &&
+           IsNewProxyBinding(js::GetProxyHandler(obj));
 }
 
 typedef bool
 (*DefineInterface)(JSContext *cx, JSObject *global, bool *enabled);
 
 extern bool
 DefineStaticJSVals(JSContext *cx);
 void
 Register(nsScriptNameSpaceManager* aNameSpaceManager);
 extern bool
 DefineConstructor(JSContext *cx, JSObject *obj, DefineInterface aDefine,
                   nsresult *aResult);
 
 namespace oldproxybindings {
 
-extern int HandlerFamily;
-inline void* ProxyFamily() { return &HandlerFamily; }
 inline bool instanceIsProxy(JSObject *obj)
 {
     return js::IsProxy(obj) &&
-           js::GetProxyHandler(obj)->family() == ProxyFamily();
+           js::GetProxyHandler(obj)->family() == ProxyFamily() &&
+           !IsNewProxyBinding(js::GetProxyHandler(obj));
 }
 extern bool
 DefineStaticJSVals(JSContext *cx);
 void
 Register(nsScriptNameSpaceManager* aNameSpaceManager);
 
 } // namespace oldproxybindings
 
--- a/js/xpconnect/tests/chrome/test_weakmaps.xul
+++ b/js/xpconnect/tests/chrome/test_weakmaps.xul
@@ -215,24 +215,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   let unpreservable_native_key = function () {
     // We only allow natives that support wrapper preservation to be used as weak
     // map keys.  We should be able to try to add unpreservable natives as keys without
     // crashing (bug 711616), but we should throw an error (bug 761620).
 
     let dummy_test_map = new WeakMap;
 
-    let div_fail = false;
-    try {
-      dummy_test_map.set(document.createElement("div").style, 1);
-    } catch (e) {
-      div_fail = true;
-    }
-    ok(div_fail, "Using elem.style as a weak map key should produce an exception because it can't be wrapper preserved.");
-
     let navi_fail = false;
     try {
       dummy_test_map.set(window.navigator, 1);
     } catch (e) {
       navi_fail = true;
     }
     ok(navi_fail, "Using window.navigator as a weak map key should produce an exception because it can't be wrapper preserved.");
 
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -834,24 +834,16 @@ public:
   /**
    * Notify that a content node's state has changed
    */
   virtual void ContentStateChanged(nsIDocument* aDocument,
                                    nsIContent* aContent,
                                    nsEventStates aStateMask) = 0;
 
   /**
-   * Given aFrame, the root frame of a stacking context, find its descendant
-   * frame under the point aPt that receives a mouse event at that location,
-   * or nullptr if there is no such frame.
-   * @param aPt the point, relative to the frame origin
-   */
-  virtual nsIFrame* GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt) = 0;
-
-  /**
    * See if reflow verification is enabled. To enable reflow verification add
    * "verifyreflow:1" to your NSPR_LOG_MODULES environment variable
    * (any non-zero debug level will work). Or, call SetVerifyReflowEnable
    * with true.
    */
   static bool GetVerifyReflowEnable();
 
   /**
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -2363,22 +2363,16 @@ nsIPresShell::GetRootScrollFrameAsScroll
 
 nsIPageSequenceFrame*
 PresShell::GetPageSequenceFrame() const
 {
   nsIFrame* frame = mFrameConstructor->GetPageSequenceFrame();
   return do_QueryFrame(frame);
 }
 
-nsIFrame*
-PresShell::GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt)
-{
-  return nsLayoutUtils::GetFrameForPoint(aFrame, aPt);
-}
-
 void
 PresShell::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
 {
 #ifdef DEBUG
   mUpdateCount++;
 #endif
   mFrameConstructor->BeginUpdate();
 
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -152,18 +152,16 @@ public:
   virtual NS_HIDDEN_(already_AddRefed<nsIContent>) GetEventTargetContent(nsEvent* aEvent);
 
 
   virtual nsresult ReconstructFrames(void);
   virtual void Freeze();
   virtual void Thaw();
   virtual void FireOrClearDelayedEvents(bool aFireEvents);
 
-  virtual nsIFrame* GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt);
-
   virtual NS_HIDDEN_(nsresult) RenderDocument(const nsRect& aRect, uint32_t aFlags,
                                               nscolor aBackgroundColor,
                                               gfxContext* aThebesContext);
 
   virtual already_AddRefed<gfxASurface> RenderNode(nsIDOMNode* aNode,
                                                    nsIntRegion* aRegion,
                                                    nsIntPoint& aPoint,
                                                    nsIntRect* aScreenRect);
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -982,26 +982,28 @@ Declaration::List(FILE* out, int32_t aIn
   fputs("{ ", out);
   nsAutoString s;
   ToString(s);
   fputs(NS_ConvertUTF16toUTF8(s).get(), out);
   fputs("}", out);
 }
 #endif
 
-void
+bool
 Declaration::GetNthProperty(uint32_t aIndex, nsAString& aReturn) const
 {
   aReturn.Truncate();
   if (aIndex < mOrder.Length()) {
     nsCSSProperty property = OrderValueAt(aIndex);
     if (0 <= property) {
       AppendASCIItoUTF16(nsCSSProps::GetStringValue(property), aReturn);
+      return true;
     }
   }
+  return false;
 }
 
 void
 Declaration::InitializeEmpty()
 {
   NS_ABORT_IF_FALSE(!mData && !mImportantData, "already initialized");
   mData = nsCSSCompressedDataBlock::CreateEmptyBlock();
 }
--- a/layout/style/Declaration.h
+++ b/layout/style/Declaration.h
@@ -65,17 +65,19 @@ public:
 
   bool HasImportantData() const { return mImportantData != nullptr; }
   bool GetValueIsImportant(nsCSSProperty aProperty) const;
   bool GetValueIsImportant(const nsAString& aProperty) const;
 
   uint32_t Count() const {
     return mOrder.Length();
   }
-  void GetNthProperty(uint32_t aIndex, nsAString& aReturn) const;
+
+  // Returns whether we actually had a property at aIndex
+  bool GetNthProperty(uint32_t aIndex, nsAString& aReturn) const;
 
   void ToString(nsAString& aString) const;
 
   nsCSSCompressedDataBlock* GetNormalBlock() const { return mData; }
   nsCSSCompressedDataBlock* GetImportantBlock() const { return mImportantData; }
 
   /**
    * Initialize this declaration as holding no data.  Cannot fail.
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -30,16 +30,17 @@
 #include "nsContentUtils.h"
 #include "nsStyleConsts.h"
 #include "nsError.h"
 #include "nsStyleUtil.h"
 #include "mozilla/css/Declaration.h"
 #include "nsCSSParser.h"
 #include "nsPrintfCString.h"
 #include "nsDOMClassInfoID.h"
+#include "mozilla/dom/CSSStyleDeclarationBinding.h"
 
 namespace css = mozilla::css;
 
 #define IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \
 /* virtual */ nsIDOMCSSRule* class_::GetDOMRule() \
   { return this; }
 #define IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_) \
 /* virtual */ void class_::MapRuleInfoInto(nsRuleData* aRuleData) \
@@ -1553,33 +1554,44 @@ nsCSSFontFaceStyleDecl::GetLength(uint32
       len++;
 
   *aLength = len;
   return NS_OK;
 }
 
 // DOMString item (in unsigned long index);
 NS_IMETHODIMP
-nsCSSFontFaceStyleDecl::Item(uint32_t index, nsAString & aResult)
- {
+nsCSSFontFaceStyleDecl::Item(uint32_t aIndex, nsAString& aReturn)
+{
+  bool found;
+  IndexedGetter(aIndex, found, aReturn);
+  if (!found) {
+    aReturn.Truncate();
+  }
+  return NS_OK;
+}
+
+void
+nsCSSFontFaceStyleDecl::IndexedGetter(uint32_t index, bool& aFound, nsAString & aResult)
+{
   int32_t nset = -1;
   for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
        id < eCSSFontDesc_COUNT;
        id = nsCSSFontDesc(id + 1)) {
     if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
         != eCSSUnit_Null) {
       nset++;
       if (nset == int32_t(index)) {
+        aFound = true;
         aResult.AssignASCII(nsCSSProps::GetStringValue(id).get());
-        return NS_OK;
+        return;
       }
     }
   }
-  aResult.Truncate();
-  return NS_OK;
+  aFound = false;
 }
 
 // readonly attribute nsIDOMCSSRule parentRule;
 NS_IMETHODIMP
 nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule** aParentRule)
 {
   NS_IF_ADDREF(*aParentRule = ContainingRule()->GetDOMRule());
   return NS_OK;
@@ -1603,16 +1615,24 @@ nsCSSFontFaceStyleDecl::SetPropertyValue
 }
 
 nsINode*
 nsCSSFontFaceStyleDecl::GetParentObject()
 {
   return ContainingRule()->GetDocument();
 }
 
+JSObject*
+nsCSSFontFaceStyleDecl::WrapObject(JSContext *cx, JSObject *scope,
+                                   bool *triedToWrap)
+{
+  return mozilla::dom::CSSStyleDeclarationBinding::Wrap(cx, scope, this,
+                                                        triedToWrap);
+}
+
 // -------------------------------------------
 // nsCSSFontFaceRule
 // 
 
 /* virtual */ already_AddRefed<css::Rule>
 nsCSSFontFaceRule::Clone() const
 {
   nsRefPtr<css::Rule> clone = new nsCSSFontFaceRule(*this);
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -159,21 +159,30 @@ protected:
 class nsCSSFontFaceRule;
 class nsCSSFontFaceStyleDecl : public nsICSSDeclaration
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMCSSSTYLEDECLARATION
   NS_DECL_NSICSSDECLARATION
 
+  nsCSSFontFaceStyleDecl()
+  {
+    SetIsDOMBinding();
+  }
+
   virtual nsINode *GetParentObject();
+  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName);
 
   nsresult GetPropertyValue(nsCSSFontDesc aFontDescID,
                             nsAString & aResult) const;
 
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
+                               bool *triedToWrap);
+
 protected:
   friend class nsCSSFontFaceRule;
 #define CSS_FONT_DESC(name_, method_) nsCSSValue m##method_;
 #include "nsCSSFontDescList.h"
 #undef CSS_FONT_DESC
 
   static nsCSSValue nsCSSFontFaceStyleDecl::* const Fields[];  
   inline nsCSSFontFaceRule* ContainingRule();
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -540,28 +540,31 @@ nsComputedDOMStyle::SetProperty(const ns
 {
   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
 }
 
 
 NS_IMETHODIMP
 nsComputedDOMStyle::Item(uint32_t aIndex, nsAString& aReturn)
 {
-  aReturn.Truncate();
-
+  return nsDOMCSSDeclaration::Item(aIndex, aReturn);
+}
+
+void
+nsComputedDOMStyle::IndexedGetter(uint32_t aIndex, bool& aFound,
+                                  nsAString& aPropName)
+{
   uint32_t length = 0;
   const ComputedStyleMapEntry* propMap = GetQueryablePropertyMap(&length);
-  if (aIndex < length) {
+  aFound = aIndex < length;
+  if (aFound) {
     CopyASCIItoUTF16(nsCSSProps::GetStringValue(propMap[aIndex].mProperty),
-                    aReturn);
+                     aPropName);
   }
-
-  return NS_OK;
-}
-
+}
 
 // Property getters...
 
 nsIDOMCSSValue*
 nsComputedDOMStyle::DoGetBinding()
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
 
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -20,26 +20,27 @@
 #include "nsWeakReference.h"
 #include "nsAutoPtr.h"
 #include "nsStyleStruct.h"
 #include "nsStyleContext.h"
 
 class nsIFrame;
 class nsIPresShell;
 
-class nsComputedDOMStyle : public nsDOMCSSDeclaration
+class nsComputedDOMStyle MOZ_FINAL : public nsDOMCSSDeclaration
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsComputedDOMStyle,
                                                                    nsICSSDeclaration)
 
   NS_DECL_NSICSSDECLARATION
 
   NS_DECL_NSIDOMCSSSTYLEDECLARATION
+  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName);
 
   nsComputedDOMStyle(mozilla::dom::Element* aElement,
                      const nsAString& aPseudoElt,
                      nsIPresShell* aPresShell);
   virtual ~nsComputedDOMStyle();
 
   static void Shutdown();
 
--- a/layout/style/nsDOMCSSAttrDeclaration.h
+++ b/layout/style/nsDOMCSSAttrDeclaration.h
@@ -18,17 +18,17 @@ namespace css {
 class Loader;
 }
 
 namespace dom {
 class Element;
 }
 }
 
-class nsDOMCSSAttributeDeclaration : public nsDOMCSSDeclaration
+class nsDOMCSSAttributeDeclaration MOZ_FINAL : public nsDOMCSSDeclaration
 {
 public:
   typedef mozilla::dom::Element Element;
   nsDOMCSSAttributeDeclaration(Element* aContent, bool aIsSMILOverride);
   ~nsDOMCSSAttributeDeclaration();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMCSSAttributeDeclaration,
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -139,27 +139,21 @@ nsDOMCSSDeclaration::GetPropertyCSSValue
   NS_ENSURE_ARG_POINTER(aReturn);
 
   // We don't support CSSValue yet so we'll just return null...
   *aReturn = nullptr;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDOMCSSDeclaration::Item(uint32_t aIndex, nsAString& aReturn)
+void
+nsDOMCSSDeclaration::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName)
 {
   css::Declaration* decl = GetCSSDeclaration(false);
-
-  aReturn.SetLength(0);
-  if (decl) {
-    decl->GetNthProperty(aIndex, aReturn);
-  }
-
-  return NS_OK;
+  aFound = decl && decl->GetNthProperty(aIndex, aPropName);
 }
 
 NS_IMETHODIMP
 nsDOMCSSDeclaration::GetPropertyValue(const nsAString& aPropertyName,
                                       nsAString& aReturn)
 {
   const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName,
                                                           nsCSSProps::eEnabled);
--- a/layout/style/nsDOMCSSDeclaration.h
+++ b/layout/style/nsDOMCSSDeclaration.h
@@ -6,16 +6,17 @@
 /* base class for DOM objects for element.style and cssStyleRule.style */
 
 #ifndef nsDOMCSSDeclaration_h___
 #define nsDOMCSSDeclaration_h___
 
 #include "nsICSSDeclaration.h"
 #include "nsIDOMCSS2Properties.h"
 #include "nsCOMPtr.h"
+#include "mozilla/dom/CSS2PropertiesBinding.h"
 
 class nsCSSParser;
 class nsIURI;
 class nsIPrincipal;
 class nsIDocument;
 
 namespace mozilla {
 namespace css {
@@ -28,40 +29,86 @@ class Rule;
 class nsDOMCSSDeclaration : public nsICSSDeclaration,
                             public nsIDOMCSS2Properties
 {
 public:
   // Only implement QueryInterface; subclasses have the responsibility
   // of implementing AddRef/Release.
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
 
+  // Declare addref and release so they can be called on us, but don't
+  // implement them.  Our subclasses must handle their own
+  // refcounting.
+  NS_IMETHOD_(nsrefcnt) AddRef() = 0;
+  NS_IMETHOD_(nsrefcnt) Release() = 0;
+
   NS_DECL_NSICSSDECLARATION
+  using nsICSSDeclaration::GetLength;
 
   // Require subclasses to implement |GetParentRule|.
   //NS_DECL_NSIDOMCSSSTYLEDECLARATION
   NS_IMETHOD GetCssText(nsAString & aCssText);
   NS_IMETHOD SetCssText(const nsAString & aCssText);
   NS_IMETHOD GetPropertyValue(const nsAString & propertyName,
                               nsAString & _retval);
   NS_IMETHOD GetPropertyCSSValue(const nsAString & propertyName,
                                  nsIDOMCSSValue **_retval);
   NS_IMETHOD RemoveProperty(const nsAString & propertyName,
                             nsAString & _retval);
   NS_IMETHOD GetPropertyPriority(const nsAString & propertyName,
                                  nsAString & _retval);
   NS_IMETHOD SetProperty(const nsAString & propertyName,
                          const nsAString & value, const nsAString & priority);
   NS_IMETHOD GetLength(uint32_t *aLength);
-  NS_IMETHOD Item(uint32_t index, nsAString & _retval);
   NS_IMETHOD GetParentRule(nsIDOMCSSRule * *aParentRule) = 0;
 
   // We implement this as a shim which forwards to GetPropertyValue
   // and SetPropertyValue; subclasses need not.
   NS_DECL_NSIDOMCSS2PROPERTIES
 
+  // WebIDL interface for CSS2Properties
+#define CSS_PROP_DOMPROP_PREFIXED(prop_) Moz ## prop_
+#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,          \
+                 kwtable_, stylestruct_, stylestructoffset_, animtype_)      \
+  void                                                                       \
+  Get##method_(nsAString& aValue, mozilla::ErrorResult& rv)                  \
+  {                                                                          \
+    rv = GetPropertyValue(eCSSProperty_##id_, aValue);                       \
+  }                                                                          \
+                                                                             \
+  void                                                                       \
+  Set##method_(const nsAString& aValue, mozilla::ErrorResult& rv)            \
+  {                                                                          \
+    rv = SetPropertyValue(eCSSProperty_##id_, aValue);                       \
+  }
+
+#define CSS_PROP_LIST_EXCLUDE_INTERNAL
+#define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_)  \
+  CSS_PROP(name_, id_, method_, flags_, pref_, X, X, X, X, X)
+#include "nsCSSPropList.h"
+
+#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)  \
+  CSS_PROP(X, propid_, aliasmethod_, X, pref_, X, X, X, X, X)
+#include "nsCSSPropAliasList.h"
+#undef CSS_PROP_ALIAS
+
+#undef CSS_PROP_SHORTHAND
+#undef CSS_PROP_LIST_EXCLUDE_INTERNAL
+#undef CSS_PROP
+#undef CSS_PROP_DOMPROP_PREFIXED
+
+  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName);
+
+  virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
+                               bool *triedToWrap)
+  {
+    return mozilla::dom::CSS2PropertiesBinding::Wrap(cx, scope, this,
+                                                     triedToWrap);
+  }
+
 protected:
   // This method can return null regardless of the value of aAllocate;
   // however, a null return should only be considered a failure
   // if aAllocate is true.
   virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate) = 0;
   virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) = 0;
   // Document that we must call BeginUpdate/EndUpdate on around the
   // calls to SetCSSDeclaration and the style rule mutation that leads
@@ -97,11 +144,15 @@ protected:
                               bool aIsImportant);
 
   // Prop-id based version of RemoveProperty.  Note that this does not
   // return the old value; it just does a straight removal.
   nsresult RemoveProperty(const nsCSSProperty aPropID);
 
 protected:
   virtual ~nsDOMCSSDeclaration();
+  nsDOMCSSDeclaration()
+  {
+    SetIsDOMBinding();
+  }
 };
 
 #endif // nsDOMCSSDeclaration_h___
--- a/layout/style/nsICSSDeclaration.h
+++ b/layout/style/nsICSSDeclaration.h
@@ -17,51 +17,132 @@
  * nsCSSProperty enums for the prop names instead of using strings.
  * This is meant for use in performance-sensitive code only!  Most
  * consumers should continue to use nsIDOMCSSStyleDeclaration.
  */
 
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsCSSProperty.h"
 #include "nsWrapperCache.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "nsString.h"
+#include "nsIDOMCSSRule.h"
+#include "nsIDOMCSSValue.h"
+#include "mozilla/ErrorResult.h"
 
-// 57eb81d1-a607-4429-926b-802519d43aad
+// dbeabbfa-6cb3-4f5c-aec2-dd558d9d681f
 #define NS_ICSSDECLARATION_IID \
- { 0x57eb81d1, 0xa607, 0x4429, \
-    {0x92, 0x6b, 0x80, 0x25, 0x19, 0xd4, 0x3a, 0xad } }
+{ 0xdbeabbfa, 0x6cb3, 0x4f5c, \
+ { 0xae, 0xc2, 0xdd, 0x55, 0x8d, 0x9d, 0x68, 0x1f } }
 
 class nsINode;
 
 class nsICSSDeclaration : public nsIDOMCSSStyleDeclaration,
                           public nsWrapperCache
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICSSDECLARATION_IID)
 
   /**
    * Method analogous to nsIDOMCSSStyleDeclaration::GetPropertyValue,
    * which obeys all the same restrictions.
    */
   NS_IMETHOD GetPropertyValue(const nsCSSProperty aPropID,
                               nsAString& aValue) = 0;
 
-  // Also have to declare the nsIDOMCSSStyleDeclaration method, so we
-  // don't hide it... very sad, but it stole the good method name
-  NS_IMETHOD GetPropertyValue(const nsAString& aPropName,
-                              nsAString& aValue) = 0;
-  
   /**
    * Method analogous to nsIDOMCSSStyleDeclaration::SetProperty.  This
    * method does NOT allow setting a priority (the priority will
    * always be set to default priority).
    */
   NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID,
                               const nsAString& aValue) = 0;
 
   virtual nsINode *GetParentObject() = 0;
+
+  // Also have to declare all the nsIDOMCSSStyleDeclaration methods,
+  // since we want to be able to call them from the WebIDL versions.
+  NS_IMETHOD GetCssText(nsAString& aCssText) = 0;
+  NS_IMETHOD SetCssText(const nsAString& aCssText) = 0;
+  NS_IMETHOD GetPropertyValue(const nsAString& aPropName,
+                              nsAString& aValue) = 0;
+  NS_IMETHOD GetPropertyCSSValue(const nsAString& aPropertyName,
+                                 nsIDOMCSSValue** aReturn) = 0;
+  NS_IMETHOD RemoveProperty(const nsAString& aPropertyName,
+                            nsAString& aReturn) = 0;
+  NS_IMETHOD GetPropertyPriority(const nsAString& aPropertyName,
+                                 nsAString& aReturn) = 0;
+  NS_IMETHOD SetProperty(const nsAString& aPropertyName,
+                         const nsAString& aValue,
+                         const nsAString& aPriority) = 0;
+  NS_IMETHOD GetLength(uint32_t* aLength) = 0;
+  NS_IMETHOD Item(uint32_t aIndex, nsAString& aReturn)
+  {
+    bool found;
+    IndexedGetter(aIndex, found, aReturn);
+    if (!found) {
+      aReturn.Truncate();
+    }
+    return NS_OK;
+  }
+  NS_IMETHOD GetParentRule(nsIDOMCSSRule * *aParentRule) = 0;
+
+  // WebIDL interface for CSSStyleDeclaration
+  void SetCssText(const nsAString& aString, mozilla::ErrorResult& rv) {
+    rv = SetCssText(aString);
+  }
+  void GetCssText(nsString& aString) {
+    // Cast to nsAString& so we end up calling our virtual
+    // |GetCssText(nsAString& aCssText)| overload, which does the real work.
+    GetCssText(static_cast<nsAString&>(aString));
+  }
+  uint32_t GetLength() {
+    uint32_t length;
+    GetLength(&length);
+    return length;
+  }
+  void Item(uint32_t aIndex, nsString& aPropName) {
+    Item(aIndex, static_cast<nsAString&>(aPropName));
+  }
+
+  // The actual implementation of the Item method and the WebIDL indexed getter
+  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) = 0;
+
+  void GetPropertyValue(const nsAString& aPropName, nsString& aValue,
+                        mozilla::ErrorResult& rv) {
+    rv = GetPropertyValue(aPropName, aValue);
+  }
+  already_AddRefed<nsIDOMCSSValue>
+    GetPropertyCSSValue(const nsAString& aPropName, mozilla::ErrorResult& rv) {
+    nsCOMPtr<nsIDOMCSSValue> val;
+    rv = GetPropertyCSSValue(aPropName, getter_AddRefs(val));
+    return val.forget();
+  }
+  void GetPropertyPriority(const nsAString& aPropName, nsString& aPriority) {
+    GetPropertyPriority(aPropName, static_cast<nsAString&>(aPriority));
+  }
+  // XXXbz we should nix the Optional thing once bug 759622 is fixed.
+  void SetProperty(const nsAString& aPropName, const nsAString& aValue,
+                   const mozilla::dom::Optional<nsAString>& aPriority,
+                   mozilla::ErrorResult& rv) {
+    if (aPriority.WasPassed()) {
+      rv = SetProperty(aPropName, aValue, aPriority.Value());
+    } else {
+      rv = SetProperty(aPropName, aValue, EmptyString());
+    }
+  }
+  void RemoveProperty(const nsAString& aPropName, nsString& aRetval,
+                      mozilla::ErrorResult& rv) {
+    rv = RemoveProperty(aPropName, aRetval);
+  }
+  already_AddRefed<nsIDOMCSSRule> GetParentRule() {
+    nsCOMPtr<nsIDOMCSSRule> rule;
+    GetParentRule(getter_AddRefs(rule));
+    return rule.forget();
+  }
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsICSSDeclaration, NS_ICSSDECLARATION_IID)
 
 #define NS_DECL_NSICSSDECLARATION                               \
   NS_IMETHOD GetPropertyValue(const nsCSSProperty aPropID,    \
                               nsAString& aValue);               \
   NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID,    \
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -124,17 +124,17 @@ ElementTransitions::HasTransitionOfPrope
   return false;
 }
 
 bool
 ElementTransitions::CanPerformOnCompositorThread() const
 {
   if (mElementProperty != nsGkAtoms::transitionsProperty) {
     if (nsLayoutUtils::IsAnimationLoggingEnabled()) {
-      printf_stderr("Gecko bug: Async animation of pseudoelements not supported.  See bug 771367\n");
+      printf_stderr("Gecko bug: Async transition of pseudoelements not supported.  See bug 771367\n");
     }
     return false;
   }
   bool hasGeometricProperty = false;
   nsIFrame* frame = mElement->GetPrimaryFrame();
   TimeStamp now = frame->PresContext()->RefreshDriver()->MostRecentRefresh();
 
   for (uint32_t i = 0, i_end = mPropertyTransitions.Length(); i < i_end; ++i) {
--- a/media/omx-plugin/OmxPlugin.cpp
+++ b/media/omx-plugin/OmxPlugin.cpp
@@ -12,16 +12,17 @@
 #else
 #include <stagefright/OMXClient.h>
 #endif
 #include "mozilla/Types.h"
 #include "MPAPI.h"
 
 #include "android/log.h"
 
+#undef LOG
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "OmxPlugin" , ## args)
 
 using namespace MPAPI;
 
 namespace android {
 
 // MediaStreamSource is a DataSource that reads from a MPAPI media stream.
 
@@ -243,31 +244,33 @@ bool OmxDecoder::Init() {
   sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
   if (extractor == NULL) {
     return false;
   }
 
   ssize_t audioTrackIndex = -1;
   ssize_t videoTrackIndex = -1;
   const char *audioMime = NULL;
+  const char *videoMime = NULL;
 
   for (size_t i = 0; i < extractor->countTracks(); ++i) {
     sp<MetaData> meta = extractor->getTrackMetaData(i);
 
     int32_t bitRate;
     if (!meta->findInt32(kKeyBitRate, &bitRate))
       bitRate = 0;
 
     const char *mime;
     if (!meta->findCString(kKeyMIMEType, &mime)) {
       continue;
     }
 
     if (videoTrackIndex == -1 && !strncasecmp(mime, "video/", 6)) {
       videoTrackIndex = i;
+      videoMime = mime;
     } else if (audioTrackIndex == -1 && !strncasecmp(mime, "audio/", 6)) {
       audioTrackIndex = i;
       audioMime = mime;
     }
   }
 
   if (videoTrackIndex == -1 && audioTrackIndex == -1) {
     return false;
@@ -297,20 +300,23 @@ bool OmxDecoder::Init() {
   if (videoTrackIndex != -1 && (videoTrack = extractor->getTrack(videoTrackIndex)) != NULL) {
     videoSource = OMXCodec::Create(omx,
                                    videoTrack->getFormat(),
                                    false, // decoder
                                    videoTrack,
                                    NULL,
                                    flags);
     if (videoSource == NULL) {
+      LOG("OMXCodec failed to initialize video decoder for \"%s\"", videoMime);
       return false;
     }
 
-    if (videoSource->start() != OK) {
+    status_t status = videoSource->start();
+    if (status != OK) {
+      LOG("videoSource->start() failed with status %#x", status);
       return false;
     }
 
     int64_t durationUs;
     if (videoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
       if (durationUs > totalDurationUs)
         totalDurationUs = durationUs;
     }
@@ -323,20 +329,25 @@ bool OmxDecoder::Init() {
     if (!strcasecmp(audioMime, "audio/raw")) {
       audioSource = audioTrack;
     } else {
       audioSource = OMXCodec::Create(omx,
                                      audioTrack->getFormat(),
                                      false, // decoder
                                      audioTrack);
     }
+
     if (audioSource == NULL) {
+      LOG("OMXCodec failed to initialize audio decoder for \"%s\"", audioMime);
       return false;
     }
-    if (audioSource->start() != OK) {
+
+    status_t status = audioSource->start();
+    if (status != OK) {
+      LOG("audioSource->start() failed with status %#x", status);
       return false;
     }
 
     int64_t durationUs;
     if (audioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) {
       if (durationUs > totalDurationUs)
         totalDurationUs = durationUs;
     }
@@ -494,17 +505,17 @@ bool OmxDecoder::ToVideoFrame(VideoFrame
     break;
   case OMX_QCOM_COLOR_FormatYVU420SemiPlanar:
     SemiPlanarYVU420Frame(aFrame, aTimeUs, aData, aSize, aKeyFrame);
     break;
   case OMX_QCOM_COLOR_FormatYVU420PackedSemiPlanar32m4ka:
     SemiPlanarYVU420Packed32m4ka(aFrame, aTimeUs, aData, aSize, aKeyFrame);
     break;
   default:
-    LOG("Unknown video color format: %x", mVideoColorFormat);
+    LOG("Unknown video color format: %#x", mVideoColorFormat);
     return false;
   }
   return true;
 }
 
 bool OmxDecoder::ToAudioFrame(AudioFrame *aFrame, int64_t aTimeUs, void *aData, size_t aDataOffset, size_t aSize, int32_t aAudioChannels, int32_t aAudioSampleRate)
 {
   aFrame->Set(aTimeUs, reinterpret_cast<char *>(aData) + aDataOffset, aSize, aAudioChannels, aAudioSampleRate);
--- a/mobile/android/base/Favicons.java
+++ b/mobile/android/base/Favicons.java
@@ -264,17 +264,17 @@ public class Favicons {
         }
 
         // Runs in background thread
         private BitmapDrawable downloadFavicon(URL faviconUrl) {
             Log.d(LOGTAG, "Downloading favicon for URL = " + mPageUrl +
                           " with favicon URL = " + mFaviconUrl);
 
             if (mFaviconUrl.startsWith("jar:jar:")) {
-                return GeckoJarReader.getBitmapDrawable(mFaviconUrl);
+                return GeckoJarReader.getBitmapDrawable(GeckoApp.mAppContext.getResources(), mFaviconUrl);
             }
 
             URI uri;
             try {
                 uri = faviconUrl.toURI();
             } catch (URISyntaxException e) {
                 Log.d(LOGTAG, "Could not get URI for favicon URL: " + mFaviconUrl);
                 return null;
--- a/mobile/android/base/GeckoInputConnection.java
+++ b/mobile/android/base/GeckoInputConnection.java
@@ -526,19 +526,19 @@ class GeckoInputConnection
 
         if (changedText.length() == 1) {
             char changedChar = changedText.charAt(0);
 
             // Some IMEs (e.g. SwiftKey X) send a string with '\n' when Enter is pressed
             // Such string cannot be handled by Gecko, so we convert it to a key press instead
             if (changedChar == '\n') {
                 processKeyDown(KeyEvent.KEYCODE_ENTER, new KeyEvent(KeyEvent.ACTION_DOWN,
-                                                                    KeyEvent.KEYCODE_ENTER), false);
+                                                                    KeyEvent.KEYCODE_ENTER));
                 processKeyUp(KeyEvent.KEYCODE_ENTER, new KeyEvent(KeyEvent.ACTION_UP,
-                                                                  KeyEvent.KEYCODE_ENTER), false);
+                                                                  KeyEvent.KEYCODE_ENTER));
                 return;
             }
 
             // If we are committing a single character and didn't have an active composition string,
             // we can send Gecko keydown/keyup events instead of composition events.
             if (mCommittingText && !hasCompositionString() && sendKeyEventsToGecko(changedChar)) {
                 // Block this thread until all pending events are processed
                 GeckoAppShell.geckoEventSync();
@@ -850,33 +850,32 @@ class GeckoInputConnection
 
         resetCompositionState();
         return this;
     }
 
     public boolean onKeyPreIme(int keyCode, KeyEvent event) {
         switch (event.getAction()) {
             case KeyEvent.ACTION_DOWN:
-                return processKeyDown(keyCode, event, true);
+                return processKeyDown(keyCode, event);
             case KeyEvent.ACTION_UP:
-                return processKeyUp(keyCode, event, true);
+                return processKeyUp(keyCode, event);
             case KeyEvent.ACTION_MULTIPLE:
                 return onKeyMultiple(keyCode, event.getRepeatCount(), event);
         }
         return false;
     }
 
     public boolean onKeyDown(int keyCode, KeyEvent event) {
-        return processKeyDown(keyCode, event, false);
+        return processKeyDown(keyCode, event);
     }
 
-    private boolean processKeyDown(int keyCode, KeyEvent event, boolean isPreIme) {
+    private boolean processKeyDown(int keyCode, KeyEvent event) {
         if (DEBUG) {
-            Log.d(LOGTAG, "IME: processKeyDown(keyCode=" + keyCode + ", event=" + event + ", "
-                          + isPreIme + ")");
+            Log.d(LOGTAG, "IME: processKeyDown(keyCode=" + keyCode + ", event=" + event + ")");
             GeckoApp.assertOnUiThread();
         }
 
         if (keyCode > KeyEvent.getMaxKeyCode())
             return false;
 
         switch (keyCode) {
             case KeyEvent.KEYCODE_MENU:
@@ -895,21 +894,16 @@ class GeckoInputConnection
                 if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0 &&
                     mIMEActionHint.equalsIgnoreCase("next"))
                     event = new KeyEvent(event.getAction(), KeyEvent.KEYCODE_TAB);
                 break;
             default:
                 break;
         }
 
-        if (isPreIme && mIMEState != IME_STATE_DISABLED &&
-            (event.getMetaState() & KeyEvent.META_ALT_ON) != 0)
-            // Let active IME process pre-IME key events
-            return false;
-
         View view = getView();
         KeyListener keyListener = TextKeyListener.getInstance();
 
         // KeyListener returns true if it handled the event for us.
         if (mIMEState == IME_STATE_DISABLED ||
                 keyCode == KeyEvent.KEYCODE_ENTER ||
                 keyCode == KeyEvent.KEYCODE_DEL ||
                 keyCode == KeyEvent.KEYCODE_TAB ||
@@ -921,43 +915,37 @@ class GeckoInputConnection
                                                                      selection.start,
                                                                      selection.length));
             GeckoAppShell.sendEventToGecko(GeckoEvent.createKeyEvent(event));
         }
         return true;
     }
 
     public boolean onKeyUp(int keyCode, KeyEvent event) {
-        return processKeyUp(keyCode, event, false);
+        return processKeyUp(keyCode, event);
     }
 
-    private boolean processKeyUp(int keyCode, KeyEvent event, boolean isPreIme) {
+    private boolean processKeyUp(int keyCode, KeyEvent event) {
         if (DEBUG) {
-            Log.d(LOGTAG, "IME: processKeyUp(keyCode=" + keyCode + ", event=" + event + ", "
-                          + isPreIme + ")");
+            Log.d(LOGTAG, "IME: processKeyUp(keyCode=" + keyCode + ", event=" + event + ")");
             GeckoApp.assertOnUiThread();
         }
 
         if (keyCode > KeyEvent.getMaxKeyCode())
             return false;
 
         switch (keyCode) {
             case KeyEvent.KEYCODE_BACK:
             case KeyEvent.KEYCODE_SEARCH:
             case KeyEvent.KEYCODE_MENU:
                 return false;
             default:
                 break;
         }
 
-        if (isPreIme && mIMEState != IME_STATE_DISABLED &&
-            (event.getMetaState() & KeyEvent.META_ALT_ON) != 0)
-            // Let active IME process pre-IME key events
-            return false;
-
         View view = getView();
         KeyListener keyListener = TextKeyListener.getInstance();
 
         if (mIMEState == IME_STATE_DISABLED ||
             keyCode == KeyEvent.KEYCODE_ENTER ||
             keyCode == KeyEvent.KEYCODE_DEL ||
             (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 ||
             !keyListener.onKeyUp(view, mEditable, keyCode, event)) {
--- a/mobile/android/base/GeckoJarReader.java
+++ b/mobile/android/base/GeckoJarReader.java
@@ -1,14 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.util;
 
+import android.content.res.Resources;
 import android.graphics.drawable.BitmapDrawable;
 import android.util.Log;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.util.EmptyStackException;
@@ -20,28 +21,28 @@ import java.util.zip.ZipInputStream;
 /* Reads out of a multiple level deep jar file such as
  *  jar:jar:file:///data/app/org.mozilla.fennec.apk!/omni.ja!/chrome/chrome/content/branding/favicon32.png
  */
 public final class GeckoJarReader {
     private static String LOGTAG = "GeckoJarReader";
 
     private GeckoJarReader() {}
 
-    public static BitmapDrawable getBitmapDrawable(String url) {
+    public static BitmapDrawable getBitmapDrawable(Resources resources, String url) {
         Stack<String> jarUrls = parseUrl(url);
         InputStream inputStream = null;
         BitmapDrawable bitmap = null;
 
         ZipFile zip = null;
         try {
             // Load the initial jar file as a zip
             zip = getZipFile(jarUrls.pop());
             inputStream = getStream(zip, jarUrls);
             if (inputStream != null) {
-                bitmap = new BitmapDrawable(inputStream);
+                bitmap = new BitmapDrawable(resources, inputStream);
             }
         } catch (IOException ex) {
             Log.e(LOGTAG, "Exception ", ex);
         } finally {
             if (inputStream != null) {
                 try {
                     inputStream.close();
                 } catch(IOException ex) {
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -172,23 +172,23 @@ size. -->
 <!ENTITY button_clear_data "Clear data">
 
 <!ENTITY abouthome_addons_title "Add-ons for your &brandShortName;">
 <!ENTITY abouthome_addons_browse "Browse all &brandShortName; add-ons">
 <!ENTITY abouthome_last_tabs_title "Your tabs from last time">
 <!ENTITY abouthome_last_tabs_open "Open all tabs from last time">
 <!ENTITY abouthome_top_sites_title "Top sites">
 <!ENTITY abouthome_top_sites_browse "Browse all your top sites">
-<!-- Localization note (abouthome_about_sync2, abouthome_about_apps): The
+<!-- Localization note (abouthome_about_sync3, abouthome_about_apps2): The
      chevron (ex: "»"; unicode= U+00BB) is used as an arrow to show that
      clicking this text in the promotions box will perform some action. Note
      that a non-breaking space (unicode= U+00A0) should be used between this
      character and the remainder of the string to prevent word wrap. -->
-<!ENTITY abouthome_about_sync2 "Set up Firefox Sync to access bookmarks, history and tabs from your other devices »">
-<!ENTITY abouthome_about_apps "Get apps from the Mozilla Marketplace and discover the best the Web has to offer »">
+<!ENTITY abouthome_about_sync3 "Set up Firefox Sync to access bookmarks, history and tabs from your other devices&#x00A0;»">
+<!ENTITY abouthome_about_apps2 "Get apps from the Mozilla Marketplace and discover the best the Web has to offer&#x00A0;»">
 <!-- Localization note (abouthome_sync_bold_name, abouthome_apps_bold_name):
      These strings are accentuated as bold text in the "abouthome_about_..."
      strings above. These strings should be a subset of the strings above and
      generally be the name of the product the string describes. -->
 <!ENTITY abouthome_sync_bold_name "Firefox Sync">
 <!ENTITY abouthome_apps_bold_name "Mozilla Marketplace">
 
 <!ENTITY filepicker_title "Choose File">
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -165,18 +165,18 @@
   <string name="button_clear_data">&button_clear_data;</string>
 
   <string name="abouthome_addons_title">&abouthome_addons_title;</string>
   <string name="abouthome_addons_browse">&abouthome_addons_browse;</string>
   <string name="abouthome_last_tabs_title">&abouthome_last_tabs_title;</string>
   <string name="abouthome_last_tabs_open">&abouthome_last_tabs_open;</string>
   <string name="abouthome_top_sites_title">&abouthome_top_sites_title;</string>
   <string name="abouthome_top_sites_browse">&abouthome_top_sites_browse;</string>
-  <string name="abouthome_about_sync">&abouthome_about_sync2;</string>
-  <string name="abouthome_about_apps">&abouthome_about_apps;</string>
+  <string name="abouthome_about_sync">&abouthome_about_sync3;</string>
+  <string name="abouthome_about_apps">&abouthome_about_apps2;</string>
   <string name="abouthome_sync_bold_name">&abouthome_sync_bold_name;</string>
   <string name="abouthome_apps_bold_name">&abouthome_apps_bold_name;</string>
 
   <string name="filepicker_title">&filepicker_title;</string>
   <string name="filepicker_audio_title">&filepicker_audio_title;</string>
   <string name="filepicker_image_title">&filepicker_image_title;</string>
   <string name="filepicker_video_title">&filepicker_video_title;</string>
 
--- a/mobile/android/base/tests/testHistoryTab.java.in
+++ b/mobile/android/base/tests/testHistoryTab.java.in
@@ -29,16 +29,17 @@ import java.io.File;
 
 public class testHistoryTab extends PixelTest {
     private static final String ABOUT_HOME_URL = "about:home";
     private static final String OPEN_NEW_TAB = "Open in New Tab";
     private static final int WAIT_FOR_CHILD_TIMEOUT = 2000;
     private String[] bookmarks = new String[] {
         "http://mochi.test:8888/tests/robocop/robocop_blank_01.html"
     };
+    private View mFirstChild;
 
     @Override
     protected int getTestType() {
         return TEST_MOCHITEST;
     }
 
     public void testHistoryTab() {
         mActions.expectGeckoEvent("Gecko:Ready").blockForEvent();
@@ -125,75 +126,86 @@ public class testHistoryTab extends Pixe
         mActions.sendSpecialKey(Actions.SpecialKey.BACK);
         mSolo.waitForText(url);
 
         View child = list.getChildAt(0);
         mSolo.clickLongOnView(child);
         mAsserter.is(false, mSolo.waitForText("Open in New Tab"), "Header rows should not show a context menu");
 
         // wait for the history list to be populated
-        waitForTest(new BooleanTest() {
+        mFirstChild = null;
+        boolean success = waitForTest(new BooleanTest() {
             public boolean test() {
-                if (list.getChildAt(1) == null) {
+                mFirstChild = list.getChildAt(1);
+                if (mFirstChild == null) {
                     return false;
                 }
-                View firstChild = list.getChildAt(1);
-                if (firstChild instanceof android.view.ViewGroup) {
-                    ViewGroup group = (ViewGroup)firstChild;
+                if (mFirstChild instanceof android.view.ViewGroup) {
+                    ViewGroup group = (ViewGroup)mFirstChild;
                     if (group.getChildCount() < 1) {
                         return false;
                     }
                     for (int i = 0; i < group.getChildCount(); i++) {
                         View grandChild = group.getChildAt(i);
                         if (grandChild instanceof android.widget.TextView) {
                             mAsserter.ok(true, "found TextView:", ((android.widget.TextView)grandChild).getText().toString());
                         }
                     }
+                } else {
+                    mAsserter.dumpLog("first child not a ViewGroup: "+mFirstChild);
+                    return false;
                 }
                 return true;
             }
         }, WAIT_FOR_CHILD_TIMEOUT);
-        child = list.getChildAt(1);
-
-        mSolo.clickLongOnView(child);
+        if (success == true && mFirstChild != null) {
+            mAsserter.dumpLog("clickLongOnView: "+mFirstChild);
+            mSolo.clickLongOnView(mFirstChild);
 
-        // TODO: Test clicking these does the right thing
-        mAsserter.ok(mSolo.waitForText("Open in New Tab"), "Context menu has New Tab option", "Open in New Tab");
-        mAsserter.ok(mSolo.searchText("Share", true), "Context menu has Share option", "Share");
-        mAsserter.ok(mSolo.searchText("Remove", true), "Context menu has Remove option", "Remove");
-        mAsserter.ok(mSolo.searchText("Add to Home Screen", true), "Context menu has Add to Home Screen option", "Add to Home Screen");
+            // TODO: Test clicking these does the right thing
+            mAsserter.ok(mSolo.waitForText("Open in New Tab"), "Context menu has New Tab option", "Open in New Tab");
+            mAsserter.ok(mSolo.searchText("Share", true), "Context menu has Share option", "Share");
+            mAsserter.ok(mSolo.searchText("Remove", true), "Context menu has Remove option", "Remove");
+            mAsserter.ok(mSolo.searchText("Add to Home Screen", true), "Context menu has Add to Home Screen option", "Add to Home Screen");
 
-        mActions.sendSpecialKey(Actions.SpecialKey.BACK);
+            mActions.sendSpecialKey(Actions.SpecialKey.BACK);
+        } else {
+            mAsserter.ok(false, "waiting for history item", "history item available");
+        }
         mActions.sendSpecialKey(Actions.SpecialKey.BACK);
     }
 
     private void testClick(String url) {
         list = getHistoryList();
         // clear VKB
         mActions.sendSpecialKey(Actions.SpecialKey.BACK);
         mSolo.waitForText(url);
 
         View child = list.getChildAt(0);
         mSolo.clickOnView(child);
         // nothing should happen
 
         Actions.EventExpecter contentEventExpecter = mActions.expectGeckoEvent("DOMContentLoaded");
-        waitForTest(new BooleanTest() {
+        mFirstChild = null;
+        boolean success = waitForTest(new BooleanTest() {
             public boolean test() {
-                if (list.getChildAt(1) == null) {
+                mFirstChild = list.getChildAt(1);
+                if (mFirstChild == null) {
                     return false;
                 }
                 return true;
             }
         }, WAIT_FOR_CHILD_TIMEOUT);
-        child = list.getChildAt(1);
-
-        mSolo.clickOnView(child);
-        contentEventExpecter.blockForEvent();
-        verifyUrl(url);
+        if (success == true && mFirstChild != null) {
+            mSolo.clickOnView(mFirstChild);
+            contentEventExpecter.blockForEvent();
+            verifyUrl(url);
+        } else {
+            mAsserter.ok(false, "waiting for history item", "history item available");
+        }
     }
 
     private ListView getHistoryList() {
         Activity awesomeBarActivity = clickOnAwesomeBar();
         mSolo.clickOnText("History");
 
         TabHost tabHost = (TabHost)mSolo.getView(TabHost.class, 0);
         return (ListView)tabHost.getCurrentView();
--- a/toolkit/components/social/MozSocialAPI.jsm
+++ b/toolkit/components/social/MozSocialAPI.jsm
@@ -8,25 +8,32 @@ Cu.import("resource://gre/modules/Servic
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "SocialService", "resource://gre/modules/SocialService.jsm");
 
 const EXPORTED_SYMBOLS = ["MozSocialAPI"];
 
 var MozSocialAPI = {
   _enabled: false,
+  _everEnabled: false,
   set enabled(val) {
     let enable = !!val;
     if (enable == this._enabled) {
       return;
     }
     this._enabled = enable;
 
     if (enable) {
       Services.obs.addObserver(injectController, "document-element-inserted", false);
+
+      if (!this._everEnabled) {
+        this._everEnabled = true;
+        Services.telemetry.getHistogramById("SOCIAL_ENABLED_ON_SESSION").add(true);
+      }
+
     } else {
       Services.obs.removeObserver(injectController, "document-element-inserted", false);
     }
   }
 };
 
 // Called on document-element-inserted, checks that the API should be injected,
 // and then calls attachToWindow as appropriate
@@ -107,16 +114,31 @@ function attachToWindow(provider, target
       enumerable: true,
       configurable: true,
       writable: true,
       value: function(toURL, callback) {
         let url = targetWindow.document.documentURIObject.resolve(toURL);
         openChatWindow(getChromeWindow(targetWindow), provider, url, callback);
       }
     },
+    openPanel: {
+      enumerable: true,
+      configurable: true,
+      writable: true,
+      value: function(toURL, offset, callback) {
+        let chromeWindow = getChromeWindow(targetWindow);
+        if (!chromeWindow.SocialFlyout)
+          return;
+        let url = targetWindow.document.documentURIObject.resolve(toURL);
+        let fullURL = ensureProviderOrigin(provider, url);
+        if (!fullURL)
+          return;
+        chromeWindow.SocialFlyout.open(fullURL, offset, callback);
+      }
+    },
     getAttention: {
       enumerable: true,
       configurable: true,
       writable: true,
       value: function() {
         getChromeWindow(targetWindow).getAttention();
       }
     },
@@ -214,16 +236,19 @@ function openServiceWindow(provider, con
   // Get the newly opened window's containing XUL window
   chromeWindow = getChromeWindow(serviceWindow);
 
   // set the window's name and origin attribute on its browser, so that it can
   // be found via getWindowByName
   chromeWindow.name = windowName;
   chromeWindow.gBrowser.selectedBrowser.setAttribute("origin", provider.origin);
 
+  // disable global history for the new window.
+  chromeWindow.gBrowser.docShell.QueryInterface(Components.interfaces.nsIDocShellHistory).useGlobalHistory = false;
+
   // we dont want the default title the browser produces, we'll fixup whenever
   // it changes.
   serviceWindow.addEventListener("DOMTitleChanged", function() {
     let sep = xulWindow.document.documentElement.getAttribute("titlemenuseparator");
     xulWindow.document.title = provider.name + sep + serviceWindow.document.title;
   });
 
   return serviceWindow;
--- a/toolkit/components/social/SocialService.jsm
+++ b/toolkit/components/social/SocialService.jsm
@@ -92,16 +92,17 @@ const SocialService = {
     Services.prefs.setBoolPref("social.enabled", enable);
     this._setEnabled(enable);
   },
   _setEnabled: function _setEnabled(enable) {
     SocialServiceInternal.providerArray.forEach(function (p) p.enabled = enable);
     SocialServiceInternal.enabled = enable;
     MozSocialAPI.enabled = enable;
     Services.obs.notifyObservers(null, "social:pref-changed", enable ? "enabled" : "disabled");
+    Services.telemetry.getHistogramById("SOCIAL_TOGGLED").add(enable);
   },
 
   // Adds a provider given a manifest, and returns the added provider.
   addProvider: function addProvider(manifest, onDone) {
     if (SocialServiceInternal.providers[manifest.origin])
       throw new Error("SocialService.addProvider: provider with this origin already exists");
 
     let provider = new SocialProvider(manifest, SocialServiceInternal.enabled);
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -2189,10 +2189,18 @@
     "kind": "flag",
     "description": "Killed due to an OOM condition",
     "cpp_guard": "ANDROID"
   },
   "SECURITY_UI": {
     "kind": "enumerated",
     "n_values": 100,
     "description": "Security UI Telemetry"
+  },
+  "SOCIAL_ENABLED_ON_SESSION": {
+    "kind": "flag",
+    "description": "Social has been enabled at least once on the current session"
+  },
+  "SOCIAL_TOGGLED": {
+    "kind": "boolean",
+    "description": "Social has been toggled to on or off"
   }
 }
--- a/toolkit/mozapps/installer/packager.mk
+++ b/toolkit/mozapps/installer/packager.mk
@@ -713,17 +713,16 @@ else
 PKGCP_OS = unix
 endif
 
 # The following target stages files into two directories: one directory for
 # core files, and one for optional extensions based on the information in
 # the MOZ_PKG_MANIFEST file and the following vars:
 # MOZ_NONLOCALIZED_PKG_LIST
 # MOZ_LOCALIZED_PKG_LIST
-# MOZ_OPTIONAL_PKG_LIST
 
 PKG_ARG = , "$(pkg)"
 
 # Define packager macro to work around make 3.81 backslash issue (bug #339933)
 
 # Controls whether missing file warnings should be fatal
 ifndef MOZ_PKG_FATAL_WARNINGS
 MOZ_PKG_FATAL_WARNINGS = 0
@@ -744,29 +743,16 @@ endif
 ifdef MOZ_OMNIJAR
 	@(cd $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && $(PACK_OMNIJAR))
 ifdef MOZ_WEBAPP_RUNTIME
 	@(cd $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/webapprt && $(PACK_OMNIJAR_WEBAPP_RUNTIME))
 endif
 endif
 	@cp -av $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/. $(DEPTH)/installer-stage/core
 	@(cd $(DEPTH)/installer-stage/core && $(CREATE_PRECOMPLETE_CMD))
-ifdef MOZ_OPTIONAL_PKG_LIST
-	@$(NSINSTALL) -D $(DEPTH)/installer-stage/optional
-	$(call PACKAGER_COPY, "$(call core_abspath,$(DIST))",\
-	  "$(call core_abspath,$(DEPTH)/installer-stage/optional)", \
-	  "$(MOZ_PKG_MANIFEST)", "$(PKGCP_OS)", 1, 0, 1 \
-	  $(foreach pkg,$(MOZ_OPTIONAL_PKG_LIST),$(PKG_ARG)) )
-	if test -d $(DEPTH)/installer-stage/optional/extensions ; then \
-		cd $(DEPTH)/installer-stage/optional/extensions; find -maxdepth 1 -mindepth 1 -exec rm -r ../../core/extensions/{} \; ; \
-	fi
-	if test -d $(DEPTH)/installer-stage/optional/distribution/extensions/ ; then \
-		cd $(DEPTH)/installer-stage/optional/distribution/extensions/; find -maxdepth 1 -mindepth 1 -exec rm -r ../../../core/distribution/extensions/{} \; ; \
-	fi
-endif
 ifdef MOZ_SIGN_PREPARED_PACKAGE_CMD
 	$(MOZ_SIGN_PREPARED_PACKAGE_CMD) $(DEPTH)/installer-stage
 endif
 
 elfhack:
 ifdef USE_ELF_HACK
 	@echo ===
 	@echo === If you get failures below, please file a bug describing the error
--- a/toolkit/system/gnome/Makefile.in
+++ b/toolkit/system/gnome/Makefile.in
@@ -10,18 +10,22 @@ VPATH	  = @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= mozgnome
 LIBRARY_NAME	= mozgnome
 FORCE_SHARED_LIB = 1
 IS_COMPONENT	= 1
 
 
-CPPSRCS = nsGnomeModule.cpp
-	
+CPPSRCS = \
+  nsGnomeModule.cpp \
+  nsAlertsService.cpp \
+  nsAlertsIconListener.cpp \
+  $(NULL)
+
 ifdef MOZ_ENABLE_GCONF
 CPPSRCS += \
   nsGConfService.cpp \
   $(NULL)
 endif
 
 ifdef MOZ_ENABLE_GNOMEVFS
 CPPSRCS += \
@@ -31,38 +35,29 @@ endif
 
 ifdef MOZ_ENABLE_GIO
 CPPSRCS += \
 	nsGIOService.cpp \
 	nsGSettingsService.cpp \
 	$(NULL)
 endif
 
-ifdef MOZ_ENABLE_LIBNOTIFY
-CPPSRCS += \
-	nsAlertsService.cpp \
-	nsAlertsIconListener.cpp \
-	$(NULL)
-endif
-
 EXTRA_DSO_LDOPTS += \
 		$(XPCOM_GLUE_LDOPTS) \
 		$(XPCOM_FROZEN_LDOPTS) \
 		$(NSPR_LIBS) \
 		$(MOZ_GCONF_LIBS) \
 		$(MOZ_GNOMEVFS_LIBS) \
 		$(GLIB_LIBS) \
-		$(MOZ_LIBNOTIFY_LIBS) \
 		$(MOZ_GIO_LIBS) \
 		$(NULL)
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/components/build/
 
 include $(topsrcdir)/config/rules.mk
 
 CXXFLAGS += \
 	$(MOZ_GCONF_CFLAGS) \
 	$(MOZ_GNOMEVFS_CFLAGS) \
 	$(MOZ_GIO_CFLAGS) \
 	$(GLIB_CFLAGS) \
-	$(MOZ_LIBNOTIFY_CFLAGS) \
 	$(MOZ_GTK2_CFLAGS) \
 	$(NULL)
--- a/toolkit/system/gnome/nsAlertsIconListener.cpp
+++ b/toolkit/system/gnome/nsAlertsIconListener.cpp
@@ -8,26 +8,32 @@
 #include "imgILoader.h"
 #include "imgIRequest.h"
 #include "nsNetUtil.h"
 #include "nsIImageToPixbuf.h"
 #include "nsIStringBundle.h"
 #include "nsIObserverService.h"
 #include "nsCRT.h"
 
+#include <dlfcn.h>
 #include <gdk/gdk.h>
 
-// Compatibility macro for <libnotify-0.7
-#ifndef NOTIFY_CHECK_VERSION
-#define NOTIFY_CHECK_VERSION(x,y,z) 0
-#endif
-
 static bool gHasActions = false;
 static bool gHasCaps = false;
 
+void* nsAlertsIconListener::libNotifyHandle = nullptr;
+bool nsAlertsIconListener::libNotifyNotAvail = false;
+nsAlertsIconListener::notify_is_initted_t nsAlertsIconListener::notify_is_initted = nullptr;
+nsAlertsIconListener::notify_init_t nsAlertsIconListener::notify_init = nullptr;
+nsAlertsIconListener::notify_get_server_caps_t nsAlertsIconListener::notify_get_server_caps = nullptr;
+nsAlertsIconListener::notify_notification_new_t nsAlertsIconListener::notify_notification_new = nullptr;
+nsAlertsIconListener::notify_notification_show_t nsAlertsIconListener::notify_notification_show = nullptr;
+nsAlertsIconListener::notify_notification_set_icon_from_pixbuf_t nsAlertsIconListener::notify_notification_set_icon_from_pixbuf = nullptr;
+nsAlertsIconListener::notify_notification_add_action_t nsAlertsIconListener::notify_notification_add_action = nullptr;
+
 static void notify_action_cb(NotifyNotification *notification,
                              gchar *action, gpointer user_data)
 {
   nsAlertsIconListener* alert = static_cast<nsAlertsIconListener*> (user_data);
   alert->SendCallback();
 }
 
 static void notify_closed_marshal(GClosure* closure,
@@ -47,22 +53,45 @@ static void notify_closed_marshal(GClosu
 
 NS_IMPL_ISUPPORTS4(nsAlertsIconListener, imgIContainerObserver,
                    imgIDecoderObserver, nsIObserver, nsISupportsWeakReference)
 
 nsAlertsIconListener::nsAlertsIconListener()
 : mLoadedFrame(false),
   mNotification(NULL)
 {
+  if (!libNotifyHandle && !libNotifyNotAvail) {
+    libNotifyHandle = dlopen("libnotify.so.4", RTLD_LAZY);
+    if (!libNotifyHandle) {
+      libNotifyHandle = dlopen("libnotify.so.1", RTLD_LAZY);
+      if (!libNotifyHandle) {
+        libNotifyNotAvail = true;
+        return;
+      }
+    }
+
+    notify_is_initted = (notify_is_initted_t)dlsym(libNotifyHandle, "notify_is_initted");
+    notify_init = (notify_init_t)dlsym(libNotifyHandle, "notify_init");
+    notify_get_server_caps = (notify_get_server_caps_t)dlsym(libNotifyHandle, "notify_get_server_caps");
+    notify_notification_new = (notify_notification_new_t)dlsym(libNotifyHandle, "notify_notification_new");
+    notify_notification_show = (notify_notification_show_t)dlsym(libNotifyHandle, "notify_notification_show");
+    notify_notification_set_icon_from_pixbuf = (notify_notification_set_icon_from_pixbuf_t)dlsym(libNotifyHandle, "notify_notification_set_icon_from_pixbuf");
+    notify_notification_add_action = (notify_notification_add_action_t)dlsym(libNotifyHandle, "notify_notification_add_action");
+    if (!notify_is_initted || !notify_init || !notify_get_server_caps || !notify_notification_new || !notify_notification_show || !notify_notification_set_icon_from_pixbuf || !notify_notification_add_action) {
+      dlclose(libNotifyHandle);
+      libNotifyHandle = nullptr;
+    }
+  }
 }
 
 nsAlertsIconListener::~nsAlertsIconListener()
 {
   if (mIconRequest)
     mIconRequest->CancelAndForgetObserver(NS_BINDING_ABORTED);
+  // Don't dlclose libnotify as it uses atexit().
 }
 
 NS_IMETHODIMP
 nsAlertsIconListener::OnStartRequest(imgIRequest* aRequest)
 {
   return NS_OK;
 }
 
@@ -180,24 +209,17 @@ nsAlertsIconListener::OnStopFrame(imgIRe
 
   mLoadedFrame = true;
   return NS_OK;
 }
 
 nsresult
 nsAlertsIconListener::ShowAlert(GdkPixbuf* aPixbuf)
 {
-  mNotification = notify_notification_new(mAlertTitle.get(),
-                                          mAlertText.get(),
-                                          NULL
-// >=libnotify-0.7.0 has no support for attaching to widgets
-#if !NOTIFY_CHECK_VERSION(0,7,0)
-                                          , NULL
-#endif
-                                          );
+  mNotification = notify_notification_new(mAlertTitle.get(), mAlertText.get(), NULL, NULL);
 
   if (!mNotification)
     return NS_ERROR_OUT_OF_MEMORY;
 
   if (aPixbuf)
     notify_notification_set_icon_from_pixbuf(mNotification, aPixbuf);
 
   NS_ADDREF(this);
@@ -279,16 +301,19 @@ nsAlertsIconListener::Observe(nsISupport
 nsresult
 nsAlertsIconListener::InitAlertAsync(const nsAString & aImageUrl,
                                      const nsAString & aAlertTitle, 
                                      const nsAString & aAlertText,
                                      bool aAlertTextClickable,
                                      const nsAString & aAlertCookie,
                                      nsIObserver * aAlertListener)
 {
+  if (!libNotifyHandle)
+    return NS_ERROR_FAILURE;
+
   if (!notify_is_initted()) {
     // Give the name of this application to libnotify
     nsCOMPtr<nsIStringBundleService> bundleService = 
       do_GetService(NS_STRINGBUNDLE_CONTRACTID);
 
     nsCAutoString appShortName;
     if (bundleService) {
       nsCOMPtr<nsIStringBundle> bundle;
--- a/toolkit/system/gnome/nsAlertsIconListener.h
+++ b/toolkit/system/gnome/nsAlertsIconListener.h
@@ -8,20 +8,21 @@
 
 #include "nsCOMPtr.h"
 #include "imgIDecoderObserver.h"
 #include "nsStringAPI.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
-#include <libnotify/notify.h>
 
 class imgIRequest;
 
+struct NotifyNotification;
+
 class nsAlertsIconListener : public imgIDecoderObserver,
                              public nsIObserver,
                              public nsSupportsWeakReference
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGICONTAINEROBSERVER
   NS_DECL_IMGIDECODEROBSERVER
@@ -36,26 +37,50 @@ public:
                           bool aAlertTextClickable,
                           const nsAString & aAlertCookie,
                           nsIObserver * aAlertListener);
 
   void SendCallback();
   void SendClosed();
 
 protected:
+  /**
+   * The only difference between libnotify.so.4 and libnotify.so.1 for these symbols
+   * is that notify_notification_new takes three arguments in libnotify.so.4 and
+   * four in libnotify.so.1.
+   * Passing the fourth argument as NULL is binary compatible.
+   */
+  typedef void (*NotifyActionCallback)(NotifyNotification*, char*, gpointer);
+  typedef bool (*notify_is_initted_t)(void);
+  typedef bool (*notify_init_t)(const char*);
+  typedef GList* (*notify_get_server_caps_t)(void);
+  typedef NotifyNotification* (*notify_notification_new_t)(const char*, const char*, const char*, const char*);
+  typedef bool (*notify_notification_show_t)(void*, char*);
+  typedef void (*notify_notification_set_icon_from_pixbuf_t)(void*, GdkPixbuf*);
+  typedef void (*notify_notification_add_action_t)(void*, const char*, const char*, NotifyActionCallback, gpointer, GFreeFunc);
+
   nsCOMPtr<imgIRequest> mIconRequest;
   nsCString mAlertTitle;
   nsCString mAlertText;
 
   nsCOMPtr<nsIObserver> mAlertListener;
   nsString mAlertCookie;
 
   bool mLoadedFrame;
   bool mAlertHasAction;
 
+  static void* libNotifyHandle;
+  static bool libNotifyNotAvail;
+  static notify_is_initted_t notify_is_initted;
+  static notify_init_t notify_init;
+  static notify_get_server_caps_t notify_get_server_caps;
+  static notify_notification_new_t notify_notification_new;
+  static notify_notification_show_t notify_notification_show;
+  static notify_notification_set_icon_from_pixbuf_t notify_notification_set_icon_from_pixbuf;
+  static notify_notification_add_action_t notify_notification_add_action;
   NotifyNotification* mNotification;
   gulong mClosureHandler;
 
   nsresult StartRequest(const nsAString & aImageUrl);
   nsresult ShowAlert(GdkPixbuf* aPixbuf);
 };
 
 #endif
--- a/toolkit/system/gnome/nsGnomeModule.cpp
+++ b/toolkit/system/gnome/nsGnomeModule.cpp
@@ -17,67 +17,59 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGC
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGnomeVFSService, Init)
 #endif
 #ifdef MOZ_ENABLE_GIO
 #include "nsGIOService.h"
 #include "nsGSettingsService.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsGIOService)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGSettingsService, Init)
 #endif
-#ifdef MOZ_ENABLE_LIBNOTIFY
 #include "nsAlertsService.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAlertsService, Init)
-#endif
 
 #ifdef MOZ_ENABLE_GCONF
 NS_DEFINE_NAMED_CID(NS_GCONFSERVICE_CID);
 #endif
 #ifdef MOZ_ENABLE_GNOMEVFS
 NS_DEFINE_NAMED_CID(NS_GNOMEVFSSERVICE_CID);
 #endif
 #ifdef MOZ_ENABLE_GIO
 NS_DEFINE_NAMED_CID(NS_GIOSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_GSETTINGSSERVICE_CID);
 #endif
-#ifdef MOZ_ENABLE_LIBNOTIFY
 NS_DEFINE_NAMED_CID(NS_SYSTEMALERTSSERVICE_CID);
-#endif
 
 
 static const mozilla::Module::CIDEntry kGnomeCIDs[] = {
 #ifdef MOZ_ENABLE_GCONF
   { &kNS_GCONFSERVICE_CID, false, NULL, nsGConfServiceConstructor },
 #endif
 #ifdef MOZ_ENABLE_GNOMEVFS
   { &kNS_GNOMEVFSSERVICE_CID, false, NULL, nsGnomeVFSServiceConstructor },
 #endif
 #ifdef MOZ_ENABLE_GIO
   { &kNS_GIOSERVICE_CID, false, NULL, nsGIOServiceConstructor },
   { &kNS_GSETTINGSSERVICE_CID, false, NULL, nsGSettingsServiceConstructor },
 #endif
-#ifdef MOZ_ENABLE_LIBNOTIFY
   { &kNS_SYSTEMALERTSSERVICE_CID, false, NULL, nsAlertsServiceConstructor },
-#endif
   { NULL }
 };
 
 static const mozilla::Module::ContractIDEntry kGnomeContracts[] = {
 #ifdef MOZ_ENABLE_GCONF
   { NS_GCONFSERVICE_CONTRACTID, &kNS_GCONFSERVICE_CID },
 #endif
 #ifdef MOZ_ENABLE_GNOMEVFS
   { NS_GNOMEVFSSERVICE_CONTRACTID, &kNS_GNOMEVFSSERVICE_CID },
 #endif
 #ifdef MOZ_ENABLE_GIO
   { NS_GIOSERVICE_CONTRACTID, &kNS_GIOSERVICE_CID },
   { NS_GSETTINGSSERVICE_CONTRACTID, &kNS_GSETTINGSSERVICE_CID },
 #endif
-#ifdef MOZ_ENABLE_LIBNOTIFY
   { NS_SYSTEMALERTSERVICE_CONTRACTID, &kNS_SYSTEMALERTSSERVICE_CID },
-#endif
   { NULL }
 };
 
 static nsresult
 InitGType ()
 {
   g_type_init();
   return NS_OK;