Merge the last PGO-green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Sat, 25 Aug 2012 11:42:21 -0400
changeset 105416 e874475efe15461988861e6172417b7b09fd7b62
parent 105390 ead893fc780c8e4c1fa43a4c688d75e725709448 (current diff)
parent 105415 54fdedb218f858cda41f4c45d91dc8ee46d998e5 (diff)
child 105446 bc23ba35391382a3de4dd325ad6baaaa88292ec3
child 105476 36f85f213ee28ce22a753c963d971408674cbfb1
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
milestone17.0a1
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..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index ed59312c14252fe9c7f37e902285d652cbb09359..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 451b83b3b9bfde3ffba768feba91566bea92210d..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
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;