diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index efcaa03e970..7ac4f8bef10 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -322,6 +322,7 @@ pref("media.fragmented-mp4.gonk.enabled", true); pref("media.video-queue.default-size", 3); // optimize images' memory usage +pref("image.downscale-during-decode.enabled", true); pref("image.mem.decodeondraw", true); pref("image.mem.allow_locking_in_content_processes", false); /* don't allow image locking */ // Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller. diff --git a/dom/animation/test/chrome/test_running_on_compositor.html b/dom/animation/test/chrome/test_running_on_compositor.html index 0b505547eaf..e901f3349ef 100644 --- a/dom/animation/test/chrome/test_running_on_compositor.html +++ b/dom/animation/test/chrome/test_running_on_compositor.html @@ -14,7 +14,7 @@ to { transform: translate(100px) } } .target { - // Element needs geometry to be eligible for layerization + /* Element needs geometry to be eligible for layerization */ width: 100px; height: 100px; background-color: white; diff --git a/dom/animation/test/mochitest.ini b/dom/animation/test/mochitest.ini index 17d60734a80..9d7006e320f 100644 --- a/dom/animation/test/mochitest.ini +++ b/dom/animation/test/mochitest.ini @@ -22,4 +22,3 @@ skip-if = buildapp == 'mulet' [css-transitions/test_element-get-animation-players.html] skip-if = buildapp == 'mulet' [mozilla/test_deferred_start.html] -skip-if = buildapp == 'mulet' || buildapp == 'b2g' # bug 1113425, 1119981 diff --git a/dom/animation/test/mozilla/test_deferred_start.html b/dom/animation/test/mozilla/test_deferred_start.html index 62276a1c4bb..c0aeee1806d 100644 --- a/dom/animation/test/mozilla/test_deferred_start.html +++ b/dom/animation/test/mozilla/test_deferred_start.html @@ -11,7 +11,7 @@ to { transform: translate(100px); } } .target { - // Element needs geometry to be eligible for layerization + /* Element needs geometry to be eligible for layerization */ width: 100px; height: 100px; background-color: white; @@ -60,13 +60,18 @@ async_test(function(t) { assert_unreached('ready promise was rejected'); }); - // We need to wait for up to two frames since the animation may not start - // until the beginning of the next refresh driver tick and it won't queue - // the ready Promise callback until that point. - }).then(waitForFrame).then(waitForFrame).then(t.step_func(function() { + // We need to wait for up to three frames. This is because in some + // cases it can take up to two frames for the initial layout + // to take place. Even after that happens we don't actually resolve the + // ready promise until the following tick. + }) + .then(waitForFrame) + .then(waitForFrame) + .then(waitForFrame) + .then(t.step_func(function() { assert_true(promiseCallbackDone, - 'ready promise callback was called before the next' - + ' requestAnimationFrame callback'); + 'ready promise for an empty animation was resolved' + + ' within three animation frames'); t.done(); })); }, 'AnimationPlayer.ready is resolved for an empty animation'); diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index c82f984c641..426e9baa591 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1832,7 +1832,7 @@ Element::IsLabelable() const } bool -Element::IsInteractiveHTMLContent() const +Element::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { return false; } diff --git a/dom/base/Element.h b/dom/base/Element.h index ca627fdaa85..a531f827936 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -276,7 +276,7 @@ public: /** * Returns if the element is interactive content as per HTML specification. */ - virtual bool IsInteractiveHTMLContent() const; + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const; /** * Is the attribute named stored in the mapped attributes? diff --git a/dom/base/moz.build b/dom/base/moz.build index 3a8948e737e..758b38148b8 100644 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -74,6 +74,7 @@ EXPORTS += [ 'nsDOMNavigationTiming.h', 'nsDOMString.h', 'nsFocusManager.h', + 'nsFormData.h', 'nsFrameMessageManager.h', 'nsGenericDOMDataNode.h', 'nsGkAtomList.h', diff --git a/dom/cache/TypeUtils.cpp b/dom/cache/TypeUtils.cpp index 69387c8207e..94937ba47c0 100644 --- a/dom/cache/TypeUtils.cpp +++ b/dom/cache/TypeUtils.cpp @@ -229,7 +229,7 @@ TypeUtils::ToPCacheResponseWithoutBody(PCacheResponse& aOut, aOut.status() = aIn.GetStatus(); aOut.statusText() = aIn.GetStatusText(); - nsRefPtr headers = aIn.Headers(); + nsRefPtr headers = aIn.UnfilteredHeaders(); MOZ_ASSERT(headers); headers->GetPHeaders(aOut.headers()); aOut.headersGuard() = headers->Guard(); @@ -278,37 +278,14 @@ TypeUtils::ToPCacheQueryParams(PCacheQueryParams& aOut, already_AddRefed TypeUtils::ToResponse(const PCacheResponse& aIn) { - nsRefPtr ir; - switch (aIn.type()) - { - case ResponseType::Error: - ir = InternalResponse::NetworkError(); - break; - case ResponseType::Opaque: - ir = InternalResponse::OpaqueResponse(); - break; - case ResponseType::Default: - ir = new InternalResponse(aIn.status(), aIn.statusText()); - break; - case ResponseType::Basic: - { - nsRefPtr inner = new InternalResponse(aIn.status(), - aIn.statusText()); - ir = InternalResponse::BasicResponse(inner); - break; - } - case ResponseType::Cors: - { - nsRefPtr inner = new InternalResponse(aIn.status(), - aIn.statusText()); - ir = InternalResponse::CORSResponse(inner); - break; - } - default: - MOZ_CRASH("Unexpected ResponseType!"); + if (aIn.type() == ResponseType::Error) { + nsRefPtr error = InternalResponse::NetworkError(); + nsRefPtr r = new Response(GetGlobalObject(), error); + return r.forget(); } - MOZ_ASSERT(ir); + nsRefPtr ir = new InternalResponse(aIn.status(), + aIn.statusText()); ir->SetUrl(NS_ConvertUTF16toUTF8(aIn.url())); nsRefPtr internalHeaders = @@ -324,6 +301,24 @@ TypeUtils::ToResponse(const PCacheResponse& aIn) nsCOMPtr stream = ReadStream::Create(aIn.body()); ir->SetBody(stream); + switch (aIn.type()) + { + case ResponseType::Default: + break; + case ResponseType::Opaque: + ir = ir->OpaqueResponse(); + break; + case ResponseType::Basic: + ir = ir->BasicResponse(); + break; + case ResponseType::Cors: + ir = ir->CORSResponse(); + break; + default: + MOZ_CRASH("Unexpected ResponseType!"); + } + MOZ_ASSERT(ir); + nsRefPtr ref = new Response(GetGlobalObject(), ir); return ref.forget(); } diff --git a/dom/cache/test/mochitest/driver.js b/dom/cache/test/mochitest/driver.js index 978d374f81e..f8d1e5f286f 100644 --- a/dom/cache/test/mochitest/driver.js +++ b/dom/cache/test/mochitest/driver.js @@ -81,8 +81,7 @@ function runTests(testFile, order) { SimpleTest.waitForExplicitFinish(); if (typeof order == "undefined") { - order = "sequential"; // sequential by default, see bug 1143222. - // TODO: Make this "both". + order = "both"; // both by default } ok(order == "parallel" || order == "sequential" || order == "both", diff --git a/dom/cache/test/mochitest/test_cache_matchAll_request.js b/dom/cache/test/mochitest/test_cache_matchAll_request.js index 97124c9ffe5..38528ff60d3 100644 --- a/dom/cache/test/mochitest/test_cache_matchAll_request.js +++ b/dom/cache/test/mochitest/test_cache_matchAll_request.js @@ -18,7 +18,10 @@ function checkResponse(r, response, responseText) { is(r.statusText, response.statusText, "Both responses should have the same status text"); return r.text().then(function(text) { - is(text, responseText, "The response body should be correct"); + // Avoid dumping out the large response text to the log if they're equal. + if (text !== responseText) { + is(text, responseText, "The response body should be correct"); + } }); } diff --git a/dom/cache/test/mochitest/test_cache_match_request.js b/dom/cache/test/mochitest/test_cache_match_request.js index 96f255ec231..f27681aa3d4 100644 --- a/dom/cache/test/mochitest/test_cache_match_request.js +++ b/dom/cache/test/mochitest/test_cache_match_request.js @@ -16,7 +16,10 @@ function checkResponse(r) { is(r.statusText, response.statusText, "Both responses should have the same status text"); return r.text().then(function(text) { - is(text, responseText, "The response body should be correct"); + // Avoid dumping out the large response text to the log if they're equal. + if (text !== responseText) { + is(text, responseText, "The response body should be correct"); + } }); } diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index 1be0d9565d3..798813e5574 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -32,6 +32,7 @@ #include "InternalRequest.h" #include "InternalResponse.h" +#include "nsFormData.h" #include "WorkerPrivate.h" #include "WorkerRunnable.h" #include "WorkerScope.h" @@ -452,6 +453,16 @@ ExtractFromBlob(const File& aFile, nsIInputStream** aStream, return NS_OK; } +nsresult +ExtractFromFormData(nsFormData& aFormData, nsIInputStream** aStream, + nsCString& aContentType) +{ + uint64_t unusedContentLength; + nsAutoCString unusedCharset; + return aFormData.GetSendInfo(aStream, &unusedContentLength, + aContentType, unusedCharset); +} + nsresult ExtractFromUSVString(const nsString& aStr, nsIInputStream** aStream, @@ -502,7 +513,7 @@ ExtractFromURLSearchParams(const URLSearchParams& aParams, } // anonymous namespace nsresult -ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit, +ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit, nsIInputStream** aStream, nsCString& aContentType) { @@ -517,6 +528,9 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStr } else if (aBodyInit.IsBlob()) { const File& blob = aBodyInit.GetAsBlob(); return ExtractFromBlob(blob, aStream, aContentType); + } else if (aBodyInit.IsFormData()) { + nsFormData& form = aBodyInit.GetAsFormData(); + return ExtractFromFormData(form, aStream, aContentType); } else if (aBodyInit.IsUSVString()) { nsAutoString str; str.Assign(aBodyInit.GetAsUSVString()); @@ -531,7 +545,7 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStr } nsresult -ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit, +ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit, nsIInputStream** aStream, nsCString& aContentType) { @@ -546,6 +560,9 @@ ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrU } else if (aBodyInit.IsBlob()) { const File& blob = aBodyInit.GetAsBlob(); return ExtractFromBlob(blob, aStream, aContentType); + } else if (aBodyInit.IsFormData()) { + nsFormData& form = aBodyInit.GetAsFormData(); + return ExtractFromFormData(form, aStream, aContentType); } else if (aBodyInit.IsUSVString()) { nsAutoString str; str.Assign(aBodyInit.GetAsUSVString()); diff --git a/dom/fetch/Fetch.h b/dom/fetch/Fetch.h index 651c2f313d9..33e75bf69db 100644 --- a/dom/fetch/Fetch.h +++ b/dom/fetch/Fetch.h @@ -26,9 +26,9 @@ class nsIGlobalObject; namespace mozilla { namespace dom { -class ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams; +class ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams; class InternalRequest; -class OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams; +class OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams; class RequestOrUSVString; namespace workers { @@ -48,7 +48,7 @@ UpdateRequestReferrer(nsIGlobalObject* aGlobal, InternalRequest* aRequest); * Stores content type in out param aContentType. */ nsresult -ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit, +ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit, nsIInputStream** aStream, nsCString& aContentType); @@ -56,7 +56,7 @@ ExtractByteStreamFromBody(const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStr * Non-owning version. */ nsresult -ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& aBodyInit, +ExtractByteStreamFromBody(const ArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& aBodyInit, nsIInputStream** aStream, nsCString& aContentType); diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp index 82e36a4ea80..759f4efd0ac 100644 --- a/dom/fetch/FetchDriver.cpp +++ b/dom/fetch/FetchDriver.cpp @@ -485,16 +485,24 @@ FetchDriver::HttpFetch(bool aCORSFlag, bool aCORSPreflightFlag, bool aAuthentica internalChan->ForceNoIntercept(); } - // Set up a CORS proxy that will handle the various requirements of the CORS - // protocol. It handles the preflight cache and CORS response headers. - // If the request is allowed, it will start our original request - // and our observer will be notified. On failure, our observer is notified - // directly. - nsRefPtr corsListener = - new nsCORSListenerProxy(this, mPrincipal, useCredentials); - rv = corsListener->Init(chan, true /* allow data uri */); - if (NS_WARN_IF(NS_FAILED(rv))) { - return FailWithNetworkError(); + nsCOMPtr listener = this; + + // Unless the cors mode is explicitly no-cors, we set up a cors proxy even in + // the same-origin case, since the proxy does not enforce cors header checks + // in the same-origin case. + if (mRequest->Mode() != RequestMode::No_cors) { + // Set up a CORS proxy that will handle the various requirements of the CORS + // protocol. It handles the preflight cache and CORS response headers. + // If the request is allowed, it will start our original request + // and our observer will be notified. On failure, our observer is notified + // directly. + nsRefPtr corsListener = + new nsCORSListenerProxy(this, mPrincipal, useCredentials); + rv = corsListener->Init(chan, true /* allow data uri */); + if (NS_WARN_IF(NS_FAILED(rv))) { + return FailWithNetworkError(); + } + listener = corsListener.forget(); } // If preflight is required, start a "CORS preflight fetch" @@ -507,12 +515,12 @@ FetchDriver::HttpFetch(bool aCORSFlag, bool aCORSPreflightFlag, bool aAuthentica nsAutoTArray unsafeHeaders; mRequest->Headers()->GetUnsafeHeaders(unsafeHeaders); - rv = NS_StartCORSPreflight(chan, corsListener, mPrincipal, + rv = NS_StartCORSPreflight(chan, listener, mPrincipal, useCredentials, unsafeHeaders, getter_AddRefs(preflightChannel)); } else { - rv = chan->AsyncOpen(corsListener, nullptr); + rv = chan->AsyncOpen(listener, nullptr); } if (NS_WARN_IF(NS_FAILED(rv))) { @@ -548,13 +556,13 @@ FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse) nsRefPtr filteredResponse; switch (mRequest->GetResponseTainting()) { case InternalRequest::RESPONSETAINT_BASIC: - filteredResponse = InternalResponse::BasicResponse(aResponse); + filteredResponse = aResponse->BasicResponse(); break; case InternalRequest::RESPONSETAINT_CORS: - filteredResponse = InternalResponse::CORSResponse(aResponse); + filteredResponse = aResponse->CORSResponse(); break; case InternalRequest::RESPONSETAINT_OPAQUE: - filteredResponse = InternalResponse::OpaqueResponse(); + filteredResponse = aResponse->OpaqueResponse(); break; default: MOZ_CRASH("Unexpected case"); @@ -775,7 +783,7 @@ FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel, if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) { rv = DoesNotRequirePreflight(aNewChannel); if (NS_FAILED(rv)) { - NS_WARNING("nsXMLHttpRequest::OnChannelRedirect: " + NS_WARNING("FetchDriver::OnChannelRedirect: " "DoesNotRequirePreflight returned failure"); return rv; } diff --git a/dom/fetch/InternalResponse.cpp b/dom/fetch/InternalResponse.cpp index be78ddd5bea..d5e52e80df1 100644 --- a/dom/fetch/InternalResponse.cpp +++ b/dom/fetch/InternalResponse.cpp @@ -23,25 +23,17 @@ InternalResponse::InternalResponse(uint16_t aStatus, const nsACString& aStatusTe { } -// Headers are not copied since BasicResponse and CORSResponse both need custom -// header handling. Body is not copied as it cannot be shared directly. -InternalResponse::InternalResponse(const InternalResponse& aOther) - : mType(aOther.mType) - , mTerminationReason(aOther.mTerminationReason) - , mURL(aOther.mURL) - , mFinalURL(aOther.mFinalURL) - , mStatus(aOther.mStatus) - , mStatusText(aOther.mStatusText) - , mContentType(aOther.mContentType) - , mSecurityInfo(aOther.mSecurityInfo) -{ -} - already_AddRefed InternalResponse::Clone() { - nsRefPtr clone = new InternalResponse(*this); + nsRefPtr clone = CreateIncompleteCopy(); + clone->mHeaders = new InternalHeaders(*mHeaders); + if (mWrappedResponse) { + clone->mWrappedResponse = mWrappedResponse->Clone(); + MOZ_ASSERT(!mBody); + return clone.forget(); + } if (!mBody) { return clone.forget(); @@ -62,27 +54,25 @@ InternalResponse::Clone() return clone.forget(); } -// static already_AddRefed -InternalResponse::BasicResponse(InternalResponse* aInner) +InternalResponse::BasicResponse() { - MOZ_ASSERT(aInner); - nsRefPtr basic = new InternalResponse(*aInner); + MOZ_ASSERT(!mWrappedResponse, "Can't BasicResponse a already wrapped response"); + nsRefPtr basic = CreateIncompleteCopy(); basic->mType = ResponseType::Basic; - basic->mHeaders = InternalHeaders::BasicHeaders(aInner->mHeaders); - basic->mBody.swap(aInner->mBody); + basic->mHeaders = InternalHeaders::BasicHeaders(Headers()); + basic->mWrappedResponse = this; return basic.forget(); } -// static already_AddRefed -InternalResponse::CORSResponse(InternalResponse* aInner) +InternalResponse::CORSResponse() { - MOZ_ASSERT(aInner); - nsRefPtr cors = new InternalResponse(*aInner); + MOZ_ASSERT(!mWrappedResponse, "Can't CORSResponse a already wrapped response"); + nsRefPtr cors = CreateIncompleteCopy(); cors->mType = ResponseType::Cors; - cors->mHeaders = InternalHeaders::CORSHeaders(aInner->mHeaders); - cors->mBody.swap(aInner->mBody); + cors->mHeaders = InternalHeaders::CORSHeaders(Headers()); + cors->mWrappedResponse = this; return cors.forget(); } diff --git a/dom/fetch/InternalResponse.h b/dom/fetch/InternalResponse.h index 27a558aefad..04020eeb5a8 100644 --- a/dom/fetch/InternalResponse.h +++ b/dom/fetch/InternalResponse.h @@ -38,27 +38,34 @@ public: return response.forget(); } - static already_AddRefed + already_AddRefed OpaqueResponse() { + MOZ_ASSERT(!mWrappedResponse, "Can't OpaqueResponse a already wrapped response"); nsRefPtr response = new InternalResponse(0, EmptyCString()); response->mType = ResponseType::Opaque; + response->mTerminationReason = mTerminationReason; + response->mURL = mURL; + response->mFinalURL = mFinalURL; + response->mSecurityInfo = mSecurityInfo; + response->mWrappedResponse = this; return response.forget(); } - // DO NOT use the inner response after filtering it since the filtered - // response will adopt the inner response's body. - static already_AddRefed - BasicResponse(InternalResponse* aInner); + already_AddRefed + BasicResponse(); - // DO NOT use the inner response after filtering it since the filtered - // response will adopt the inner response's body. - static already_AddRefed - CORSResponse(InternalResponse* aInner); + already_AddRefed + CORSResponse(); ResponseType Type() const { + MOZ_ASSERT_IF(mType == ResponseType::Error, !mWrappedResponse); + MOZ_ASSERT_IF(mType == ResponseType::Default, !mWrappedResponse); + MOZ_ASSERT_IF(mType == ResponseType::Basic, mWrappedResponse); + MOZ_ASSERT_IF(mType == ResponseType::Cors, mWrappedResponse); + MOZ_ASSERT_IF(mType == ResponseType::Opaque, mWrappedResponse); return mType; } @@ -111,9 +118,28 @@ public: return mHeaders; } + InternalHeaders* + UnfilteredHeaders() + { + if (mWrappedResponse) { + return mWrappedResponse->Headers(); + }; + + return Headers(); + } + void GetBody(nsIInputStream** aStream) { + if (Type() == ResponseType::Opaque) { + *aStream = nullptr; + return; + } + + if (mWrappedResponse) { + MOZ_ASSERT(!mBody); + return mWrappedResponse->GetBody(aStream); + } nsCOMPtr stream = mBody; stream.forget(aStream); } @@ -121,6 +147,9 @@ public: void SetBody(nsIInputStream* aBody) { + if (mWrappedResponse) { + return mWrappedResponse->SetBody(aBody); + } // A request's body may not be reset once set. MOZ_ASSERT(!mBody); mBody = aBody; @@ -142,9 +171,22 @@ private: ~InternalResponse() { } - // Used to create filtered and cloned responses. - // Does not copy headers or body stream. - explicit InternalResponse(const InternalResponse& aOther); + explicit InternalResponse(const InternalResponse& aOther) = delete; + InternalResponse& operator=(const InternalResponse&) = delete; + + // Returns an instance of InternalResponse which is a copy of this + // InternalResponse, except headers, body and wrapped response (if any) which + // are left uninitialized. Used for cloning and filtering. + already_AddRefed CreateIncompleteCopy() + { + nsRefPtr copy = new InternalResponse(mStatus, mStatusText); + copy->mType = mType; + copy->mTerminationReason = mTerminationReason; + copy->mURL = mURL; + copy->mFinalURL = mFinalURL; + copy->mSecurityInfo = mSecurityInfo; + return copy.forget(); + } ResponseType mType; nsCString mTerminationReason; @@ -154,8 +196,13 @@ private: const nsCString mStatusText; nsRefPtr mHeaders; nsCOMPtr mBody; - nsCString mContentType; nsCString mSecurityInfo; + + // For filtered responses. + // Cache, and SW interception should always serialize/access the underlying + // unfiltered headers and when deserializing, create an InternalResponse + // with the unfiltered headers followed by wrapping it. + nsRefPtr mWrappedResponse; }; } // namespace dom diff --git a/dom/fetch/Request.cpp b/dom/fetch/Request.cpp index 8eab5a82b2d..035053df3a2 100644 --- a/dom/fetch/Request.cpp +++ b/dom/fetch/Request.cpp @@ -228,7 +228,7 @@ Request::Constructor(const GlobalObject& aGlobal, return nullptr; } - const OwningArrayBufferOrArrayBufferViewOrBlobOrUSVStringOrURLSearchParams& bodyInit = aInit.mBody.Value(); + const OwningArrayBufferOrArrayBufferViewOrBlobOrFormDataOrUSVStringOrURLSearchParams& bodyInit = aInit.mBody.Value(); nsCOMPtr stream; nsCString contentType; aRv = ExtractByteStreamFromBody(bodyInit, diff --git a/dom/fetch/Response.cpp b/dom/fetch/Response.cpp index 6a8123b6d77..6044eddc17d 100644 --- a/dom/fetch/Response.cpp +++ b/dom/fetch/Response.cpp @@ -99,7 +99,7 @@ Response::Redirect(const GlobalObject& aGlobal, const nsAString& aUrl, return nullptr; } - Optional body; + Optional body; ResponseInit init; init.mStatus = aStatus; nsRefPtr r = Response::Constructor(aGlobal, body, init, aRv); @@ -120,7 +120,7 @@ Response::Redirect(const GlobalObject& aGlobal, const nsAString& aUrl, /*static*/ already_AddRefed Response::Constructor(const GlobalObject& aGlobal, - const Optional& aBody, + const Optional& aBody, const ResponseInit& aInit, ErrorResult& aRv) { if (aInit.mStatus < 200 || aInit.mStatus > 599) { diff --git a/dom/fetch/Response.h b/dom/fetch/Response.h index 2585e18f597..35ccef282af 100644 --- a/dom/fetch/Response.h +++ b/dom/fetch/Response.h @@ -103,7 +103,7 @@ public: static already_AddRefed Constructor(const GlobalObject& aGlobal, - const Optional& aBody, + const Optional& aBody, const ResponseInit& aInit, ErrorResult& rv); nsIGlobalObject* GetParentObject() const diff --git a/dom/html/HTMLAnchorElement.h b/dom/html/HTMLAnchorElement.h index fcb50177fb2..203835849ef 100644 --- a/dom/html/HTMLAnchorElement.h +++ b/dom/html/HTMLAnchorElement.h @@ -43,7 +43,7 @@ public: virtual bool Draggable() const MOZ_OVERRIDE; // Element - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE { return true; } diff --git a/dom/html/HTMLAudioElement.cpp b/dom/html/HTMLAudioElement.cpp index 39d1d5df8f6..04d8313103c 100644 --- a/dom/html/HTMLAudioElement.cpp +++ b/dom/html/HTMLAudioElement.cpp @@ -41,7 +41,7 @@ HTMLAudioElement::~HTMLAudioElement() } bool -HTMLAudioElement::IsInteractiveHTMLContent() const +HTMLAudioElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { return HasAttr(kNameSpaceID_None, nsGkAtoms::controls); } diff --git a/dom/html/HTMLAudioElement.h b/dom/html/HTMLAudioElement.h index 3b6ef48d351..f1f050c00d5 100644 --- a/dom/html/HTMLAudioElement.h +++ b/dom/html/HTMLAudioElement.h @@ -24,7 +24,7 @@ public: explicit HTMLAudioElement(already_AddRefed& aNodeInfo); // Element - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE; + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE; // nsIDOMHTMLMediaElement using HTMLMediaElement::GetPaused; diff --git a/dom/html/HTMLButtonElement.h b/dom/html/HTMLButtonElement.h index 776eaf87d42..a2e8cf55a8e 100644 --- a/dom/html/HTMLButtonElement.h +++ b/dom/html/HTMLButtonElement.h @@ -37,7 +37,7 @@ public: NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLButtonElement, button) // Element - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE { return true; } diff --git a/dom/html/HTMLIFrameElement.h b/dom/html/HTMLIFrameElement.h index 2a6af020961..550aec691a1 100644 --- a/dom/html/HTMLIFrameElement.h +++ b/dom/html/HTMLIFrameElement.h @@ -27,7 +27,7 @@ public: NS_DECL_ISUPPORTS_INHERITED // Element - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE { return true; } diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp index 7a313355701..80450b0290f 100644 --- a/dom/html/HTMLImageElement.cpp +++ b/dom/html/HTMLImageElement.cpp @@ -149,7 +149,7 @@ NS_IMPL_STRING_ATTR(HTMLImageElement, UseMap, usemap) NS_IMPL_INT_ATTR(HTMLImageElement, Vspace, vspace) bool -HTMLImageElement::IsInteractiveHTMLContent() const +HTMLImageElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { return HasAttr(kNameSpaceID_None, nsGkAtoms::usemap); } diff --git a/dom/html/HTMLImageElement.h b/dom/html/HTMLImageElement.h index 47cf8ae6b7d..acc4463b575 100644 --- a/dom/html/HTMLImageElement.h +++ b/dom/html/HTMLImageElement.h @@ -47,7 +47,7 @@ public: virtual bool Draggable() const MOZ_OVERRIDE; // Element - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE; + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE; // nsIDOMHTMLImageElement NS_DECL_NSIDOMHTMLIMAGEELEMENT diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index f2a4d9084b2..217663f89fc 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -3222,7 +3222,7 @@ HTMLInputElement::Focus(ErrorResult& aError) } bool -HTMLInputElement::IsInteractiveHTMLContent() const +HTMLInputElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { return mType != NS_FORM_INPUT_HIDDEN; } diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h index 6a3d06384d6..0a625beb729 100644 --- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -120,7 +120,7 @@ public: virtual void Focus(ErrorResult& aError) MOZ_OVERRIDE; // Element - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE; + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE; // nsIDOMHTMLInputElement NS_DECL_NSIDOMHTMLINPUTELEMENT diff --git a/dom/html/HTMLLabelElement.cpp b/dom/html/HTMLLabelElement.cpp index 110a04cf3dd..5929714dac8 100644 --- a/dom/html/HTMLLabelElement.cpp +++ b/dom/html/HTMLLabelElement.cpp @@ -88,7 +88,7 @@ InInteractiveHTMLContent(nsIContent* aContent, nsIContent* aStop) nsIContent* content = aContent; while (content && content != aStop) { if (content->IsElement() && - content->AsElement()->IsInteractiveHTMLContent()) { + content->AsElement()->IsInteractiveHTMLContent(true)) { return true; } content = content->GetParent(); diff --git a/dom/html/HTMLLabelElement.h b/dom/html/HTMLLabelElement.h index 9f857b56905..5ac54e41a36 100644 --- a/dom/html/HTMLLabelElement.h +++ b/dom/html/HTMLLabelElement.h @@ -33,7 +33,7 @@ public: NS_DECL_ISUPPORTS_INHERITED // Element - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE { return true; } diff --git a/dom/html/HTMLObjectElement.cpp b/dom/html/HTMLObjectElement.cpp index 9e78159609a..bb06e2e9f73 100644 --- a/dom/html/HTMLObjectElement.cpp +++ b/dom/html/HTMLObjectElement.cpp @@ -50,7 +50,7 @@ HTMLObjectElement::~HTMLObjectElement() } bool -HTMLObjectElement::IsInteractiveHTMLContent() const +HTMLObjectElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { return HasAttr(kNameSpaceID_None, nsGkAtoms::usemap); } diff --git a/dom/html/HTMLObjectElement.h b/dom/html/HTMLObjectElement.h index eae048efb7b..489c135aabb 100644 --- a/dom/html/HTMLObjectElement.h +++ b/dom/html/HTMLObjectElement.h @@ -37,7 +37,7 @@ public: #endif // Element - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE; + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE; // nsIDOMHTMLObjectElement NS_DECL_NSIDOMHTMLOBJECTELEMENT diff --git a/dom/html/HTMLSelectElement.h b/dom/html/HTMLSelectElement.h index c73799f3c76..8fdab9a5e84 100644 --- a/dom/html/HTMLSelectElement.h +++ b/dom/html/HTMLSelectElement.h @@ -148,7 +148,7 @@ public: virtual int32_t TabIndexDefault() MOZ_OVERRIDE; // Element - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE { return true; } diff --git a/dom/html/HTMLTextAreaElement.h b/dom/html/HTMLTextAreaElement.h index d7ced597fbc..055ede1d5ca 100644 --- a/dom/html/HTMLTextAreaElement.h +++ b/dom/html/HTMLTextAreaElement.h @@ -54,7 +54,7 @@ public: virtual int32_t TabIndexDefault() MOZ_OVERRIDE; // Element - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE { return true; } diff --git a/dom/html/HTMLVideoElement.cpp b/dom/html/HTMLVideoElement.cpp index 8df0bf6024e..c3be706b83e 100644 --- a/dom/html/HTMLVideoElement.cpp +++ b/dom/html/HTMLVideoElement.cpp @@ -127,7 +127,7 @@ nsresult HTMLVideoElement::SetAcceptHeader(nsIHttpChannel* aChannel) } bool -HTMLVideoElement::IsInteractiveHTMLContent() const +HTMLVideoElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { return HasAttr(kNameSpaceID_None, nsGkAtoms::controls); } diff --git a/dom/html/HTMLVideoElement.h b/dom/html/HTMLVideoElement.h index 6359c20629a..e23d5c69569 100644 --- a/dom/html/HTMLVideoElement.h +++ b/dom/html/HTMLVideoElement.h @@ -50,7 +50,7 @@ public: virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) MOZ_OVERRIDE; // Element - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE; + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE; // WebIDL diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index 3728f1bb2ca..713aa39802c 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -1794,11 +1794,11 @@ nsGenericHTMLElement::IsLabelable() const } bool -nsGenericHTMLElement::IsInteractiveHTMLContent() const +nsGenericHTMLElement::IsInteractiveHTMLContent(bool aIgnoreTabindex) const { return IsAnyOfHTMLElements(nsGkAtoms::details, nsGkAtoms::embed, nsGkAtoms::keygen) || - HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex); + (!aIgnoreTabindex && HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex)); } already_AddRefed diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h index 4cbde8eb612..de8acc9050b 100644 --- a/dom/html/nsGenericHTMLElement.h +++ b/dom/html/nsGenericHTMLElement.h @@ -923,7 +923,7 @@ public: } virtual bool IsLabelable() const MOZ_OVERRIDE; - virtual bool IsInteractiveHTMLContent() const MOZ_OVERRIDE; + virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const MOZ_OVERRIDE; static bool TouchEventsEnabled(JSContext* /* unused */, JSObject* /* unused */); diff --git a/dom/html/test/forms/test_interactive_content_in_label.html b/dom/html/test/forms/test_interactive_content_in_label.html index 86a7860066a..705864114c5 100644 --- a/dom/html/test/forms/test_interactive_content_in_label.html +++ b/dom/html/test/forms/test_interactive_content_in_label.html @@ -32,13 +32,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=229925 - tabindex object + tabindex