Merge the last PGO-green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Sat, 14 Jul 2012 22:56:29 -0400
changeset 99356 648510be4091b9e31bcb95982b5fb2667517e98f
parent 99355 2b1f3007410005999822584f81da8762ee3ac6c0 (current diff)
parent 99330 5b5f4f615e007d9b512d235c086eabd426510743 (diff)
child 99357 57abb5f70e019cbd6d5261386ca35371b7849d47
push id11959
push userryanvm@gmail.com
push dateSun, 15 Jul 2012 12:40:42 +0000
treeherdermozilla-inbound@f4ce0394ab10 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone16.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge the last PGO-green inbound changeset to m-c.
--- a/accessible/tests/mochitest/events/test_focus_autocomplete.xul
+++ b/accessible/tests/mochitest/events/test_focus_autocomplete.xul
@@ -225,17 +225,17 @@
             var itemX = {}, itemY = {}, treeX = {}, treeY = {};
             accessible.getBounds(itemX, itemY, {}, {});
             tree.getBounds(treeX, treeY, {}, {});
             x = itemX.value - treeX.value;
             y = itemY.value - treeY.value;
           }
         }
 
-        synthesizeMouse(node, x + 1, y + 1, {}, targetWindow);
+        synthesizeMouseAtCenter(node, {}, targetWindow);
       }
 
       this.getID = function selectByClick_getID()
       {
         return "select by click " + prettyName(aIDFunc.call(null, aIDFuncArg));
       }
     }
 
index bb9cdf30a0ce9f4598513ca47ea93c54eeb5f52d..433c25e1a39d85ef3c4545b7e0f6dd0c6baab724
GIT binary patch
literal 236
zc$@+302BX-P)<h;3K|Lk000e1NJLTq000mG000UI1^@s6y}sU@00029Nkl<ZC{vw~
zy$ZrG6h=EZ2)?jm27epH$=4BG9r_L;R*J=%8c47q*L=Z%f=$H>r$ag4p)?_)1h-uA
z(VS13SvsZ|aNuI&w|Fqddg)^NP)bqP!GVhny#@O2rGX%&jDmxU&DVesB1&hVs;*I5
z1McS-Yb}-KB?=t49|6w!AOwoy93=#>@d5WaLkDelo0F7x%JbviacHBiZ{Eemu||N5
mX*^o%p9ns-2xPC?KV(lIVEPvZT@;D{0000<MNUMnLSTaKI$&D>
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -1285,26 +1285,27 @@ toolbar[iconsize="small"] #feed-button {
 .ac-result-type-tag,
 .autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) {
   list-style-image: url("chrome://browser/skin/places/tag.png");
   width: 16px;
   height: 16px;
 }
 
 .ac-comment {
-  font-size: 1.15em;
+  font-size: 1.05em;
 }
 
 .ac-extra > .ac-comment {
   font-size: inherit;
 }
 
 .ac-url-text,
 .ac-action-text {
   color: -moz-nativehyperlinktext;
+  font-size: 0.9em;
 }
 
 richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
   list-style-image: url("chrome://browser/skin/actionicon-tab.png");
   padding: 0 3px;
 }
 
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
index ae2c789cbd2ecbc57ff8dbb40940a04f5f3d50d8..ab78613132887820625051be89da9a706e4b0cfe
GIT binary patch
literal 645
zc$@)+0($+4P)<h;3K|Lk000e1NJLTq001BW000&U1^@s6p;?|p0006^Nkl<ZNQuRi
z&5Ke|7{+f+?u1q?%6<EiOp#_G`L(`&3}(6za-j<sB8r<RC<rEE{sf~d6f-0<+7QvM
zAf1`Q0%>T5`CwuwsA-(l2-^D$=Ufie*twlWi=TSWeSWWx_nxaZ8jUpI_xsO;!{NJ$
zM52{SrCRB9x+#J+oI?g#?m3;#X`j!x7zhNKR)7On<AXw>(EVI4H&>}t>eXu1_!Bsn
z&*$f;#0>Y`Zuf&oBr;0{4Js-HvT)#<1>*7eLa9`$m&;{i9LP|%$vv0L<qigewPZ5+
zIFrd3G9U{Fu2`T|EEWwJkmVlmcsv(kvDnjWHfzX$EIF6pnnR+|XtPi#7&0I$7Vvt#
zCv{z4pxa}}fGjySvw+F~)gPdI2~}^Q@+MN<#LAD6>SL_@N22;iriu6Qf1ugy=Z>I*
zv&17}m-uoFyDWn&_Zr04G0t(oX_y6u!{IC~d?vR4!VYEUd4c}H0SfF$c)!hoD;C(I
z#SKZe*(IFlEWN#UcsS_N=S>U#CLFlpEkJ=!l5FuSK-e4e&vZ6e*56os{&EVgSYVy#
zNwO{!(5{AcI~}iC@YklU-#87IfB6LQk?2Z-tc@37GgdA5tK^&z3tT2X5G#_r9}EUp
zeksti;P<!(agsLR3wrMmZzSn3XHwY2@94NK;Ud#D3(#(?vBg&wX~X4%_I~Ww*__v7
z9Gq+K_xn%G0(4Mgmu1N!D{%RsTX&`}e*3=nkk*&SILpY~ynWAU7N8dgasD512>ala
f<SYlv9(g|jcN*i;D;K{P00000NkvXXu0mjf3lB0;
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -1109,17 +1109,17 @@ toolbar[mode="icons"] #zoom-in-button {
 .ac-result-type-keyword,
 .autocomplete-treebody::-moz-tree-image(keyword, treecolAutoCompleteImage) {
   list-style-image: url(chrome://global/skin/icons/search-textbox.png);
   margin: 2px;
   width: 12px;
   height: 12px;
 }
 
-richlistitem[selected="true"][current="true"] > hbox > .ac-result-type-bookmark,
+richlistitem[selected="true"][current="true"] > .ac-title-box > .ac-result-type-bookmark,
 .autocomplete-treebody::-moz-tree-image(selected, current, bookmark, treecolAutoCompleteImage) {
   list-style-image: url("chrome://browser/skin/places/star-icons.png");
   -moz-image-region: rect(0, 64px, 16px, 48px);
 }
 
 .ac-result-type-tag,
 .autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) {
   list-style-image: url("chrome://browser/skin/places/tag.png");
@@ -1134,30 +1134,30 @@ richlistitem[selected="true"][current="t
 .ac-url-text,
 .ac-action-text {
   color: -moz-nativehyperlinktext;
   font: message-box;
 }
 
 richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
   list-style-image: url("chrome://browser/skin/actionicon-tab.png");
-  -moz-image-region: rect(0, 16px, 16px, 0);
+  -moz-image-region: rect(0, 16px, 11px, 0);
   padding: 0 3px;
 }
 
 richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-box > .ac-action-icon {
-  -moz-image-region: rect(16px, 16px, 32px, 0);
+  -moz-image-region: rect(11px, 16px, 22px, 0);
 }
 
 window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
-  -moz-image-region: rect(0, 32px, 16px, 16px);
+  -moz-image-region: rect(0, 32px, 11px, 16px);
 }
 
 window[tabsontop="false"] richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-box > .ac-action-icon {
-  -moz-image-region: rect(16px, 32px, 32px, 16px);
+  -moz-image-region: rect(11px, 32px, 22px, 16px);
 }
 
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: GrayText;
 }
 
 .ac-comment[selected="true"],
 .ac-url-text[selected="true"],
index f60f218e724db02776b92175919cf553ec007191..ced958ebbe39646e15fef004e6c1a5bb3f2f21f5
GIT binary patch
literal 425
zc$@*L0apHrP)<h;3K|Lk000e1NJLTq000mG000&U1^@s6$*LTD0004SNkl<ZIE|gt
zT}#4X7zW@M#E$v{=6QdiqwFZ?w{;RhK_5i1nn_}2t0sPoRf;(0&=f^5ORbO&^C%}i
zJ&&klTlLO^3+KE0zR`&c02nz8WxU51TI4)l?njggM3m|e6`*^Rq3pQF#uq|38;hpu
zpz3Y7&A-^9d(reGU{<vZ1m)sqGTQ`2YyF8b!Dz8>890**5YIeup{!-#^vVGFzRrcR
zQv+Lq;u0@)kklF%QOW~$<|YH1M~M|tG9a9&aPeanJFCNijf2?QULe&BTo>@+l(<lK
zKag%xmj;qTI5#|Wf;!Y?>$^Ad_K6BR{yRsgL*2=*Fe~PsUl_tS9wed;djCadl<`;w
z27^He58hDwAFr5|>;_tR@XV=g_Z4WM&Z%WL&_GpAji~{=aG@G{;6z#X_kkr;Mh2&n
zX`0L9|AG%6U;<xrD9b4~>iAf%X9{?sp|nF9b=gO^D~vvt?vO!UdIny!I3w>D%N<S~
T8or7A00000NkvXXu0mjf^CG#N
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -1484,57 +1484,64 @@ html|*.urlbar-input:-moz-lwtheme:-moz-pl
 .ac-result-type-tag,
 .autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) {
   list-style-image: url("chrome://browser/skin/places/tag.png");
   width: 16px;
   height: 16px;
 }
 
 .ac-comment {
-  font-size: 1.15em;
+  font-size: 1.06em;
 }
 
 .ac-extra > .ac-comment {
-  font-size: inherit;
+  font-size: 1em;
 }
 
 .ac-url-text,
 .ac-action-text {
+  font-size: 1em;
   color: -moz-nativehyperlinktext;
 }
 
 %ifndef WINSTRIPE_AERO
 @media (-moz-windows-default-theme) {
-  .ac-url-text,
-  .ac-action-text {
-    color: #006600;
+  .ac-url-text:not([selected="true"]),
+  .ac-action-text:not([selected="true"]) {
+    color: #008800;
   }
 }
 %endif
 
 richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
   list-style-image: url("chrome://browser/skin/actionicon-tab.png");
-  -moz-image-region: rect(0, 16px, 16px, 0);
+  -moz-image-region: rect(0, 16px, 11px, 0);
   padding: 0 3px;
 }
 
-richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-box > .ac-action-icon {
-  -moz-image-region: rect(16px, 16px, 32px, 0);
-}
+%ifdef WINSTRIPE_AERO
+@media not all and (-moz-windows-default-theme) {
+%endif
+  richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-box > .ac-action-icon {
+    -moz-image-region: rect(11px, 16px, 22px, 0);
+  }
+
+  .ac-comment[selected="true"],
+  .ac-url-text[selected="true"],
+  .ac-action-text[selected="true"] {
+    color: inherit !important;
+  }
+%ifdef WINSTRIPE_AERO
+}
+%endif
 
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: GrayText;
 }
 
-.ac-comment[selected="true"],
-.ac-url-text[selected="true"],
-.ac-action-text[selected="true"] {
-  color: inherit !important;
-}
-
 .autocomplete-treebody::-moz-tree-cell-text(suggesthint, treecolAutoCompleteComment),
 .autocomplete-treebody::-moz-tree-cell-text(suggestfirst, treecolAutoCompleteComment)
 {
   color: GrayText;
   font-size: smaller;
 }
 
 .autocomplete-treebody::-moz-tree-cell(suggesthint) {
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -550,16 +550,17 @@ nsHTMLDocument::StartDocumentLoad(const 
     MOZ_ASSERT(false, "Bad parser command");
     return NS_ERROR_INVALID_ARG;
   }
 
   bool html = contentType.EqualsLiteral(TEXT_HTML);
   bool xhtml = !html && contentType.EqualsLiteral(APPLICATION_XHTML_XML);
   bool plainText = !html && !xhtml && (contentType.EqualsLiteral(TEXT_PLAIN) ||
     contentType.EqualsLiteral(TEXT_CSS) ||
+    contentType.EqualsLiteral(TEXT_CACHE_MANIFEST) ||
     contentType.EqualsLiteral(APPLICATION_JAVASCRIPT) ||
     contentType.EqualsLiteral(APPLICATION_XJAVASCRIPT) ||
     contentType.EqualsLiteral(TEXT_ECMASCRIPT) ||
     contentType.EqualsLiteral(APPLICATION_ECMASCRIPT) ||
     contentType.EqualsLiteral(TEXT_JAVASCRIPT) ||
     contentType.EqualsLiteral(APPLICATION_JSON));
   if (!(html || xhtml || plainText || viewSource)) {
     MOZ_ASSERT(false, "Channel with bad content type.");
--- a/ipc/chromium/src/chrome/common/child_process_host.cc
+++ b/ipc/chromium/src/chrome/common/child_process_host.cc
@@ -175,16 +175,19 @@ void ChildProcessHost::ListenerHook::OnC
   host_->Notify(NotificationType::CHILD_PROCESS_HOST_CONNECTED);
 }
 
 void ChildProcessHost::ListenerHook::OnChannelError() {
   host_->opening_channel_ = false;
   host_->OnChannelError();
 }
 
+void ChildProcessHost::ListenerHook::GetQueuedMessages(std::queue<IPC::Message>& queue) {
+  host_->GetQueuedMessages(queue);
+}
 
 ChildProcessHost::Iterator::Iterator() : all_(true) {
   iterator_ = Singleton<ChildProcessList>::get()->begin();
 }
 
 ChildProcessHost::Iterator::Iterator(ProcessType type)
     : all_(false), type_(type) {
   iterator_ = Singleton<ChildProcessList>::get()->begin();
--- a/ipc/chromium/src/chrome/common/child_process_host.h
+++ b/ipc/chromium/src/chrome/common/child_process_host.h
@@ -94,16 +94,17 @@ class ChildProcessHost :
   // OnMessageReceived/OnChannelConnected and do our own processing before
   // calling the subclass' implementation.
   class ListenerHook : public IPC::Channel::Listener {
    public:
     ListenerHook(ChildProcessHost* host);
     virtual void OnMessageReceived(const IPC::Message& msg);
     virtual void OnChannelConnected(int32 peer_pid);
     virtual void OnChannelError();
+    virtual void GetQueuedMessages(std::queue<IPC::Message>& queue);
    private:
     ChildProcessHost* host_;
   };
 
   ListenerHook listener_;
 
   ResourceDispatcherHost* resource_dispatcher_host_;
 
--- a/ipc/chromium/src/chrome/common/ipc_channel.h
+++ b/ipc/chromium/src/chrome/common/ipc_channel.h
@@ -1,15 +1,16 @@
 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #ifndef CHROME_COMMON_IPC_CHANNEL_H_
 #define CHROME_COMMON_IPC_CHANNEL_H_
 
+#include <queue>
 #include "chrome/common/ipc_message.h"
 
 namespace IPC {
 
 //------------------------------------------------------------------------------
 
 class Channel : public Message::Sender {
   // Security tests need access to the pipe handle.
@@ -26,16 +27,20 @@ class Channel : public Message::Sender {
 
     // Called when the channel is connected and we have received the internal
     // Hello message from the peer.
     virtual void OnChannelConnected(int32 peer_pid) {}
 
     // Called when an error is detected that causes the channel to close.
     // This method is not called when a channel is closed normally.
     virtual void OnChannelError() {}
+
+    // If the listener has queued messages, swap them for |queue| like so
+    //   swap(impl->my_queued_messages, queue);
+    virtual void GetQueuedMessages(std::queue<Message>& queue) {}
   };
 
   enum Mode {
     MODE_SERVER,
     MODE_CLIENT
   };
 
   enum {
--- a/ipc/glue/AsyncChannel.cpp
+++ b/ipc/glue/AsyncChannel.cpp
@@ -8,17 +8,18 @@
 #include "mozilla/ipc/AsyncChannel.h"
 #include "mozilla/ipc/BrowserProcessSubThread.h"
 #include "mozilla/ipc/ProtocolUtils.h"
 
 #include "nsDebug.h"
 #include "nsTraceRefcnt.h"
 #include "nsXULAppAPI.h"
 
-using mozilla::MonitorAutoLock;
+using namespace mozilla;
+using namespace std;
 
 template<>
 struct RunnableMethodTraits<mozilla::ipc::AsyncChannel>
 {
     static void RetainCallee(mozilla::ipc::AsyncChannel* obj) { }
     static void ReleaseCallee(mozilla::ipc::AsyncChannel* obj) { }
 };
 
@@ -110,51 +111,60 @@ AsyncChannel::ProcessLink::Open(mozilla:
                                 MessageLoop *aIOLoop,
                                 Side aSide)
 {
     NS_PRECONDITION(aTransport, "need transport layer");
 
     // FIXME need to check for valid channel
 
     mTransport = aTransport;
-    mExistingListener = mTransport->set_listener(this);
 
     // FIXME figure out whether we're in parent or child, grab IO loop
     // appropriately
     bool needOpen = true;
     if(aIOLoop) {
         // We're a child or using the new arguments.  Either way, we
         // need an open.
         needOpen = true;
         mChan->mChild = (aSide == AsyncChannel::Unknown) || (aSide == AsyncChannel::Child);
     } else {
         NS_PRECONDITION(aSide == Unknown, "expected default side arg");
 
         // parent
         mChan->mChild = false;
         needOpen = false;
         aIOLoop = XRE_GetIOMessageLoop();
-        // FIXME assuming that the parent waits for the OnConnected event.
-        // FIXME see GeckoChildProcessHost.cpp.  bad assumption!
-        mChan->mChannelState = ChannelConnected;
     }
 
     mIOLoop = aIOLoop;
 
     NS_ASSERTION(mIOLoop, "need an IO loop");
     NS_ASSERTION(mChan->mWorkerLoop, "need a worker loop");
 
-    if (needOpen) {             // child process
+    {
         MonitorAutoLock lock(*mChan->mMonitor);
 
-        mIOLoop->PostTask(FROM_HERE, 
-                          NewRunnableMethod(this, &ProcessLink::OnChannelOpened));
+        if (needOpen) {
+            // Transport::Connect() has not been called.  Call it so
+            // we start polling our pipe and processing outgoing
+            // messages.
+            mIOLoop->PostTask(
+                FROM_HERE,
+                NewRunnableMethod(this, &ProcessLink::OnChannelOpened));
+        } else {
+            // Transport::Connect() has already been called.  Take
+            // over the channel from the previous listener and process
+            // any queued messages.
+            mIOLoop->PostTask(
+                FROM_HERE,
+                NewRunnableMethod(this, &ProcessLink::OnTakeConnectedChannel));
+        }
 
         // FIXME/cjones: handle errors
-        while (mChan->mChannelState != ChannelConnected) {
+        while (!mChan->Connected()) {
             mChan->mMonitor->Wait();
         }
     }
 }
 
 void
 AsyncChannel::ProcessLink::EchoMessage(Message *msg)
 {
@@ -665,22 +675,58 @@ AsyncChannel::ProcessLink::OnEchoMessage
 }
 
 void
 AsyncChannel::ProcessLink::OnChannelOpened()
 {
     mChan->AssertLinkThread();
     {
         MonitorAutoLock lock(*mChan->mMonitor);
+
+        mExistingListener = mTransport->set_listener(this);
+#ifdef DEBUG
+        if (mExistingListener) {
+            queue<Message> pending;
+            mExistingListener->GetQueuedMessages(pending);
+            MOZ_ASSERT(pending.empty());
+        }
+#endif  // DEBUG
+
         mChan->mChannelState = ChannelOpening;
+        lock.Notify();
     }
     /*assert*/mTransport->Connect();
 }
 
 void
+AsyncChannel::ProcessLink::OnTakeConnectedChannel()
+{
+    AssertIOThread();
+
+    queue<Message> pending;
+    {
+        MonitorAutoLock lock(*mChan->mMonitor);
+
+        mChan->mChannelState = ChannelConnected;
+
+        mExistingListener = mTransport->set_listener(this);
+        if (mExistingListener) {
+            mExistingListener->GetQueuedMessages(pending);
+        }
+        lock.Notify();
+    }
+
+    // Dispatch whatever messages the previous listener had queued up.
+    while (!pending.empty()) {
+        OnMessageReceived(pending.front());
+        pending.pop();
+    }
+}
+
+void
 AsyncChannel::ProcessLink::OnChannelConnected(int32 peer_pid)
 {
     AssertIOThread();
 
     {
         MonitorAutoLock lock(*mChan->mMonitor);
         mChan->mChannelState = ChannelConnected;
         mChan->mMonitor->Notify();
--- a/ipc/glue/AsyncChannel.h
+++ b/ipc/glue/AsyncChannel.h
@@ -145,16 +145,17 @@ public:
     class ProcessLink : public Link, public Transport::Listener {
     protected:
         Transport* mTransport;
         MessageLoop* mIOLoop;       // thread where IO happens
         Transport::Listener* mExistingListener; // channel's previous listener
     
         void OnCloseChannel();
         void OnChannelOpened();
+        void OnTakeConnectedChannel();
         void OnEchoMessage(Message* msg);
 
         void AssertIOThread() const
         {
             NS_ABORT_IF_FALSE(mIOLoop == MessageLoop::current(),
                               "not on I/O thread!");
         }
 
@@ -203,17 +204,20 @@ protected:
     void AssertWorkerThread() const
     {
         NS_ABORT_IF_FALSE(mWorkerLoop == MessageLoop::current(),
                           "not on worker thread!");
     }
 
     bool Connected() const {
         mMonitor->AssertCurrentThreadOwns();
-        return ChannelConnected == mChannelState;
+        // The transport layer allows us to send messages before
+        // receiving the "connected" ack from the remote side.
+        return (ChannelOpening == mChannelState ||
+                ChannelConnected == mChannelState);
     }
 
     // Return true if |msg| is a special message targeted at the IO
     // thread, in which case it shouldn't be delivered to the worker.
     virtual bool MaybeInterceptSpecialIOMessage(const Message& msg);
     void ProcessGoodbyeMessage();
 
     // Runs on the link thread. Invoked either from the I/O thread methods above
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -688,27 +688,37 @@ GeckoChildProcessHost::OnChannelConnecte
   mLaunched = true;
 
   if (!base::OpenPrivilegedProcessHandle(peer_pid, &mChildProcessHandle))
       NS_RUNTIMEABORT("can't open handle to child process");
 
   lock.Notify();
 }
 
-// XXX/cjones: these next two methods should basically never be called.
-// after the process is launched, its channel will be used to create
-// one of our channels, AsyncChannel et al.
 void
 GeckoChildProcessHost::OnMessageReceived(const IPC::Message& aMsg)
 {
+  // We never process messages ourself, just save them up for the next
+  // listener.
+  mQueue.push(aMsg);
 }
+
 void
 GeckoChildProcessHost::OnChannelError()
 {
-  // XXXbent Notify that the child process is gone?
+  // FIXME/bug 773925: save up this error for the next listener.
+}
+
+void
+GeckoChildProcessHost::GetQueuedMessages(std::queue<IPC::Message>& queue)
+{
+  // If this is called off the IO thread, bad things will happen.
+  DCHECK(MessageLoopForIO::current());
+  swap(queue, mQueue);
+  // We expect the next listener to take over processing of our queue.
 }
 
 void
 GeckoChildProcessHost::OnWaitableEventSignaled(base::WaitableEvent *event)
 {
   if (mDelegate) {
     mDelegate->OnWaitableEventSignaled(event);
   }
--- a/ipc/glue/GeckoChildProcessHost.h
+++ b/ipc/glue/GeckoChildProcessHost.h
@@ -41,16 +41,17 @@ public:
                   base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture());
   bool AsyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>());
   bool PerformAsyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>(),
                           base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture());
 
   virtual void OnChannelConnected(int32 peer_pid);
   virtual void OnMessageReceived(const IPC::Message& aMsg);
   virtual void OnChannelError();
+  virtual void GetQueuedMessages(std::queue<IPC::Message>& queue);
 
   void InitializeChannel();
 
   virtual bool CanShutdown() { return true; }
 
   virtual void OnWaitableEventSignaled(base::WaitableEvent *event);
 
   IPC::Channel* GetChannel() {
@@ -98,14 +99,23 @@ protected:
 #endif
 
 private:
   DISALLOW_EVIL_CONSTRUCTORS(GeckoChildProcessHost);
 
   // Does the actual work for AsyncLaunch, on the IO thread.
   bool PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts,
                                   base::ProcessArchitecture arch);
+
+  // In between launching the subprocess and handing off its IPC
+  // channel, there's a small window of time in which *we* might still
+  // be the channel listener, and receive messages.  That's bad
+  // because we have no idea what to do with those messages.  So queue
+  // them here until we hand off the eventual listener.
+  //
+  // FIXME/cjones: this strongly indicates bad design.  Shame on us.
+  std::queue<IPC::Message> mQueue;
 };
 
 } /* namespace ipc */
 } /* namespace mozilla */
 
 #endif /* __IPC_GLUE_GECKOCHILDPROCESSHOST_H__ */
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -1767,18 +1767,19 @@ def _generateMessageClass(clsname, msgid
 
     def appendToMsg(thing):
         return StmtExpr(ExprCall(ExprSelect(msgvar, '.', 'append'),
                                  args=[ thing ]))
     logger.addstmts([
         StmtExpr(ExprCall(
             ExprVar('StringAppendF'),
             args=[ ExprAddrOf(msgvar),
-                   ExprLiteral.String('[time:%" PRId64 "]'),
-                   ExprCall(ExprVar('PR_Now')) ])),
+                   ExprLiteral.String('[time:%" PRId64 "][%d]'),
+                   ExprCall(ExprVar('PR_Now')),
+                   ExprCall(ExprVar('base::GetCurrentProcId')) ])),
         appendToMsg(pfxvar),
         appendToMsg(ExprLiteral.String(clsname +'(')),
         Whitespace.NL
     ])
 
     # TODO turn this back on when string stuff is sorted
 
     logger.addstmt(appendToMsg(ExprLiteral.String('[TODO])\\n')))
--- a/layout/build/nsContentDLF.cpp
+++ b/layout/build/nsContentDLF.cpp
@@ -55,16 +55,17 @@ nsresult
 NS_NewContentViewer(nsIContentViewer** aResult);
 
 // XXXbz if you change the MIME types here, be sure to update
 // nsIParser.h and DetermineParseMode in nsParser.cpp and
 // nsHTMLDocument::StartDocumentLoad accordingly.
 static const char* const gHTMLTypes[] = {
   TEXT_HTML,
   TEXT_PLAIN,
+  TEXT_CACHE_MANIFEST,
   TEXT_CSS,
   TEXT_JAVASCRIPT,
   TEXT_ECMASCRIPT,
   APPLICATION_JAVASCRIPT,
   APPLICATION_ECMASCRIPT,
   APPLICATION_XJAVASCRIPT,
   APPLICATION_JSON,
   VIEWSOURCE_CONTENT_TYPE,
--- a/layout/build/nsContentDLF.h
+++ b/layout/build/nsContentDLF.h
@@ -62,16 +62,17 @@ NS_NewContentDocumentLoaderFactory(nsIDo
     { "Gecko-Content-Viewers", AUDIO_WEBM, "@mozilla.org/content/document-loader-factory;1" },
 #else
 #define CONTENTDLF_WEBM_CATEGORIES
 #endif
 
 #define CONTENTDLF_CATEGORIES \
     { "Gecko-Content-Viewers", TEXT_HTML, "@mozilla.org/content/document-loader-factory;1" }, \
     { "Gecko-Content-Viewers", TEXT_PLAIN, "@mozilla.org/content/document-loader-factory;1" }, \
+    { "Gecko-Content-Viewers", TEXT_CACHE_MANIFEST, "@mozilla.org/content/document-loader-factory;1" }, \
     { "Gecko-Content-Viewers", TEXT_CSS, "@mozilla.org/content/document-loader-factory;1" }, \
     { "Gecko-Content-Viewers", TEXT_JAVASCRIPT, "@mozilla.org/content/document-loader-factory;1" }, \
     { "Gecko-Content-Viewers", TEXT_ECMASCRIPT, "@mozilla.org/content/document-loader-factory;1" }, \
     { "Gecko-Content-Viewers", APPLICATION_JAVASCRIPT, "@mozilla.org/content/document-loader-factory;1" }, \
     { "Gecko-Content-Viewers", APPLICATION_ECMASCRIPT, "@mozilla.org/content/document-loader-factory;1" }, \
     { "Gecko-Content-Viewers", APPLICATION_XJAVASCRIPT, "@mozilla.org/content/document-loader-factory;1" }, \
     { "Gecko-Content-Viewers", APPLICATION_JSON, "@mozilla.org/content/document-loader-factory;1" }, \
     { "Gecko-Content-Viewers", APPLICATION_XHTML_XML, "@mozilla.org/content/document-loader-factory;1" }, \
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1526,16 +1526,17 @@ var SelectionHandler = {
     // Get the element's view
     this._view = aElement.ownerDocument.defaultView;
     this._isRTL = (this._view.getComputedStyle(aElement, "").direction == "rtl");
 
     let computedStyle = this._view.getComputedStyle(this._view.document.documentElement);
     this._viewOffset = { top: parseInt(computedStyle.getPropertyValue("margin-top").replace("px", "")),
                          left: parseInt(computedStyle.getPropertyValue("margin-left").replace("px", "")),
                          zoom: BrowserApp.selectedTab.getViewport().zoom };
+    this.updateViewOffsetScroll();
 
     // Remove any previous selected or created ranges. Tapping anywhere on a
     // page will create an empty range.
     let selection = this._view.getSelection();
     selection.removeAllRanges();
 
     // Position the caret using a fake mouse click
     let cwu = BrowserApp.selectedBrowser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).
@@ -1566,17 +1567,17 @@ var SelectionHandler = {
       selection.collapseToStart();
       return;
     }
 
     // Add a listener to end the selection if it's removed programatically
     selection.QueryInterface(Ci.nsISelectionPrivate).addSelectionListener(this);
 
     // Initialize the cache
-    this.cache = {};
+    this.cache = { start: {}, end: {}};
     this.updateCacheForSelection();
 
     this.showHandles();
     this._active = true;
   },
 
   showContextMenu: function sh_showContextMenu(aX, aY) {
     let [SELECT_ALL, COPY, SHARE] = [0, 1, 2];
@@ -1622,40 +1623,28 @@ var SelectionHandler = {
         });
         break;
       }
     }
   },
 
   // aX/aY are in top-level window browser coordinates
   moveSelection: function sh_moveSelection(aIsStartHandle, aX, aY) {
-    /* XXX bug 765367: Because the handles are in the document, the element
-       will always be the handle the user touched. These checks are disabled
-       until we can figure out a way to get the element under the handle.
-    let contentWindow = BrowserApp.selectedBrowser.contentWindow;
-    let element = ElementTouchHelper.elementFromPoint(contentWindow, aX, aY);
-    if (!element)
-      element = ElementTouchHelper.anyElementFromPoint(contentWindow, aX, aY);
-
-    // The element can be null if it's outside the viewport. We also want
-    // to avoid setting focus in a textbox [Bugs 654352 & 667243] and limit
-    // the selection to the initial content window (don't leave or enter iframes).
-    if (!element || element instanceof Ci.nsIDOMHTMLInputElement ||
-                    element instanceof Ci.nsIDOMHTMLTextAreaElement ||
-                    element.ownerDocument.defaultView != this._view)
-      return;
-    */
-
     // Update the handle position as it's dragged
-    let leftTop = "left:" + (aX + this._view.scrollX - this._viewOffset.left) + "px;" +
-                  "top:" + (aY + this._view.scrollY - this._viewOffset.top) + "px;";
-    if (aIsStartHandle)
+    let leftTop = "left:" + (aX + this._viewOffset.scrollX - this._viewOffset.left) + "px;" +
+                  "top:" + (aY + this._viewOffset.scrollY - this._viewOffset.top) + "px;";
+    if (aIsStartHandle) {
       this._start.style.cssText = this._start.style.cssText + leftTop;
-    else
+      this.cache.start.left = aX;
+      this.cache.start.top = aY;
+    } else {
       this._end.style.cssText = this._end.style.cssText + leftTop;
+      this.cache.end.left = aX;
+      this.cache.end.top = aY;
+    }
 
     let cwu = this._view.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
 
     // The handles work the same on both LTR and RTL pages, but the underlying selection
     // works differently, so we need to reverse how we send mouse events on RTL pages.
     if (this._isRTL) {
       // Position the caret at the end handle using a fake mouse click
       if (!aIsStartHandle)
@@ -1681,51 +1670,48 @@ var SelectionHandler = {
       let oldEnd = this._end;
 
       oldStart.setAttribute("anonid", "selection-handle-end");
       oldEnd.setAttribute("anonid", "selection-handle-start");
 
       this._start = oldEnd;
       this._end = oldStart;
 
+      // We need to update the cache for the new handles
+      this.updateCacheForHandleRects();
+
       // Re-send mouse events to update the selection corresponding to the new handles
       if (this._isRTL) {
         this._sendEndMouseEvents(cwu, false);
         this._sendStartMouseEvents(cwu, true);
       } else {
         this._sendStartMouseEvents(cwu, false);
         this._sendEndMouseEvents(cwu, true);
       }
     }
   },
 
   _sendStartMouseEvents: function sh_sendStartMouseEvents(cwu, useShift) {
-    let start = this._start.getBoundingClientRect();
-    let x = start.right - this.HANDLE_PADDING;
+    let x = this.cache.start.left + this.HANDLE_PADDING + this.HANDLE_WIDTH;
     // Send mouse events 1px above handle to avoid hitting the handle div (bad things happen in that case)
-    let y = start.top - 1;
+    let y = this.cache.start.top - 1;
 
     this._sendMouseEvents(cwu, useShift, x, y);
   },
 
   _sendEndMouseEvents: function sh_sendEndMouseEvents(cwu, useShift) {
-    let end = this._end.getBoundingClientRect();
-    let x = end.left + this.HANDLE_PADDING;
+    let x = this.cache.end.left + this.HANDLE_PADDING;
     // Send mouse events 1px above handle to avoid hitting the handle div (bad things happen in that case)
-    let y = end.top - 1;
+    let y = this.cache.end.top - 1;
 
     this._sendMouseEvents(cwu, useShift, x, y);
   },
 
   _sendMouseEvents: function sh_sendMouseEvents(cwu, useShift, x, y) {
-    let contentWindow = BrowserApp.selectedBrowser.contentWindow;
-    let element = ElementTouchHelper.elementFromPoint(contentWindow, x, y);
-    if (!element)
-      element = ElementTouchHelper.anyElementFromPoint(contentWindow, x, y);
-
+    let element = cwu.elementFromPoint(x, y, false, true);
     // Don't send mouse events to the other handle
     if (element instanceof Ci.nsIDOMHTMLHtmlElement)
       return;
 
     cwu.sendMouseEventToWindow("mousedown", x, y, 0, 0, useShift ? Ci.nsIDOMNSEvent.SHIFT_MASK : 0, true);
     cwu.sendMouseEventToWindow("mouseup", x, y, 0, 0, useShift ? Ci.nsIDOMNSEvent.SHIFT_MASK : 0, true);
   },
 
@@ -1747,21 +1733,17 @@ var SelectionHandler = {
 
         selection.removeAllRanges();
         selection.QueryInterface(Ci.nsISelectionPrivate).removeSelectionListener(this);
       }
     }
 
     // Only try copying text if there's text to copy!
     if (selectedText.length) {
-      let contentWindow = BrowserApp.selectedBrowser.contentWindow;
-      let element = ElementTouchHelper.elementFromPoint(contentWindow, aX, aY);
-      if (!element)
-        element = ElementTouchHelper.anyElementFromPoint(contentWindow, aX, aY);
-
+      let element = ElementTouchHelper.anyElementFromPoint(BrowserApp.selectedBrowser.contentWindow, aX, aY);
       // Only try copying text if the tap happens in the same view
       if (element.ownerDocument.defaultView == this._view) {
         let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
         clipboard.copyString(selectedText, element.ownerDocument);
         NativeWindow.toast.show(Strings.browser.GetStringFromName("selectionHelper.textCopied"), "short");
       }
     }
 
@@ -1803,43 +1785,65 @@ var SelectionHandler = {
 
     let selectionReversed = false;
     if (this.cache.start) {
       // If the end moved past the old end, but we're dragging the start handle, then that handle should become the end handle (and vice versa)
       selectionReversed = (aIsStartHandle && (end.y > this.cache.end.y || (end.y == this.cache.end.y && end.x > this.cache.end.x))) ||
                           (!aIsStartHandle && (start.y < this.cache.start.y || (start.y == this.cache.start.y && start.x < this.cache.start.x)));
     }
 
-    this.cache.start = start;
-    this.cache.end = end;
+    this.cache.start.x = start.x;
+    this.cache.start.y = start.y;
+    this.cache.end.x = end.x;
+    this.cache.end.y = end.y;
 
     return selectionReversed;
   },
 
+  // Updates the cached client rect left/top values for the handles.
+  updateCacheForHandleRects: function sh_updateCacheForHandleRects() {
+    let start = this._start.getBoundingClientRect();
+    this.cache.start.left = start.left;
+    this.cache.start.top = start.top;
+
+    let end = this._end.getBoundingClientRect();
+    this.cache.end.left = end.left;
+    this.cache.end.top = end.top;
+  },
+
+  updateViewOffsetScroll: function sh_updateViewOffsetScroll() {
+    let cwu = this._view.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+    let scrollX = {}, scrollY = {};
+    cwu.getScrollXY(false, scrollX, scrollY);
+
+    this._viewOffset.scrollX = scrollX.value;
+    this._viewOffset.scrollY = scrollY.value;
+  },
+
   // Adjust start/end positions to account for scroll, and account for the dimensions of the
   // handle elements to ensure the handles point exactly at the ends of the selection.
   positionHandles: function sh_positionHandles(adjustScale) {
     let startCss = this._start.style.cssText;
     let endCss = this._end.style.cssText;
 
     if (adjustScale) { 
       let heightWidth = "height:" + this.HANDLE_HEIGHT / this._viewOffset.zoom + "px;" + 
                         "width:" + this.HANDLE_WIDTH / this._viewOffset.zoom + "px;";
 
       startCss += heightWidth;
       endCss += heightWidth;
     }
 
-    startCss += "left:" + (this.cache.start.x + this._view.scrollX - this._viewOffset.left -
+    startCss += "left:" + (this.cache.start.x + this._viewOffset.scrollX - this._viewOffset.left -
                            this.HANDLE_PADDING - this.HANDLE_HORIZONTAL_OFFSET - this.HANDLE_WIDTH / this._viewOffset.zoom) + "px;" +
-                "top:" + (this.cache.start.y + this._view.scrollY - this._viewOffset.top) + "px;";
-
-    endCss += "left:" + (this.cache.end.x + this._view.scrollX - this._viewOffset.left -
+                "top:" + (this.cache.start.y + this._viewOffset.scrollY - this._viewOffset.top) + "px;";
+
+    endCss += "left:" + (this.cache.end.x + this._viewOffset.scrollX - this._viewOffset.left -
                          this.HANDLE_PADDING + this.HANDLE_HORIZONTAL_OFFSET) + "px;" +
-              "top:" + (this.cache.end.y + this._view.scrollY - this._viewOffset.top) + "px;";
+              "top:" + (this.cache.end.y + this._viewOffset.scrollY - this._viewOffset.top) + "px;";
 
     this._start.style.cssText = startCss;
     this._end.style.cssText = endCss;
   },
 
   showHandles: function sh_showHandles() {
     let doc = this._view.document;
     this._start = doc.getAnonymousElementByAttribute(doc.documentElement, "anonid", "selection-handle-start");
@@ -1847,16 +1851,17 @@ var SelectionHandler = {
 
     if (!this._start || !this._end) {
       Cu.reportError("SelectionHandler.showHandles: Couldn't find anonymous handle elements");
       this.endSelection();
       return;
     }
 
     this.positionHandles(true);
+    this.updateCacheForHandleRects();
 
     this._start.setAttribute("showing", "true");
     this._end.setAttribute("showing", "true");
 
     this._start.addEventListener("touchend", this, true);
     this._end.addEventListener("touchend", this, true);
 
     this._start.addEventListener("touchstart", this, true);
@@ -1897,16 +1902,20 @@ var SelectionHandler = {
         let touch = aEvent.changedTouches[0];
         this._touchId = touch.identifier;
 
         // Keep track of what part of the handle the user touched
         let rect = aEvent.target.getBoundingClientRect();
         this._touchDelta = { x: touch.clientX - rect.left,
                              y: touch.clientY - rect.top };
 
+        // Update the cache in case the page panned since last touch
+        this.updateCacheForHandleRects();
+        this.updateViewOffsetScroll();
+
         aEvent.target.addEventListener("touchmove", this, false);
         break;
 
       case "touchend":
         aEvent.target.removeEventListener("touchmove", this, false);
 
         this._touchId = null;
         this._touchDelta = null;
--- a/netwerk/mime/nsMimeTypes.h
+++ b/netwerk/mime/nsMimeTypes.h
@@ -122,16 +122,17 @@
 #define TEXT_JSSS                           "text/jsss"
 #define TEXT_XML                            "text/xml"
 #define TEXT_RDF                            "text/rdf"
 #define TEXT_XUL                            "application/vnd.mozilla.xul+xml"
 #define TEXT_ECMASCRIPT                     "text/ecmascript"
 #define TEXT_JAVASCRIPT                     "text/javascript"
 #define TEXT_XSL                            "text/xsl"
 #define TEXT_EVENT_STREAM                   "text/event-stream"
+#define TEXT_CACHE_MANIFEST                 "text/cache-manifest"
 
 #define VIDEO_MPEG                          "video/mpeg"
 #define VIDEO_MP4                           "video/mp4"
 #define VIDEO_RAW                           "video/x-raw-yuv"
 #define VIDEO_OGG                           "video/ogg"
 #define VIDEO_WEBM                          "video/webm"
 #define APPLICATION_OGG                     "application/ogg"
 
--- a/parser/htmlparser/src/nsParser.cpp
+++ b/parser/htmlparser/src/nsParser.cpp
@@ -787,16 +787,17 @@ DetermineHTMLParseMode(const nsString& a
 
 static void
 DetermineParseMode(const nsString& aBuffer, nsDTDMode& aParseMode,
                    eParserDocType& aDocType, const nsACString& aMimeType)
 {
   if (aMimeType.EqualsLiteral(TEXT_HTML)) {
     DetermineHTMLParseMode(aBuffer, aParseMode, aDocType);
   } else if (aMimeType.EqualsLiteral(TEXT_PLAIN) ||
+             aMimeType.EqualsLiteral(TEXT_CACHE_MANIFEST) ||
              aMimeType.EqualsLiteral(TEXT_CSS) ||
              aMimeType.EqualsLiteral(APPLICATION_JAVASCRIPT) ||
              aMimeType.EqualsLiteral(APPLICATION_XJAVASCRIPT) ||
              aMimeType.EqualsLiteral(APPLICATION_JSON) ||
              aMimeType.EqualsLiteral(TEXT_ECMASCRIPT) ||
              aMimeType.EqualsLiteral(APPLICATION_ECMASCRIPT) ||
              aMimeType.EqualsLiteral(TEXT_JAVASCRIPT)) {
     aDocType = ePlainText;
--- a/parser/htmlparser/tests/mochitest/Makefile.in
+++ b/parser/htmlparser/tests/mochitest/Makefile.in
@@ -51,21 +51,23 @@ MOCHITEST_FILES =	parser_datreader.js \
 		file_bug594730-6.html \
 		file_bug594730-7.html \
 		file_bug594730-8.html \
 		file_bug594730-9.html \
 		test_bug599584.html \
 		iframe_bug599584.html \
 		test_bug613662.html \
 		test_bug613662.xhtml \
+		test_bug639362.html \
 		test_bug642908.html \
 		file_bug642908.sjs \
 		test_bug645115.html \
 		test_bug655682.html \
 		file_bug655682.sjs \
+		test_bug667533.html \
 		file_bug672453_not_declared.html \
 		file_bug672453_late_meta.html \
 		file_bug672453_meta_restart.html \
 		file_bug672453_meta_unsupported.html \
 		file_bug672453_http_unsupported.html \
 		file_bug672453_http_unsupported.html^headers^ \
 		file_bug672453_bomless_utf16.html \
 		file_bug672453_meta_utf16.html \
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/mochitest/test_bug639362.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=639362
+-->
+<head>
+  <title>Test for Bug 639362</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=639362">Mozilla Bug 639362</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+function loaded(iframe) {
+  is(iframe.contentWindow.location.href, iframe.src, "should load correct URL");
+  is(iframe.contentDocument.body.textContent, 'CACHE MANIFEST', "text/cache-manifest should be treated as text");
+  SimpleTest.finish();
+}
+</script>
+<iframe src="data:text/cache-manifest,CACHE MANIFEST" onload="loaded(this);"></iframe>
+</body>
+</html>
--- a/testing/testsuite-targets.mk
+++ b/testing/testsuite-targets.mk
@@ -130,16 +130,19 @@ endif
 	$(CHECK_TEST_ERROR)
 
 ifeq ($(OS_ARCH),Darwin)
 webapprt_stub_path = $(TARGET_DIST)/$(MOZ_MACBUNDLE_NAME)/Contents/MacOS/webapprt-stub$(BIN_SUFFIX)
 endif
 ifeq ($(OS_ARCH),WINNT)
 webapprt_stub_path = $(TARGET_DIST)/bin/webapprt-stub$(BIN_SUFFIX)
 endif
+ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
+webapprt_stub_path = $(TARGET_DIST)/bin/webapprt-stub$(BIN_SUFFIX)
+endif
 
 ifdef webapprt_stub_path
 webapprt-test-content:
 	$(RUN_MOCHITEST) --webapprt-content --appname $(webapprt_stub_path)
 	$(CHECK_TEST_ERROR)
 webapprt-test-chrome:
 	$(RUN_MOCHITEST) --webapprt-chrome --appname $(webapprt_stub_path) --browser-arg -test-mode
 	$(CHECK_TEST_ERROR)
--- a/toolkit/identity/tests/chrome/test_sandbox.xul
+++ b/toolkit/identity/tests/chrome/test_sandbox.xul
@@ -26,16 +26,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 "use strict";
 
 SimpleTest.waitForExplicitFinish();
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
+const OSX_10_5 = navigator.oscpu == "Intel Mac OS X 10.5";
 
 const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
 
 const TEST_URL_1 = "https://example.com/";
 // No trailing slash plus port to test normalization
 const TEST_URL_2 = "https://example.com:443";
 
 const TEST_BASE = "http://mochi.test:8888/chrome/toolkit/identity/tests/chrome/"
@@ -122,17 +123,17 @@ function check_loaded_content(aNothingSh
 
   let xhr = new XMLHttpRequest();
   xhr.open("GET", STATE_URL + "?get_loaded", true);
   xhr.onload = function() {
     is(xhr.status, 200, "Check successful response");
 
     if (aNothingShouldLoad) {
       is(xhr.responseText, "NOTHING", "Check that nothing was loaded on the server");
-    } else {
+    } else if (!OSX_10_5) {
       let loadedTypes = xhr.responseText == "NOTHING" ? [] : xhr.responseText.split(",");
 
       // TODO: Media should be disabled after bug 759964.
       is(loadedTypes.length, 4, "Check number of loaded content types: " + xhr.responseText)
       todo_is(loadedTypes.length, 2, "Check number of loaded content types: " + xhr.responseText)
 
       isnot(loadedTypes.indexOf("application/javascript"), -1, "Check JS was loaded");
       isnot(loadedTypes.indexOf("text/html"), -1, "Check iframe was loaded");
--- a/toolkit/themes/gnomestripe/global/autocomplete.css
+++ b/toolkit/themes/gnomestripe/global/autocomplete.css
@@ -108,62 +108,78 @@ treechildren.autocomplete-treebody::-moz
 }
 
 .autocomplete-richlistitem[selected="true"] {
   background-color: Highlight;
   color: HighlightText;
 }
 
 .autocomplete-richlistitem {
-  padding: 1px 2px;
+  padding: 6px 2px;
   color: MenuText;
 }
 
-.autocomplete-richlistitem:not(:first-child) {
-  border-top: 1px solid ThreeDLightShadow;
+.ac-url-box {
+  margin-top: 1px;
 }
 
 .ac-site-icon {
   width: 16px; 
   height: 16px;
-  margin: 0 5px -3px 3px;
+  margin-bottom: -2px;
+  -moz-margin-start: 3px;
+  -moz-margin-end: 6px;
 }
 
 .ac-type-icon {
   width: 16px; 
   height: 16px;
+  -moz-margin-start: 6px;
+  -moz-margin-end: 4px;
 }
 
 .ac-extra > .ac-result-type-tag {
   margin: 0 4px;
 }
 
 .ac-extra > .ac-comment {
   padding-right: 4px;
 }
 
 .ac-ellipsis-after {
-  margin: 2px 0px 0px 0px !important;
+  margin: 0 !important;
   padding: 0; 
   min-width: 1em;
 }
 
 .ac-normal-text {
-  margin: 2px 0px 0px 0px !important;
+  margin: 0 !important;
   padding: 0;
 }
 
 .ac-normal-text > html|span {
   margin: 0 !important;
   padding: 0;
 }
 
 html|span.ac-emphasize-text {
-  font-weight: bold;
-  text-decoration: underline;
+  box-shadow: inset 0 0 1px 1px rgba(0,0,0,0.1);
+  background-color: rgba(0,0,0,0.05);
+  border-radius: 2px;
+  text-shadow: 0 0 currentColor; /*faux bold effect*/
+}
+
+.ac-url-text > html|span.ac-emphasize-text,
+.ac-action-text > html|span.ac-emphasize-text {
+  box-shadow: none;
+}
+
+.ac-normal-text[selected="true"] > html|span.ac-emphasize-text {
+  box-shadow: inset 0 0 1px 1px rgba(255,255,255,0.3);
+  background-color: rgba(255,255,255,0.2);
 }
 
 html|span.ac-emphasize-alt {
   text-decoration: underline;
 }
 
 .ac-title, .ac-url {
   overflow: hidden;
--- a/toolkit/themes/pinstripe/global/autocomplete.css
+++ b/toolkit/themes/pinstripe/global/autocomplete.css
@@ -90,64 +90,83 @@ treechildren.autocomplete-treebody::-moz
 .autocomplete-richlistbox {
   -moz-appearance: none;
   margin: 0;
 }
 
 .autocomplete-richlistitem[selected="true"] {
   background-color: Highlight;
   color: HighlightText;
+  background-image: -moz-linear-gradient(rgba(255,255,255,0.3), transparent);
 }
 
 .autocomplete-richlistitem {
-  padding: 1px 2px;
+  padding: 5px 2px;
 }
 
-.autocomplete-richlistitem:not(:first-child) {
-  border-top: 1px solid ThreeDLightShadow;
+.ac-url-box {
+  margin-top: 1px;
 }
 
 .ac-site-icon {
   width: 16px; 
   height: 16px;
-  margin: 0 5px -3px 3px;
+  margin-bottom: -1px;
+  -moz-margin-start: 7px;
+  -moz-margin-end: 5px;
 }
 
 .ac-type-icon {
-  width: 16px; 
+  width: 16px;
   height: 16px;
+  -moz-margin-start: 6px;
+  -moz-margin-end: 4px;
+}
+
+.ac-url-box > .ac-site-icon,
+.ac-url-box > .ac-type-icon {
+  /* Otherwise the spacer is big enough to stretch its container */
+  height: auto;
 }
 
 .ac-extra > .ac-result-type-tag {
   margin: 0 4px;
 }
 
 .ac-extra > .ac-comment {
   padding-right: 4px;
 }
 
 .ac-ellipsis-after {
-  margin: 2px 0px 0px 0px !important;
+  margin: 0 !important;
   padding: 0; 
   min-width: 1.1em;
 }
 
 .ac-normal-text {
-  margin: 2px 0px 0px 0px !important;
+  margin: 0 !important;
   padding: 0;
 }
 
 .ac-normal-text > html|span {
   margin: 0 !important;
   padding: 0;
 }
 
 html|span.ac-emphasize-text {
-  font-weight: bold;
-  text-decoration: underline;
+  box-shadow: inset 0 0 1px 1px rgba(208,208,208,0.4);
+  background-color: rgba(208,208,208,0.2);
+  border-radius: 2px;
+  text-shadow: 0 0 currentColor;
+}
+
+.ac-url-text > html|span.ac-emphasize-text,
+.ac-action-text > html|span.ac-emphasize-text {
+  box-shadow: inset 0 0 1px 1px rgba(183,210,226,0.4);
+  background-color: rgba(183,210,226,0.3);
 }
 
 html|span.ac-emphasize-alt {
   text-decoration: underline;
 }
 
 .ac-title, .ac-url {
   overflow: hidden;
new file mode 100644
--- /dev/null
+++ b/toolkit/themes/winstripe/global/autocomplete-aero.css
@@ -0,0 +1,7 @@
+/* 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/. */
+
+%define WINSTRIPE_AERO
+%include autocomplete.css
+%undef WINSTRIPE_AERO
--- a/toolkit/themes/winstripe/global/autocomplete.css
+++ b/toolkit/themes/winstripe/global/autocomplete.css
@@ -91,67 +91,122 @@ treechildren.autocomplete-treebody::-moz
 
 /* ::::: richlistbox autocomplete ::::: */
 
 .autocomplete-richlistbox {
   -moz-appearance: none;
   margin: 0;
 }
 
+.autocomplete-richlistitem {
+  padding: 1px;
+}
+
 .autocomplete-richlistitem[selected="true"] {
   background-color: Highlight;
   color: HighlightText;
 }
 
-.autocomplete-richlistitem {
-  padding: 1px 2px;
+%ifdef WINSTRIPE_AERO
+@media (-moz-windows-default-theme) {
+  /*
+  -moz-appearance: menuitem is almost right, but the hover effect is not
+  transparent and is lighter than desired.
+  */
+  .autocomplete-richlistitem[selected="true"] {
+    color: inherit;
+    background-color: transparent;
+    /* four gradients for the bevel highlights on each edge, one for blue background */
+    background-image:
+      -moz-linear-gradient(to bottom, rgba(255,255,255,0.9) 3px, rgba(255,255,255,0) 3px),
+      -moz-linear-gradient(to right, rgba(255,255,255,0.5) 3px, rgba(255,255,255,0) 3px),
+      -moz-linear-gradient(to left, rgba(255,255,255,0.5) 3px, rgba(255,255,255,0) 3px),
+      -moz-linear-gradient(to top, rgba(255,255,255,0.4) 3px, rgba(255,255,255,0) 3px),
+      -moz-linear-gradient(to bottom, rgba(163,196,247,0.3), rgba(122,180,246,0.3));
+    background-clip: content-box;
+    border-radius: 6px;
+    outline: 1px solid rgb(124,163,206);
+    -moz-outline-radius: 3px;
+    outline-offset: -2px;
+  }
+}
+%endif
+
+.ac-title-box {
+  margin-top: 4px;
 }
 
-.autocomplete-richlistitem:not(:first-child) {
-  border-top: 1px solid ThreeDLightShadow;
+.ac-url-box {
+  margin: 1px 0 4px;
 }
 
 .ac-site-icon {
   width: 16px; 
   height: 16px;
-  margin: 0 5px -3px 3px;
+  margin: 0 5px -2px;
 }
 
 .ac-type-icon {
   width: 16px; 
   height: 16px;
+  -moz-margin-start: 6px;
+  -moz-margin-end: 4px;
+  margin-bottom: -1px;
+}
+
+.ac-url-box > .ac-site-icon,
+.ac-url-box > .ac-type-icon {
+  /* Otherwise the spacer is big enough to stretch its container */
+  height: auto;
 }
 
 .ac-extra > .ac-result-type-tag {
   margin: 0 4px;
 }
 
 .ac-extra > .ac-comment {
   padding-right: 4px;
 }
 
 .ac-ellipsis-after {
-  margin: 2px 0px 0px 0px !important;
+  margin: 0 !important;
   padding: 0; 
   min-width: 1em;
 }
 
 .ac-normal-text {
-  margin: 2px 0px 0px 0px !important;
+  margin: 0 !important;
   padding: 0;
 }
 
 .ac-normal-text > html|span {
   margin: 0 !important;
   padding: 0;
 }
 
 html|span.ac-emphasize-text {
-  font-weight: bold;
-  text-decoration: underline;
+  box-shadow: inset 0 0 1px 1px rgba(208,208,208,0.5);
+  background-color: rgba(208,208,208,0.3);
+  border-radius: 2px;
+  text-shadow: 0 0 currentColor;
+}
+
+@media (-moz-windows-default-theme) {
+%ifdef WINSTRIPE_AERO
+  html|span.ac-emphasize-text {
+    box-shadow: inset 0 0 1px 1px rgba(0,0,0,0.1);
+    background-color: rgba(0,0,0,0.05);
+  }
+%else
+  .ac-url-text > html|span.ac-emphasize-text,
+  .ac-action-text > html|span.ac-emphasize-text {
+    box-shadow: inset 0 0 1px 1px rgba(202,214,201,0.3);
+    background-color: rgba(202,214,201,0.2);
+  }
+%endif
 }
 
 html|span.ac-emphasize-alt {
   text-decoration: underline;
 }
 
 .ac-title, .ac-url {
   overflow: hidden;
--- a/toolkit/themes/winstripe/global/jar.mn
+++ b/toolkit/themes/winstripe/global/jar.mn
@@ -185,17 +185,17 @@ toolkit.jar:
 % skin global classic/1.0 %skin/classic/aero/global/ os=WINNT osversion>=6
         skin/classic/aero/global/about.css
         skin/classic/aero/global/aboutCache.css
         skin/classic/aero/global/aboutCacheEntry.css
         skin/classic/aero/global/aboutMemory.css
         skin/classic/aero/global/aboutSupport.css
         skin/classic/aero/global/appPicker.css
         skin/classic/aero/global/arrow.css
-        skin/classic/aero/global/autocomplete.css
+*       skin/classic/aero/global/autocomplete.css                        (autocomplete-aero.css)
         skin/classic/aero/global/button.css
         skin/classic/aero/global/checkbox.css
         skin/classic/aero/global/colorpicker.css
         skin/classic/aero/global/commonDialog.css
 *       skin/classic/aero/global/config.css
         skin/classic/aero/global/customizeToolbar.css
         skin/classic/aero/global/datetimepicker.css
         skin/classic/aero/global/dialog.css
--- a/webapprt/gtk2/webapprt.cpp
+++ b/webapprt/gtk2/webapprt.cpp
@@ -23,16 +23,18 @@ const char kAPP_INI[] = "application.ini
 const char kWEBAPP_INI[] = "webapp.ini";
 const char kWEBAPPRT_INI[] = "webapprt.ini";
 const char kWEBAPPRT_PATH[] = "webapprt";
 const char kAPP_ENV_VAR[] = "XUL_APP_FILE";
 const char kAPP_RT[] = "webapprt-stub";
 
 int* pargc;
 char*** pargv;
+char profile[MAXPATHLEN];
+bool isProfileOverridden = false;
 
 XRE_GetFileFromPathType XRE_GetFileFromPath;
 XRE_CreateAppDataType XRE_CreateAppData;
 XRE_FreeAppDataType XRE_FreeAppData;
 XRE_mainType XRE_main;
 
 const nsDynamicFunctionLoad kXULFuncs[] = {
   { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
@@ -115,36 +117,38 @@ bool CopyFile(const char* inputFile, con
 
   // Close file descriptors
   close(inputFD);
   close(outputFD);
 
   return (bytesRead >= 0);
 }
 
-bool GRELoadAndLaunch(const char* firefoxDir, const char* profile)
+bool GRELoadAndLaunch(const char* firefoxDir)
 {
   char xpcomDllPath[MAXPATHLEN];
   snprintf(xpcomDllPath, MAXPATHLEN, "%s/%s", firefoxDir, XPCOM_DLL);
 
   if (NS_FAILED(XPCOMGlueStartup(xpcomDllPath))) {
     ErrorDialog("Couldn't load the XPCOM library");
     return false;
   }
 
   if (NS_FAILED(XPCOMGlueLoadXULFunctions(kXULFuncs))) {
     ErrorDialog("Couldn't load libxul");
     return false;
   }
 
-  // Override the class name part of the WM_CLASS property, so that the
-  // DE can match our window to the correct launcher
-  char programClass[MAXPATHLEN];
-  snprintf(programClass, MAXPATHLEN, "owa-%s", profile);
-  g_set_prgname(programClass);
+  if (!isProfileOverridden) {
+    // Override the class name part of the WM_CLASS property, so that the
+    // DE can match our window to the correct launcher
+    char programClass[MAXPATHLEN];
+    snprintf(programClass, MAXPATHLEN, "owa-%s", profile);
+    g_set_prgname(programClass);
+  }
 
   // NOTE: The GRE has successfully loaded, so we can use XPCOM now
   { // Scope for any XPCOM stuff we create
     ScopedLogging log;
 
     // Get the path to the runtime
     char rtPath[MAXPATHLEN];
     snprintf(rtPath, MAXPATHLEN, "%s/%s", firefoxDir, kWEBAPPRT_PATH);
@@ -168,18 +172,20 @@ bool GRELoadAndLaunch(const char* firefo
     }
 
     nsXREAppData *webShellAppData;
     if (NS_FAILED(XRE_CreateAppData(rtINI, &webShellAppData))) {
       ErrorDialog("Couldn't read WebappRT application.ini");
       return false;
     }
 
-    SetAllocatedString(webShellAppData->profile, profile);
-    SetAllocatedString(webShellAppData->name, profile);
+    if (!isProfileOverridden) {
+      SetAllocatedString(webShellAppData->profile, profile);
+      SetAllocatedString(webShellAppData->name, profile);
+    }
 
     nsCOMPtr<nsIFile> directory;
     if (NS_FAILED(XRE_GetFileFromPath(rtPath, getter_AddRefs(directory)))) {
       ErrorDialog("Couldn't open runtime directory");
       return false;
     }
 
     nsCOMPtr<nsIFile> xreDir;
@@ -226,20 +232,39 @@ int main(int argc, char *argv[])
   pargv = &argv;
 
   // Get current executable path
   char curExePath[MAXPATHLEN];
   if (NS_FAILED(mozilla::BinaryPath::Get(argv[0], curExePath))) {
     ErrorDialog("Couldn't read current executable path");
     return 255;
   }
+  char curExeDir[MAXPATHLEN];
+  GetDirFromPath(curExeDir, curExePath);
+
+  for (int i = 1; i < argc; i++) {
+    if (!strcmp(argv[i], "-profile")) {
+      isProfileOverridden = true;
+      break;
+    }
+  }
+
+  char firefoxDir[MAXPATHLEN];
+
+  // Check if Firefox is in the ../../dist/bin directory (relative to the webapp runtime)
+  // This is the case for webapprt chrome and content tests.
+  snprintf(firefoxDir, MAXPATHLEN, "%s/../../dist/bin", curExeDir);
+  if (access(firefoxDir, F_OK) != -1) {
+    if (GRELoadAndLaunch(firefoxDir))
+      return 0;
+
+    return 255;
+  }
 
   // Set up webAppIniPath with path to webapp.ini
-  char curExeDir[MAXPATHLEN];
-  GetDirFromPath(curExeDir, curExePath);
   char webAppIniPath[MAXPATHLEN];
   snprintf(webAppIniPath, MAXPATHLEN, "%s/%s", curExeDir, kWEBAPP_INI);
 
   // Open webapp.ini as an INI file
   nsINIParser parser;
   if (NS_FAILED(parser.Init(webAppIniPath))) {
     ErrorDialog("Couldn't open webapp.ini");
     return 255;
@@ -247,24 +272,22 @@ int main(int argc, char *argv[])
 
   // Set up our environment to know where webapp.ini was loaded from
   if (setenv(kAPP_ENV_VAR, webAppIniPath, 1) == -1) {
     ErrorDialog("Couldn't set up app environment");
     return 255;
   }
 
   // Get profile dir from webapp.ini
-  char profile[MAXPATHLEN];
   if (NS_FAILED(parser.GetString("Webapp", "Profile", profile, MAXPATHLEN))) {
     ErrorDialog("Couldn't retrieve profile from web app INI file");
     return 255;
   }
 
   // Get the location of Firefox from our webapp.ini
-  char firefoxDir[MAXPATHLEN];
   if (NS_FAILED(parser.GetString("WebappRT", "InstallDir", firefoxDir, MAXPATHLEN))) {
     ErrorDialog("Couldn't find your Firefox install directory.");
     return 255;
   }
 
   // Set up appIniPath with path to application.ini.
   // This is in the Firefox installation directory.
   char appIniPath[MAXPATHLEN];
@@ -280,17 +303,17 @@ int main(int argc, char *argv[])
   char buildid[MAXPATHLEN];
   if (NS_FAILED(parser.GetString("App", "BuildID", buildid, MAXPATHLEN))) {
     ErrorDialog("Couldn't read BuildID from Firefox application.ini");
     return 255;
   }
 
   // If WebAppRT version == Firefox version, load XUL and execute the application
   if (!strcmp(buildid, NS_STRINGIFY(GRE_BUILDID))) {
-    if (GRELoadAndLaunch(firefoxDir, profile))
+    if (GRELoadAndLaunch(firefoxDir))
       return 0;
   }
   // Else, copy WebAppRT from Firefox installation and re-execute the process
   else
     CopyAndRelaunch(firefoxDir, curExePath);
 
   return 255;
 }
--- a/widget/gonk/nsLookAndFeel.cpp
+++ b/widget/gonk/nsLookAndFeel.cpp
@@ -369,8 +369,14 @@ nsLookAndFeel::GetFontImpl(FontID aID, n
     aFontName.AssignLiteral("\"Droid Sans\"");
     aFontStyle.style = NS_FONT_STYLE_NORMAL;
     aFontStyle.weight = NS_FONT_WEIGHT_NORMAL;
     aFontStyle.stretch = NS_FONT_STRETCH_NORMAL;
     aFontStyle.size = 9.0 * 96.0f / 72.0f;
     aFontStyle.systemFont = true;
     return true;
 }
+
+/*virtual*/
+bool
+nsLookAndFeel::GetEchoPasswordImpl() {
+    return true;
+}
--- a/widget/gonk/nsLookAndFeel.h
+++ b/widget/gonk/nsLookAndFeel.h
@@ -10,14 +10,15 @@
 class nsLookAndFeel : public nsXPLookAndFeel
 {
 public:
     nsLookAndFeel();
     virtual ~nsLookAndFeel();
 
     virtual bool GetFontImpl(FontID aID, nsString& aName, gfxFontStyle& aStyle);
     virtual nsresult GetIntImpl(IntID aID, PRInt32 &aResult);
+    virtual bool GetEchoPasswordImpl();
 
 protected:
     virtual nsresult NativeGetColor(ColorID aID, nscolor &aColor);
 };
 
 #endif