Merge last green changeset from mozilla-inbound to mozilla-central
authorMatt Brubeck <mbrubeck@mozilla.com>
Mon, 21 Nov 2011 08:41:42 -0800
changeset 80564 9276e3274f18d69c840df1fa44f8b5b32d0e567a
parent 80563 78cd6a30e25063fc7d7bf3ec8c23975fc46112cc (current diff)
parent 80544 0c4d3b7be17e12c03984b859c8bffc90dde1a83e (diff)
child 80565 75404dfd5ba5167bc968ae78f5adecbcf6611b00
child 80600 03fcc784d866ab1e07d4cb75f5222919c016d44f
push id3503
push userCallek@gmail.com
push dateMon, 21 Nov 2011 16:56:51 +0000
treeherdermozilla-inbound@069e4da44a5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone11.0a1
first release with
nightly win64
9276e3274f18 / 11.0a1 / 20111121092346 / files
nightly linux32
nightly linux64
nightly mac
nightly win32
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly win64
Merge last green changeset from mozilla-inbound to mozilla-central
content/canvas/test/webgl/disable-quickCheckAPI.patch
--- a/caps/src/nsSecurityManagerFactory.cpp
+++ b/caps/src/nsSecurityManagerFactory.cpp
@@ -139,16 +139,18 @@ netscape_security_isPrivilegeEnabled(JSC
                  do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
         if (NS_SUCCEEDED(rv)) {
             //            NS_ASSERTION(cx == GetCurrentContext(), "unexpected context");
 
             rv = securityManager->IsCapabilityEnabled(cap.ptr(), &result);
             if (NS_FAILED(rv)) 
                 result = JS_FALSE;
         }
+    } else {
+        return JS_FALSE;
     }
     JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(result));
     return JS_TRUE;
 }
 
 
 static JSBool
 netscape_security_enablePrivilege(JSContext *cx, uintN argc, jsval *vp)
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -139,16 +139,17 @@ class nsIBidiKeyboard;
 class nsIMIMEHeaderParam;
 class nsIObserver;
 class nsPresContext;
 class nsIChannel;
 class nsAutoScriptBlockerSuppressNodeRemoved;
 struct nsIntMargin;
 class nsPIDOMWindow;
 class nsIDocumentLoaderFactory;
+class nsIDOMHTMLInputElement;
 
 namespace mozilla {
 
 namespace layers {
   class LayerManager;
 } // namespace layers
 
 namespace dom {
@@ -1104,27 +1105,27 @@ public:
    *                       insert in the document. If empty no root element will
    *                       be created.
    * @param aDoctype Doctype node to insert in the document.
    * @param aDocumentURI URI of the document. Must not be null.
    * @param aBaseURI Base URI of the document. Must not be null.
    * @param aPrincipal Prinicpal of the document. Must not be null.
    * @param aScriptObject The object from which the context for event handling
    *                      can be got.
-   * @param aSVGDocument Force SVG Document creation.
+   * @param aFlavor Select the kind of document to create.
    * @param aResult [out] The document that was created.
    */
   static nsresult CreateDocument(const nsAString& aNamespaceURI, 
                                  const nsAString& aQualifiedName, 
                                  nsIDOMDocumentType* aDoctype,
                                  nsIURI* aDocumentURI,
                                  nsIURI* aBaseURI,
                                  nsIPrincipal* aPrincipal,
                                  nsIScriptGlobalObject* aScriptObject,
-                                 bool aSVGDocument,
+                                 DocumentFlavor aFlavor,
                                  nsIDOMDocument** aResult);
 
   /**
    * Sets the text contents of a node by replacing all existing children
    * with a single text child.
    *
    * The function always notifies.
    *
@@ -1842,17 +1843,28 @@ public:
                                 nsIURI* aURI,
                                 bool aSetUpForAboutBlank);
 
   static nsresult Btoa(const nsAString& aBinaryData,
                        nsAString& aAsciiBase64String);
 
   static nsresult Atob(const nsAString& aAsciiString,
                        nsAString& aBinaryData);
-  
+
+  /**
+   * Returns whether the input element passed in parameter has the autocomplete
+   * functionnality enabled. It is taking into account the form owner.
+   * NOTE: the caller has to make sure autocomplete makes sense for the
+   * element's type.
+   *
+   * @param aInput the input element to check. NOTE: aInput can't be null.
+   * @return whether the input element has autocomplete enabled.
+   */
+  static bool IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput);
+
 private:
   static bool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static nsIDOMScriptObjectFactory *GetDOMScriptObjectFactory();
 
   static nsresult HoldScriptObject(PRUint32 aLangID, void* aObject);
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -125,16 +125,23 @@ class Element;
 
 #define NS_IDOCUMENT_IID \
 { 0xc3e40e8e, 0x8b91, 0x424c, \
   { 0xbe, 0x9c, 0x9c, 0xc1, 0x76, 0xa7, 0xf7, 0x24 } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
+// Enum for requesting a particular type of document when creating a doc
+enum DocumentFlavor {
+  DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
+  DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true
+  DocumentFlavorSVG // SVGDocument
+};
+
 // Document states
 
 // RTL locale: specific to the XUL localedir attribute
 #define NS_DOCUMENT_STATE_RTL_LOCALE              NS_DEFINE_EVENT_STATE_MACRO(0)
 // Window activation status
 #define NS_DOCUMENT_STATE_WINDOW_INACTIVE         NS_DEFINE_EVENT_STATE_MACRO(1)
 
 //----------------------------------------------------------------------
@@ -1886,17 +1893,17 @@ NS_NewDOMDocument(nsIDOMDocument** aInst
                   const nsAString& aNamespaceURI, 
                   const nsAString& aQualifiedName, 
                   nsIDOMDocumentType* aDoctype,
                   nsIURI* aDocumentURI,
                   nsIURI* aBaseURI,
                   nsIPrincipal* aPrincipal,
                   bool aLoadedAsData,
                   nsIScriptGlobalObject* aEventObject,
-                  bool aSVGDocument);
+                  DocumentFlavor aFlavor);
 
 // This is used only for xbl documents created from the startup cache.
 // Non-cached documents are created in the same manner as xml documents.
 nsresult
 NS_NewXBLDocument(nsIDOMDocument** aInstancePtrResult,
                   nsIURI* aDocumentURI,
                   nsIURI* aBaseURI,
                   nsIPrincipal* aPrincipal);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -173,16 +173,17 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsFrameManager.h"
 #include "BasicLayers.h"
 #include "nsFocusManager.h"
 #include "nsTextEditorState.h"
 #include "nsIPluginHost.h"
 #include "nsICategoryManager.h"
 #include "nsIViewManager.h"
 #include "nsEventStateManager.h"
+#include "nsIDOMHTMLInputElement.h"
 
 #ifdef IBMBIDI
 #include "nsIBidiKeyboard.h"
 #endif
 #include "nsCycleCollectionParticipant.h"
 
 // for ReportToConsole
 #include "nsIStringBundle.h"
@@ -644,16 +645,37 @@ nsContentUtils::Atob(const nsAString& aA
 
   nsresult rv = nsXPConnect::Base64Decode(aAsciiBase64String, aBinaryData);
   if (NS_FAILED(rv) && rv == NS_ERROR_INVALID_ARG) {
     return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
   }
   return rv;
 }
 
+bool
+nsContentUtils::IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput)
+{
+  NS_PRECONDITION(aInput, "aInput should not be null!");
+
+  nsAutoString autocomplete;
+  aInput->GetAutocomplete(autocomplete);
+
+  if (autocomplete.IsEmpty()) {
+    nsCOMPtr<nsIDOMHTMLFormElement> form;
+    aInput->GetForm(getter_AddRefs(form));
+    if (!form) {
+      return true;
+    }
+
+    form->GetAutocomplete(autocomplete);
+  }
+
+  return autocomplete.EqualsLiteral("on");
+}
+
 /**
  * Access a cached parser service. Don't addref. We need only one
  * reference to it and this class has that one.
  */
 /* static */
 nsIParserService*
 nsContentUtils::GetParserService()
 {
@@ -3701,22 +3723,22 @@ nsContentUtils::ParseFragmentXML(const n
 /* static */
 nsresult
 nsContentUtils::CreateDocument(const nsAString& aNamespaceURI, 
                                const nsAString& aQualifiedName, 
                                nsIDOMDocumentType* aDoctype,
                                nsIURI* aDocumentURI, nsIURI* aBaseURI,
                                nsIPrincipal* aPrincipal,
                                nsIScriptGlobalObject* aEventObject,
-                               bool aSVGDocument,
+                               DocumentFlavor aFlavor,
                                nsIDOMDocument** aResult)
 {
   nsresult rv = NS_NewDOMDocument(aResult, aNamespaceURI, aQualifiedName,
                                   aDoctype, aDocumentURI, aBaseURI, aPrincipal,
-                                  true, aEventObject, aSVGDocument);
+                                  true, aEventObject, aFlavor);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDocument> document = do_QueryInterface(*aResult);
   
   // created documents are immediately "complete" (ready to use)
   document->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
   return NS_OK;
 }
--- a/content/base/src/nsDOMParser.cpp
+++ b/content/base/src/nsDOMParser.cpp
@@ -183,17 +183,19 @@ nsDOMParser::ParseFromStream(nsIInputStr
   // Here we have to cheat a little bit...  Setting the base URI won't
   // work if the document has a null principal, so use
   // mOriginalPrincipal when creating the document, then reset the
   // principal.
   nsCOMPtr<nsIDOMDocument> domDocument;
   rv = nsContentUtils::CreateDocument(EmptyString(), EmptyString(), nsnull,
                                       mDocumentURI, mBaseURI,
                                       mOriginalPrincipal,
-                                      scriptHandlingObject, svg,
+                                      scriptHandlingObject,
+                                      svg ? DocumentFlavorSVG :
+                                            DocumentFlavorLegacyGuess,
                                       getter_AddRefs(domDocument));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create a fake channel 
   nsCOMPtr<nsIChannel> parserChannel;
   NS_NewInputStreamChannel(getter_AddRefs(parserChannel), mDocumentURI, nsnull,
                            nsDependentCString(contentType), nsnull);
   NS_ENSURE_STATE(parserChannel);
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1442,17 +1442,19 @@ nsDOMImplementation::CreateDocument(cons
   nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
     do_QueryReferent(mScriptObject);
   
   NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject);
 
   return nsContentUtils::CreateDocument(aNamespaceURI, aQualifiedName, aDoctype,
                                         mDocumentURI, mBaseURI,
                                         mOwner->NodePrincipal(),
-                                        scriptHandlingObject, false, aReturn);
+                                        scriptHandlingObject,
+                                        DocumentFlavorLegacyGuess,
+                                        aReturn);
 }
 
 NS_IMETHODIMP
 nsDOMImplementation::CreateHTMLDocument(const nsAString& aTitle,
                                         nsIDOMDocument** aReturn)
 {
   *aReturn = nsnull;
   NS_ENSURE_STATE(mOwner);
@@ -1474,17 +1476,18 @@ nsDOMImplementation::CreateHTMLDocument(
     do_QueryReferent(mScriptObject);
 
   NS_ENSURE_STATE(!mScriptObject || scriptHandlingObject);
                                                        
   nsCOMPtr<nsIDOMDocument> document;
   rv = nsContentUtils::CreateDocument(EmptyString(), EmptyString(),
                                       doctype, mDocumentURI, mBaseURI,
                                       mOwner->NodePrincipal(),
-                                      scriptHandlingObject, false,
+                                      scriptHandlingObject,
+                                      DocumentFlavorLegacyGuess,
                                       getter_AddRefs(document));
   NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
 
   nsCOMPtr<nsIContent> root;
   rv = doc->CreateElem(NS_LITERAL_STRING("html"), NULL, kNameSpaceID_XHTML,
                        getter_AddRefs(root));
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -254,17 +254,16 @@ GK_ATOM(controls, "controls")
 GK_ATOM(coords, "coords")
 GK_ATOM(copy, "copy")
 GK_ATOM(copyOf, "copy-of")
 GK_ATOM(count, "count")
 GK_ATOM(crop, "crop")
 GK_ATOM(crossorigin, "crossorigin")
 GK_ATOM(curpos, "curpos")
 GK_ATOM(current, "current")
-GK_ATOM(currentloop, "currentloop")
 GK_ATOM(cycler, "cycler")
 GK_ATOM(data, "data")
 GK_ATOM(datalist, "datalist")
 GK_ATOM(dataType, "data-type")
 GK_ATOM(dateTime, "date-time")
 GK_ATOM(datasources, "datasources")
 GK_ATOM(datetime, "datetime")
 GK_ATOM(dblclick, "dblclick")
@@ -528,18 +527,16 @@ GK_ATOM(listing, "listing")
 GK_ATOM(listitem, "listitem")
 GK_ATOM(listrows, "listrows")
 GK_ATOM(load, "load")
 GK_ATOM(localedir, "localedir")
 GK_ATOM(localName, "local-name")
 GK_ATOM(longdesc, "longdesc")
 #ifdef MOZ_MEDIA
 GK_ATOM(loop, "loop")
-GK_ATOM(loopend, "loopend")
-GK_ATOM(loopstart, "loopstart")
 #endif
 GK_ATOM(low, "low")
 GK_ATOM(lowerFirst, "lower-first")
 GK_ATOM(lowest, "lowest")
 GK_ATOM(lowsrc, "lowsrc")
 GK_ATOM(ltr, "ltr")
 GK_ATOM(lwtheme, "lwtheme")
 GK_ATOM(lwthemetextcolor, "lwthemetextcolor")
@@ -776,24 +773,20 @@ GK_ATOM(parentfocused, "parentfocused")
 GK_ATOM(parsetype, "parsetype")
 GK_ATOM(pattern, "pattern")
 GK_ATOM(patternSeparator, "pattern-separator")
 GK_ATOM(perMille, "per-mille")
 GK_ATOM(percent, "percent")
 GK_ATOM(persist, "persist")
 GK_ATOM(phase, "phase")
 GK_ATOM(ping, "ping")
-#ifdef MOZ_MEDIA
-GK_ATOM(pixelratio, "pixelratio")
-#endif
 GK_ATOM(placeholder, "placeholder")
 GK_ATOM(plaintext, "plaintext")
 #ifdef MOZ_MEDIA
 GK_ATOM(playbackrate, "playbackrate")
-GK_ATOM(playcount, "playcount")
 #endif
 GK_ATOM(pointSize, "point-size")
 GK_ATOM(poly, "poly")
 GK_ATOM(polygon, "polygon")
 GK_ATOM(popup, "popup")
 GK_ATOM(popupalign, "popupalign")
 GK_ATOM(popupanchor, "popupanchor")
 GK_ATOM(popupgroup, "popupgroup")
--- a/content/base/src/nsTreeSanitizer.cpp
+++ b/content/base/src/nsTreeSanitizer.cpp
@@ -239,18 +239,16 @@ nsIAtom** const kAttributesHTML[] = {
   &nsGkAtoms::itemtype,
   &nsGkAtoms::kind,
   &nsGkAtoms::label,
   &nsGkAtoms::lang,
   &nsGkAtoms::list,
   &nsGkAtoms::longdesc,
 #ifdef MOZ_MEDIA
   &nsGkAtoms::loop,
-  &nsGkAtoms::loopend,
-  &nsGkAtoms::loopstart,
 #endif
   &nsGkAtoms::low,
   &nsGkAtoms::max,
   &nsGkAtoms::maxlength,
   &nsGkAtoms::media,
   &nsGkAtoms::method,
   &nsGkAtoms::min,
   &nsGkAtoms::mozdonotsend,
@@ -258,23 +256,19 @@ nsIAtom** const kAttributesHTML[] = {
   &nsGkAtoms::name,
   &nsGkAtoms::nohref,
   &nsGkAtoms::noshade,
   &nsGkAtoms::novalidate,
   &nsGkAtoms::nowrap,
   &nsGkAtoms::open,
   &nsGkAtoms::optimum,
   &nsGkAtoms::pattern,
-#ifdef MOZ_MEDIA
-  &nsGkAtoms::pixelratio,
-#endif
   &nsGkAtoms::placeholder,
 #ifdef MOZ_MEDIA
   &nsGkAtoms::playbackrate,
-  &nsGkAtoms::playcount,
 #endif
   &nsGkAtoms::pointSize,
 #ifdef MOZ_MEDIA
   &nsGkAtoms::poster,
   &nsGkAtoms::preload,
 #endif
   &nsGkAtoms::prompt,
   &nsGkAtoms::pubdate,
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -65,17 +65,16 @@
 #include "nsIScriptGlobalObject.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIMIMEService.h"
 #include "nsCExternalHandlerService.h"
 #include "nsIVariant.h"
 #include "xpcprivate.h"
-#include "nsIParser.h"
 #include "XPCQuickStubs.h"
 #include "nsStringStream.h"
 #include "nsIStreamConverterService.h"
 #include "nsICachingChannel.h"
 #include "nsContentUtils.h"
 #include "nsEventDispatcher.h"
 #include "nsDOMJSUtils.h"
 #include "nsCOMArray.h"
@@ -151,16 +150,18 @@ using namespace mozilla;
    XML_HTTP_REQUEST_SENT |                  \
    XML_HTTP_REQUEST_STOPPED)
 
 #define NS_BADCERTHANDLER_CONTRACTID \
   "@mozilla.org/content/xmlhttprequest-bad-cert-handler;1"
 
 #define NS_PROGRESS_EVENT_INTERVAL 50
 
+NS_IMPL_ISUPPORTS1(nsXHRParseEndListener, nsIDOMEventListener)
+
 class nsResumeTimeoutsEvent : public nsRunnable
 {
 public:
   nsResumeTimeoutsEvent(nsPIDOMWindow* aWindow) : mWindow(aWindow) {}
 
   NS_IMETHOD Run()
   {
     mWindow->ResumeTimeouts(false);
@@ -426,17 +427,21 @@ nsXMLHttpRequest::nsXMLHttpRequest()
   : mResponseBodyDecodedPos(0),
     mResponseType(XML_HTTP_RESPONSE_TYPE_DEFAULT),
     mRequestObserver(nsnull), mState(XML_HTTP_REQUEST_UNSENT),
     mUploadTransferred(0), mUploadTotal(0), mUploadComplete(true),
     mProgressSinceLastProgressEvent(false),
     mUploadProgress(0), mUploadProgressMax(0),
     mErrorLoad(false), mTimerIsActive(false),
     mProgressEventWasDelayed(false),
-    mLoadLengthComputable(false), mLoadTotal(0),
+    mLoadLengthComputable(false),
+    mIsHtml(false),
+    mWarnAboutMultipartHtml(false),
+    mWarnAboutSyncHtml(false),
+    mLoadTotal(0),
     mFirstStartRequestSeen(false),
     mInLoadProgressEvent(false),
     mResultJSON(JSVAL_VOID),
     mResultArrayBuffer(nsnull)
 {
   nsLayoutStatics::AddRef();
 }
 
@@ -716,17 +721,44 @@ nsXMLHttpRequest::GetResponseXML(nsIDOMD
   if (mResponseType != XML_HTTP_RESPONSE_TYPE_DEFAULT &&
       mResponseType != XML_HTTP_RESPONSE_TYPE_DOCUMENT) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
   if ((XML_HTTP_REQUEST_DONE & mState) && mResponseXML) {
     *aResponseXML = mResponseXML;
     NS_ADDREF(*aResponseXML);
   }
-
+  if (mWarnAboutMultipartHtml) {
+    mWarnAboutMultipartHtml = false;
+    nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
+                                    "HTMLMultipartXHRWarning",
+                                    nsnull,
+                                    0,
+                                    nsnull, // Response URL not kept around
+                                    EmptyString(),
+                                    0,
+                                    0,
+                                    nsIScriptError::warningFlag,
+                                    "DOM",
+                                    mOwner->WindowID());
+  }
+  if (mWarnAboutSyncHtml) {
+    mWarnAboutSyncHtml = false;
+    nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
+                                    "HTMLSyncXHRWarning",
+                                    nsnull,
+                                    0,
+                                    nsnull, // Response URL not kept around
+                                    EmptyString(),
+                                    0,
+                                    0,
+                                    nsIScriptError::warningFlag,
+                                    "DOM",
+                                    mOwner->WindowID());
+  }
   return NS_OK;
 }
 
 /*
  * This piece copied from nsXMLDocument, we try to get the charset
  * from HTTP headers.
  */
 nsresult
@@ -847,17 +879,17 @@ NS_IMETHODIMP nsXMLHttpRequest::GetRespo
 
   if (!(mState & (XML_HTTP_REQUEST_DONE | XML_HTTP_REQUEST_LOADING))) {
     return NS_OK;
   }
 
   // We only decode text lazily if we're also parsing to a doc.
   // Also, if we've decoded all current data already, then no need to decode
   // more.
-  if (!mResponseXML ||
+  if (IsWaitingForHTMLCharset() || !mResponseXML ||
       mResponseBodyDecodedPos == mResponseBody.Length()) {
     aResponseText = mResponseText;
     return NS_OK;
   }
 
   nsresult rv;
 
   nsCOMPtr<nsIDocument> document = do_QueryInterface(mResponseXML);
@@ -1436,16 +1468,26 @@ nsXMLHttpRequest::GetCurrentHttpChannel(
 }
 
 bool
 nsXMLHttpRequest::IsSystemXHR()
 {
   return !!nsContentUtils::IsSystemPrincipal(mPrincipal);
 }
 
+bool
+nsXMLHttpRequest::IsWaitingForHTMLCharset()
+{
+  if (!mIsHtml) {
+    return false;
+  }
+  nsCOMPtr<nsIDocument> doc = do_QueryInterface(mResponseXML);
+  return doc->GetDocumentCharacterSetSource() < kCharsetFromDocTypeDefault;
+}
+
 nsresult
 nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
 {
   // First check if cross-site requests are enabled...
   if (IsSystemXHR()) {
     return NS_OK;
   }
 
@@ -1870,25 +1912,51 @@ nsXMLHttpRequest::OnStartRequest(nsIRequ
                      mResponseType == XML_HTTP_RESPONSE_TYPE_DOCUMENT;
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
   if (parseBody && httpChannel) {
     nsCAutoString method;
     httpChannel->GetRequestMethod(method);
     parseBody = !method.EqualsLiteral("HEAD");
   }
 
+  mIsHtml = false;
+  mWarnAboutMultipartHtml = false;
+  mWarnAboutSyncHtml = false;
   if (parseBody && NS_SUCCEEDED(status)) {
     // We can gain a huge performance win by not even trying to
     // parse non-XML data. This also protects us from the situation
     // where we have an XML document and sink, but HTML (or other)
     // parser, which can produce unreliable results.
     nsCAutoString type;
     channel->GetContentType(type);
 
-    if (type.Find("xml") == kNotFound) {
+    if (type.EqualsLiteral("text/html")) {
+      if (!(mState & XML_HTTP_REQUEST_ASYNC)) {
+        // We don't make cool new features available in the bad synchronous
+        // mode. The synchronous mode is for legacy only.
+        mWarnAboutSyncHtml = true;
+        mState &= ~XML_HTTP_REQUEST_PARSEBODY;
+      } else if (mState & XML_HTTP_REQUEST_MULTIPART) {
+        // HTML parsing is supported only for non-multipart responses. The
+        // multipart implementation assumes that it's OK to start the next part
+        // immediately after the last part. That doesn't work with the HTML
+        // parser, because when OnStopRequest for one part has fired, the
+        // parser thread still hasn't posted back the runnables that make the
+        // parsing appear finished.
+        //
+        // On the other hand, multipart support seems to be a legacy feature,
+        // so it isn't clear that use cases justify adding support for deferring
+        // the multipart stream events between parts to accommodate the
+        // asynchronous nature of the HTML parser.
+        mWarnAboutMultipartHtml = true;
+        mState &= ~XML_HTTP_REQUEST_PARSEBODY;
+      } else {
+        mIsHtml = true;
+      }
+    } else if (type.Find("xml") == kNotFound) {
       mState &= ~XML_HTTP_REQUEST_PARSEBODY;
     }
   } else {
     // The request failed, so we shouldn't be parsing anyway
     mState &= ~XML_HTTP_REQUEST_PARSEBODY;
   }
 
   if (mState & XML_HTTP_REQUEST_PARSEBODY) {
@@ -1903,17 +1971,19 @@ nsXMLHttpRequest::OnStartRequest(nsIRequ
 
     // Create an empty document from it.  Here we have to cheat a little bit...
     // Setting the base URI to |baseURI| won't work if the document has a null
     // principal, so use mPrincipal when creating the document, then reset the
     // principal.
     const nsAString& emptyStr = EmptyString();
     nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(mOwner);
     rv = nsContentUtils::CreateDocument(emptyStr, emptyStr, nsnull, docURI,
-                                        baseURI, mPrincipal, global, false,
+                                        baseURI, mPrincipal, global,
+                                        mIsHtml ? DocumentFlavorHTML :
+                                                  DocumentFlavorLegacyGuess,
                                         getter_AddRefs(mResponseXML));
     NS_ENSURE_SUCCESS(rv, rv);
     nsCOMPtr<nsIDocument> responseDoc = do_QueryInterface(mResponseXML);
     responseDoc->SetPrincipal(documentPrincipal);
 
     if (IsSystemXHR()) {
       responseDoc->ForceEnableXULXBL();
     }
@@ -1988,32 +2058,31 @@ nsXMLHttpRequest::OnStopRequest(nsIReque
   // make sure to notify the listener if we were aborted
   // XXX in fact, why don't we do the cleanup below in this case??
   if (mState & XML_HTTP_REQUEST_UNSENT) {
     if (mXMLParserStreamListener)
       (void) mXMLParserStreamListener->OnStopRequest(request, ctxt, status);
     return NS_OK;
   }
 
-  nsCOMPtr<nsIParser> parser;
-
   // Is this good enough here?
   if (mState & XML_HTTP_REQUEST_PARSEBODY && mXMLParserStreamListener) {
-    parser = do_QueryInterface(mXMLParserStreamListener);
-    NS_ABORT_IF_FALSE(parser, "stream listener was expected to be a parser");
     mXMLParserStreamListener->OnStopRequest(request, ctxt, status);
   }
 
   mXMLParserStreamListener = nsnull;
   mReadRequest = nsnull;
   mContext = nsnull;
 
   // If we're received data since the last progress event, make sure to fire
-  // an event for it.
-  MaybeDispatchProgressEvents(true);
+  // an event for it, except in the HTML case, defer the last progress event
+  // until the parser is done.
+  if (!mIsHtml) {
+    MaybeDispatchProgressEvents(true);
+  }
 
   nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
   NS_ENSURE_TRUE(channel, NS_ERROR_UNEXPECTED);
 
   if (NS_SUCCEEDED(status) && mResponseType == XML_HTTP_RESPONSE_TYPE_BLOB) {
     if (!mResponseBlob) {
       CreateResponseBlob(request);
     }
@@ -2048,39 +2117,60 @@ nsXMLHttpRequest::OnStopRequest(nsIReque
   if (NS_FAILED(status)) {
     // This can happen if the server is unreachable. Other possible
     // reasons are that the user leaves the page or hits the ESC key.
 
     mErrorLoad = true;
     mResponseXML = nsnull;
   }
 
-  NS_ASSERTION(!parser || parser->IsParserEnabled(),
-               "Parser blocked somehow?");
-
   // If we're uninitialized at this point, we encountered an error
   // earlier and listeners have already been notified. Also we do
   // not want to do this if we already completed.
   if (mState & (XML_HTTP_REQUEST_UNSENT |
                 XML_HTTP_REQUEST_DONE)) {
     return NS_OK;
   }
 
+  if (!mResponseXML) {
+    ChangeStateToDone();
+    return NS_OK;
+  }
+  if (mIsHtml) {
+    NS_ASSERTION(!(mState & XML_HTTP_REQUEST_SYNCLOOPING),
+      "We weren't supposed to support HTML parsing with XHR!");
+    nsCOMPtr<nsIDOMEventTarget> eventTarget = do_QueryInterface(mResponseXML);
+    nsEventListenerManager* manager = eventTarget->GetListenerManager(true);
+    manager->AddEventListenerByType(new nsXHRParseEndListener(this),
+                                    NS_LITERAL_STRING("DOMContentLoaded"),
+                                    NS_EVENT_FLAG_BUBBLE |
+                                    NS_EVENT_FLAG_SYSTEM_EVENT);
+    return NS_OK;
+  }
   // We might have been sent non-XML data. If that was the case,
   // we should null out the document member. The idea in this
   // check here is that if there is no document element it is not
   // an XML document. We might need a fancier check...
-  if (mResponseXML) {
-    nsCOMPtr<nsIDOMElement> root;
-    mResponseXML->GetDocumentElement(getter_AddRefs(root));
-    if (!root) {
-      mResponseXML = nsnull;
-    }
+  nsCOMPtr<nsIDOMElement> root;
+  mResponseXML->GetDocumentElement(getter_AddRefs(root));
+  if (!root) {
+    mResponseXML = nsnull;
   }
-
+  ChangeStateToDone();
+  return NS_OK;
+}
+
+void
+nsXMLHttpRequest::ChangeStateToDone()
+{
+  if (mIsHtml) {
+    // In the HTML case, this has to be deferred, because the parser doesn't
+    // do it's job synchronously.
+    MaybeDispatchProgressEvents(true);
+  }
   ChangeState(XML_HTTP_REQUEST_DONE, true);
 
   NS_NAMED_LITERAL_STRING(errorStr, ERROR_STR);
   NS_NAMED_LITERAL_STRING(loadStr, LOAD_STR);
   DispatchProgressEvent(this,
                         mErrorLoad ? errorStr : loadStr,
                         !mErrorLoad,
                         mLoadTransferred,
@@ -2096,18 +2186,16 @@ nsXMLHttpRequest::OnStopRequest(nsIReque
     // methods/members will not throw.
     // This matches what IE does.
     mChannel = nsnull;
   }
   else if (!(mState & XML_HTTP_REQUEST_GOT_FINAL_STOP)) {
     // We're a multipart request, so we're not done. Reset to opened.
     ChangeState(XML_HTTP_REQUEST_OPENED);
   }
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXMLHttpRequest::SendAsBinary(const nsAString &aBody)
 {
   char *data = static_cast<char*>(NS_Alloc(aBody.Length() + 1));
   if (!data)
     return NS_ERROR_OUT_OF_MEMORY;
@@ -3045,21 +3133,23 @@ nsXMLHttpRequest::MaybeDispatchProgressE
                             mUploadTotal, mUploadProgress,
                             mUploadProgressMax);
     }
   } else {
     if (aFinalProgress) {
       mLoadTotal = mLoadTransferred;
       mLoadLengthComputable = true;
     }
-    mInLoadProgressEvent = true;
-    DispatchProgressEvent(this, NS_LITERAL_STRING(PROGRESS_STR),
-                          true, mLoadLengthComputable, mLoadTransferred,
-                          mLoadTotal, mLoadTransferred, mLoadTotal);
-    mInLoadProgressEvent = false;
+    if (aFinalProgress || !IsWaitingForHTMLCharset()) {
+      mInLoadProgressEvent = true;
+      DispatchProgressEvent(this, NS_LITERAL_STRING(PROGRESS_STR),
+                            true, mLoadLengthComputable, mLoadTransferred,
+                            mLoadTotal, mLoadTransferred, mLoadTotal);
+      mInLoadProgressEvent = false;
+    }
     if (mResponseType == XML_HTTP_RESPONSE_TYPE_CHUNKED_TEXT ||
         mResponseType == XML_HTTP_RESPONSE_TYPE_CHUNKED_ARRAYBUFFER) {
       mResponseBody.Truncate();
       mResponseText.Truncate();
       mResultArrayBuffer = nsnull;
     }
   }
 
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -118,16 +118,17 @@ class nsXMLHttpRequest : public nsXHREve
                          public nsIStreamListener,
                          public nsIChannelEventSink,
                          public nsIProgressEventSink,
                          public nsIInterfaceRequestor,
                          public nsSupportsWeakReference,
                          public nsIJSNativeInitializer,
                          public nsITimerCallback
 {
+  friend class nsXHRParseEndListener;
 public:
   nsXMLHttpRequest();
   virtual ~nsXMLHttpRequest();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIXMLHttpRequest
   NS_DECL_NSIXMLHTTPREQUEST
@@ -230,16 +231,20 @@ protected:
 
   nsresult GetInnerEventListener(nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
                                  nsIDOMEventListener** aListener);
 
   already_AddRefed<nsIHttpChannel> GetCurrentHttpChannel();
 
   bool IsSystemXHR();
 
+  bool IsWaitingForHTMLCharset();
+
+  void ChangeStateToDone();
+
   /**
    * Check if aChannel is ok for a cross-site request by making sure no
    * inappropriate headers are set, and no username/password is set.
    *
    * Also updates the XML_HTTP_REQUEST_USE_XSITE_AC bit.
    */
   nsresult CheckChannelForCrossSiteRequest(nsIChannel* aChannel);
 
@@ -342,16 +347,19 @@ protected:
   PRUint64 mUploadProgress; // For legacy
   PRUint64 mUploadProgressMax; // For legacy
 
   bool mErrorLoad;
 
   bool mTimerIsActive;
   bool mProgressEventWasDelayed;
   bool mLoadLengthComputable;
+  bool mIsHtml;
+  bool mWarnAboutMultipartHtml;
+  bool mWarnAboutSyncHtml;
   PRUint64 mLoadTotal; // 0 if not known.
   PRUint64 mLoadTransferred;
   nsCOMPtr<nsITimer> mProgressNotifier;
 
   bool mFirstStartRequestSeen;
   bool mInLoadProgressEvent;
   
   nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
@@ -427,9 +435,29 @@ protected:
   // Use nsDOMProgressEvent so that we can forward
   // most of the method calls easily.
   nsRefPtr<nsDOMProgressEvent> mInner;
   nsCOMPtr<nsPIDOMWindow> mWindow;
   PRUint64 mCurProgress;
   PRUint64 mMaxProgress;
 };
 
+class nsXHRParseEndListener : public nsIDOMEventListener
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_IMETHOD HandleEvent(nsIDOMEvent *event)
+  {
+    nsCOMPtr<nsIXMLHttpRequest> xhr = do_QueryReferent(mXHR);
+    if (xhr) {
+      static_cast<nsXMLHttpRequest*>(xhr.get())->ChangeStateToDone();
+    }
+    mXHR = nsnull;
+    return NS_OK;
+  }
+  nsXHRParseEndListener(nsIXMLHttpRequest* aXHR)
+    : mXHR(do_GetWeakReference(aXHR)) {}
+  virtual ~nsXHRParseEndListener() {}
+private:
+  nsWeakPtr mXHR;
+};
+
 #endif
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -500,16 +500,22 @@ include $(topsrcdir)/config/rules.mk
 		accesscontrol.resource^headers^ \
 		invalid_accesscontrol.resource \
 		invalid_accesscontrol.resource^headers^ \
 		test_xhr_progressevents.html \
 		progressserver.sjs \
 		somedatas.resource \
 		somedatas.resource^headers^ \
 		delayedServerEvents.sjs \
+		test_html_in_xhr.html \
+		file_html_in_xhr.html \
+		file_html_in_xhr2.html \
+		file_html_in_xhr3.html \
+		file_html_in_xhr.sjs \
+		file_html_in_xhr_slow.sjs \
 		test_bug664916.html \
 		test_bug666604.html \
 		test_bug675121.html \
 		file_bug675121.sjs \
 		test_bug675166.html \
 		test_bug682554.html \
 		test_bug682592.html \
 		bug682592-subframe.html \
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_html_in_xhr.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html><!--  -->
+<meta charset="Windows-1251">
+<script>
+document.documentElement.setAttribute("data-fail", "FAIL");
+</script>
+<script src="file_html_in_xhr.sjs"></script>
+<script src="file_html_in_xhr.sjs" defer></script>
+<script src="file_html_in_xhr.sjs" async></script>
+<link type="stylesheet" href="file_html_in_xhr.sjs">
+<body onload='document.documentElement.setAttribute("data-fail", "FAIL");'>
+<img src="file_html_in_xhr.sjs">
+<iframe src="file_html_in_xhr.sjs"></iframe>
+<video poster="file_html_in_xhr.sjs" src="file_html_in_xhr.sjs"></video>
+<object data="file_html_in_xhr.sjs"></object>
+<noscript><div></div></noscript>
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_html_in_xhr.sjs
@@ -0,0 +1,15 @@
+function handleRequest(request, response)
+{
+  response.setHeader("Content-Type", "text/javascript", false);
+  if (request.queryString.indexOf("report") != -1) {
+    if (getState("loaded") == "loaded") {
+      response.write("ok(false, 'This script was not supposed to get fetched.'); continueAfterReport();");
+    } else {
+      response.write("ok(true, 'This script was not supposed to get fetched.'); continueAfterReport();");      
+    }
+  } else {
+    setState("loaded", "loaded");
+    response.write('document.documentElement.setAttribute("data-fail", "FAIL");');
+  }
+}
+
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_html_in_xhr2.html
@@ -0,0 +1,1 @@
+<meta charset="windows-1251">
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_html_in_xhr3.html
@@ -0,0 +1,1 @@
+SUCCESS
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_html_in_xhr_slow.sjs
@@ -0,0 +1,24 @@
+var timer;
+
+function handleRequest(request, response)
+{
+  var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
+    .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
+  converter.charset = "windows-1251";
+  var stream = converter.convertToInputStream("\u042E");
+  var out = response.bodyOutputStream;
+  response.setHeader("Cache-Control", "no-cache", false);
+  response.setHeader("Content-Type", "text/html", false);
+  out.writeFrom(stream, 1);
+  var firstPart = "<meta charset='windows";
+  out.write(firstPart, firstPart.length);
+  out.flush();
+  response.processAsync();
+  timer = Components.classes["@mozilla.org/timer;1"]
+    .createInstance(Components.interfaces.nsITimer);
+  timer.initWithCallback(function() {
+      response.write("-1251'>");      
+      response.finish();
+    }, 500, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
+}
+
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_html_in_xhr.html
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=651072
+-->
+<head>
+  <title>Test for Bug 651072</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload=runTest();>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=651072">Mozilla Bug 651072</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 651072 **/
+SimpleTest.waitForExplicitFinish();
+
+var xhr = new XMLHttpRequest();
+
+function runTest() {
+  xhr.onreadystatechange = function() {
+    if (this.readyState == 4) {
+      ok(this.responseXML, "Should have gotten responseXML");
+      is(this.responseXML.characterSet, "windows-1251", "Wrong character encoding");
+      is(this.responseXML.documentElement.firstChild.data, " \u042E ", "Decoded using the wrong encoding.");
+      is(this.responseText.indexOf("\u042E"), 27, "Bad responseText");
+      is(this.responseXML.getElementsByTagName("div").length, 1, "There should be one div.");
+      ok(!this.responseXML.documentElement.hasAttribute("data-fail"), "Should not have a data-fail attribute.");
+      var scripts = this.responseXML.getElementsByTagName("script");
+      is(scripts.length, 4, "Unexpected number of scripts.");
+      while (scripts.length) {
+        // These should not run when moved to another doc
+        document.body.appendChild(scripts[0]);
+      }
+      var s = document.createElement("script");
+      s.src = "file_html_in_xhr.sjs?report=1";
+      document.body.appendChild(s);
+    }
+  }
+  xhr.open("GET", "file_html_in_xhr.html", true);
+  xhr.send();
+}
+
+function continueAfterReport() {
+  ok(!document.documentElement.hasAttribute("data-fail"), "Should not have a data-fail attribute on mochitest doc.");  
+  xhr = new XMLHttpRequest();
+  xhr.onprogress = function() {
+    ok(this.responseText, "Got falsy responseText");
+    if (this.responseText) {
+      ok(this.responseText.length, "Got zero-length responseText");
+      if (this.responseText.length) {
+        is(this.responseText.charCodeAt(0), 0x042E, "Wrong character encoding for slow text");
+      }
+    }
+  }
+  xhr.onreadystatechange = function() {
+    if (this.readyState == 4) {
+      testNonParsingText();
+    }
+  }
+  xhr.open("GET", "file_html_in_xhr_slow.sjs");
+  xhr.send();   
+}
+
+function testNonParsingText() {
+  xhr = new XMLHttpRequest();
+  xhr.onreadystatechange = function() {
+    if (this.readyState == 4) {
+      is(this.responseText.indexOf("\u042E"), -1, "Honored meta in text mode.");
+      is(this.responseText.indexOf("\uFFFD"), 29, "Honored meta in text mode 2.");
+      testChunkedText();
+    }
+  }
+  xhr.open("GET", "file_html_in_xhr2.html");
+  xhr.responseType = "text";
+  xhr.send();   
+}
+
+function testChunkedText() {
+  xhr = new XMLHttpRequest();
+  xhr.onprogress = function() {
+    is(this.responseText.indexOf("\u042E"), -1, "Honored meta in chunked text mode.");
+  }
+  xhr.onreadystatechange = function() {
+    if (this.readyState == 4) {
+      testSyncXHR();
+    }
+  }
+  xhr.open("GET", "file_html_in_xhr2.html");
+  xhr.responseType = "moz-chunked-text";
+  xhr.send();   
+}
+
+function testSyncXHR() {
+  xhr = new XMLHttpRequest();
+  xhr.open("GET", "file_html_in_xhr3.html", false);
+  xhr.send();   
+  is(xhr.responseText, "SUCCESS\n", "responseText should be ready by now");
+  is(xhr.responseXML, null, "responseXML should be null in the sync case");
+  SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
+
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -391,16 +391,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHTMLMediaElement)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
 NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 // nsIDOMHTMLMediaElement
 NS_IMPL_URI_ATTR(nsHTMLMediaElement, Src, src)
 NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Controls, controls)
 NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Autoplay, autoplay)
+NS_IMPL_BOOL_ATTR(nsHTMLMediaElement, Loop, loop)
 NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLMediaElement, Preload, preload, NULL)
 
 /* readonly attribute nsIDOMHTMLMediaElement mozAutoplayEnabled; */
 NS_IMETHODIMP nsHTMLMediaElement::GetMozAutoplayEnabled(bool *aAutoplayEnabled)
 {
   *aAutoplayEnabled = mAutoplayEnabled;
 
   return NS_OK;
@@ -1417,22 +1418,16 @@ bool nsHTMLMediaElement::ParseAttribute(
     { "",         nsHTMLMediaElement::PRELOAD_ATTR_EMPTY },
     { "none",     nsHTMLMediaElement::PRELOAD_ATTR_NONE },
     { "metadata", nsHTMLMediaElement::PRELOAD_ATTR_METADATA },
     { "auto",     nsHTMLMediaElement::PRELOAD_ATTR_AUTO },
     { 0 }
   };
 
   if (aNamespaceID == kNameSpaceID_None) {
-    if (aAttribute == nsGkAtoms::loopstart ||
-        aAttribute == nsGkAtoms::loopend ||
-        aAttribute == nsGkAtoms::start ||
-        aAttribute == nsGkAtoms::end) {
-      return aResult.ParseDoubleValue(aValue);
-    }
     if (ParseImageAttribute(aAttribute, aValue, aResult)) {
       return true;
     }
     if (aAttribute == nsGkAtoms::preload) {
       return aResult.ParseEnumValue(aValue, kPreloadTable, false);
     }
   }
 
@@ -2077,16 +2072,21 @@ void nsHTMLMediaElement::PlaybackEnded()
   // We changed the state of IsPlaybackEnded which can affect AddRemoveSelfReference
   AddRemoveSelfReference();
 
   if (mDecoder && mDecoder->IsInfinite()) {
     LOG(PR_LOG_DEBUG, ("%p, got duration by reaching the end of the stream", this));
     DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
   }
 
+  if (HasAttr(kNameSpaceID_None, nsGkAtoms::loop)) {
+    SetCurrentTime(0);
+    return;
+  }
+
   FireTimeUpdate(false);
   DispatchAsyncEvent(NS_LITERAL_STRING("ended"));
 }
 
 void nsHTMLMediaElement::SeekStarted()
 {
   DispatchAsyncEvent(NS_LITERAL_STRING("seeking"));
   FireTimeUpdate(false);
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -694,17 +694,17 @@ nsHTMLDocument::StartDocumentLoad(const 
   
   if (loadAsHtml5 && !viewSource &&
       (!(contentType.EqualsLiteral("text/html") || plainText) &&
       aCommand && !nsCRT::strcmp(aCommand, "view"))) {
     loadAsHtml5 = false;
   }
   
   // TODO: Proper about:blank treatment is bug 543435
-  if (loadAsHtml5 && !viewSource) {
+  if (loadAsHtml5 && aCommand && !nsCRT::strcmp(aCommand, "view")) {
     // mDocumentURI hasn't been set, yet, so get the URI from the channel
     nsCOMPtr<nsIURI> uri;
     aChannel->GetOriginalURI(getter_AddRefs(uri));
     // Adapted from nsDocShell:
     // GetSpec can be expensive for some URIs, so check the scheme first.
     bool isAbout = false;
     if (uri && NS_SUCCEEDED(uri->SchemeIs("about", &isAbout)) && isAbout) {
       nsCAutoString str;
@@ -766,19 +766,16 @@ nsHTMLDocument::StartDocumentLoad(const 
   // content viewer set up yet, and therefore do not have a useful
   // mParentDocument.
 
   // in this block of code, if we get an error result, we return it
   // but if we get a null pointer, that's perfectly legal for parent
   // and parentContentViewer
   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
 
-  // No support yet for docshell-less HTML
-  NS_ENSURE_TRUE(docShell || !IsHTML(), NS_ERROR_FAILURE);
-
   nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(docShell));
 
   nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
   if (docShellAsItem) {
     docShellAsItem->GetSameTypeParent(getter_AddRefs(parentAsItem));
   }
 
   nsCOMPtr<nsIDocShell> parent(do_QueryInterface(parentAsItem));
@@ -805,19 +802,16 @@ nsHTMLDocument::StartDocumentLoad(const 
      muCV = do_QueryInterface(cv);
   } else {
     muCV = do_QueryInterface(parentContentViewer);
     if (muCV) {
       muCVIsParent = true;
     }
   }
 
-  nsCAutoString scheme;
-  uri->GetScheme(scheme);
-
   nsCAutoString urlSpec;
   uri->GetSpec(urlSpec);
 #ifdef DEBUG_charset
   printf("Determining charset for %s\n", urlSpec.get());
 #endif
 
   // These are the charset source and charset for our document
   PRInt32 charsetSource;
@@ -825,18 +819,19 @@ nsHTMLDocument::StartDocumentLoad(const 
 
   // These are the charset source and charset for the parser.  This can differ
   // from that for the document if the channel is a wyciwyg channel.
   PRInt32 parserCharsetSource;
   nsCAutoString parserCharset;
 
   nsCOMPtr<nsIWyciwygChannel> wyciwygChannel;
   
-  if (!IsHTML()) {
-    charsetSource = kCharsetFromDocTypeDefault;
+  if (!IsHTML() || !docShell) { // no docshell for text/html XHR
+    charsetSource = IsHTML() ? kCharsetFromWeakDocTypeDefault
+                             : kCharsetFromDocTypeDefault;
     charset.AssignLiteral("UTF-8");
     TryChannelCharset(aChannel, charsetSource, charset);
     parserCharsetSource = charsetSource;
     parserCharset = charset;
   } else {
     NS_ASSERTION(docShell && docShellAsItem, "Unexpected null value");
     
     nsCOMPtr<nsIDocumentCharsetInfo> dcInfo;
@@ -941,16 +936,17 @@ nsHTMLDocument::StartDocumentLoad(const 
     muCV->SetPrevDocCharacterSet(charset);
 
   if (cachingChan) {
     NS_ASSERTION(charset == parserCharset,
                  "How did those end up different here?  wyciwyg channels are "
                  "not nsICachingChannel");
     rv = cachingChan->SetCacheTokenCachedCharset(charset);
     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "cannot SetMetaDataElement");
+    rv = NS_OK; // don't propagate error
   }
 
   // Set the parser as the stream listener for the document loader...
   if (mParser) {
     rv = NS_OK;
     nsCOMPtr<nsIStreamListener> listener = mParser->GetStreamListener();
     listener.forget(aDocListener);
 
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -116,16 +116,17 @@ include $(topsrcdir)/config/rules.mk
 		test_decoder_disable.html \
 		test_delay_load.html \
 		test_error_on_404.html \
 		test_error_in_video_document.html \
 		test_info_leak.html \
 		test_load.html \
 		test_load_candidates.html \
 		test_load_source.html \
+		test_loop.html \
 		test_media_selection.html \
 		test_mozLoadFrom.html \
 		test_networkState.html \
 		test_new_audio.html \
 		test_paused.html \
 		test_paused_after_ended.html \
 		test_play_events.html \
 		test_play_events_2.html \
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_loop.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test looping support</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+var manager = new MediaTestManager;
+
+function startTest(test, token) {
+  manager.started(token);
+  var v = document.createElement('video');
+  v.token = token;
+  v.src = test.name;
+  v.name = test.name;
+  v.playCount = 0;
+  v.seekingCount = 0;
+  v.seekedCount = 0;
+  v.loop = true;
+
+  v.addEventListener("play", function (e) {
+    e.target.playCount += 1;
+    ok(e.target.playCount == 1, "Should get exactly one play event.");
+  }, false);
+
+  v.addEventListener("seeking", function (e) {
+    e.target.seekingCount += 1;
+  }, false);
+
+  v.addEventListener("seeked", function (e) {
+    e.target.seekedCount += 1;
+    if (e.target.seekedCount == 3) {
+      ok(e.target.seekingCount == 3, "Expect matched pairs of seeking/seeked events.");
+      e.target.loop = false;
+    }
+  }, false);
+
+  v.addEventListener("ended", function (e) {
+    ok(!e.target.loop, "Shouldn't get ended event while looping.");
+    e.target.parentNode.removeChild(v);
+    manager.finished(e.target.token);
+  }, false);
+
+  document.body.appendChild(v);
+  v.play();
+}
+
+manager.runTests(gSmallTests, startTest);
+</script>
+</pre>
+</body>
+</html>
--- a/content/xbl/src/nsXBLProtoImplField.cpp
+++ b/content/xbl/src/nsXBLProtoImplField.cpp
@@ -64,17 +64,17 @@ nsXBLProtoImplField::nsXBLProtoImplField
   if (aReadOnly) {
     nsAutoString readOnly; readOnly.Assign(aReadOnly);
     if (readOnly.LowerCaseEqualsLiteral("true"))
       mJSAttributes |= JSPROP_READONLY;
   }
 }
 
 
-nsXBLProtoImplField::nsXBLProtoImplField(bool aIsReadOnly)
+nsXBLProtoImplField::nsXBLProtoImplField(const bool aIsReadOnly)
   : mNext(nsnull),
     mFieldText(nsnull),
     mFieldTextLength(0),
     mLineNumber(0)
 {
   MOZ_COUNT_CTOR(nsXBLProtoImplField);
 
   mJSAttributes = JSPROP_ENUMERATE;
--- a/content/xbl/src/nsXBLProtoImplProperty.h
+++ b/content/xbl/src/nsXBLProtoImplProperty.h
@@ -50,17 +50,17 @@
 class nsXBLProtoImplProperty: public nsXBLProtoImplMember
 {
 public:
   nsXBLProtoImplProperty(const PRUnichar* aName,
                          const PRUnichar* aGetter, 
                          const PRUnichar* aSetter,
                          const PRUnichar* aReadOnly);
 
-  nsXBLProtoImplProperty(const PRUnichar* aName, bool aIsReadOnly);
+  nsXBLProtoImplProperty(const PRUnichar* aName, const bool aIsReadOnly);
  
   virtual ~nsXBLProtoImplProperty();
 
   void AppendGetterText(const nsAString& aGetter);
   void AppendSetterText(const nsAString& aSetter);
 
   void SetGetterLineNumber(PRUint32 aLineNumber);
   void SetSetterLineNumber(PRUint32 aLineNumber);
--- a/content/xml/document/src/nsXMLDocument.cpp
+++ b/content/xml/document/src/nsXMLDocument.cpp
@@ -100,31 +100,34 @@ NS_NewDOMDocument(nsIDOMDocument** aInst
                   const nsAString& aNamespaceURI, 
                   const nsAString& aQualifiedName, 
                   nsIDOMDocumentType* aDoctype,
                   nsIURI* aDocumentURI,
                   nsIURI* aBaseURI,
                   nsIPrincipal* aPrincipal,
                   bool aLoadedAsData,
                   nsIScriptGlobalObject* aEventObject,
-                  bool aSVGDocument)
+                  DocumentFlavor aFlavor)
 {
   // Note: can't require that aDocumentURI/aBaseURI/aPrincipal be non-null,
   // since at least one caller (XMLHttpRequest) doesn't have decent args to
   // pass in.
   
   nsresult rv;
 
   *aInstancePtrResult = nsnull;
 
   nsCOMPtr<nsIDocument> d;
   bool isHTML = false;
   bool isXHTML = false;
-  if (aSVGDocument) {
+  if (aFlavor == DocumentFlavorSVG) {
     rv = NS_NewSVGDocument(getter_AddRefs(d));
+  } else if (aFlavor == DocumentFlavorHTML) {
+    rv = NS_NewHTMLDocument(getter_AddRefs(d));
+    isHTML = true;
   } else if (aDoctype) {
     nsAutoString publicId, name;
     aDoctype->GetPublicId(publicId);
     if (publicId.IsEmpty()) {
       aDoctype->GetName(name);
     }
     if (name.EqualsLiteral("html") ||
         publicId.EqualsLiteral("-//W3C//DTD HTML 4.01//EN") ||
@@ -224,17 +227,17 @@ NS_NewXBLDocument(nsIDOMDocument** aInst
                   nsIURI* aDocumentURI,
                   nsIURI* aBaseURI,
                   nsIPrincipal* aPrincipal)
 {
   nsresult rv = NS_NewDOMDocument(aInstancePtrResult,
                                   NS_LITERAL_STRING("http://www.mozilla.org/xbl"),
                                   NS_LITERAL_STRING("bindings"), nsnull,
                                   aDocumentURI, aBaseURI, aPrincipal, false,
-                                  nsnull, false);
+                                  nsnull, DocumentFlavorLegacyGuess);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDocument> idoc = do_QueryInterface(*aInstancePtrResult);
   nsDocument* doc = static_cast<nsDocument*>(idoc.get());
   doc->SetLoadedAsInteractiveData(true);
   doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
 
   return NS_OK;
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -108,17 +108,17 @@ Navigator::~Navigator()
   }
 }
 
 NS_INTERFACE_MAP_BEGIN(Navigator)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator)
   NS_INTERFACE_MAP_ENTRY(nsIDOMClientInformation)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorGeolocation)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorBattery)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMMozNavigatorBattery)
   NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorDesktopNotification)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(Navigator)
 NS_IMPL_RELEASE(Navigator)
 
 void
@@ -741,21 +741,35 @@ NS_IMETHODIMP Navigator::GetMozNotificat
   return NS_OK;
 }
 
 //*****************************************************************************
 //    Navigator::nsIDOMNavigatorBattery
 //*****************************************************************************
 
 NS_IMETHODIMP
-Navigator::GetMozBattery(nsIDOMBatteryManager** aBattery)
+Navigator::GetMozBattery(nsIDOMMozBatteryManager** aBattery)
 {
   if (!mBatteryManager) {
+    *aBattery = nsnull;
+
+    nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mDocShell);
+    NS_ENSURE_TRUE(window, NS_OK);
+
+    nsCOMPtr<nsIDocument> document = do_GetInterface(mDocShell);
+    NS_ENSURE_TRUE(document, NS_OK);
+
+    nsIScriptGlobalObject* sgo = document->GetScopeObject();
+    NS_ENSURE_TRUE(sgo, NS_OK);
+
+    nsIScriptContext* scx = sgo->GetContext();
+    NS_ENSURE_TRUE(scx, NS_OK);
+
     mBatteryManager = new battery::BatteryManager();
-    mBatteryManager->Init();
+    mBatteryManager->Init(window->GetCurrentInnerWindow(), scx);
   }
 
   NS_ADDREF(*aBattery = mBatteryManager);
 
   return NS_OK;
 }
 
 PRInt64
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -66,28 +66,28 @@ namespace dom {
 namespace battery {
 class BatteryManager;
 } // namespace battery
 
 class Navigator : public nsIDOMNavigator,
                   public nsIDOMClientInformation,
                   public nsIDOMNavigatorGeolocation,
                   public nsIDOMNavigatorDesktopNotification,
-                  public nsIDOMNavigatorBattery
+                  public nsIDOMMozNavigatorBattery
 {
 public:
   Navigator(nsIDocShell *aDocShell);
   virtual ~Navigator();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMNAVIGATOR
   NS_DECL_NSIDOMCLIENTINFORMATION
   NS_DECL_NSIDOMNAVIGATORGEOLOCATION
   NS_DECL_NSIDOMNAVIGATORDESKTOPNOTIFICATION
-  NS_DECL_NSIDOMNAVIGATORBATTERY
+  NS_DECL_NSIDOMMOZNAVIGATORBATTERY
 
   static void Init();
 
   void SetDocShell(nsIDocShell *aDocShell);
   nsIDocShell *GetDocShell()
   {
     return mDocShell;
   }
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1380,17 +1380,17 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(GeoPositionAddress, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(GeoPositionError, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
-  NS_DEFINE_CLASSINFO_DATA(BatteryManager, nsDOMGenericSH,
+  NS_DEFINE_CLASSINFO_DATA(MozBatteryManager, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(CSSFontFaceStyleDecl, nsCSSStyleDeclSH,
                            ARRAY_SCRIPTABLE_FLAGS)
 
 #if defined(MOZ_MEDIA)
@@ -2282,17 +2282,17 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Navigator, nsIDOMNavigator)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigator)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorGeolocation)
     DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMNavigatorDesktopNotification,
                                         Navigator::HasDesktopNotificationSupport())
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMClientInformation)
-    DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMNavigatorBattery,
+    DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMMozNavigatorBattery,
                                         battery::BatteryManager::HasSupport())
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Plugin, nsIDOMPlugin)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMPlugin)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(PluginArray, nsIDOMPluginArray)
@@ -3861,18 +3861,18 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN(GeoPositionAddress, nsIDOMGeoPositionAddress)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionAddress)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(GeoPositionError, nsIDOMGeoPositionError)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionError)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(BatteryManager, nsIDOMBatteryManager)
-     DOM_CLASSINFO_MAP_ENTRY(nsIDOMBatteryManager)
+  DOM_CLASSINFO_MAP_BEGIN(MozBatteryManager, nsIDOMMozBatteryManager)
+     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozBatteryManager)
      DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule, nsIDOMCSSFontFaceRule)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(CSSFontFaceStyleDecl,
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -421,17 +421,17 @@ DOMCI_CLASS(MessageEvent)
 
 // Geolocation
 DOMCI_CLASS(GeoGeolocation)
 DOMCI_CLASS(GeoPosition)
 DOMCI_CLASS(GeoPositionCoords)
 DOMCI_CLASS(GeoPositionAddress)
 DOMCI_CLASS(GeoPositionError)
 
-DOMCI_CLASS(BatteryManager)
+DOMCI_CLASS(MozBatteryManager)
 
 // @font-face in CSS
 DOMCI_CLASS(CSSFontFaceRule)
 DOMCI_CLASS(CSSFontFaceStyleDecl)
 
 #if defined(MOZ_MEDIA)
 // WhatWG Video Element
 DOMCI_CLASS(HTMLVideoElement)
--- a/dom/battery/BatteryManager.cpp
+++ b/dom/battery/BatteryManager.cpp
@@ -47,63 +47,69 @@
  * We have to use macros here because our leak analysis tool things we are
  * leaking strings when we have |static const nsString|. Sad :(
  */
 #define LEVELCHANGE_EVENT_NAME           NS_LITERAL_STRING("levelchange")
 #define CHARGINGCHANGE_EVENT_NAME        NS_LITERAL_STRING("chargingchange")
 #define DISCHARGINGTIMECHANGE_EVENT_NAME NS_LITERAL_STRING("dischargingtimechange")
 #define CHARGINGTIMECHANGE_EVENT_NAME    NS_LITERAL_STRING("chargingtimechange")
 
-DOMCI_DATA(BatteryManager, mozilla::dom::battery::BatteryManager)
+DOMCI_DATA(MozBatteryManager, mozilla::dom::battery::BatteryManager)
 
 namespace mozilla {
 namespace dom {
 namespace battery {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(BatteryManager)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BatteryManager,
-                                                  nsDOMEventTargetHelper)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLevelChangeListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnChargingChangeListener)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnDischargingTimeChangeListener)
+                                                  nsDOMEventTargetWrapperCache)
+  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(levelchange)
+  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(chargingchange)
+  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(chargingtimechange)
+  NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(dischargingtimechange)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BatteryManager,
-                                                nsDOMEventTargetHelper)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLevelChangeListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnChargingChangeListener)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnDischargingTimeChangeListener)
+                                                nsDOMEventTargetWrapperCache)
+  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(levelchange)
+  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(chargingchange)
+  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(chargingtimechange)
+  NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(dischargingtimechange)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BatteryManager)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMBatteryManager)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BatteryManager)
-NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMMozBatteryManager)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozBatteryManager)
+NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
 
-NS_IMPL_ADDREF_INHERITED(BatteryManager, nsDOMEventTargetHelper)
-NS_IMPL_RELEASE_INHERITED(BatteryManager, nsDOMEventTargetHelper)
+NS_IMPL_ADDREF_INHERITED(BatteryManager, nsDOMEventTargetWrapperCache)
+NS_IMPL_RELEASE_INHERITED(BatteryManager, nsDOMEventTargetWrapperCache)
 
 BatteryManager::BatteryManager()
   : mLevel(kDefaultLevel)
   , mCharging(kDefaultCharging)
   , mRemainingTime(kUnknownRemainingTime)
 {
 }
 
 BatteryManager::~BatteryManager()
 {
   if (mListenerManager) {
     mListenerManager->Disconnect();
   }
 }
 
 void
-BatteryManager::Init()
+BatteryManager::Init(nsPIDOMWindow *aWindow, nsIScriptContext* aScriptContext)
 {
+  // Those vars come from nsDOMEventTargetHelper.
+  mOwner = aWindow;
+  mScriptContext = aScriptContext;
+
   hal::RegisterBatteryObserver(this);
 
   hal::BatteryInformation* batteryInfo = new hal::BatteryInformation();
   hal::GetCurrentBatteryInformation(batteryInfo);
 
   UpdateFromBatteryInfo(*batteryInfo);
 
   delete batteryInfo;
@@ -152,71 +158,20 @@ BatteryManager::GetChargingTime(double* 
     return NS_OK;
   }
 
   *aChargingTime = mRemainingTime;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-BatteryManager::GetOnlevelchange(nsIDOMEventListener** aOnlevelchange)
-{
-  return GetInnerEventListener(mOnLevelChangeListener, aOnlevelchange);
-}
-
-NS_IMETHODIMP
-BatteryManager::SetOnlevelchange(nsIDOMEventListener* aOnlevelchange)
-{
-  return RemoveAddEventListener(LEVELCHANGE_EVENT_NAME, mOnLevelChangeListener,
-                                aOnlevelchange);
-}
-
-NS_IMETHODIMP
-BatteryManager::GetOnchargingchange(nsIDOMEventListener** aOnchargingchange)
-{
-  return GetInnerEventListener(mOnChargingChangeListener, aOnchargingchange);
-}
-
-NS_IMETHODIMP
-BatteryManager::SetOnchargingchange(nsIDOMEventListener* aOnchargingchange)
-{
-  return RemoveAddEventListener(CHARGINGCHANGE_EVENT_NAME,
-                                mOnChargingChangeListener, aOnchargingchange);
-}
-
-NS_IMETHODIMP
-BatteryManager::GetOndischargingtimechange(nsIDOMEventListener** aOndischargingtimechange)
-{
-  return GetInnerEventListener(mOnDischargingTimeChangeListener,
-                               aOndischargingtimechange);
-}
-
-NS_IMETHODIMP
-BatteryManager::SetOndischargingtimechange(nsIDOMEventListener* aOndischargingtimechange)
-{
-  return RemoveAddEventListener(DISCHARGINGTIMECHANGE_EVENT_NAME,
-                                mOnDischargingTimeChangeListener,
-                                aOndischargingtimechange);
-}
-
-NS_IMETHODIMP
-BatteryManager::GetOnchargingtimechange(nsIDOMEventListener** aOnchargingtimechange)
-{
-  return GetInnerEventListener(mOnChargingTimeChangeListener,
-                               aOnchargingtimechange);
-}
-
-NS_IMETHODIMP
-BatteryManager::SetOnchargingtimechange(nsIDOMEventListener* aOnchargingtimechange)
-{
-  return RemoveAddEventListener(CHARGINGTIMECHANGE_EVENT_NAME,
-                                mOnChargingTimeChangeListener,
-                                aOnchargingtimechange);
-}
+NS_IMPL_EVENT_HANDLER(BatteryManager, levelchange)
+NS_IMPL_EVENT_HANDLER(BatteryManager, chargingchange)
+NS_IMPL_EVENT_HANDLER(BatteryManager, chargingtimechange)
+NS_IMPL_EVENT_HANDLER(BatteryManager, dischargingtimechange)
 
 nsresult
 BatteryManager::DispatchTrustedEventToSelf(const nsAString& aEventName)
 {
   nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
   nsresult rv = event->InitEvent(aEventName, false, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/dom/battery/BatteryManager.h
+++ b/dom/battery/BatteryManager.h
@@ -34,50 +34,53 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_dom_battery_BatteryManager_h
 #define mozilla_dom_battery_BatteryManager_h
 
 #include "nsIDOMBatteryManager.h"
-#include "nsDOMEventTargetHelper.h"
+#include "nsDOMEventTargetWrapperCache.h"
 #include "nsCycleCollectionParticipant.h"
 #include "mozilla/Observer.h"
 #include "Types.h"
 
+class nsPIDOMWindow;
+class nsIScriptContext;
+
 namespace mozilla {
 
 namespace hal {
 class BatteryInformation;
 } // namespace hal
 
 namespace dom {
 namespace battery {
 
-class BatteryManager : public nsIDOMBatteryManager
-                     , public nsDOMEventTargetHelper
+class BatteryManager : public nsDOMEventTargetWrapperCache
+                     , public nsIDOMMozBatteryManager
                      , public BatteryObserver
 {
 public:
   NS_DECL_ISUPPORTS
-  NS_DECL_NSIDOMBATTERYMANAGER
-  NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
+  NS_DECL_NSIDOMMOZBATTERYMANAGER
+  NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetWrapperCache::)
 
   BatteryManager();
   virtual ~BatteryManager();
 
-  void Init();
+  void Init(nsPIDOMWindow *aWindow, nsIScriptContext* aScriptContext);
   void Shutdown();
 
   // For IObserver.
   void Notify(const hal::BatteryInformation& aBatteryInfo);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BatteryManager,
-                                           nsDOMEventTargetHelper)
+                                           nsDOMEventTargetWrapperCache)
 
   /**
    * Returns whether the battery api is supported (ie. not disabled by the user)
    * @return whether the battery api is supported.
    */
   static bool HasSupport();
 
 
@@ -96,19 +99,19 @@ private:
   double mLevel;
   bool   mCharging;
   /**
    * Represents the discharging time or the charging time, dpending on the
    * current battery status (charging or not).
    */
   double mRemainingTime;
 
-  nsRefPtr<nsDOMEventListenerWrapper> mOnLevelChangeListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnChargingChangeListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnDischargingTimeChangeListener;
-  nsRefPtr<nsDOMEventListenerWrapper> mOnChargingTimeChangeListener;
+  NS_DECL_EVENT_HANDLER(levelchange);
+  NS_DECL_EVENT_HANDLER(chargingchange);
+  NS_DECL_EVENT_HANDLER(chargingtimechange);
+  NS_DECL_EVENT_HANDLER(dischargingtimechange);
 };
 
 } // namespace battery
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_battery_BatteryManager_h
--- a/dom/battery/nsIDOMBatteryManager.idl
+++ b/dom/battery/nsIDOMBatteryManager.idl
@@ -33,18 +33,18 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMEventTarget.idl"
 
 interface nsIDOMEventListener;
 
-[scriptable, function, uuid(6dcb803b-e968-4c02-88f5-049a3f2a2efb)]
-interface nsIDOMBatteryManager : nsIDOMEventTarget
+[scriptable, function, uuid(98b6237b-9654-43de-97e0-acf4b091b4e7)]
+interface nsIDOMMozBatteryManager : nsIDOMEventTarget
 {
   readonly attribute double     level;
   readonly attribute boolean    charging;
   readonly attribute double     dischargingTime;
   readonly attribute double     chargingTime;
 
   attribute nsIDOMEventListener onlevelchange;
   attribute nsIDOMEventListener onchargingchange;
--- a/dom/battery/nsIDOMNavigatorBattery.idl
+++ b/dom/battery/nsIDOMNavigatorBattery.idl
@@ -31,15 +31,15 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 
-interface nsIDOMBatteryManager;
+interface nsIDOMMozBatteryManager;
 
-[scriptable, uuid(a19eedd7-6c26-4676-bd34-7ca74ca5f565)]
-interface nsIDOMNavigatorBattery : nsISupports
+[scriptable, uuid(c295f049-be3d-4f83-9f7c-5c3e91d6ecb9)]
+interface nsIDOMMozNavigatorBattery : nsISupports
 {
-  readonly attribute nsIDOMBatteryManager mozBattery;
+  readonly attribute nsIDOMMozBatteryManager mozBattery;
 };
--- a/dom/battery/test/test_battery_basics.html
+++ b/dom/battery/test/test_battery_basics.html
@@ -9,16 +9,22 @@
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Battery API **/
 
+// Testing prefixing.
+ok(!("NavigatorBattery" in window), "NavigatorBattery shouldn't be visible");
+ok(("MozNavigatorBattery" in window), "MozNavigatorBattery should be visible");
+ok(!("BatteryManager" in window), "BatteryManager shouldn't be visible");
+ok(("MozBatteryManager" in window), "MozBatteryManager should be visible");
+
 ok('mozBattery' in navigator, "navigator.mozBattery should exist");
 
 var battery = navigator.mozBattery;
 is(battery.level, 1.0, "Default battery level should be 1.0");
 is(battery.charging, true, "Default charging value should be true");
 is(battery.dischargingTime, Infinity, "Default dischargingTime should be Inifinity");
 is(battery.chargingTime, Infinity, "Default chargingTime should be Inifinity");
 
--- a/dom/interfaces/html/nsIDOMHTMLMediaElement.idl
+++ b/dom/interfaces/html/nsIDOMHTMLMediaElement.idl
@@ -52,17 +52,17 @@
 
 // undef the GetCurrentTime macro defined in WinBase.h from the MS Platform SDK
 %{C++
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 %}
 
-[scriptable, uuid(642a3b85-4edb-4c01-a162-06b5d88171e7)]
+[scriptable, uuid(f6eddb8a-7480-4b15-af2c-cc6ce9a7c140)]
 interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
 {
   // error state
   readonly attribute nsIDOMMediaError error;
 
   // network state
            attribute DOMString src;
   readonly attribute DOMString currentSrc;
@@ -89,16 +89,17 @@ interface nsIDOMHTMLMediaElement : nsIDO
            attribute double currentTime;
   readonly attribute double initialTime;
   readonly attribute double duration;
   readonly attribute boolean paused;
   readonly attribute nsIDOMTimeRanges seekable;
   readonly attribute boolean ended;
   readonly attribute boolean mozAutoplayEnabled;
            attribute boolean autoplay;
+           attribute boolean loop;
   void play();
   void pause();
 
   // controls
            attribute boolean controls;
            attribute double volume;
            attribute boolean muted;
 
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -110,8 +110,10 @@ TextContentWarning=Use of attributes' te
 EnablePrivilegeWarning=Use of enablePrivilege is deprecated.  Please use code that runs with the system principal (e.g. an extension) instead.
 PositionWarning=Use of XMLHttpRequest's progress events' position attribute is deprecated.
 TotalSizeWarning=Use of XMLHttpRequest's progress events' totalSize attribute is deprecated.
 nsIJSONDecodeDeprecatedWarning=nsIJSON.decode is deprecated.  Please use JSON.parse instead.
 nsIJSONEncodeDeprecatedWarning=nsIJSON.encode is deprecated.  Please use JSON.stringify instead.
 nsIDOMWindowInternalWarning=Use of nsIDOMWindowInternal is deprecated. Use nsIDOMWindow instead.
 InputEncodingWarning=Use of inputEncoding is deprecated.
 GlobalStorageWarning=Use of globalStorage is deprecated. Please use localStorage instead.
+HTMLMultipartXHRWarning=HTML parsing in XMLHttpRequest is not supported for multipart responses.
+HTMLSyncXHRWarning=HTML parsing in XMLHttpRequest is not supported in the synchronous mode.
--- a/gfx/layers/d3d9/Nv3DVUtils.cpp
+++ b/gfx/layers/d3d9/Nv3DVUtils.cpp
@@ -122,23 +122,25 @@ Nv3DVUtils::SetDeviceInfo(IUnknown *devU
   }
 
   if (!m3DVStreaming) {
       return;
   }
 
   bool rv = false;
   rv = m3DVStreaming->Nv3DVSetDevice(devUnknown);
-  if (!rv) {
+  if (NS_FAILED(rv)) {
       NS_WARNING("Nv3DVStreaming Nv3DVControl failed!");
       return;
   }
 
   rv = m3DVStreaming->Nv3DVControl(NV_STEREO_MODE_RIGHT_LEFT, true, FIREFOX_3DV_APP_HANDLE);
-  NS_ASSERTION(rv, "Nv3DVStreaming Nv3DVControl failed!");
+  if (NS_FAILED(rv)) {
+    NS_WARNING("Nv3DVStreaming Nv3DVControl failed!");
+  }
 }
 
 /*
  * Send Stereo Control Information. Used mainly to re-route 
  * calls from ImageLayerD3D9 to the 3DV COM object
  */
 void 
 Nv3DVUtils::SendNv3DVControl(Nv_Stereo_Mode eStereoMode, bool bEnableStereo, DWORD dw3DVAppHandle)
--- a/gfx/thebes/gfxUserFontSet.cpp
+++ b/gfx/thebes/gfxUserFontSet.cpp
@@ -574,21 +574,20 @@ gfxUserFontSet::OnLoadComplete(gfxProxyF
                    aDownloadStatus);
     }
 
     if (aFontData) {
         NS_Free((void*)aFontData);
     }
 
     // error occurred, load next src
-    LoadStatus status;
+    (void)LoadNext(aProxy);
 
-    status = LoadNext(aProxy);
-
-    // Even if loading failed, we need to bump the font-set generation
+    // We ignore the status returned by LoadNext();
+    // even if loading failed, we need to bump the font-set generation
     // and return true in order to trigger reflow, so that fallback
     // will be used where the text was "masked" by the pending download
     IncrementGeneration();
     return true;
 }
 
 
 gfxUserFontSet::LoadStatus
--- a/js/jsd/Makefile.in
+++ b/js/jsd/Makefile.in
@@ -37,29 +37,31 @@
 # ***** END LICENSE BLOCK *****
 
 
 
 DEPTH		= ../..
 topsrcdir	= @top_srcdir@
 VPATH		= @srcdir@
 srcdir		= @srcdir@
+relativesrcdir  = js/jsd
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= jsdebug
 LIBRARY_NAME	= jsd
 DIRS	= idl
 CPPSRCS	 = jsd_xpc.cpp
 IS_COMPONENT = 1
 LIBXUL_LIBRARY = 1
 
 MODULE_NAME = JavaScript_Debugger
 EXPORT_LIBRARY = 1
 
+XPCSHELL_TESTS  = test
 
 # REQUIRES	= java js
 
 EXPORTS		= jsdebug.h
 
 ifdef JS_THREADSAFE
 DEFINES         += -DJS_THREADSAFE
 endif
new file mode 100644
--- /dev/null
+++ b/js/jsd/test/test_jsval_retval.js
@@ -0,0 +1,39 @@
+// Bug 689101 - if the binary layout of jsval does not match between C and C++
+// code, then calls to functions returning jsval may get compiled differently
+// than the callee, resulting in parameters being shifted over by one.
+//
+// An example is where on Windows, calling jsdValue.getWrappedValue() will
+// return a random floating point number instead of an object.
+//
+// This test must be run with debugging already enabled
+
+function run_test() {
+    const Cc = Components.classes;
+    const Ci = Components.interfaces;
+    const DebuggerService = Cc["@mozilla.org/js/jsd/debugger-service;1"];
+    const jsdIDebuggerService = Ci.jsdIDebuggerService;
+    var jsd = DebuggerService.getService(jsdIDebuggerService);
+
+    do_check_true(jsd.isOn);
+
+    var n = 0;
+    function f() {
+        n++;
+    }
+
+    jsd.enumerateScripts({ enumerateScript: function(script) {
+        script.setBreakpoint(0);
+    } });
+
+    jsd.breakpointHook = function(frame, type, dummy) {
+        var scope = frame.scope;
+        var parent = scope.jsParent; // Probably does not need to be called
+        var wrapped = scope.getWrappedValue();
+        // Do not try to print 'wrapped'; it may be an internal Call object
+        // that will crash when you toString it. Different bug.
+        do_check_eq(typeof(wrapped), "object");
+        return Ci.jsdIExecutionHook.RETURN_CONTINUE;
+    };
+
+    f();
+}
new file mode 100644
--- /dev/null
+++ b/js/jsd/test/xpcshell.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+head =
+tail =
+
+[test_jsval_retval.js]
+debug = 1
--- a/js/public/Utility.h
+++ b/js/public/Utility.h
@@ -341,24 +341,24 @@ unsigned char _BitScanReverse64(unsigned
  */
 #define JS_FLOOR_LOG2W(n) (JS_ASSERT((n) != 0), js_FloorLog2wImpl(n))
 
 #if JS_BYTES_PER_WORD == 4
 # ifdef JS_HAS_BUILTIN_BITSCAN32
 #  define js_FloorLog2wImpl(n)                                                \
     ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n)))
 # else
-extern size_t js_FloorLog2wImpl(size_t n);
+JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n);
 # endif
 #elif JS_BYTES_PER_WORD == 8
 # ifdef JS_HAS_BUILTIN_BITSCAN64
 #  define js_FloorLog2wImpl(n)                                                \
     ((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n)))
 # else
-extern size_t js_FloorLog2wImpl(size_t n);
+JS_PUBLIC_API(size_t) js_FloorLog2wImpl(size_t n);
 # endif
 #else
 # error "NOT SUPPORTED"
 #endif
 
 JS_END_EXTERN_C
 
 #ifdef __cplusplus
--- a/js/src/jit-test/tests/basic/bug698584.js
+++ b/js/src/jit-test/tests/basic/bug698584.js
@@ -1,14 +1,21 @@
-// |jit-test| error: InternalError
+// |jit-test| allow-oom;
 /* 
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/licenses/publicdomain/
  */
 
-const MAX = 10000;
-var str = "";
-for (var i = 0; i < MAX; ++i) {
-    /x/.test(str);
-    str += str + 'xxxxxxxxxxxxxx';
+try
+{ 
+  const MAX = 10000;
+  var str = "";
+  for (var i = 0; i < MAX; ++i) {
+      /x/.test(str);
+      str += str + 'xxxxxxxxxxxxxx';
+  }
+}
+catch (e)
+{
+  assertEq(""+e, "InternalError: allocation size overflow");
 }
 
 /* Don't crash */
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -547,22 +547,19 @@ DumpXPC(JSContext *cx, uintN argc, jsval
         xpc->DebugDump((int16)depth);
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 static JSBool
 GC(JSContext *cx, uintN argc, jsval *vp)
 {
-    JSRuntime *rt;
-
-    rt = cx->runtime;
     JS_GC(cx);
 #ifdef JS_GCMETER
-    js_DumpGCStats(rt, stdout);
+    js_DumpGCStats(cx->runtime, stdout);
 #endif
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 #ifdef JS_GC_ZEAL
 static JSBool
 GCZeal(JSContext *cx, uintN argc, jsval *vp)
@@ -1231,16 +1228,19 @@ ProcessArgs(JSContext *cx, JSObject *obj
         case 'S':
             JS_ToggleOptions(cx, JSOPTION_WERROR);
         case 's':
             JS_ToggleOptions(cx, JSOPTION_STRICT);
             break;
         case 'x':
             JS_ToggleOptions(cx, JSOPTION_XML);
             break;
+        case 'd':
+            xpc_ActivateDebugMode();
+            break;
         case 'P':
             if (JS_GET_CLASS(cx, JS_GetPrototype(cx, obj)) != &global_class) {
                 JSObject *gobj;
 
                 if (!JS_DeepFreezeObject(cx, obj))
                     return JS_FALSE;
                 gobj = JS_NewGlobalObject(cx, &global_class);
                 if (!gobj || !JS_SplicePrototype(cx, gobj, obj))
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2714,26 +2714,25 @@ nsXPCComponents_Utils::LookupMethod()
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
     // it would a be a big surprise if there is a member without an interface :)
     XPCNativeInterface* iface = inner_cc.GetInterface();
     if (!iface)
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
     jsval funval;
-    JSFunction *oldfunction;
 
     // get (and perhaps lazily create) the member's cloned function
     if (!member->NewFunctionObject(inner_cc, iface,
                                    JSVAL_TO_OBJECT(argv[0]),
                                    &funval))
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
-    oldfunction = JS_ValueToFunction(inner_cc, funval);
-    NS_ASSERTION(oldfunction, "Function is not a function");
+    NS_ASSERTION(JS_ValueToFunction(inner_cc, funval),
+                 "Function is not a function");
 
     // Stick the function in the return value. This roots it.
     *retval = funval;
 
     // Tell XPConnect that we returned the function through the call context.
     cc->SetReturnValueWasSet(true);
     return NS_OK;
 }
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -267,17 +267,17 @@ CompartmentCallback(JSContext *cx, JSCom
     nsAutoPtr<xpc::CompartmentPrivate> priv(static_cast<xpc::CompartmentPrivate*>(JS_SetCompartmentPrivate(cx, compartment, nsnull)));
     if (!priv)
         return JS_TRUE;
 
     if (xpc::PtrAndPrincipalHashKey *key = priv->key) {
         XPCCompartmentMap &map = self->GetCompartmentMap();
 #ifdef DEBUG
         {
-            JSCompartment *current = NULL;  // init to shut GCC up
+            JSCompartment *current = NULL;
             NS_ASSERTION(map.Get(key, &current), "no compartment?");
             NS_ASSERTION(current == compartment, "compartment mismatch");
         }
 #endif
         map.Remove(key);
     } else {
         nsISupports *ptr = priv->ptr;
         XPCMTCompartmentMap &map = self->GetMTCompartmentMap();
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -2273,17 +2273,17 @@ CallMethodHelper::~CallMethodHelper()
             if (paramInfo.GetType().IsArray()) {
                 void* p = dp->val.p;
                 if (!p)
                     continue;
 
                 // Clean up the array contents if necessary.
                 if (dp->DoesValNeedCleanup()) {
                     // We need some basic information to properly destroy the array.
-                    JSUint32 array_count;
+                    JSUint32 array_count = 0;
                     nsXPTType datum_type;
                     if (!GetArraySizeFromParam(i, &array_count) ||
                         !NS_SUCCEEDED(mIFaceInfo->GetTypeForParam(mVTableIndex,
                                                                   &paramInfo,
                                                                   1, &datum_type))) {
                         // XXXbholley - I'm not convinced that the above calls will
                         // ever fail.
                         NS_ERROR("failed to get array information, we'll leak here");
@@ -2408,17 +2408,17 @@ CallMethodHelper::GatherAndConvertResult
         const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(i);
         if (!paramInfo.IsOut() && !paramInfo.IsDipper())
             continue;
 
         const nsXPTType& type = paramInfo.GetType();
         nsXPTCVariant* dp = GetDispatchParam(i);
         jsval v = JSVAL_NULL;
         AUTO_MARK_JSVAL(mCallContext, &v);
-        JSUint32 array_count;
+        JSUint32 array_count = 0;
         nsXPTType datum_type;
         bool isArray = type.IsArray();
         bool isSizedString = isArray ?
                 JS_FALSE :
                 type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS ||
                 type.TagPart() == nsXPTType::T_PWSTRING_SIZE_IS;
 
         if (isArray) {
@@ -2733,17 +2733,17 @@ CallMethodHelper::ConvertDependentParams
     for (uint8 i = 0; i < paramCount; i++) {
         const nsXPTParamInfo& paramInfo = mMethodInfo->GetParam(i);
         const nsXPTType& type = paramInfo.GetType();
 
         if (!type.IsDependent())
             continue;
 
         nsXPTType datum_type;
-        JSUint32 array_count;
+        JSUint32 array_count = 0;
         bool isArray = type.IsArray();
 
         bool isSizedString = isArray ?
             JS_FALSE :
             type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS ||
             type.TagPart() == nsXPTType::T_PWSTRING_SIZE_IS;
 
         nsXPTCVariant* dp = GetDispatchParam(i);
--- a/js/xpconnect/src/XPCWrappedNativeInfo.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeInfo.cpp
@@ -262,17 +262,17 @@ XPCNativeInterface::NewInstance(XPCCallC
 
     int i;
     JSBool failed = JS_FALSE;
     PRUint16 constCount;
     PRUint16 methodCount;
     PRUint16 totalCount;
     PRUint16 realTotalCount = 0;
     XPCNativeMember* cur;
-    JSString*  str;
+    JSString* str = NULL;
     jsid name;
     jsid interfaceName;
 
     // XXX Investigate lazy init? This is a problem given the
     // 'placement new' scheme - we need to at least know how big to make
     // the object. We might do a scan of methods to determine needed size,
     // then make our object, but avoid init'ing *any* members until asked?
     // Find out how often we create these objects w/o really looking at
--- a/js/xpconnect/src/nsDOMQS.h
+++ b/js/xpconnect/src/nsDOMQS.h
@@ -50,16 +50,17 @@ xpc_qsUnwrapThis<_interface>(JSContext *
                              jsval *pThisVal,                                 \
                              XPCLazyCallContext *lccx,                        \
                              bool failureFatal)                               \
 {                                                                             \
     nsresult rv;                                                              \
     nsISupports *native = castNativeFromWrapper(cx, obj, callee, _bit,        \
                                                 pThisRef, pThisVal, lccx,     \
                                                 &rv);                         \
+    *ppThis = NULL;  /* avoids uninitialized warnings in callers */           \
     if (failureFatal && !native)                                              \
         return xpc_qsThrow(cx, rv);                                           \
     *ppThis = static_cast<_interface*>(static_cast<_base*>(native));          \
     return JS_TRUE;                                                           \
 }                                                                             \
                                                                               \
 NS_SPECIALIZE_TEMPLATE                                                        \
 inline nsresult                                                               \
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -2573,16 +2573,24 @@ fail:
      * always safe to turn debug mode off, since DeactivateDebugger prevents
      * debugger callbacks from having any effect.
      */
     if (gDesiredDebugMode)
         JS_SetRuntimeDebugMode(rt, JS_FALSE);
     gDesiredDebugMode = gDebugMode = JS_FALSE;
 }
 
+NS_EXPORT_(void)
+xpc_ActivateDebugMode()
+{
+    XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
+    nsXPConnect::GetXPConnect()->SetDebugModeWhenPossible(true, true);
+    nsXPConnect::CheckForDebugMode(rt->GetJSRuntime());
+}
+
 /* JSContext Pop (); */
 NS_IMETHODIMP
 nsXPConnect::Pop(JSContext * *_retval)
 {
     XPCPerThreadData* data = XPCPerThreadData::GetData(nsnull);
 
     if (!data) {
         if (_retval)
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -590,16 +590,18 @@ public:
                                     bool showThisProps);
 
 
     static bool ReportAllJSExceptions()
     {
       return gReportAllJSExceptions > 0;
     }
 
+    static void CheckForDebugMode(JSRuntime *rt);
+
 protected:
     nsXPConnect();
 
 private:
     static PRThread* FindMainThread();
 
 private:
     // Singleton instance
@@ -619,17 +621,16 @@ private:
 
     typedef nsBaseHashtable<nsVoidPtrHashKey, nsISupports*, nsISupports*> ScopeSet;
     ScopeSet mScopes;
     nsCOMPtr<nsIXPCScriptable> mBackstagePass;
 
     static PRUint32 gReportAllJSExceptions;
     static JSBool gDebugMode;
     static JSBool gDesiredDebugMode;
-    static inline void CheckForDebugMode(JSRuntime *rt);
 
 public:
     static nsIScriptSecurityManager *gScriptSecurityManager;
 };
 
 /***************************************************************************/
 
 class XPCRootSetElem
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -177,16 +177,21 @@ xpc_UnmarkGrayObjectRecursive(JSObject* 
 // be reached through it.
 inline void
 xpc_UnmarkGrayObject(JSObject *obj)
 {
     if (obj && xpc_IsGrayGCThing(obj))
         xpc_UnmarkGrayObjectRecursive(obj);
 }
 
+// No JS can be on the stack when this is called. Probably only useful from
+// xpcshell.
+NS_EXPORT_(void)
+xpc_ActivateDebugMode();
+
 class nsIMemoryMultiReporterCallback;
 
 namespace mozilla {
 namespace xpconnect {
 namespace memory {
 
 struct CompartmentStats
 {
--- a/memory/jemalloc/osx_zone_types.h
+++ b/memory/jemalloc/osx_zone_types.h
@@ -36,16 +36,22 @@
  * We need access to some structs that come with a specific version of OSX 
  * but can't copy them here because of licensing restrictions (see bug
  * 603655). The structs below are equivalent in that they'll always be
  * compiled to the same representation on all platforms.
  *
  * `void*` and `void (*)()` may not be the same size on weird platforms, but
  * the size of a function pointer shouldn't vary according to its parameters
  * or return type.
+ *
+ * Apple's version of these structures, complete with member names and
+ * comments, is available online at
+ *
+ * http://www.opensource.apple.com/source/Libc/Libc-763.12/include/malloc/malloc.h
+ *
  */
 
 /*
  * OSX 10.5 - Leopard
  */
 typedef struct _leopard_malloc_zone {
  	void *m1;
 	void *m2;
--- a/parser/html/nsHtml5Parser.cpp
+++ b/parser/html/nsHtml5Parser.cpp
@@ -123,18 +123,20 @@ NS_IMETHODIMP_(void)
 nsHtml5Parser::GetCommand(nsCString& aCommand)
 {
   aCommand.Assign("view");
 }
 
 NS_IMETHODIMP_(void)
 nsHtml5Parser::SetCommand(const char* aCommand)
 {
-  NS_ASSERTION(!strcmp(aCommand, "view") || !strcmp(aCommand, "view-source"),
-      "Parser command was not view");
+  NS_ASSERTION(!strcmp(aCommand, "view") ||
+               !strcmp(aCommand, "view-source") ||
+               !strcmp(aCommand, kLoadAsData),
+               "Unsupported parser command");
 }
 
 NS_IMETHODIMP_(void)
 nsHtml5Parser::SetCommand(eParserCommands aParserCommand)
 {
   NS_ASSERTION(aParserCommand == eViewNormal, 
                "Parser command was not eViewNormal.");
 }
@@ -707,16 +709,18 @@ nsHtml5Parser::MarkAsNotScriptCreated(co
   NS_PRECONDITION(!mStreamParser, "Must not call this twice.");
   eParserMode mode = NORMAL;
   if (!nsCRT::strcmp(aCommand, "view-source")) {
     mode = VIEW_SOURCE_HTML;
   } else if (!nsCRT::strcmp(aCommand, "view-source-xml")) {
     mode = VIEW_SOURCE_XML;
   } else if (!nsCRT::strcmp(aCommand, "plain-text")) {
     mode = PLAIN_TEXT;
+  } else if (!nsCRT::strcmp(aCommand, kLoadAsData)) {
+    mode = LOAD_AS_DATA;
   }
 #ifdef DEBUG
   else {
     NS_ASSERTION(!nsCRT::strcmp(aCommand, "view"),
         "Unsupported parser command!");
   }
 #endif
   mStreamParser = new nsHtml5StreamParser(mExecutor, this, mode);
@@ -824,16 +828,19 @@ nsHtml5Parser::Initialize(nsIDocument* a
                           nsISupports* aContainer,
                           nsIChannel* aChannel)
 {
   return mExecutor->Init(aDoc, aURI, aContainer, aChannel);
 }
 
 void
 nsHtml5Parser::StartTokenizer(bool aScriptingEnabled) {
+  if (!aScriptingEnabled) {
+    mExecutor->PreventScriptExecution();
+  }
   mTreeBuilder->setScriptingEnabled(aScriptingEnabled);
   mTokenizer->start();
 }
 
 void
 nsHtml5Parser::InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState,
                                              PRInt32 aLine)
 {
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -351,16 +351,20 @@ nsHtml5StreamParser::SetupDecodingFromBo
   mBomState = BOM_SNIFFING_OVER;
   return rv;
 }
 
 void
 nsHtml5StreamParser::SniffBOMlessUTF16BasicLatin(const PRUint8* aFromSegment,
                                                  PRUint32 aCountToSniffingLimit)
 {
+  // Avoid underspecified heuristic craziness for XHR
+  if (mMode == LOAD_AS_DATA) {
+    return;
+  }
   // Make sure there's enough data. Require room for "<title></title>"
   if (mSniffingLength + aCountToSniffingLimit < 30) {
     return;
   }
   // even-numbered bytes tracked at 0, odd-numbered bytes tracked at 1
   bool byteZero[2] = { false, false };
   bool byteNonZero[2] = { false, false };
   PRUint32 i = 0;
@@ -604,16 +608,25 @@ nsHtml5StreamParser::FinalizeSniffing(co
     }
     // fall thru; callback may have changed charset  
   }
   if (mCharsetSource == kCharsetUninitialized) {
     // Hopefully this case is never needed, but dealing with it anyway
     mCharset.AssignLiteral("windows-1252");
     mCharsetSource = kCharsetFromWeakDocTypeDefault;
     mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
+  } else if (mMode == LOAD_AS_DATA &&
+             mCharsetSource == kCharsetFromWeakDocTypeDefault) {
+    NS_ASSERTION(mReparseForbidden, "Reparse should be forbidden for XHR");
+    NS_ASSERTION(!mFeedChardet, "Should not feed chardet for XHR");
+    NS_ASSERTION(mCharset.EqualsLiteral("UTF-8"),
+                 "XHR should default to UTF-8");
+    // Now mark charset source as non-weak to signal that we have a decision
+    mCharsetSource = kCharsetFromDocTypeDefault;
+    mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
   }
   return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount);
 }
 
 nsresult
 nsHtml5StreamParser::SniffStreamBytes(const PRUint8* aFromSegment,
                                       PRUint32 aCount,
                                       PRUint32* aWriteCount)
@@ -685,25 +698,27 @@ nsHtml5StreamParser::SniffStreamBytes(co
         break;
       default:
         mBomState = BOM_SNIFFING_OVER;
         break;
     }
   }
   // if we get here, there either was no BOM or the BOM sniffing isn't complete yet
   
-  if (!mMetaScanner && (mMode == NORMAL || mMode == VIEW_SOURCE_HTML)) {
+  if (!mMetaScanner && (mMode == NORMAL ||
+                        mMode == VIEW_SOURCE_HTML ||
+                        mMode == LOAD_AS_DATA)) {
     mMetaScanner = new nsHtml5MetaScanner();
   }
   
   if (mSniffingLength + aCount >= NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE) {
     // this is the last buffer
     PRUint32 countToSniffingLimit =
         NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE - mSniffingLength;
-    if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML) {
+    if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML || mMode == LOAD_AS_DATA) {
       nsHtml5ByteReadable readable(aFromSegment, aFromSegment +
           countToSniffingLimit);
       mMetaScanner->sniff(&readable, getter_AddRefs(mUnicodeDecoder), mCharset);
       if (mUnicodeDecoder) {
         mUnicodeDecoder->SetInputErrorBehavior(
             nsIUnicodeDecoder::kOnError_Recover);
         // meta scan successful
         mCharsetSource = kCharsetFromMetaPrescan;
@@ -714,17 +729,17 @@ nsHtml5StreamParser::SniffStreamBytes(co
             aWriteCount);
       }
     }
     return FinalizeSniffing(aFromSegment, aCount, aWriteCount,
         countToSniffingLimit);
   }
 
   // not the last buffer
-  if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML) {
+  if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML || mMode == LOAD_AS_DATA) {
     nsHtml5ByteReadable readable(aFromSegment, aFromSegment + aCount);
     mMetaScanner->sniff(&readable, getter_AddRefs(mUnicodeDecoder), mCharset);
     if (mUnicodeDecoder) {
       // meta scan successful
       mUnicodeDecoder->SetInputErrorBehavior(
           nsIUnicodeDecoder::kOnError_Recover);
       mCharsetSource = kCharsetFromMetaPrescan;
       mFeedChardet = false;
@@ -864,17 +879,18 @@ nsHtml5StreamParser::OnStartRequest(nsIR
 
   mStreamState = STREAM_BEING_READ;
 
   if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
     mTokenizer->StartViewSource();
   }
   // For View Source, the parser should run with scripts "enabled" if a normal
   // load would have scripts enabled.
-  bool scriptingEnabled = mExecutor->IsScriptEnabled();
+  bool scriptingEnabled = mMode == LOAD_AS_DATA ?
+                                   false : mExecutor->IsScriptEnabled();
   mOwner->StartTokenizer(scriptingEnabled);
   mTreeBuilder->setScriptingEnabled(scriptingEnabled);
   mTokenizer->start();
   mExecutor->Start();
   mExecutor->StartReadingFromStage();
 
   if (mMode == PLAIN_TEXT) {
     mTreeBuilder->StartPlainText();
--- a/parser/html/nsHtml5StreamParser.h
+++ b/parser/html/nsHtml5StreamParser.h
@@ -74,17 +74,22 @@ enum eParserMode {
   /**
    * View document as XML source
    */
   VIEW_SOURCE_XML,
 
   /**
    * View document as plain text
    */
-  PLAIN_TEXT
+  PLAIN_TEXT,
+
+  /**
+   * Load as data (XHR)
+   */
+  LOAD_AS_DATA
 };
 
 enum eBomState {
   /**
    * BOM sniffing hasn't started.
    */
   BOM_SNIFFING_NOT_STARTED = 0,
 
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -730,20 +730,20 @@ nsHtml5TreeOpExecutor::RunScript(nsICont
   if (!mParser) {
     NS_ASSERTION(sele->IsMalformed(), "Script wasn't marked as malformed.");
     // We got here not because of an end tag but because the tree builder
     // popped an incomplete script element on EOF. Returning here to avoid
     // calling back into mParser anymore.
     return;
   }
   
+  if (mPreventScriptExecution) {
+    sele->PreventExecution();
+  }
   if (mFragmentMode) {
-    if (mPreventScriptExecution) {
-      sele->PreventExecution();
-    }
     return;
   }
 
   if (sele->GetScriptDeferred() || sele->GetScriptAsync()) {
     DebugOnly<bool> block = sele->AttemptToExecute();
     NS_ASSERTION(!block, "Defer or async script tried to block.");
     return;
   }
--- a/parser/html/nsHtml5TreeOpExecutor.h
+++ b/parser/html/nsHtml5TreeOpExecutor.h
@@ -148,17 +148,17 @@ class nsHtml5TreeOpExecutor : public nsC
      * Unimplemented. For interface compat only.
      */
     NS_IMETHOD WillParse();
 
     /**
      * 
      */
     NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) {
-      NS_ASSERTION(GetDocument()->GetScriptGlobalObject(), 
+      NS_ASSERTION(!mDocShell || GetDocument()->GetScriptGlobalObject(),
                    "Script global object not ready");
       mDocument->AddObserver(this);
       WillBuildModelImpl();
       GetDocument()->BeginLoad();
       return NS_OK;
     }
 
     /**
@@ -248,16 +248,20 @@ class nsHtml5TreeOpExecutor : public nsC
      * executing; don't set to false when parsing a fragment directly into
      * a document--only when parsing to an actual DOM fragment
      */
     void EnableFragmentMode(bool aPreventScriptExecution) {
       mFragmentMode = true;
       mPreventScriptExecution = aPreventScriptExecution;
     }
     
+    void PreventScriptExecution() {
+      mPreventScriptExecution = true;
+    }
+
     bool IsFragmentMode() {
       return mFragmentMode;
     }
 
     /**
      * Marks this parser as broken and tells the stream parser (if any) to
      * terminate.
      */
--- a/parser/htmlparser/public/nsIParser.h
+++ b/parser/htmlparser/public/nsIParser.h
@@ -86,17 +86,17 @@ enum eParserDocType {
 };
 
 
 // define Charset source constants
 // note: the value order defines the priority; higher numbers take priority
 #define kCharsetUninitialized           0
 #define kCharsetFromWeakDocTypeDefault  1
 #define kCharsetFromUserDefault         2
-#define kCharsetFromDocTypeDefault      3
+#define kCharsetFromDocTypeDefault      3 // This and up confident for XHR
 #define kCharsetFromCache               4
 #define kCharsetFromParentFrame         5
 #define kCharsetFromAutoDetection       6
 #define kCharsetFromHintPrevDoc         7
 #define kCharsetFromMetaPrescan         8 // this one and smaller: HTML5 Tentative
 #define kCharsetFromMetaTag             9 // this one and greater: HTML5 Confident
 #define kCharsetFromIrreversibleAutoDetection 10
 #define kCharsetFromByteOrderMark      11
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -494,21 +494,25 @@ class XPCShellTests(object):
 
       # create a temp dir that the JS harness can stick a profile in
       self.profileDir = self.setupProfileDir()
       self.leakLogFile = self.setupLeakLogging()
 
       # The test file will have to be loaded after the head files.
       cmdT = self.buildCmdTestFile(name)
 
+      args = self.xpcsRunArgs
+      if 'debug' in test:
+          args.insert(0, '-d')
+
       try:
         self.log.info("TEST-INFO | %s | running test ..." % name)
         startTime = time.time()
 
-        proc = self.launchProcess(cmdH + cmdT + self.xpcsRunArgs,
+        proc = self.launchProcess(cmdH + cmdT + args,
                     stdout=pStdout, stderr=pStderr, env=self.env, cwd=testdir)
 
         # Allow user to kill hung subprocess with SIGINT w/o killing this script
         # - don't move this line above launchProcess, or child will inherit the SIG_IGN
         signal.signal(signal.SIGINT, markGotSIGINT)
         # |stderr == None| as |pStderr| was either |None| or redirected to |stdout|.
         stdout, stderr = self.communicate(proc)
         signal.signal(signal.SIGINT, signal.SIG_DFL)
--- a/testing/xpcshell/xpcshell.ini
+++ b/testing/xpcshell/xpcshell.ini
@@ -43,16 +43,17 @@ skip-if = os == "android"
 [include:modules/libpref/test/unit/xpcshell.ini]
 [include:intl/strres/tests/unit/xpcshell.ini]
 [include:intl/unicharutil/tests/unit/xpcshell.ini]
 [include:intl/uconv/tests/unit/xpcshell.ini]
 [include:netwerk/test/unit/xpcshell.ini]
 [include:netwerk/test/httpserver/test/xpcshell.ini]
 [include:js/ductwork/debugger/tests/xpcshell.ini]
 [include:js/jetpack/tests/unit/xpcshell.ini]
+[include:js/jsd/test/xpcshell.ini]
 [include:js/xpconnect/tests/unit/xpcshell.ini]
 [include:modules/libjar/test/unit/xpcshell.ini]
 [include:extensions/cookie/test/unit/xpcshell.ini]
 [include:storage/test/unit/xpcshell.ini]
 [include:rdf/tests/unit/xpcshell.ini]
 [include:gfx/tests/unit/xpcshell.ini]
 [include:widget/tests/unit/xpcshell.ini]
 [include:content/base/test/unit/xpcshell.ini]
--- a/toolkit/components/satchel/nsFormFillController.cpp
+++ b/toolkit/components/satchel/nsFormFillController.cpp
@@ -66,16 +66,17 @@
 #include "nsILoginManager.h"
 #include "nsIDOMMouseEvent.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsToolkitCompsCID.h"
 #include "nsEmbedCID.h"
 #include "nsIDOMNSEditableElement.h"
 #include "nsIDOMNSEvent.h"
 #include "mozilla/dom/Element.h"
+#include "nsContentUtils.h"
 
 NS_IMPL_ISUPPORTS5(nsFormFillController,
                    nsIFormFillController,
                    nsIAutoCompleteInput,
                    nsIAutoCompleteSearch,
                    nsIDOMEventListener,
                    nsIMutationObserver)
 
@@ -568,17 +569,18 @@ nsFormFillController::StartSearch(const 
     // XXX aPreviousResult shouldn't ever be a historyResult type, since we're not letting
     // satchel manage the field?
     rv = mLoginManager->AutoCompleteSearch(aSearchString,
                                          aPreviousResult,
                                          mFocusedInput,
                                          getter_AddRefs(result));
   } else {
     nsCOMPtr<nsIAutoCompleteResult> formHistoryResult;
-    if (!IsInputAutoCompleteOff()) {
+
+    if (mFocusedInput && nsContentUtils::IsAutocompleteEnabled(mFocusedInput)) {
       nsCOMPtr <nsIFormAutoComplete> formAutoComplete =
         do_GetService("@mozilla.org/satchel/form-autocomplete;1", &rv);
       NS_ENSURE_SUCCESS(rv, rv);
 
       rv = formAutoComplete->AutoCompleteSearch(aSearchParam,
                                                 aSearchString,
                                                 mFocusedInput,
                                                 aPreviousResult,
@@ -754,58 +756,37 @@ nsFormFillController::Focus(nsIDOMEvent*
 
   nsCOMPtr<nsIDOMHTMLInputElement> input = do_QueryInterface(target);
   if (!input)
     return NS_OK;
 
   bool isReadOnly = false;
   input->GetReadOnly(&isReadOnly);
 
-  nsAutoString autocomplete;
-  input->GetAttribute(NS_LITERAL_STRING("autocomplete"), autocomplete);
+  bool autocomplete = nsContentUtils::IsAutocompleteEnabled(input);
+
+  nsCOMPtr<nsIDOMHTMLElement> datalist;
+  input->GetList(getter_AddRefs(datalist));
+  bool hasList = datalist != nsnull;
 
   PRInt32 dummy;
   bool isPwmgrInput = false;
   if (mPwmgrInputs.Get(input, &dummy))
       isPwmgrInput = true;
 
   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(input);
-  if (formControl && formControl->IsSingleLineTextControl(true) &&
-      !isReadOnly || isPwmgrInput) {
+  if (isPwmgrInput || (formControl &&
+                       formControl->IsSingleLineTextControl(PR_TRUE) &&
+                       (hasList || autocomplete) && !isReadOnly)) {
     StartControllingInput(input);
   }
 
   return NS_OK;
 }
 
-bool
-nsFormFillController::IsInputAutoCompleteOff()
-{
-  bool autoCompleteOff = false;
-
-  if (mFocusedInput) {
-    nsAutoString autocomplete;
-    mFocusedInput->GetAttribute(NS_LITERAL_STRING("autocomplete"), autocomplete);
-
-    // Check the input for autocomplete="off", then the form
-    if (autocomplete.LowerCaseEqualsLiteral("off")) {
-      autoCompleteOff = true;
-    } else {
-
-      nsCOMPtr<nsIDOMHTMLFormElement> form;
-      mFocusedInput->GetForm(getter_AddRefs(form));
-      if (form)
-        form->GetAttribute(NS_LITERAL_STRING("autocomplete"), autocomplete);
-      autoCompleteOff = autocomplete.LowerCaseEqualsLiteral("off");
-    }
-  }
-
-  return autoCompleteOff;
-}
-
 nsresult
 nsFormFillController::KeyPress(nsIDOMEvent* aEvent)
 {
   NS_ASSERTION(mController, "should have a controller!");
   if (!mFocusedInput || !mController)
     return NS_OK;
 
   nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aEvent);
--- a/toolkit/components/satchel/nsFormFillController.h
+++ b/toolkit/components/satchel/nsFormFillController.h
@@ -99,17 +99,16 @@ protected:
   inline nsIDocShell *GetDocShellForInput(nsIDOMHTMLInputElement *aInput);
   inline nsIDOMWindow *GetWindowForDocShell(nsIDocShell *aDocShell);
   inline PRInt32 GetIndexOfDocShell(nsIDocShell *aDocShell);
 
   static PLDHashOperator RemoveForDOMDocumentEnumerator(nsISupports* aKey,
                                                         PRInt32& aEntry,
                                                         void* aUserData);
   bool IsEventTrusted(nsIDOMEvent *aEvent);
-  bool IsInputAutoCompleteOff();
   // members //////////////////////////////////////////
 
   nsCOMPtr<nsIAutoCompleteController> mController;
   nsCOMPtr<nsILoginManager> mLoginManager;
   nsCOMPtr<nsIDOMHTMLInputElement> mFocusedInput;
   nsCOMPtr<nsIAutoCompletePopup> mFocusedPopup;
 
   nsCOMPtr<nsISupportsArray> mDocShells;
--- a/toolkit/content/tests/chrome/test_tooltip.xul
+++ b/toolkit/content/tests/chrome/test_tooltip.xul
@@ -121,17 +121,17 @@ var popupTests = [
        "cannot get tooltipNode from other document");
 
     var buttonrect = document.getElementById("withtooltip").getBoundingClientRect();
     var rect = tooltip.getBoundingClientRect();
     var popupstyle = window.getComputedStyle(document.getElementById("thetooltip"), "");
 
     is(Math.round(rect.left),
        Math.round(buttonrect.left + parseFloat(popupstyle.marginLeft) + 6),
-       testname + " top position of tooltip");
+       testname + " left position of tooltip");
     is(Math.round(rect.top),
        Math.round(buttonrect.top + parseFloat(popupstyle.marginTop) + 6),
        testname + " top position of tooltip");
 
     var labelrect = document.getElementById("label").getBoundingClientRect();
     ok(labelrect.right < rect.right, testname + " tooltip width");
     ok(labelrect.bottom < rect.bottom, testname + " tooltip height");
 
@@ -171,17 +171,17 @@ var popupTests = [
   result: function(testname) {
     var buttonrect = document.getElementById("withtooltip").getBoundingClientRect();
     var rect = document.getElementById("thetooltip").getBoundingClientRect();
     var popupstyle = window.getComputedStyle(document.getElementById("thetooltip"), "");
     var buttonstyle = window.getComputedStyle(document.getElementById("withtooltip"), "");
 
     is(Math.round(rect.left),
        Math.round(buttonrect.left + parseFloat(popupstyle.marginLeft) + 4),
-       testname + " top position of tooltip");
+       testname + " left position of tooltip");
     is(Math.round(rect.top),
        Math.round(buttonrect.top + parseFloat(popupstyle.marginTop) + 4),
        testname + " top position of tooltip");
 
     var labelrect = document.getElementById("label").getBoundingClientRect();
     ok(labelrect.right < rect.right, testname + " tooltip width");
     ok(labelrect.bottom < rect.bottom, testname + " tooltip height");
 
@@ -216,17 +216,17 @@ var popupTests = [
   result: function(testname) {
     var buttonrect = document.getElementById("withtooltip").getBoundingClientRect();
     var rect = document.getElementById("thetooltip").getBoundingClientRect();
     var popupstyle = window.getComputedStyle(document.getElementById("thetooltip"), "");
     var buttonstyle = window.getComputedStyle(document.getElementById("withtooltip"), "");
 
     is(Math.round(rect.left),
        Math.round(buttonrect.left + parseFloat(popupstyle.marginLeft) + 6),
-       testname + " top position of tooltip");
+       testname + " left position of tooltip");
     is(Math.round(rect.top),
        Math.round(buttonrect.top + parseFloat(popupstyle.marginTop) + 6),
        testname + " top position of tooltip");
 
     var labelrect = document.getElementById("label").getBoundingClientRect();
     ok(labelrect.right < rect.right, testname + " tooltip width");
     ok(labelrect.bottom < rect.bottom, testname + " tooltip height");
 
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -59,17 +59,17 @@ using namespace mozilla;
 // and weakly link against jemalloc_stats.
 extern "C" {
 extern void jemalloc_stats(jemalloc_stats_t* stats)
   NS_VISIBILITY_DEFAULT __attribute__((weak));
 }
 #  endif  // XP_LINUX
 #endif  // MOZ_MEMORY
 
-#if defined(XP_LINUX) || defined(XP_MACOSX)
+#if defined(XP_LINUX) || defined(XP_MACOSX) || defined(SOLARIS)
 
 #include <sys/time.h>
 #include <sys/resource.h>
 
 static PRInt64 GetHardPageFaults()
 {
   struct rusage usage;
   int err = getrusage(RUSAGE_SELF, &usage);
@@ -117,16 +117,62 @@ static PRInt64 GetVsize()
     return GetProcSelfStatmField(0);
 }
 
 static PRInt64 GetResident()
 {
     return GetProcSelfStatmField(1);
 }
 
+#elif defined(SOLARIS)
+
+#include <procfs.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+static void XMappingIter(PRInt64& Vsize, PRInt64& Resident)
+{
+    int mapfd = open("/proc/self/xmap", O_RDONLY);
+    struct stat st;
+    prxmap_t *prmapp;
+    if (mapfd >= 0) {
+        if (!fstat(mapfd, &st)) {
+            int nmap = st.st_size / sizeof(prxmap_t);
+            prmapp = (prxmap_t*)malloc((nmap + 1) * sizeof(prxmap_t));
+            int n = read(mapfd, prmapp, (nmap + 1) * sizeof(prxmap_t));
+            if (n > 0) {
+                Vsize = 0;
+                Resident = 0;
+                for (int i = 0; i < n / sizeof(prxmap_t); i++) {
+                    Vsize += prmapp[i].pr_size;
+                    Resident += prmapp[i].pr_rss * prmapp[i].pr_pagesize;
+                }
+            }
+            free(prmapp);
+        }
+        close(mapfd);
+    }
+}
+
+static PRInt64 GetVsize()
+{
+    PRInt64 Vsize = -1;
+    PRInt64 Resident = -1;
+    XMappingIter(Vsize, Resident);
+    return Vsize;
+}
+
+static PRInt64 GetResident()
+{
+    PRInt64 Vsize = -1;
+    PRInt64 Resident = -1;
+    XMappingIter(Vsize, Resident);
+    return Resident;
+}
+
 #elif defined(XP_MACOSX)
 
 #include <mach/mach_init.h>
 #include <mach/task.h>
 
 static bool GetTaskBasicInfo(struct task_basic_info *ti)
 {
     mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
@@ -219,32 +265,32 @@ static PRInt64 GetResident()
 
 static PRInt64 GetResident()
 {
     return (PRInt64) -1;
 }
 
 #endif
 
-#if defined(XP_LINUX) || defined(XP_MACOSX) || defined(XP_WIN)
+#if defined(XP_LINUX) || defined(XP_MACOSX) || defined(XP_WIN) || defined(SOLARIS)
 NS_MEMORY_REPORTER_IMPLEMENT(Vsize,
     "vsize",
     KIND_OTHER,
     UNITS_BYTES,
     GetVsize,
     "Memory mapped by the process, including code and data segments, the "
     "heap, thread stacks, memory explicitly mapped by the process via mmap "
     "and similar operations, and memory shared with other processes. "
     "This is the vsize figure as reported by 'top' and 'ps'.  This figure is of "
     "limited use on Mac, where processes share huge amounts of memory with one "
     "another.  But even on other operating systems, 'resident' is a much better "
     "measure of the memory resources used by the process.")
 #endif
 
-#if defined(XP_LINUX) || defined(XP_MACOSX)
+#if defined(XP_LINUX) || defined(XP_MACOSX) || defined(SOLARIS)
 NS_MEMORY_REPORTER_IMPLEMENT(PageFaultsSoft,
     "page-faults-soft",
     KIND_OTHER,
     UNITS_COUNT_CUMULATIVE,
     GetSoftPageFaults,
     "The number of soft page faults (also known as \"minor page faults\") that "
     "have occurred since the process started.  A soft page fault occurs when the "
     "process tries to access a page which is present in physical memory but is "
@@ -452,21 +498,21 @@ nsMemoryReporterManager::Init()
 #endif
 
 #define REGISTER(_x)  RegisterReporter(new NS_MEMORY_REPORTER_NAME(_x))
 
     REGISTER(HeapAllocated);
     REGISTER(HeapUnallocated);
     REGISTER(Resident);
 
-#if defined(XP_LINUX) || defined(XP_MACOSX) || defined(XP_WIN)
+#if defined(XP_LINUX) || defined(XP_MACOSX) || defined(XP_WIN) || defined(SOLARIS)
     REGISTER(Vsize);
 #endif
 
-#if defined(XP_LINUX) || defined(XP_MACOSX)
+#if defined(XP_LINUX) || defined(XP_MACOSX) || defined(SOLARIS)
     REGISTER(PageFaultsSoft);
     REGISTER(PageFaultsHard);
 #endif
 
 #if defined(XP_WIN) && MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
     REGISTER(Private);
 #endif