mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:25:44 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1229623 - Remove compilation/database.py from mach_bootstrap.py. r=mshal (16de324bd5) - Bug 1228208 - Make sure ICU flags are prepended before system flags. r=glandium (77a099bb4a) - Bug 1176968 part 2: Add "requirement flags" field to media query features, and logic for ignoring the feature if requirements aren't met. r=heycam (f2fb438cc7) - Bug 1176968 part 3: Add support for "-webkit-device-pixel-ratio" media query, along with its min/max variants (behind a pref). r=heycam (d9cf15f3f3) - Bug 1176968 part 4: Add tests for -webkit-device-pixel-ratio, based on existing -moz tests. r=heycam (7a143f1310) - Bug 1230863 - Remove unused nsPresContext args from many functions. r=roc. (8f3ca74bb8) - Add APZ support for mousewheel.acceleration prefs. (bug 1214170 part 1, r=kats) (f9ead80db9) - Add APZ support for mousewheel delta multiplier prefs. (bug 1214170 part 2, r=kats) (111d111124) - Bug 1143618 - Follow-up to fix static analysis build bustage. r=me on a CLOSED TREE (57c395593f) - Bug 1021845 - Before compositing, clip the visible region of a layer to the layer's clip rect. r=mattwoodrow (493ad91934) - Bug 1152046 - move ClosingService::Start/Shutdown to nsIOService. r=mayhemer (4d078b7611) - Bug 1226909 part 1: Do security checks in a redirect handler rather than when opening the redirected channel. r=ckerschb (30d23ad2ee) - Bug 1226909 part 2: Let CORS preflight logic grab information from nsILoadInfo rather than duplicate it. r=ckerschb (04ece9d251) - Bug 1214361 Test final response types after redirect. r=sicking a=abillings (3f288cae02) - Bug 1210302 - Part 4: Add automated tests; r=sicking (b43a9a02c4) - Bug 1226909 part 3: Move logic of when to initiate CORS preflight into channels. Allow CORS preflight to happen when doing a same-origin to cross-origin redirect. r=ckerschb (816498fdb5) - Bug 1216793 - check against tracking protection list in fetch(). r=gcp (1ddeb07832) - Bug 1228342 - initialize mTainting by all constructors. r=bkelly (60e63d22bd) - Bug 1226909 part 4: Make AsyncOpen2 set taining information on channels. Use this information in XHR and fetch(). r=bkelly (3b0bc77efc) - Bug 1214819. Add support for @crossorigin to <link rel=prefetch> so resources can be prefetched via anonymous CORS, for example. r=hurley (de8b0aef94) - Bug 1216687: Add nsILoadInfo flags for cookie policies. r=ckerschb (f2634fd5b0) - Bug 1213443 - Parallelism for <link rel=prefetch> r=bz (f5ee458126)
This commit is contained in:
@@ -36,10 +36,10 @@ elif test -n "$gonkdir" -a "$ANDROID_VERSION" -ge 17; then
|
||||
MOZ_NATIVE_ICU=1
|
||||
MOZ_SHARED_ICU=1
|
||||
else
|
||||
MOZ_ICU_CFLAGS='-I$(topsrcdir)/intl/icu/source/common -I$(topsrcdir)/intl/icu/source/i18n'
|
||||
AC_SUBST_LIST(MOZ_ICU_CFLAGS)
|
||||
MOZ_ICU_INCLUDES="/intl/icu/source/common /intl/icu/source/i18n"
|
||||
fi
|
||||
|
||||
AC_SUBST_LIST(MOZ_ICU_INCLUDES)
|
||||
AC_SUBST(MOZ_NATIVE_ICU)
|
||||
|
||||
MOZ_ARG_WITH_STRING(intl-api,
|
||||
|
||||
@@ -86,7 +86,6 @@ MACH_MODULES = [
|
||||
'python/mozbuild/mozbuild/mach_commands.py',
|
||||
'python/mozbuild/mozbuild/backend/mach_commands.py',
|
||||
'python/mozbuild/mozbuild/compilation/codecomplete.py',
|
||||
'python/mozbuild/mozbuild/compilation/database.py',
|
||||
'python/mozbuild/mozbuild/frontend/mach_commands.py',
|
||||
'services/common/tests/mach_commands.py',
|
||||
'testing/luciddream/mach_commands.py',
|
||||
|
||||
@@ -429,7 +429,6 @@ nsScriptSecurityManager::IsSystemPrincipal(nsIPrincipal* aPrincipal,
|
||||
////////////////////////////////////
|
||||
NS_IMPL_ISUPPORTS(nsScriptSecurityManager,
|
||||
nsIScriptSecurityManager,
|
||||
nsIChannelEventSink,
|
||||
nsIObserver)
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
@@ -1236,41 +1235,6 @@ nsScriptSecurityManager::CanGetService(JSContext *cx,
|
||||
return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Method implementing nsIChannelEventSink //
|
||||
/////////////////////////////////////////////
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::AsyncOnChannelRedirect(nsIChannel* oldChannel,
|
||||
nsIChannel* newChannel,
|
||||
uint32_t redirFlags,
|
||||
nsIAsyncVerifyRedirectCallback *cb)
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> oldPrincipal;
|
||||
GetChannelResultPrincipal(oldChannel, getter_AddRefs(oldPrincipal));
|
||||
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
newChannel->GetURI(getter_AddRefs(newURI));
|
||||
nsCOMPtr<nsIURI> newOriginalURI;
|
||||
newChannel->GetOriginalURI(getter_AddRefs(newOriginalURI));
|
||||
|
||||
NS_ENSURE_STATE(oldPrincipal && newURI && newOriginalURI);
|
||||
|
||||
const uint32_t flags =
|
||||
nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT |
|
||||
nsIScriptSecurityManager::DISALLOW_SCRIPT;
|
||||
nsresult rv = CheckLoadURIWithPrincipal(oldPrincipal, newURI, flags);
|
||||
if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) {
|
||||
rv = CheckLoadURIWithPrincipal(oldPrincipal, newOriginalURI, flags);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
cb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////
|
||||
// Method implementing nsIObserver //
|
||||
/////////////////////////////////////
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "nsIAddonPolicyService.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "plstr.h"
|
||||
@@ -39,7 +38,6 @@ class OriginAttributes;
|
||||
{ 0xba, 0x18, 0x00, 0x60, 0xb0, 0xf1, 0x99, 0xa2 }}
|
||||
|
||||
class nsScriptSecurityManager final : public nsIScriptSecurityManager,
|
||||
public nsIChannelEventSink,
|
||||
public nsIObserver
|
||||
{
|
||||
public:
|
||||
@@ -49,7 +47,6 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISCRIPTSECURITYMANAGER
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
static nsScriptSecurityManager*
|
||||
|
||||
@@ -14,13 +14,11 @@ function run_test() {
|
||||
}
|
||||
|
||||
// Make sure the queue has items in it...
|
||||
var queue = prefetch.enumerateQueue();
|
||||
do_check_true(queue.hasMoreElements());
|
||||
do_check_true(prefetch.hasMoreElements());
|
||||
|
||||
// Now disable the pref to force the queue to empty...
|
||||
prefs.setBoolPref("network.prefetch-next", false);
|
||||
queue = prefetch.enumerateQueue();
|
||||
do_check_false(queue.hasMoreElements());
|
||||
do_check_false(prefetch.hasMoreElements());
|
||||
|
||||
// Now reenable the pref, and add more items to the queue.
|
||||
prefs.setBoolPref("network.prefetch-next", true);
|
||||
@@ -28,7 +26,5 @@ function run_test() {
|
||||
var uri = ios.newURI("http://localhost/" + i, null, null);
|
||||
prefetch.prefetchURI(uri, uri, null, true);
|
||||
}
|
||||
queue = prefetch.enumerateQueue();
|
||||
do_check_true(queue.hasMoreElements());
|
||||
do_check_true(prefetch.hasMoreElements());
|
||||
}
|
||||
|
||||
|
||||
@@ -678,7 +678,7 @@ EventSource::InitChannelAndRequestEventSource()
|
||||
nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
|
||||
if (mWithCredentials) {
|
||||
securityFlags |= nsILoadInfo::SEC_REQUIRE_CORS_WITH_CREDENTIALS;
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
|
||||
+2
-36
@@ -1180,7 +1180,8 @@ Navigator::SendBeacon(const nsAString& aUrl,
|
||||
rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
uri,
|
||||
doc,
|
||||
nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
|
||||
nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS |
|
||||
nsILoadInfo::SEC_COOKIES_INCLUDE,
|
||||
nsIContentPolicy::TYPE_BEACON);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -1291,41 +1292,6 @@ Navigator::SendBeacon(const nsAString& aUrl,
|
||||
channel->SetLoadGroup(loadGroup);
|
||||
|
||||
RefPtr<BeaconStreamListener> beaconListener = new BeaconStreamListener();
|
||||
|
||||
// Start a preflight if cross-origin and content type is not whitelisted
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan = nsContentUtils::GetSecurityManager();
|
||||
rv = secMan->CheckSameOriginURI(documentURI, uri, false);
|
||||
bool crossOrigin = NS_FAILED(rv);
|
||||
nsAutoCString contentType, parsedCharset;
|
||||
rv = NS_ParseRequestContentType(mimeType, contentType, parsedCharset);
|
||||
if (crossOrigin &&
|
||||
mimeType.Length() > 0 &&
|
||||
!contentType.Equals(APPLICATION_WWW_FORM_URLENCODED) &&
|
||||
!contentType.Equals(MULTIPART_FORM_DATA) &&
|
||||
!contentType.Equals(TEXT_PLAIN)) {
|
||||
|
||||
// we need to set the sameOriginChecker as a notificationCallback
|
||||
// so we can tell the channel not to follow redirects
|
||||
nsCOMPtr<nsIInterfaceRequestor> soc = nsContentUtils::SameOriginChecker();
|
||||
channel->SetNotificationCallbacks(soc);
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> internalChannel =
|
||||
do_QueryInterface(channel);
|
||||
if (!internalChannel) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return false;
|
||||
}
|
||||
nsTArray<nsCString> unsafeHeaders;
|
||||
unsafeHeaders.AppendElement(NS_LITERAL_CSTRING("Content-Type"));
|
||||
rv = internalChannel->SetCorsPreflightParameters(unsafeHeaders,
|
||||
true,
|
||||
doc->NodePrincipal());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(rv);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
rv = channel->AsyncOpen2(beaconListener);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
|
||||
@@ -294,6 +294,7 @@ GK_ATOM(destructor, "destructor")
|
||||
GK_ATOM(details, "details")
|
||||
GK_ATOM(deviceAspectRatio, "device-aspect-ratio")
|
||||
GK_ATOM(deviceHeight, "device-height")
|
||||
GK_ATOM(devicePixelRatio, "device-pixel-ratio")
|
||||
GK_ATOM(deviceWidth, "device-width")
|
||||
GK_ATOM(dfn, "dfn")
|
||||
GK_ATOM(dialog, "dialog")
|
||||
|
||||
@@ -300,7 +300,7 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType,
|
||||
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL
|
||||
: nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) {
|
||||
securityFlags |= nsILoadInfo::SEC_REQUIRE_CORS_WITH_CREDENTIALS;
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
}
|
||||
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
||||
|
||||
|
||||
+67
-139
@@ -123,11 +123,10 @@ using namespace mozilla::dom;
|
||||
#define XML_HTTP_REQUEST_PARSEBODY (1 << 9) // Internal
|
||||
#define XML_HTTP_REQUEST_SYNCLOOPING (1 << 10) // Internal
|
||||
#define XML_HTTP_REQUEST_BACKGROUND (1 << 13) // Internal
|
||||
#define XML_HTTP_REQUEST_USE_XSITE_AC (1 << 14) // Internal
|
||||
#define XML_HTTP_REQUEST_NEED_AC_PREFLIGHT_IF_XSITE (1 << 15) // Internal
|
||||
#define XML_HTTP_REQUEST_AC_WITH_CREDENTIALS (1 << 16) // Internal
|
||||
#define XML_HTTP_REQUEST_TIMED_OUT (1 << 17) // Internal
|
||||
#define XML_HTTP_REQUEST_DELETED (1 << 18) // Internal
|
||||
#define XML_HTTP_REQUEST_HAD_UPLOAD_LISTENERS_ON_SEND (1 << 14) // Internal
|
||||
#define XML_HTTP_REQUEST_AC_WITH_CREDENTIALS (1 << 15) // Internal
|
||||
#define XML_HTTP_REQUEST_TIMED_OUT (1 << 16) // Internal
|
||||
#define XML_HTTP_REQUEST_DELETED (1 << 17) // Internal
|
||||
|
||||
#define XML_HTTP_REQUEST_LOADSTATES \
|
||||
(XML_HTTP_REQUEST_UNSENT | \
|
||||
@@ -1067,9 +1066,22 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx,
|
||||
}
|
||||
|
||||
bool
|
||||
nsXMLHttpRequest::IsDeniedCrossSiteRequest()
|
||||
nsXMLHttpRequest::IsCrossSiteCORSRequest()
|
||||
{
|
||||
if ((mState & XML_HTTP_REQUEST_USE_XSITE_AC) && mChannel) {
|
||||
if (!mChannel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
|
||||
MOZ_ASSERT(loadInfo);
|
||||
|
||||
return loadInfo->GetTainting() == LoadTainting::CORS;
|
||||
}
|
||||
|
||||
bool
|
||||
nsXMLHttpRequest::IsDeniedCrossSiteCORSRequest()
|
||||
{
|
||||
if (IsCrossSiteCORSRequest()) {
|
||||
nsresult rv;
|
||||
mChannel->GetStatus(&rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -1091,7 +1103,7 @@ nsXMLHttpRequest::GetResponseURL(nsAString& aUrl)
|
||||
|
||||
// Make sure we don't leak responseURL information from denied cross-site
|
||||
// requests.
|
||||
if (IsDeniedCrossSiteRequest()) {
|
||||
if (IsDeniedCrossSiteCORSRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1119,7 +1131,7 @@ nsXMLHttpRequest::Status()
|
||||
{
|
||||
// Make sure we don't leak status information from denied cross-site
|
||||
// requests.
|
||||
if (IsDeniedCrossSiteRequest()) {
|
||||
if (IsDeniedCrossSiteCORSRequest()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1169,7 +1181,7 @@ nsXMLHttpRequest::GetStatusText(nsCString& aStatusText)
|
||||
|
||||
// Make sure we don't leak status information from denied cross-site
|
||||
// requests.
|
||||
if (IsDeniedCrossSiteRequest()) {
|
||||
if (IsDeniedCrossSiteCORSRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1264,7 +1276,7 @@ nsXMLHttpRequest::IsSafeHeader(const nsACString& header, nsIHttpChannel* httpCha
|
||||
return false;
|
||||
}
|
||||
// if this is not a CORS call all headers are safe
|
||||
if (!(mState & XML_HTTP_REQUEST_USE_XSITE_AC)){
|
||||
if (!IsCrossSiteCORSRequest()) {
|
||||
return true;
|
||||
}
|
||||
// Check for dangerous headers
|
||||
@@ -1530,17 +1542,6 @@ nsXMLHttpRequest::IsSystemXHR()
|
||||
return mIsSystem || nsContentUtils::IsSystemPrincipal(mPrincipal);
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
|
||||
{
|
||||
// A system XHR (chrome code or a web app with the right permission) can
|
||||
// load anything, and same-origin loads are always allowed.
|
||||
if (!IsSystemXHR() &&
|
||||
!nsContentUtils::CheckMayLoad(mPrincipal, aChannel, true)) {
|
||||
mState |= XML_HTTP_REQUEST_USE_XSITE_AC;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url,
|
||||
bool async, const nsAString& user,
|
||||
@@ -1686,6 +1687,10 @@ nsXMLHttpRequest::Open(const nsACString& inMethod, const nsACString& url,
|
||||
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
|
||||
}
|
||||
|
||||
if (mIsAnon) {
|
||||
secFlags |= nsILoadInfo::SEC_COOKIES_OMIT;
|
||||
}
|
||||
|
||||
// If we have the document, use it. Unfortunately, for dedicated workers
|
||||
// 'doc' ends up being the parent document, which is not the document
|
||||
// that we want to use. So make sure to avoid using 'doc' in that situation.
|
||||
@@ -1712,8 +1717,7 @@ nsXMLHttpRequest::Open(const nsACString& inMethod, const nsACString& url,
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mState &= ~(XML_HTTP_REQUEST_USE_XSITE_AC |
|
||||
XML_HTTP_REQUEST_NEED_AC_PREFLIGHT_IF_XSITE);
|
||||
mState &= ~XML_HTTP_REQUEST_HAD_UPLOAD_LISTENERS_ON_SEND;
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
|
||||
if (httpChannel) {
|
||||
@@ -1920,12 +1924,6 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Always treat tainted channels as cross-origin.
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
|
||||
if (loadInfo && loadInfo->GetTainting() != LoadTainting::Basic) {
|
||||
mState |= XML_HTTP_REQUEST_USE_XSITE_AC;
|
||||
}
|
||||
|
||||
// Don't do anything if we have been aborted
|
||||
if (mState & XML_HTTP_REQUEST_UNSENT)
|
||||
return NS_OK;
|
||||
@@ -2121,7 +2119,11 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||
mResponseXML->ForceEnableXULXBL();
|
||||
}
|
||||
|
||||
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
|
||||
MOZ_ASSERT(loadInfo);
|
||||
bool isCrossSite = loadInfo->GetTainting() != LoadTainting::Basic;
|
||||
|
||||
if (isCrossSite) {
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mResponseXML);
|
||||
if (htmlDoc) {
|
||||
htmlDoc->DisableCookieAccess();
|
||||
@@ -2140,7 +2142,7 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||
|
||||
rv = mResponseXML->StartDocumentLoad(kLoadAsData, channel, loadGroup,
|
||||
nullptr, getter_AddRefs(listener),
|
||||
!(mState & XML_HTTP_REQUEST_USE_XSITE_AC));
|
||||
!isCrossSite);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mXMLParserStreamListener = listener;
|
||||
@@ -2804,33 +2806,19 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
||||
}
|
||||
}
|
||||
|
||||
if (httpChannel) {
|
||||
nsAutoCString contentTypeHeader;
|
||||
rv = httpChannel->GetRequestHeader(NS_LITERAL_CSTRING("Content-Type"),
|
||||
contentTypeHeader);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (!nsContentUtils::IsAllowedNonCorsContentType(contentTypeHeader)) {
|
||||
mCORSUnsafeHeaders.AppendElement(NS_LITERAL_CSTRING("Content-Type"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResetResponse();
|
||||
|
||||
CheckChannelForCrossSiteRequest(mChannel);
|
||||
|
||||
bool withCredentials = !!(mState & XML_HTTP_REQUEST_AC_WITH_CREDENTIALS);
|
||||
|
||||
if (!IsSystemXHR() && withCredentials) {
|
||||
if (!IsSystemXHR() && !mIsAnon &&
|
||||
(mState & XML_HTTP_REQUEST_AC_WITH_CREDENTIALS)) {
|
||||
// This is quite sad. We have to create the channel in .open(), since the
|
||||
// chrome-only xhr.channel API depends on that. However .withCredentials
|
||||
// can be modified after, so we don't know what to set the
|
||||
// SEC_REQUIRE_CORS_WITH_CREDENTIALS flag to when the channel is
|
||||
// SEC_COOKIES_INCLUDE flag to when the channel is
|
||||
// created. So set it here using a hacky internal API.
|
||||
|
||||
// Not doing this for system XHR uses since those don't use CORS.
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
|
||||
static_cast<LoadInfo*>(loadInfo.get())->SetWithCredentialsSecFlag();
|
||||
static_cast<LoadInfo*>(loadInfo.get())->SetIncludeCookiesSecFlag();
|
||||
}
|
||||
|
||||
// Blocking gets are common enough out of XHR that we should mark
|
||||
@@ -2852,10 +2840,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
||||
internalHttpChannel->SetResponseTimeoutEnabled(false);
|
||||
}
|
||||
|
||||
if (mIsAnon) {
|
||||
AddLoadFlags(mChannel, nsIRequest::LOAD_ANONYMOUS);
|
||||
}
|
||||
else {
|
||||
if (!mIsAnon) {
|
||||
AddLoadFlags(mChannel, nsIChannel::LOAD_EXPLICIT_CREDENTIALS);
|
||||
}
|
||||
|
||||
@@ -2891,23 +2876,16 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
||||
mRequestSentTime = PR_Now();
|
||||
StartTimeoutTimer();
|
||||
|
||||
// Check if we need to do a preflight request.
|
||||
if (!mCORSUnsafeHeaders.IsEmpty() ||
|
||||
(mUpload && mUpload->HasListeners()) ||
|
||||
(!method.LowerCaseEqualsLiteral("get") &&
|
||||
!method.LowerCaseEqualsLiteral("post") &&
|
||||
!method.LowerCaseEqualsLiteral("head"))) {
|
||||
mState |= XML_HTTP_REQUEST_NEED_AC_PREFLIGHT_IF_XSITE;
|
||||
// Check if we should enabled cross-origin upload listeners.
|
||||
if (mUpload && mUpload->HasListeners()) {
|
||||
mState |= XML_HTTP_REQUEST_HAD_UPLOAD_LISTENERS_ON_SEND;
|
||||
}
|
||||
|
||||
// Set up the preflight if needed
|
||||
if ((mState & XML_HTTP_REQUEST_USE_XSITE_AC) &&
|
||||
(mState & XML_HTTP_REQUEST_NEED_AC_PREFLIGHT_IF_XSITE)) {
|
||||
NS_ENSURE_TRUE(internalHttpChannel, NS_ERROR_DOM_BAD_URI);
|
||||
|
||||
rv = internalHttpChannel->SetCorsPreflightParameters(mCORSUnsafeHeaders,
|
||||
withCredentials, mPrincipal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!IsSystemXHR()) {
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
|
||||
loadInfo->SetCorsPreflightInfo(mCORSUnsafeHeaders,
|
||||
mState & XML_HTTP_REQUEST_HAD_UPLOAD_LISTENERS_ON_SEND);
|
||||
}
|
||||
|
||||
mIsMappedArrayBuffer = false;
|
||||
@@ -3078,7 +3056,7 @@ nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
|
||||
}
|
||||
|
||||
if (!safeHeader) {
|
||||
if (!mCORSUnsafeHeaders.Contains(header)) {
|
||||
if (!mCORSUnsafeHeaders.Contains(header, nsCaseInsensitiveCStringArrayComparator())) {
|
||||
mCORSUnsafeHeaders.AppendElement(header);
|
||||
}
|
||||
}
|
||||
@@ -3283,8 +3261,9 @@ nsXMLHttpRequest::SetWithCredentials(bool aWithCredentials, ErrorResult& aRv)
|
||||
// Return error if we're already processing a request. Note that we can't use
|
||||
// ReadyState() here, because it can't differentiate between "opened" and
|
||||
// "sent", so we use mState directly.
|
||||
if (!(mState & XML_HTTP_REQUEST_UNSENT) &&
|
||||
!(mState & XML_HTTP_REQUEST_OPENED)) {
|
||||
if ((!(mState & XML_HTTP_REQUEST_UNSENT) &&
|
||||
!(mState & XML_HTTP_REQUEST_OPENED)) ||
|
||||
mIsAnon) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
@@ -3329,46 +3308,6 @@ nsXMLHttpRequest::ChangeState(uint32_t aState, bool aBroadcast)
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple helper class that just forwards the redirect callback back
|
||||
* to the nsXMLHttpRequest.
|
||||
*/
|
||||
class AsyncVerifyRedirectCallbackForwarder final : public nsIAsyncVerifyRedirectCallback
|
||||
{
|
||||
public:
|
||||
explicit AsyncVerifyRedirectCallbackForwarder(nsXMLHttpRequest* xhr)
|
||||
: mXHR(xhr)
|
||||
{
|
||||
}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(AsyncVerifyRedirectCallbackForwarder)
|
||||
|
||||
// nsIAsyncVerifyRedirectCallback implementation
|
||||
NS_IMETHOD OnRedirectVerifyCallback(nsresult result) override
|
||||
{
|
||||
mXHR->OnRedirectVerifyCallback(result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~AsyncVerifyRedirectCallbackForwarder() {}
|
||||
|
||||
RefPtr<nsXMLHttpRequest> mXHR;
|
||||
};
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(AsyncVerifyRedirectCallbackForwarder, mXHR)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AsyncVerifyRedirectCallbackForwarder)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(AsyncVerifyRedirectCallbackForwarder)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(AsyncVerifyRedirectCallbackForwarder)
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// nsIChannelEventSink methods:
|
||||
//
|
||||
@@ -3380,30 +3319,17 @@ nsXMLHttpRequest::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
{
|
||||
NS_PRECONDITION(aNewChannel, "Redirect without a channel?");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) {
|
||||
CheckChannelForCrossSiteRequest(aNewChannel);
|
||||
|
||||
// Disable redirects for preflighted cross-site requests entirely for now
|
||||
if ((mState & XML_HTTP_REQUEST_USE_XSITE_AC) &&
|
||||
(mState & XML_HTTP_REQUEST_NEED_AC_PREFLIGHT_IF_XSITE)) {
|
||||
aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare to receive callback
|
||||
mRedirectCallback = callback;
|
||||
mNewRedirectChannel = aNewChannel;
|
||||
|
||||
if (mChannelEventSink) {
|
||||
RefPtr<AsyncVerifyRedirectCallbackForwarder> fwd =
|
||||
new AsyncVerifyRedirectCallbackForwarder(this);
|
||||
nsCOMPtr<nsIAsyncVerifyRedirectCallback> fwd =
|
||||
EnsureXPCOMifier();
|
||||
|
||||
rv = mChannelEventSink->AsyncOnChannelRedirect(aOldChannel,
|
||||
aNewChannel,
|
||||
aFlags, fwd);
|
||||
nsresult rv = mChannelEventSink->AsyncOnChannelRedirect(aOldChannel,
|
||||
aNewChannel,
|
||||
aFlags, fwd);
|
||||
if (NS_FAILED(rv)) {
|
||||
mRedirectCallback = nullptr;
|
||||
mNewRedirectChannel = nullptr;
|
||||
@@ -3414,7 +3340,7 @@ nsXMLHttpRequest::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
nsXMLHttpRequest::OnRedirectVerifyCallback(nsresult result)
|
||||
{
|
||||
NS_ASSERTION(mRedirectCallback, "mRedirectCallback not set in callback");
|
||||
@@ -3426,13 +3352,12 @@ nsXMLHttpRequest::OnRedirectVerifyCallback(nsresult result)
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
|
||||
if (httpChannel) {
|
||||
// Ensure all original headers are duplicated for the new channel (bug #553888)
|
||||
for (uint32_t i = mModifiedRequestHeaders.Length(); i > 0; ) {
|
||||
--i;
|
||||
if (mModifiedRequestHeaders[i].value.IsEmpty()) {
|
||||
httpChannel->SetEmptyRequestHeader(mModifiedRequestHeaders[i].header);
|
||||
for (RequestHeader& requestHeader : mModifiedRequestHeaders) {
|
||||
if (requestHeader.value.IsEmpty()) {
|
||||
httpChannel->SetEmptyRequestHeader(requestHeader.header);
|
||||
} else {
|
||||
httpChannel->SetRequestHeader(mModifiedRequestHeaders[i].header,
|
||||
mModifiedRequestHeaders[i].value,
|
||||
httpChannel->SetRequestHeader(requestHeader.header,
|
||||
requestHeader.value,
|
||||
false);
|
||||
}
|
||||
}
|
||||
@@ -3445,6 +3370,8 @@ nsXMLHttpRequest::OnRedirectVerifyCallback(nsresult result)
|
||||
|
||||
mRedirectCallback->OnRedirectVerifyCallback(result);
|
||||
mRedirectCallback = nullptr;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
@@ -3548,8 +3475,8 @@ nsXMLHttpRequest::OnStatus(nsIRequest *aRequest, nsISupports *aContext, nsresult
|
||||
bool
|
||||
nsXMLHttpRequest::AllowUploadProgress()
|
||||
{
|
||||
return !(mState & XML_HTTP_REQUEST_USE_XSITE_AC) ||
|
||||
(mState & XML_HTTP_REQUEST_NEED_AC_PREFLIGHT_IF_XSITE);
|
||||
return !IsCrossSiteCORSRequest() ||
|
||||
(mState & XML_HTTP_REQUEST_HAD_UPLOAD_LISTENERS_ON_SEND);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
@@ -3609,7 +3536,7 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
|
||||
// If authentication fails, XMLHttpRequest origin and
|
||||
// the request URL are same origin, ...
|
||||
/* Disabled - bug: 799540
|
||||
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
|
||||
if (IsCrossSiteCORSRequest()) {
|
||||
showPrompt = false;
|
||||
}
|
||||
*/
|
||||
@@ -3816,6 +3743,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXMLHttpRequestXPCOMifier)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#undef Status
|
||||
#endif
|
||||
|
||||
class AsyncVerifyRedirectCallbackForwarder;
|
||||
class nsFormData;
|
||||
class nsIJARChannel;
|
||||
class nsILoadGroup;
|
||||
@@ -426,7 +425,8 @@ private:
|
||||
return Send(Nullable<RequestBody>(aBody));
|
||||
}
|
||||
|
||||
bool IsDeniedCrossSiteRequest();
|
||||
bool IsCrossSiteCORSRequest();
|
||||
bool IsDeniedCrossSiteCORSRequest();
|
||||
|
||||
// Tell our channel what network interface ID we were told to use.
|
||||
// If it's an HTTP channel and we were told to use a non-default
|
||||
@@ -620,18 +620,9 @@ protected:
|
||||
|
||||
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.
|
||||
*/
|
||||
void CheckChannelForCrossSiteRequest(nsIChannel* aChannel);
|
||||
|
||||
void StartProgressEventTimer();
|
||||
|
||||
friend class AsyncVerifyRedirectCallbackForwarder;
|
||||
void OnRedirectVerifyCallback(nsresult result);
|
||||
nsresult OnRedirectVerifyCallback(nsresult result);
|
||||
|
||||
nsresult Open(const nsACString& method, const nsACString& url, bool async,
|
||||
const mozilla::dom::Optional<nsAString>& user,
|
||||
@@ -843,6 +834,7 @@ private:
|
||||
// XMLHttpRequest via XPCOM stuff.
|
||||
class nsXMLHttpRequestXPCOMifier final : public nsIStreamListener,
|
||||
public nsIChannelEventSink,
|
||||
public nsIAsyncVerifyRedirectCallback,
|
||||
public nsIProgressEventSink,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsITimerCallback
|
||||
@@ -867,6 +859,7 @@ public:
|
||||
NS_FORWARD_NSISTREAMLISTENER(mXHR->)
|
||||
NS_FORWARD_NSIREQUESTOBSERVER(mXHR->)
|
||||
NS_FORWARD_NSICHANNELEVENTSINK(mXHR->)
|
||||
NS_FORWARD_NSIASYNCVERIFYREDIRECTCALLBACK(mXHR->)
|
||||
NS_FORWARD_NSIPROGRESSEVENTSINK(mXHR->)
|
||||
NS_FORWARD_NSITIMERCALLBACK(mXHR->)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.setStatusLine(null, 302, "Moved");
|
||||
response.setHeader("Location", "http://www.mozilla.org", false);
|
||||
response.setHeader("Location", "http://nosuchdomain.localhost", false);
|
||||
}
|
||||
|
||||
|
||||
@@ -364,7 +364,7 @@ function runTest() {
|
||||
yield undefined;
|
||||
|
||||
|
||||
// use chrome XHR and access URI properties from chrome privileged script
|
||||
// use the systemXHR special privilege
|
||||
SpecialPowers.addPermission("systemXHR", true, document);
|
||||
xhr = new XMLHttpRequest({mozAnon: false, mozSystem: true});
|
||||
xhr.open("GET", "http://mochi.test:8888/tests/dom/base/test/file_XHRDocURI.xml");
|
||||
@@ -377,8 +377,7 @@ function runTest() {
|
||||
baseURI: "http://mochi.test:8888/tests/dom/base/test/file_XHRDocURI.xml",
|
||||
elementBaseURI: "http://www.example.com/"
|
||||
};
|
||||
var xml = SpecialPowers.wrap(xhr.responseXML);
|
||||
testChromeXMLDocURI(xml, expects);
|
||||
testXMLDocURI(xhr.responseXML, expects);
|
||||
if (xhr.readyState == 4) {
|
||||
gen.next();
|
||||
}
|
||||
@@ -397,8 +396,7 @@ function runTest() {
|
||||
documentURI: "http://mochi.test:8888/tests/dom/base/test/file_XHRDocURI.html",
|
||||
baseURI: "http://mochi.test:8888/tests/dom/base/test/file_XHRDocURI.html"
|
||||
};
|
||||
var doc = SpecialPowers.wrap(xhr.response);
|
||||
testChromeHTMLDocURI(doc, "http://mochi.test:8888/tests/dom/base/test/file_XHRDocURI.html", expects);
|
||||
testHTMLDocURI(xhr.response, expects);
|
||||
if (xhr.readyState == 4) {
|
||||
gen.next();
|
||||
}
|
||||
@@ -417,8 +415,7 @@ function runTest() {
|
||||
baseURI: "http://example.com/tests/dom/base/test/file_XHRDocURI.xml",
|
||||
elementBaseURI: "http://www.example.com/"
|
||||
};
|
||||
var xml = SpecialPowers.wrap(xhr.responseXML);
|
||||
testChromeXMLDocURI(xml, expects);
|
||||
testXMLDocURI(xhr.responseXML, expects);
|
||||
if (xhr.readyState == 4) {
|
||||
gen.next();
|
||||
}
|
||||
@@ -437,8 +434,7 @@ function runTest() {
|
||||
documentURI: "http://example.com/tests/dom/base/test/file_XHRDocURI.html",
|
||||
baseURI: "http://example.com/tests/dom/base/test/file_XHRDocURI.html"
|
||||
};
|
||||
var doc = SpecialPowers.wrap(xhr.response);
|
||||
testChromeHTMLDocURI(doc, "http://example.com/tests/dom/base/test/file_XHRDocURI.html", expects);
|
||||
testHTMLDocURI(xhr.response, expects);
|
||||
if (xhr.readyState == 4) {
|
||||
gen.next();
|
||||
}
|
||||
@@ -457,8 +453,7 @@ function runTest() {
|
||||
baseURI: "http://example.com/tests/dom/base/test/file_XHRDocURI.xml",
|
||||
elementBaseURI: "http://www.example.com/"
|
||||
};
|
||||
var xml = SpecialPowers.wrap(xhr.responseXML);
|
||||
testChromeXMLDocURI(xml, expects);
|
||||
testXMLDocURI(xhr.responseXML, expects);
|
||||
if (xhr.readyState == 4) {
|
||||
gen.next();
|
||||
}
|
||||
@@ -477,8 +472,7 @@ function runTest() {
|
||||
documentURI: "http://example.com/tests/dom/base/test/file_XHRDocURI.html",
|
||||
baseURI: "http://example.com/tests/dom/base/test/file_XHRDocURI.html"
|
||||
};
|
||||
var doc = SpecialPowers.wrap(xhr.response);
|
||||
testChromeHTMLDocURI(doc, "http://example.com/tests/dom/base/test/file_XHRDocURI.html", expects);
|
||||
testHTMLDocURI(xhr.response, expects);
|
||||
if (xhr.readyState == 4) {
|
||||
gen.next();
|
||||
}
|
||||
|
||||
@@ -466,7 +466,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583
|
||||
{
|
||||
// credentials using the auth cache
|
||||
var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
|
||||
xhr.withCredentials = true;
|
||||
// also, test mixed mode UI
|
||||
xhr.open("GET", "https://example.com/tests/dom/base/test/file_restrictedEventSource.sjs?test=user1_xhr", true, "user 1", "password 1");
|
||||
xhr.send();
|
||||
@@ -495,7 +494,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583
|
||||
function doTest5_d(test_id)
|
||||
{
|
||||
var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
|
||||
xhr.withCredentials = true;
|
||||
xhr.open("GET", "https://example.com/tests/dom/base/test/file_restrictedEventSource.sjs?test=user2_xhr", true, "user 2", "password 2");
|
||||
xhr.send();
|
||||
xhr.onloadend = function() {
|
||||
@@ -523,7 +521,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583
|
||||
{
|
||||
// credentials using the auth cache
|
||||
var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
|
||||
xhr.withCredentials = true;
|
||||
xhr.open("GET", "http://example.org/tests/dom/base/test/file_restrictedEventSource.sjs?test=user1_xhr", true, "user 1", "password 1");
|
||||
xhr.send();
|
||||
xhr.onloadend = function() {
|
||||
@@ -551,7 +548,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583
|
||||
function doTest5_f(test_id)
|
||||
{
|
||||
var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true});
|
||||
xhr.withCredentials = true;
|
||||
xhr.open("GET", "http://example.org/tests/dom/base/test/file_restrictedEventSource.sjs?test=user2_xhr", true, "user 2", "password 2");
|
||||
xhr.send();
|
||||
xhr.onloadend = function() {
|
||||
|
||||
@@ -587,16 +587,16 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
case WidgetMouseEvent::eLeftButton:
|
||||
BeginTrackingDragGesture(aPresContext, mouseEvent, aTargetFrame);
|
||||
mLClickCount = mouseEvent->clickCount;
|
||||
SetClickCount(aPresContext, mouseEvent, aStatus);
|
||||
SetClickCount(mouseEvent, aStatus);
|
||||
sNormalLMouseEventInProcess = true;
|
||||
break;
|
||||
case WidgetMouseEvent::eMiddleButton:
|
||||
mMClickCount = mouseEvent->clickCount;
|
||||
SetClickCount(aPresContext, mouseEvent, aStatus);
|
||||
SetClickCount(mouseEvent, aStatus);
|
||||
break;
|
||||
case WidgetMouseEvent::eRightButton:
|
||||
mRClickCount = mouseEvent->clickCount;
|
||||
SetClickCount(aPresContext, mouseEvent, aStatus);
|
||||
SetClickCount(mouseEvent, aStatus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -612,7 +612,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
// then fall through...
|
||||
case WidgetMouseEvent::eRightButton:
|
||||
case WidgetMouseEvent::eMiddleButton:
|
||||
SetClickCount(aPresContext, mouseEvent, aStatus);
|
||||
SetClickCount(mouseEvent, aStatus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -3087,7 +3087,7 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
// Make sure to dispatch the click even if there is no frame for
|
||||
// the current target element. This is required for Web compatibility.
|
||||
ret = CheckForAndDispatchClick(presContext, mouseEvent, aStatus);
|
||||
ret = CheckForAndDispatchClick(mouseEvent, aStatus);
|
||||
}
|
||||
|
||||
nsIPresShell *shell = presContext->GetPresShell();
|
||||
@@ -4519,8 +4519,7 @@ EventStateManager::UpdateDragDataTransfer(WidgetDragEvent* dragEvent)
|
||||
}
|
||||
|
||||
nsresult
|
||||
EventStateManager::SetClickCount(nsPresContext* aPresContext,
|
||||
WidgetMouseEvent* aEvent,
|
||||
EventStateManager::SetClickCount(WidgetMouseEvent* aEvent,
|
||||
nsEventStatus* aStatus)
|
||||
{
|
||||
nsCOMPtr<nsIContent> mouseContent;
|
||||
@@ -4623,8 +4622,7 @@ EventStateManager::InitAndDispatchClickEvent(WidgetMouseEvent* aEvent,
|
||||
}
|
||||
|
||||
nsresult
|
||||
EventStateManager::CheckForAndDispatchClick(nsPresContext* aPresContext,
|
||||
WidgetMouseEvent* aEvent,
|
||||
EventStateManager::CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
|
||||
nsEventStatus* aStatus)
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
@@ -5695,14 +5693,16 @@ EventStateManager::WheelPrefs::NeedToComputeLineOrPageDelta(
|
||||
(mMultiplierY[index] != 1.0 && mMultiplierY[index] != -1.0);
|
||||
}
|
||||
|
||||
bool
|
||||
EventStateManager::WheelPrefs::HasUserPrefsForDelta(WidgetWheelEvent* aEvent)
|
||||
void
|
||||
EventStateManager::WheelPrefs::GetUserPrefsForEvent(WidgetWheelEvent* aEvent,
|
||||
double* aOutMultiplierX,
|
||||
double* aOutMultiplierY)
|
||||
{
|
||||
Index index = GetIndexFor(aEvent);
|
||||
Init(index);
|
||||
|
||||
return mMultiplierX[index] != 1.0 ||
|
||||
mMultiplierY[index] != 1.0;
|
||||
*aOutMultiplierX = mMultiplierX[index];
|
||||
*aOutMultiplierY = mMultiplierY[index];
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -5712,10 +5712,13 @@ EventStateManager::WheelEventIsScrollAction(WidgetWheelEvent* aEvent)
|
||||
WheelPrefs::GetInstance()->ComputeActionFor(aEvent) == WheelPrefs::ACTION_SCROLL;
|
||||
}
|
||||
|
||||
bool
|
||||
EventStateManager::WheelEventNeedsDeltaMultipliers(WidgetWheelEvent* aEvent)
|
||||
void
|
||||
EventStateManager::GetUserPrefsForWheelEvent(WidgetWheelEvent* aEvent,
|
||||
double* aOutMultiplierX,
|
||||
double* aOutMultiplierY)
|
||||
{
|
||||
return WheelPrefs::GetInstance()->HasUserPrefsForDelta(aEvent);
|
||||
WheelPrefs::GetInstance()->GetUserPrefsForEvent(
|
||||
aEvent, aOutMultiplierX, aOutMultiplierY);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -242,9 +242,10 @@ public:
|
||||
// Returns true if the given WidgetWheelEvent will resolve to a scroll action.
|
||||
static bool WheelEventIsScrollAction(WidgetWheelEvent* aEvent);
|
||||
|
||||
// Returns true if user prefs for wheel deltas apply to the given
|
||||
// WidgetWheelEvent.
|
||||
static bool WheelEventNeedsDeltaMultipliers(WidgetWheelEvent* aEvent);
|
||||
// Returns user-set multipliers for a wheel event.
|
||||
static void GetUserPrefsForWheelEvent(WidgetWheelEvent* aEvent,
|
||||
double* aOutMultiplierX,
|
||||
double* aOutMultiplierY);
|
||||
|
||||
// Returns whether or not a frame can be vertically scrolled with a mouse
|
||||
// wheel (as opposed to, say, a selection or touch scroll).
|
||||
@@ -384,11 +385,8 @@ protected:
|
||||
nsIContent* aMouseTarget,
|
||||
nsWeakFrame aCurrentTarget,
|
||||
bool aNoContentDispatch);
|
||||
nsresult SetClickCount(nsPresContext* aPresContext,
|
||||
WidgetMouseEvent* aEvent,
|
||||
nsEventStatus* aStatus);
|
||||
nsresult CheckForAndDispatchClick(nsPresContext* aPresContext,
|
||||
WidgetMouseEvent* aEvent,
|
||||
nsresult SetClickCount(WidgetMouseEvent* aEvent, nsEventStatus* aStatus);
|
||||
nsresult CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
|
||||
nsEventStatus* aStatus);
|
||||
void EnsureDocument(nsPresContext* aPresContext);
|
||||
void FlushPendingEvents(nsPresContext* aPresContext);
|
||||
@@ -456,7 +454,9 @@ protected:
|
||||
* Returns whether or not ApplyUserPrefsToDelta() would change the delta
|
||||
* values of an event.
|
||||
*/
|
||||
bool HasUserPrefsForDelta(WidgetWheelEvent* aEvent);
|
||||
void GetUserPrefsForEvent(WidgetWheelEvent* aEvent,
|
||||
double* aOutMultiplierX,
|
||||
double* aOutMultiplierY);
|
||||
|
||||
/**
|
||||
* If ApplyUserPrefsToDelta() changed the delta values with customized
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "nsPresContext.h"
|
||||
#include "prtime.h"
|
||||
#include "Units.h"
|
||||
#include "AsyncScrollBase.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@@ -137,7 +138,7 @@ WheelTransaction::UpdateTransaction(WidgetWheelEvent* aEvent)
|
||||
|
||||
SetTimeout();
|
||||
|
||||
if (sScrollSeriesCounter != 0 && OutOfTime(sTime, kScrollSeriesTimeout)) {
|
||||
if (sScrollSeriesCounter != 0 && OutOfTime(sTime, kScrollSeriesTimeoutMs)) {
|
||||
sScrollSeriesCounter = 0;
|
||||
}
|
||||
sScrollSeriesCounter++;
|
||||
@@ -383,14 +384,9 @@ WheelTransaction::AccelerateWheelDelta(WidgetWheelEvent* aEvent,
|
||||
}
|
||||
|
||||
/* static */ double
|
||||
WheelTransaction::ComputeAcceleratedWheelDelta(double aDelta,
|
||||
int32_t aFactor)
|
||||
WheelTransaction::ComputeAcceleratedWheelDelta(double aDelta, int32_t aFactor)
|
||||
{
|
||||
if (aDelta == 0.0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (aDelta * sScrollSeriesCounter * (double)aFactor / 10);
|
||||
return mozilla::ComputeAcceleratedWheelDelta(aDelta, sScrollSeriesCounter, aFactor);
|
||||
}
|
||||
|
||||
/* static */ int32_t
|
||||
|
||||
@@ -151,8 +151,6 @@ public:
|
||||
bool aAllowScrollSpeedOverride);
|
||||
|
||||
protected:
|
||||
static const uint32_t kScrollSeriesTimeout = 80; // in milliseconds
|
||||
|
||||
static void BeginTransaction(nsIFrame* aTargetFrame,
|
||||
WidgetWheelEvent* aEvent);
|
||||
// Be careful, UpdateTransaction may fire a DOM event, therefore, the target
|
||||
|
||||
+55
-271
@@ -43,7 +43,7 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS(FetchDriver,
|
||||
nsIStreamListener, nsIChannelEventSink, nsIInterfaceRequestor,
|
||||
nsIStreamListener, nsIInterfaceRequestor,
|
||||
nsIThreadRetargetableStreamListener)
|
||||
|
||||
FetchDriver::FetchDriver(InternalRequest* aRequest, nsIPrincipal* aPrincipal,
|
||||
@@ -51,7 +51,6 @@ FetchDriver::FetchDriver(InternalRequest* aRequest, nsIPrincipal* aPrincipal,
|
||||
: mPrincipal(aPrincipal)
|
||||
, mLoadGroup(aLoadGroup)
|
||||
, mRequest(aRequest)
|
||||
, mHasBeenCrossSite(false)
|
||||
, mResponseAvailableCalled(false)
|
||||
, mFetchCalled(false)
|
||||
{
|
||||
@@ -86,61 +85,6 @@ FetchDriver::Fetch(FetchDriverObserver* aObserver)
|
||||
return NS_DispatchToCurrentThread(r);
|
||||
}
|
||||
|
||||
nsresult
|
||||
FetchDriver::SetTainting()
|
||||
{
|
||||
workers::AssertIsOnMainThread();
|
||||
|
||||
// If we've already been cross-site then we should be fully updated
|
||||
if (mHasBeenCrossSite) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoCString url;
|
||||
mRequest->GetURL(url);
|
||||
nsCOMPtr<nsIURI> requestURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(requestURI), url,
|
||||
nullptr, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Begin Step 8 of the Main Fetch algorithm
|
||||
// https://fetch.spec.whatwg.org/#fetching
|
||||
|
||||
// request's current url's origin is request's origin and the CORS flag is unset
|
||||
// request's current url's scheme is "data" and request's same-origin data-URL flag is set
|
||||
// request's current url's scheme is "about"
|
||||
|
||||
// We have to manually check about:blank here since it's not treated as
|
||||
// an inheriting URL by CheckMayLoad.
|
||||
if (NS_IsAboutBlank(requestURI) ||
|
||||
NS_SUCCEEDED(mPrincipal->CheckMayLoad(requestURI, false /* report */,
|
||||
true /*allowIfInheritsPrincipal*/))) {
|
||||
// What the spec calls "basic fetch" is handled within our necko channel
|
||||
// code. Therefore everything goes through HTTP Fetch
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mHasBeenCrossSite = true;
|
||||
|
||||
// request's mode is "same-origin"
|
||||
if (mRequest->Mode() == RequestMode::Same_origin) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
// request's mode is "no-cors"
|
||||
if (mRequest->Mode() == RequestMode::No_cors) {
|
||||
mRequest->MaybeIncreaseResponseTainting(LoadTainting::Opaque);
|
||||
// What the spec calls "basic fetch" is handled within our necko channel
|
||||
// code. Therefore everything goes through HTTP Fetch
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
mRequest->MaybeIncreaseResponseTainting(LoadTainting::CORS);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
FetchDriver::ContinueFetch()
|
||||
{
|
||||
@@ -177,8 +121,14 @@ FetchDriver::HttpFetch()
|
||||
ios);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = SetTainting();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// Unsafe requests aren't allowed with when using no-core mode.
|
||||
if (mRequest->Mode() == RequestMode::No_cors &&
|
||||
mRequest->UnsafeRequest() &&
|
||||
(!mRequest->HasSimpleMethod() ||
|
||||
!mRequest->Headers()->HasOnlySimpleHeaders())) {
|
||||
MOZ_ASSERT(false, "The API should have caught this");
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
// Step 2 deals with letting ServiceWorkers intercept requests. This is
|
||||
// handled by Necko after the channel is opened.
|
||||
@@ -202,35 +152,19 @@ FetchDriver::HttpFetch()
|
||||
// is unset or response tainting is "opaque"
|
||||
// is true, and unset otherwise."
|
||||
|
||||
// This is effectivetly the opposite of the use credentials flag in "HTTP
|
||||
// network or cache fetch" in the spec and decides whether to transmit
|
||||
// cookies and other identifying information. LOAD_ANONYMOUS also prevents
|
||||
// new cookies sent by the server from being stored. This value will
|
||||
// propagate across redirects, which is what we want.
|
||||
const nsLoadFlags credentialsFlag =
|
||||
(mRequest->GetCredentialsMode() == RequestCredentials::Omit ||
|
||||
(mHasBeenCrossSite &&
|
||||
mRequest->GetCredentialsMode() == RequestCredentials::Same_origin &&
|
||||
mRequest->Mode() == RequestMode::No_cors)) ?
|
||||
nsIRequest::LOAD_ANONYMOUS : 0;
|
||||
|
||||
// Set skip serviceworker flag.
|
||||
// While the spec also gates on the client being a ServiceWorker, we can't
|
||||
// infer that here. Instead we rely on callers to set the flag correctly.
|
||||
const nsLoadFlags bypassFlag = mRequest->SkipServiceWorker() ?
|
||||
nsIChannel::LOAD_BYPASS_SERVICE_WORKER : 0;
|
||||
|
||||
nsSecurityFlags secFlags;
|
||||
if (mRequest->Mode() == RequestMode::Cors &&
|
||||
mRequest->GetCredentialsMode() == RequestCredentials::Include) {
|
||||
secFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS |
|
||||
nsILoadInfo::SEC_REQUIRE_CORS_WITH_CREDENTIALS;
|
||||
} else if (mRequest->Mode() == RequestMode::Cors) {
|
||||
secFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
nsSecurityFlags secFlags = nsILoadInfo::SEC_ABOUT_BLANK_INHERITS;
|
||||
if (mRequest->Mode() == RequestMode::Cors) {
|
||||
secFlags |= nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
} else if (mRequest->Mode() == RequestMode::Same_origin) {
|
||||
secFlags = nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS;
|
||||
secFlags |= nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS;
|
||||
} else if (mRequest->Mode() == RequestMode::No_cors) {
|
||||
secFlags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
|
||||
secFlags |= nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected request mode!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
@@ -240,50 +174,53 @@ FetchDriver::HttpFetch()
|
||||
secFlags |= nsILoadInfo::SEC_DONT_FOLLOW_REDIRECTS;
|
||||
}
|
||||
|
||||
// This is handles the use credentials flag in "HTTP
|
||||
// network or cache fetch" in the spec and decides whether to transmit
|
||||
// cookies and other identifying information.
|
||||
if (mRequest->GetCredentialsMode() == RequestCredentials::Include) {
|
||||
secFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
} else if (mRequest->GetCredentialsMode() == RequestCredentials::Omit) {
|
||||
secFlags |= nsILoadInfo::SEC_COOKIES_OMIT;
|
||||
} else if (mRequest->GetCredentialsMode() == RequestCredentials::Same_origin) {
|
||||
secFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected credentials mode!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// From here on we create a channel and set its properties with the
|
||||
// information from the InternalRequest. This is an implementation detail.
|
||||
MOZ_ASSERT(mLoadGroup);
|
||||
nsCOMPtr<nsIChannel> chan;
|
||||
|
||||
nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL |
|
||||
bypassFlag | nsIChannel::LOAD_CLASSIFY_URI;
|
||||
if (mDocument) {
|
||||
MOZ_ASSERT(mDocument->NodePrincipal() == mPrincipal);
|
||||
rv = NS_NewChannel(getter_AddRefs(chan),
|
||||
uri,
|
||||
mDocument,
|
||||
secFlags |
|
||||
nsILoadInfo::SEC_ABOUT_BLANK_INHERITS,
|
||||
secFlags,
|
||||
mRequest->ContentPolicyType(),
|
||||
mLoadGroup,
|
||||
nullptr, /* aCallbacks */
|
||||
nsIRequest::LOAD_NORMAL | credentialsFlag | bypassFlag,
|
||||
loadFlags,
|
||||
ios);
|
||||
} else {
|
||||
rv = NS_NewChannel(getter_AddRefs(chan),
|
||||
uri,
|
||||
mPrincipal,
|
||||
secFlags |
|
||||
nsILoadInfo::SEC_ABOUT_BLANK_INHERITS,
|
||||
secFlags,
|
||||
mRequest->ContentPolicyType(),
|
||||
mLoadGroup,
|
||||
nullptr, /* aCallbacks */
|
||||
nsIRequest::LOAD_NORMAL | credentialsFlag | bypassFlag,
|
||||
loadFlags,
|
||||
ios);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mLoadGroup = nullptr;
|
||||
|
||||
// Insert ourselves into the notification callbacks chain so we can handle
|
||||
// cross-origin redirects.
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsIInterfaceRequestor> notificationCallbacks;
|
||||
chan->GetNotificationCallbacks(getter_AddRefs(notificationCallbacks));
|
||||
MOZ_ASSERT(!notificationCallbacks);
|
||||
}
|
||||
#endif
|
||||
chan->SetNotificationCallbacks(this);
|
||||
|
||||
// FIXME(nsm): Bug 1120715.
|
||||
// Step 3.4 "If request's cache mode is default and request's header list
|
||||
// contains a header named `If-Modified-Since`, `If-None-Match`,
|
||||
@@ -408,24 +345,11 @@ FetchDriver::HttpFetch()
|
||||
// implementation is handled by the http channel calling into
|
||||
// nsCORSListenerProxy. We just inform it which unsafe headers are included
|
||||
// in the request.
|
||||
if (IsUnsafeRequest()) {
|
||||
if (mRequest->Mode() == RequestMode::No_cors) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
mRequest->SetRedirectMode(RequestRedirect::Error);
|
||||
|
||||
if (mRequest->Mode() == RequestMode::Cors) {
|
||||
nsAutoTArray<nsCString, 5> unsafeHeaders;
|
||||
mRequest->Headers()->GetUnsafeHeaders(unsafeHeaders);
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> internalChan = do_QueryInterface(httpChan);
|
||||
NS_ENSURE_TRUE(internalChan, NS_ERROR_DOM_BAD_URI);
|
||||
|
||||
rv = internalChan->SetCorsPreflightParameters(
|
||||
unsafeHeaders,
|
||||
mRequest->GetCredentialsMode() == RequestCredentials::Include,
|
||||
mPrincipal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = chan->GetLoadInfo();
|
||||
loadInfo->SetCorsPreflightInfo(unsafeHeaders, false);
|
||||
}
|
||||
|
||||
rv = chan->AsyncOpen2(this);
|
||||
@@ -435,15 +359,6 @@ FetchDriver::HttpFetch()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
FetchDriver::IsUnsafeRequest()
|
||||
{
|
||||
return mHasBeenCrossSite &&
|
||||
(mRequest->UnsafeRequest() &&
|
||||
(!mRequest->HasSimpleMethod() ||
|
||||
!mRequest->Headers()->HasOnlySimpleHeaders()));
|
||||
}
|
||||
|
||||
already_AddRefed<InternalResponse>
|
||||
FetchDriver::BeginAndGetFilteredResponse(InternalResponse* aResponse,
|
||||
nsIURI* aFinalURI,
|
||||
@@ -557,6 +472,23 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
|
||||
nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(aRequest);
|
||||
|
||||
// On a successful redirect we perform the following substeps of HTTP Fetch,
|
||||
// step 5, "redirect status", step 11.
|
||||
|
||||
// Step 11.5 "Append locationURL to request's url list." so that when we set the
|
||||
// Response's URL from the Request's URL in Main Fetch, step 15, we get the
|
||||
// final value. Note, we still use a single URL value instead of a list.
|
||||
// Because of that we only need to do this after the request finishes.
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
rv = NS_GetFinalChannelURI(channel, getter_AddRefs(newURI));
|
||||
if (NS_FAILED(rv)) {
|
||||
FailWithNetworkError();
|
||||
return rv;
|
||||
}
|
||||
nsAutoCString newUrl;
|
||||
newURI->GetSpec(newUrl);
|
||||
mRequest->SetURL(newUrl);
|
||||
|
||||
bool foundOpaqueRedirect = false;
|
||||
|
||||
if (httpChannel) {
|
||||
@@ -663,18 +595,13 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
||||
return rv;
|
||||
}
|
||||
|
||||
LoadTainting channelTainting = LoadTainting::Basic;
|
||||
if (loadInfo) {
|
||||
channelTainting = loadInfo->GetTainting();
|
||||
}
|
||||
|
||||
// Propagate any tainting from the channel back to our response here. This
|
||||
// step is not reflected in the spec because the spec is written such that
|
||||
// FetchEvent.respondWith() just passes the already-tainted Response back to
|
||||
// the outer fetch(). In gecko, however, we serialize the Response through
|
||||
// the channel and must regenerate the tainting from the channel in the
|
||||
// interception case.
|
||||
mRequest->MaybeIncreaseResponseTainting(channelTainting);
|
||||
mRequest->MaybeIncreaseResponseTainting(loadInfo->GetTainting());
|
||||
|
||||
// Resolves fetch() promise which may trigger code running in a worker. Make
|
||||
// sure the Response is fully initialized before calling this.
|
||||
@@ -747,143 +674,6 @@ FetchDriver::OnStopRequest(nsIRequest* aRequest,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This is called when the channel is redirected.
|
||||
NS_IMETHODIMP
|
||||
FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||
nsIChannel* aNewChannel,
|
||||
uint32_t aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *aCallback)
|
||||
{
|
||||
NS_PRECONDITION(aNewChannel, "Redirect without a channel?");
|
||||
|
||||
if (NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags) ||
|
||||
NS_IsHSTSUpgradeRedirect(aOldChannel, aNewChannel, aFlags)) {
|
||||
aCallback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We should only ever get here if we use a "follow" redirect policy,
|
||||
// or if if we set an "error" policy as a result of a CORS policy.
|
||||
MOZ_ASSERT(mRequest->GetRedirectMode() == RequestRedirect::Follow ||
|
||||
(mRequest->GetRedirectMode() == RequestRedirect::Error &&
|
||||
IsUnsafeRequest()));
|
||||
|
||||
// HTTP Fetch step 5, "redirect status", step 1
|
||||
if (NS_WARN_IF(mRequest->GetRedirectMode() == RequestRedirect::Error)) {
|
||||
aOldChannel->Cancel(NS_BINDING_FAILED);
|
||||
return NS_BINDING_FAILED;
|
||||
}
|
||||
|
||||
// HTTP Fetch step 5, "redirect status", steps 2 through 6 are automatically
|
||||
// handled by necko before calling AsyncOnChannelRedirect() with the new
|
||||
// nsIChannel.
|
||||
|
||||
// HTTP Fetch step 5, "redirect status", steps 7 and 8 enforcing a redirect
|
||||
// count are done by Necko. The pref used is "network.http.redirection-limit"
|
||||
// which is set to 20 by default.
|
||||
|
||||
// HTTP Fetch Step 9, "redirect status". This is enforced by the
|
||||
// nsCORSListenerProxy. It forbids redirecting to data:
|
||||
|
||||
// HTTP Fetch step 5, "redirect status", step 10 requires us to halt the
|
||||
// redirect, but successfully return an opaqueredirect Response to the
|
||||
// initiating Fetch.
|
||||
|
||||
// The following steps are from HTTP Fetch step 5, "redirect status", step 11
|
||||
// which requires the RequestRedirect to be "follow". We asserted that we're
|
||||
// in either "follow" or "error" mode here.
|
||||
|
||||
// HTTP Fetch step 5, "redirect status", steps 11.1 and 11.2 block redirecting
|
||||
// to a URL with credentials in CORS mode. This is implemented in
|
||||
// nsCORSListenerProxy.
|
||||
|
||||
// On a successful redirect we perform the following substeps of HTTP Fetch,
|
||||
// step 5, "redirect status", step 11.
|
||||
|
||||
// Step 11.5 "Append locationURL to request's url list." so that when we set the
|
||||
// Response's URL from the Request's URL in Main Fetch, step 15, we get the
|
||||
// final value. Note, we still use a single URL value instead of a list.
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
nsresult rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI));
|
||||
if (NS_FAILED(rv)) {
|
||||
aOldChannel->Cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// We need to update our request's URL.
|
||||
nsAutoCString newUrl;
|
||||
newURI->GetSpec(newUrl);
|
||||
mRequest->SetURL(newUrl);
|
||||
|
||||
// Implement Main Fetch step 8 again on redirect.
|
||||
rv = SetTainting();
|
||||
if (NS_FAILED(rv)) {
|
||||
aOldChannel->Cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Requests that require preflight are not permitted to redirect.
|
||||
// Fetch spec section 4.2 "HTTP Fetch", step 4.9 just uses the manual
|
||||
// redirect flag to decide whether to execute step 4.10 or not. We do not
|
||||
// represent it in our implementation.
|
||||
// The only thing we do is to check if the request requires a preflight (part
|
||||
// of step 4.9), in which case we abort. This part cannot be done by
|
||||
// nsCORSListenerProxy since it does not have access to mRequest.
|
||||
// which case. Step 4.10.3 is handled by OnRedirectVerifyCallback(), and all
|
||||
// the other steps are handled by nsCORSListenerProxy.
|
||||
|
||||
if (IsUnsafeRequest()) {
|
||||
// We can't handle redirects that require preflight yet.
|
||||
// This is especially true for no-cors requests, which much always be
|
||||
// blocked if they require preflight.
|
||||
|
||||
// Simply fire an error here.
|
||||
aOldChannel->Cancel(NS_BINDING_FAILED);
|
||||
return NS_BINDING_FAILED;
|
||||
}
|
||||
|
||||
// Otherwise, we rely on necko and the CORS proxy to do the right thing
|
||||
// as the redirect is followed. In general this means http
|
||||
// fetch. If we've ever been CORS, we need to stay CORS.
|
||||
|
||||
// Possibly set the LOAD_ANONYMOUS flag on the channel.
|
||||
if (mHasBeenCrossSite &&
|
||||
mRequest->GetCredentialsMode() == RequestCredentials::Same_origin &&
|
||||
mRequest->Mode() == RequestMode::No_cors) {
|
||||
// In the case of a "no-cors" mode request with "same-origin" credentials,
|
||||
// we have to set LOAD_ANONYMOUS manually here in order to avoid sending
|
||||
// credentials on a cross-origin redirect.
|
||||
nsLoadFlags flags;
|
||||
rv = aNewChannel->GetLoadFlags(&flags);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
flags |= nsIRequest::LOAD_ANONYMOUS;
|
||||
rv = aNewChannel->SetLoadFlags(flags);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
aOldChannel->Cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
{
|
||||
// Make sure nothing in the redirect chain screws up our credentials
|
||||
// settings. LOAD_ANONYMOUS must be set if we RequestCredentials is "omit"
|
||||
// or "same-origin".
|
||||
nsLoadFlags flags;
|
||||
aNewChannel->GetLoadFlags(&flags);
|
||||
bool shouldBeAnon =
|
||||
mRequest->GetCredentialsMode() == RequestCredentials::Omit ||
|
||||
(mHasBeenCrossSite &&
|
||||
mRequest->GetCredentialsMode() == RequestCredentials::Same_origin);
|
||||
MOZ_ASSERT(!!(flags & nsIRequest::LOAD_ANONYMOUS) == shouldBeAnon);
|
||||
}
|
||||
#endif
|
||||
|
||||
aCallback->OnRedirectVerifyCallback(NS_OK);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FetchDriver::CheckListenerChain()
|
||||
{
|
||||
@@ -893,12 +683,6 @@ FetchDriver::CheckListenerChain()
|
||||
NS_IMETHODIMP
|
||||
FetchDriver::GetInterface(const nsIID& aIID, void **aResult)
|
||||
{
|
||||
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
|
||||
*aResult = static_cast<nsIChannelEventSink*>(this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsIStreamListener))) {
|
||||
*aResult = static_cast<nsIStreamListener*>(this);
|
||||
NS_ADDREF_THIS();
|
||||
|
||||
@@ -55,7 +55,6 @@ private:
|
||||
};
|
||||
|
||||
class FetchDriver final : public nsIStreamListener,
|
||||
public nsIChannelEventSink,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIThreadRetargetableStreamListener
|
||||
{
|
||||
@@ -63,7 +62,6 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
|
||||
|
||||
@@ -82,7 +80,6 @@ private:
|
||||
nsCOMPtr<nsIOutputStream> mPipeOutputStream;
|
||||
RefPtr<FetchDriverObserver> mObserver;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
bool mHasBeenCrossSite;
|
||||
|
||||
DebugOnly<bool> mResponseAvailableCalled;
|
||||
DebugOnly<bool> mFetchCalled;
|
||||
@@ -92,10 +89,8 @@ private:
|
||||
FetchDriver& operator=(const FetchDriver&) = delete;
|
||||
~FetchDriver();
|
||||
|
||||
nsresult SetTainting();
|
||||
nsresult ContinueFetch();
|
||||
nsresult HttpFetch();
|
||||
bool IsUnsafeRequest();
|
||||
// Returns the filtered response sent to the observer.
|
||||
// Callers who don't have access to a channel can pass null for aFinalURI.
|
||||
already_AddRefed<InternalResponse>
|
||||
|
||||
@@ -151,6 +151,7 @@ public:
|
||||
return RefPtr<ImportLoader>(mImportLoader).forget();
|
||||
}
|
||||
|
||||
virtual CORSMode GetCORSMode() const override;
|
||||
protected:
|
||||
virtual ~HTMLLinkElement();
|
||||
|
||||
@@ -161,7 +162,6 @@ protected:
|
||||
nsAString& aMedia,
|
||||
bool* aIsScoped,
|
||||
bool* aIsAlternate) override;
|
||||
virtual CORSMode GetCORSMode() const override;
|
||||
protected:
|
||||
// nsGenericHTMLElement
|
||||
virtual void GetItemValueText(DOMString& text) override;
|
||||
|
||||
@@ -1267,7 +1267,7 @@ nsresult HTMLMediaElement::LoadResource()
|
||||
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
|
||||
|
||||
if (GetCORSMode() == CORS_USE_CREDENTIALS) {
|
||||
securityFlags |= nsILoadInfo::SEC_REQUIRE_CORS_WITH_CREDENTIALS;
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video));
|
||||
|
||||
@@ -106,3 +106,4 @@ LOCAL_INCLUDES += [
|
||||
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
|
||||
LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
|
||||
|
||||
@@ -23,7 +23,13 @@ var testIcon = {
|
||||
}]
|
||||
};
|
||||
|
||||
var invalidMimeTypes = ['application / text', 'test;test', ';test?test', 'application\\text'];
|
||||
var invalidMimeTypes = [
|
||||
'application / text',
|
||||
'test;test',
|
||||
';test?test',
|
||||
'application\\text',
|
||||
'image/jpeg, image/gif'
|
||||
];
|
||||
invalidMimeTypes.forEach((invalidMime) => {
|
||||
var expected = `Expect invalid mime to be treated like undefined.`;
|
||||
testIcon.icons[0].type = invalidMime;
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsContentSecurityManager, nsIContentSecurityManager)
|
||||
NS_IMPL_ISUPPORTS(nsContentSecurityManager,
|
||||
nsIContentSecurityManager,
|
||||
nsIChannelEventSink)
|
||||
|
||||
static nsresult
|
||||
ValidateSecurityFlags(nsILoadInfo* aLoadInfo)
|
||||
@@ -24,12 +26,6 @@ ValidateSecurityFlags(nsILoadInfo* aLoadInfo)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// make sure that cors-with-credentials is only used in combination with CORS.
|
||||
if (aLoadInfo->GetRequireCorsWithCredentials() &&
|
||||
securityMode != nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
|
||||
MOZ_ASSERT(false, "can not use cors-with-credentials without cors");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// all good, found the right security flags
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -84,7 +80,7 @@ URIHasFlags(nsIURI* aURI, uint32_t aURIFlags)
|
||||
}
|
||||
|
||||
static nsresult
|
||||
DoSOPChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo)
|
||||
DoSOPChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo, nsIChannel* aChannel)
|
||||
{
|
||||
if (aLoadInfo->GetAllowChrome() &&
|
||||
(URIHasFlags(aURI, nsIProtocolHandler::URI_IS_UI_RESOURCE) ||
|
||||
@@ -93,19 +89,10 @@ DoSOPChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo)
|
||||
return DoCheckLoadURIChecks(aURI, aLoadInfo);
|
||||
}
|
||||
|
||||
nsIPrincipal* loadingPrincipal = aLoadInfo->LoadingPrincipal();
|
||||
bool sameOriginDataInherits =
|
||||
aLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS;
|
||||
NS_ENSURE_FALSE(NS_HasBeenCrossOrigin(aChannel, true),
|
||||
NS_ERROR_DOM_BAD_URI);
|
||||
|
||||
if (sameOriginDataInherits &&
|
||||
aLoadInfo->GetAboutBlankInherits() &&
|
||||
NS_IsAboutBlank(aURI)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return loadingPrincipal->CheckMayLoad(aURI,
|
||||
true, // report to console
|
||||
sameOriginDataInherits);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
@@ -125,7 +112,8 @@ DoCORSChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo,
|
||||
RefPtr<nsCORSListenerProxy> corsListener =
|
||||
new nsCORSListenerProxy(aInAndOutListener,
|
||||
loadingPrincipal,
|
||||
aLoadInfo->GetRequireCorsWithCredentials());
|
||||
aLoadInfo->GetCookiePolicy() ==
|
||||
nsILoadInfo::SEC_COOKIES_INCLUDE);
|
||||
// XXX: @arg: DataURIHandling::Allow
|
||||
// lets use DataURIHandling::Allow for now and then decide on callsite basis. see also:
|
||||
// http://mxr.mozilla.org/mozilla-central/source/dom/security/nsCORSListenerProxy.h#33
|
||||
@@ -351,22 +339,17 @@ nsContentSecurityManager::doContentSecurityCheck(nsIChannel* aChannel,
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// if dealing with a redirected channel then we have already installed
|
||||
// streamlistener and redirect proxies and so we are done.
|
||||
if (loadInfo->GetInitialSecurityCheckDone()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// make sure that only one of the five security flags is set in the loadinfo
|
||||
// e.g. do not require same origin and allow cross origin at the same time
|
||||
nsresult rv = ValidateSecurityFlags(loadInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// lets store the initialSecurityCheckDone flag which indicates whether the channel
|
||||
// was initialy evaluated by the contentSecurityManager. Once the inital
|
||||
// asyncOpen() of the channel went through the contentSecurityManager then
|
||||
// redirects do not have perform all the security checks, e.g. no reason
|
||||
// to setup CORS again.
|
||||
bool initialSecurityCheckDone = loadInfo->GetInitialSecurityCheckDone();
|
||||
|
||||
// now lets set the initalSecurityFlag for subsequent calls
|
||||
rv = loadInfo->SetInitialSecurityCheckDone(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// since aChannel was openend using asyncOpen2() we have to make sure
|
||||
// that redirects of that channel also get openend using asyncOpen2()
|
||||
// please note that some implementations of ::AsyncOpen2 might already
|
||||
@@ -375,13 +358,7 @@ nsContentSecurityManager::doContentSecurityCheck(nsIChannel* aChannel,
|
||||
rv = loadInfo->SetEnforceSecurity(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> finalChannelURI;
|
||||
rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(finalChannelURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsSecurityFlags securityMode = loadInfo->GetSecurityMode();
|
||||
|
||||
// Allow subresource loads if TriggeringPrincipal is the SystemPrincipal.
|
||||
// Allow subresource loads if TriggeringPrincipal is the SystemPrincipal.
|
||||
// For example, allow user stylesheets to load XBL from external files.
|
||||
if (nsContentUtils::IsSystemPrincipal(loadInfo->TriggeringPrincipal()) &&
|
||||
loadInfo->GetExternalContentPolicyType() != nsIContentPolicy::TYPE_DOCUMENT &&
|
||||
@@ -389,42 +366,145 @@ nsContentSecurityManager::doContentSecurityCheck(nsIChannel* aChannel,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if none of the REQUIRE_SAME_ORIGIN flags are set, then SOP does not apply
|
||||
if ((securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS) ||
|
||||
(securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED)) {
|
||||
rv = DoSOPChecks(finalChannelURI, loadInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// if dealing with a redirected channel then we only enforce SOP
|
||||
// and can return at this point.
|
||||
if (initialSecurityCheckDone) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if ((securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS) ||
|
||||
(securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL)) {
|
||||
// Please note that DoCheckLoadURIChecks should only be enforced for
|
||||
// cross origin requests. If the flag SEC_REQUIRE_CORS_DATA_INHERITS is set
|
||||
// within the loadInfo, then then CheckLoadURIWithPrincipal is performed
|
||||
// within nsCorsListenerProxy
|
||||
rv = DoCheckLoadURIChecks(finalChannelURI, loadInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (securityMode == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
|
||||
if (loadInfo->GetSecurityMode() == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
|
||||
rv = DoCORSChecks(aChannel, loadInfo, aInAndOutListener);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = CheckChannel(aChannel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> finalChannelURI;
|
||||
rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(finalChannelURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Perform all ContentPolicy checks (MixedContent, CSP, ...)
|
||||
rv = DoContentSecurityChecks(finalChannelURI, loadInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// now lets set the initalSecurityFlag for subsequent calls
|
||||
rv = loadInfo->SetInitialSecurityCheckDone(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// all security checks passed - lets allow the load
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsContentSecurityManager::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||
nsIChannel* aNewChannel,
|
||||
uint32_t aRedirFlags,
|
||||
nsIAsyncVerifyRedirectCallback *aCb)
|
||||
{
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aOldChannel->GetLoadInfo();
|
||||
// Are we enforcing security using LoadInfo?
|
||||
if (loadInfo && loadInfo->GetEnforceSecurity()) {
|
||||
nsresult rv = CheckChannel(aNewChannel);
|
||||
if (NS_FAILED(rv)) {
|
||||
aOldChannel->Cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
// Also verify that the redirecting server is allowed to redirect to the
|
||||
// given URI
|
||||
nsCOMPtr<nsIPrincipal> oldPrincipal;
|
||||
nsContentUtils::GetSecurityManager()->
|
||||
GetChannelResultPrincipal(aOldChannel, getter_AddRefs(oldPrincipal));
|
||||
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
aNewChannel->GetURI(getter_AddRefs(newURI));
|
||||
nsCOMPtr<nsIURI> newOriginalURI;
|
||||
aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI));
|
||||
|
||||
NS_ENSURE_STATE(oldPrincipal && newURI && newOriginalURI);
|
||||
|
||||
const uint32_t flags =
|
||||
nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT |
|
||||
nsIScriptSecurityManager::DISALLOW_SCRIPT;
|
||||
nsresult rv = nsContentUtils::GetSecurityManager()->
|
||||
CheckLoadURIWithPrincipal(oldPrincipal, newURI, flags);
|
||||
if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) {
|
||||
rv = nsContentUtils::GetSecurityManager()->
|
||||
CheckLoadURIWithPrincipal(oldPrincipal, newOriginalURI, flags);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aCb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
AddLoadFlags(nsIRequest *aRequest, nsLoadFlags aNewFlags)
|
||||
{
|
||||
nsLoadFlags flags;
|
||||
aRequest->GetLoadFlags(&flags);
|
||||
flags |= aNewFlags;
|
||||
aRequest->SetLoadFlags(flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that this channel passes all security checks. Returns an error code
|
||||
* if this requesst should not be permitted.
|
||||
*/
|
||||
nsresult
|
||||
nsContentSecurityManager::CheckChannel(nsIChannel* aChannel)
|
||||
{
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
|
||||
MOZ_ASSERT(loadInfo);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Handle cookie policies
|
||||
uint32_t cookiePolicy = loadInfo->GetCookiePolicy();
|
||||
if (cookiePolicy == nsILoadInfo::SEC_COOKIES_SAME_ORIGIN) {
|
||||
nsIPrincipal* loadingPrincipal = loadInfo->LoadingPrincipal();
|
||||
|
||||
// It doesn't matter what we pass for the third, data-inherits, argument.
|
||||
// Any protocol which inherits won't pay attention to cookies anyway.
|
||||
rv = loadingPrincipal->CheckMayLoad(uri, false, false);
|
||||
if (NS_FAILED(rv)) {
|
||||
AddLoadFlags(aChannel, nsIRequest::LOAD_ANONYMOUS);
|
||||
}
|
||||
}
|
||||
else if (cookiePolicy == nsILoadInfo::SEC_COOKIES_OMIT) {
|
||||
AddLoadFlags(aChannel, nsIRequest::LOAD_ANONYMOUS);
|
||||
}
|
||||
|
||||
nsSecurityFlags securityMode = loadInfo->GetSecurityMode();
|
||||
|
||||
// CORS mode is handled by nsCORSListenerProxy
|
||||
if (securityMode == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
|
||||
if (NS_HasBeenCrossOrigin(aChannel)) {
|
||||
loadInfo->MaybeIncreaseTainting(LoadTainting::CORS);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if none of the REQUIRE_SAME_ORIGIN flags are set, then SOP does not apply
|
||||
if ((securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS) ||
|
||||
(securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED)) {
|
||||
rv = DoSOPChecks(uri, loadInfo, aChannel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if ((securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS) ||
|
||||
(securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL)) {
|
||||
if (NS_HasBeenCrossOrigin(aChannel)) {
|
||||
loadInfo->MaybeIncreaseTainting(LoadTainting::Opaque);
|
||||
}
|
||||
// Please note that DoCheckLoadURIChecks should only be enforced for
|
||||
// cross origin requests. If the flag SEC_REQUIRE_CORS_DATA_INHERITS is set
|
||||
// within the loadInfo, then then CheckLoadURIWithPrincipal is performed
|
||||
// within nsCorsListenerProxy
|
||||
rv = DoCheckLoadURIChecks(uri, loadInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// ==== nsIContentSecurityManager implementation =====
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "nsIContentSecurityManager.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
|
||||
class nsIStreamListener;
|
||||
|
||||
@@ -19,10 +20,12 @@ class nsIStreamListener;
|
||||
{ 0xa2, 0x94, 0xa6, 0x51, 0xfa, 0x35, 0x22, 0x7f } }
|
||||
|
||||
class nsContentSecurityManager : public nsIContentSecurityManager
|
||||
, public nsIChannelEventSink
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICONTENTSECURITYMANAGER
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
|
||||
nsContentSecurityManager() {}
|
||||
|
||||
@@ -30,6 +33,8 @@ public:
|
||||
nsCOMPtr<nsIStreamListener>& aInAndOutListener);
|
||||
|
||||
private:
|
||||
static nsresult CheckChannel(nsIChannel* aChannel);
|
||||
|
||||
virtual ~nsContentSecurityManager() {}
|
||||
|
||||
};
|
||||
|
||||
@@ -27,7 +27,9 @@ function handleRequest(request, response)
|
||||
var curHop = hops[query.hop - 1];
|
||||
query.allowOrigin = curHop.allowOrigin;
|
||||
query.allowHeaders = curHop.allowHeaders;
|
||||
query.allowMethods = curHop.allowMethods;
|
||||
query.allowCred = curHop.allowCred;
|
||||
query.noAllowPreflight = curHop.noAllowPreflight;
|
||||
if (curHop.setCookie) {
|
||||
query.setCookie = unescape(curHop.setCookie);
|
||||
}
|
||||
|
||||
@@ -104,6 +104,16 @@ function runTest() {
|
||||
"Accept-Language": "sv-SE" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "Content-Type": "foo/bar, text/plain" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "Content-Type": "foo/bar, text/plain, garbage" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
|
||||
// Custom headers
|
||||
{ pass: 1,
|
||||
@@ -250,6 +260,16 @@ function runTest() {
|
||||
"Accept-Language": "sv-SE" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "HEAD",
|
||||
headers: { "Content-Type": "foo/bar, text/plain" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "HEAD",
|
||||
headers: { "Content-Type": "foo/bar, text/plain, garbage" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
|
||||
// HEAD with custom headers
|
||||
{ pass: 1,
|
||||
@@ -327,6 +347,18 @@ function runTest() {
|
||||
"Accept-Language": "sv-SE" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "POST",
|
||||
body: "hi there",
|
||||
headers: { "Content-Type": "foo/bar, text/plain" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "POST",
|
||||
body: "hi there",
|
||||
headers: { "Content-Type": "foo/bar, text/plain, garbage" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
|
||||
// POST with custom headers
|
||||
{ pass: 1,
|
||||
@@ -1052,7 +1084,7 @@ function runTest() {
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
{ pass: 1,
|
||||
method: "POST",
|
||||
body: "hi there",
|
||||
headers: { "Content-Type": "text/plain",
|
||||
@@ -1067,11 +1099,133 @@ function runTest() {
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "POST",
|
||||
body: "hi there",
|
||||
headers: { "Content-Type": "text/plain",
|
||||
"my-header": "myValue",
|
||||
},
|
||||
hops: [{ server: "http://example.org",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowHeaders: "my-header",
|
||||
},
|
||||
{ server: "http://sub1.test1.example.org",
|
||||
allowOrigin: origin,
|
||||
allowHeaders: "my-header",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "POST",
|
||||
body: "hi there",
|
||||
headers: { "Content-Type": "text/plain",
|
||||
"my-header": "myValue",
|
||||
},
|
||||
hops: [{ server: "http://example.org",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowHeaders: "my-header",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowHeaders: "my-header",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "POST",
|
||||
body: "hi there",
|
||||
headers: { "Content-Type": "text/plain",
|
||||
"my-header": "myValue",
|
||||
},
|
||||
hops: [{ server: "http://example.org",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowHeaders: "my-header",
|
||||
},
|
||||
{ server: "http://example.org",
|
||||
allowOrigin: origin,
|
||||
allowHeaders: "my-header",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "POST",
|
||||
body: "hi there",
|
||||
headers: { "Content-Type": "text/plain",
|
||||
"my-header": "myValue",
|
||||
},
|
||||
hops: [{ server: "http://example.org",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
hops: [{ server: "http://example.org",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "DELETE",
|
||||
hops: [{ server: "http://example.org",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
{ server: "http://sub1.test1.example.org",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "DELETE",
|
||||
hops: [{ server: "http://example.org",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "DELETE",
|
||||
hops: [{ server: "http://example.org",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
{ server: "http://example.org",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "DELETE",
|
||||
hops: [{ server: "http://example.org",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -18,7 +18,6 @@ var tests = { "font-src": thisSite+page+"?testid=font-src",
|
||||
"object-src": thisSite+page+"?testid=object-src",
|
||||
"script-src": thisSite+page+"?testid=script-src",
|
||||
"style-src": thisSite+page+"?testid=style-src",
|
||||
"worker": thisSite+page+"?testid=worker",
|
||||
"xhr-src": thisSite+page+"?testid=xhr-src",
|
||||
"from-worker": thisSite+page+"?testid=from-worker",
|
||||
"from-blob-worker": thisSite+page+"?testid=from-blob-worker",
|
||||
|
||||
@@ -14,13 +14,8 @@ function handleRequest(request, response)
|
||||
var resource = "/tests/dom/security/test/csp/file_redirects_resource.sjs";
|
||||
|
||||
// CSP header value
|
||||
var additional = ""
|
||||
if (query['testid'] == "worker") {
|
||||
additional = "; script-src 'self' 'unsafe-inline'";
|
||||
}
|
||||
response.setHeader("Content-Security-Policy",
|
||||
"default-src 'self' blob: ; style-src 'self' 'unsafe-inline'" + additional,
|
||||
false);
|
||||
"default-src 'self' blob: ; style-src 'self' 'unsafe-inline'", false);
|
||||
|
||||
// downloadable font that redirects to another site
|
||||
if (query["testid"] == "font-src") {
|
||||
@@ -69,12 +64,6 @@ function handleRequest(request, response)
|
||||
return;
|
||||
}
|
||||
|
||||
// worker script resource that redirects to another site
|
||||
if (query["testid"] == "worker") {
|
||||
response.write('<script>var worker = new Worker("'+resource+'?res=worker&redir=other&id=worker-redir");</script>');
|
||||
return;
|
||||
}
|
||||
|
||||
// script that XHR's to a resource that redirects to another site
|
||||
if (query["testid"] == "xhr-src") {
|
||||
response.write('<script src="'+resource+'?res=xhr"></script>');
|
||||
|
||||
@@ -85,13 +85,6 @@ function handleRequest(request, response)
|
||||
return;
|
||||
}
|
||||
|
||||
// web worker resource
|
||||
if (query["res"] == "worker") {
|
||||
response.setHeader("Content-Type", "application/javascript", false);
|
||||
response.write("worker script data...");
|
||||
return;
|
||||
}
|
||||
|
||||
// internal stylesheet that loads an image from an external site
|
||||
if (query["res"] == "cssLoader") {
|
||||
let bgURL = thisSite + resource + '?redir=other&res=image&id=' + query["id"];
|
||||
|
||||
@@ -82,14 +82,12 @@ var testExpectedResults = { "font-src": true,
|
||||
"script-src-redir": false,
|
||||
"style-src": true,
|
||||
"style-src-redir": false,
|
||||
"worker": true,
|
||||
"worker-redir": false,
|
||||
"xhr-src": true,
|
||||
"xhr-src-redir": false,
|
||||
"from-worker": true,
|
||||
"script-src-redir-from-worker": true, /* redir is allowed since policy isn't inherited */
|
||||
"xhr-src-redir-from-worker": true, /* redir is allowed since policy isn't inherited */
|
||||
"fetch-src-redir-from-worker": true, /* redir is allowed since policy isn't inherited */
|
||||
"script-src-redir-from-worker": true, // redir is allowed since policy isn't inherited
|
||||
"xhr-src-redir-from-worker": true, // redir is allowed since policy isn't inherited
|
||||
"fetch-src-redir-from-worker": true, // redir is allowed since policy isn't inherited
|
||||
"from-blob-worker": true,
|
||||
"script-src-redir-from-blob-worker": false,
|
||||
"xhr-src-redir-from-blob-worker": false,
|
||||
|
||||
@@ -10,6 +10,7 @@ support-files = beacon-frame.html
|
||||
[test_beaconFrame.html]
|
||||
[test_beaconPreflight.html]
|
||||
[test_beaconPreflightFailure.html]
|
||||
[test_beaconPreflightWithCustomContentType.html]
|
||||
[test_beaconContentPolicy.html]
|
||||
[test_beaconOriginHeader.html]
|
||||
[test_beaconCORSRedirect.html]
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1210302
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1210302</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1210302">Mozilla Bug 936340</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var beaconUrl = "http://example.com/tests/dom/tests/mochitest/beacon/beacon-preflight-handler.sjs?beacon";
|
||||
|
||||
var intervalID = null;
|
||||
|
||||
function queryIfBeaconSucceeded() {
|
||||
clearInterval(intervalID);
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "beacon-preflight-handler.sjs?verify", true);
|
||||
xhr.onload = function() {
|
||||
is(xhr.responseText, "green", "SendBeacon should have succeeded after preflight!");
|
||||
SimpleTest.finish();
|
||||
};
|
||||
xhr.onerror = function() {
|
||||
ok(false, "xhr request returned error");
|
||||
SimpleTest.finish();
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
// not enabled by default yet.
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({'set': [["beacon.enabled", true]]}, beginTest);
|
||||
|
||||
function beginTest() {
|
||||
var abv = new Uint8Array([0,1,2,3]);
|
||||
var blob = new Blob(abv, {type: "application/badness, text/plain"});
|
||||
var sent = navigator.sendBeacon(beaconUrl, blob);
|
||||
ok(sent, "sending the beacon should start successfully");
|
||||
|
||||
// we have to make sure sending the beacon did not fail, so
|
||||
// we have to wait for 2 seconds before we can query the result.
|
||||
intervalID = setInterval(queryIfBeaconSucceeded, 2000);
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -204,6 +204,18 @@ function testModeCors() {
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "Content-Type": "foo/bar, text/plain" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
|
||||
{ pass: 0,
|
||||
method: "GET",
|
||||
headers: { "Content-Type": "foo/bar, text/plain, garbage" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
|
||||
// Custom headers
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
@@ -349,6 +361,16 @@ function testModeCors() {
|
||||
"Accept-Language": "sv-SE" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "HEAD",
|
||||
headers: { "Content-Type": "foo/bar, text/plain" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "HEAD",
|
||||
headers: { "Content-Type": "foo/bar, text/plain, garbage" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
|
||||
// HEAD with custom headers
|
||||
{ pass: 1,
|
||||
@@ -426,6 +448,18 @@ function testModeCors() {
|
||||
"Accept-Language": "sv-SE" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "POST",
|
||||
body: "hi there",
|
||||
headers: { "Content-Type": "foo/bar, text/plain" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "POST",
|
||||
body: "hi there",
|
||||
headers: { "Content-Type": "foo/bar, text/plain, garbage" },
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
|
||||
// POST with custom headers
|
||||
{ pass: 1,
|
||||
@@ -1079,7 +1113,7 @@ function testCrossOriginCredentials() {
|
||||
return finalPromise;
|
||||
}
|
||||
|
||||
function testRedirects() {
|
||||
function testCORSRedirects() {
|
||||
var origin = "http://mochi.test:8888";
|
||||
|
||||
var tests = [
|
||||
@@ -1249,6 +1283,20 @@ function testRedirects() {
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "POST",
|
||||
body: "hi there",
|
||||
headers: { "Content-Type": "text/plain",
|
||||
"my-header": "myValue",
|
||||
},
|
||||
hops: [{ server: "http://mochi.test:8888",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowHeaders: "my-header",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "POST",
|
||||
body: "hi there",
|
||||
@@ -1260,6 +1308,7 @@ function testRedirects() {
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowHeaders: "my-header",
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -1281,12 +1330,24 @@ function testRedirects() {
|
||||
}
|
||||
],
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "DELETE",
|
||||
hops: [{ server: "http://mochi.test:8888",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "DELETE",
|
||||
hops: [{ server: "http://mochi.test:8888",
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
noAllowPreflight: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -1296,9 +1357,11 @@ function testRedirects() {
|
||||
},
|
||||
{ server: "http://test1.example.com",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
{ server: "http://test2.example.com",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -1320,9 +1383,11 @@ function testRedirects() {
|
||||
method: "DELETE",
|
||||
hops: [{ server: "http://example.com",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
{ server: "http://sub1.test1.mochi.test:8888",
|
||||
allowOrigin: origin,
|
||||
allowMethods: "DELETE",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -1418,6 +1483,98 @@ function testRedirects() {
|
||||
return Promise.all(fetches);
|
||||
}
|
||||
|
||||
function testNoCORSRedirects() {
|
||||
var origin = "http://mochi.test:8888";
|
||||
|
||||
var tests = [
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
hops: [{ server: "http://example.com",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
hops: [{ server: origin,
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "GET",
|
||||
hops: [{ server: origin,
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
},
|
||||
{ server: origin,
|
||||
}
|
||||
],
|
||||
},
|
||||
{ pass: 1,
|
||||
method: "POST",
|
||||
body: 'upload body here',
|
||||
hops: [{ server: origin
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ pass: 0,
|
||||
method: "DELETE",
|
||||
hops: [{ server: origin
|
||||
},
|
||||
{ server: "http://example.com",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
var fetches = [];
|
||||
for (test of tests) {
|
||||
req = {
|
||||
url: test.hops[0].server + corsServerPath + "hop=1&hops=" +
|
||||
escape(test.hops.toSource()),
|
||||
method: test.method,
|
||||
headers: test.headers,
|
||||
body: test.body,
|
||||
};
|
||||
|
||||
if (test.pass) {
|
||||
if (test.body)
|
||||
req.url += "&body=" + escape(test.body);
|
||||
}
|
||||
|
||||
fetches.push((function(req, test) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolve(new Request(req.url, { mode: 'no-cors',
|
||||
method: req.method,
|
||||
headers: req.headers,
|
||||
body: req.body }));
|
||||
}).then(function(request) {
|
||||
return fetch(request);
|
||||
}).then(function(res) {
|
||||
ok(test.pass, "Expected test to pass for " + test.toSource());
|
||||
// All requests are cross-origin no-cors, we should always have
|
||||
// an opaque response here. All values on the opaque response
|
||||
// should be hidden.
|
||||
is(res.type, 'opaque', 'wrong response type for ' + test.toSource());
|
||||
is(res.status, 0, "wrong status in test for " + test.toSource());
|
||||
is(res.statusText, "", "wrong status text for " + test.toSource());
|
||||
is(res.url, '', 'wrong response url for ' + test.toSource());
|
||||
return res.text().then(function(v) {
|
||||
is(v, "", "wrong responseText in test for " + test.toSource());
|
||||
});
|
||||
}, function(e) {
|
||||
ok(!test.pass, "Expected test failure for " + test.toSource());
|
||||
ok(e instanceof TypeError, "Exception should be TypeError for " + test.toSource());
|
||||
});
|
||||
})(req, test));
|
||||
}
|
||||
|
||||
return Promise.all(fetches);
|
||||
}
|
||||
|
||||
function testReferrer() {
|
||||
var referrer;
|
||||
if (self && self.location) {
|
||||
@@ -1446,7 +1603,8 @@ function runTest() {
|
||||
.then(testModeCors)
|
||||
.then(testSameOriginCredentials)
|
||||
.then(testCrossOriginCredentials)
|
||||
.then(testRedirects)
|
||||
.then(testCORSRedirects)
|
||||
.then(testNoCORSRedirects)
|
||||
.then(testReferrer)
|
||||
// Put more promise based tests here.
|
||||
}
|
||||
|
||||
@@ -623,9 +623,8 @@ static bool
|
||||
WillHandleWheelEvent(WidgetWheelEvent* aEvent)
|
||||
{
|
||||
return EventStateManager::WheelEventIsScrollAction(aEvent) &&
|
||||
(aEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_LINE
|
||||
|| aEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL) &&
|
||||
!EventStateManager::WheelEventNeedsDeltaMultipliers(aEvent);
|
||||
(aEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_LINE ||
|
||||
aEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -1084,8 +1083,17 @@ APZCTreeManager::ProcessWheelEvent(WidgetWheelEvent& aEvent,
|
||||
scrollMode,
|
||||
ScrollWheelInput::DeltaTypeForDeltaMode(aEvent.deltaMode),
|
||||
origin,
|
||||
aEvent.deltaX,
|
||||
aEvent.deltaY);
|
||||
aEvent.deltaX, aEvent.deltaY);
|
||||
|
||||
// We add the user multiplier as a separate field, rather than premultiplying
|
||||
// it, because if the input is converted back to a WidgetWheelEvent, then
|
||||
// EventStateManager would apply the delta a second time. We could in theory
|
||||
// work around this by asking ESM to customize the event much sooner, and
|
||||
// then save the "customizedByUserPrefs" bit on ScrollWheelInput - but for
|
||||
// now, this seems easier.
|
||||
EventStateManager::GetUserPrefsForWheelEvent(&aEvent,
|
||||
&input.mUserDeltaMultiplierX,
|
||||
&input.mUserDeltaMultiplierY);
|
||||
|
||||
nsEventStatus status = ReceiveInputEvent(input, aOutTargetGuid, aOutInputBlockId);
|
||||
aEvent.refPoint.x = input.mOrigin.x;
|
||||
|
||||
@@ -1564,7 +1564,18 @@ AsyncPanZoomController::GetScrollWheelDelta(const ScrollWheelInput& aEvent) cons
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected scroll delta type");
|
||||
}
|
||||
|
||||
if (isRootContent && gfxPrefs::MouseWheelHasRootScrollDeltaOverride()) {
|
||||
// Apply user-set multipliers.
|
||||
delta.x *= aEvent.mUserDeltaMultiplierX;
|
||||
delta.y *= aEvent.mUserDeltaMultiplierY;
|
||||
|
||||
// For the conditions under which we allow system scroll overrides, see
|
||||
// EventStateManager::DeltaAccumulator::ComputeScrollAmountForDefaultAction
|
||||
// and WheelTransaction::OverrideSystemScrollSpeed.
|
||||
if (isRootContent &&
|
||||
gfxPrefs::MouseWheelHasRootScrollDeltaOverride() &&
|
||||
!aEvent.IsCustomizedByUserPrefs() &&
|
||||
aEvent.mDeltaType == ScrollWheelInput::SCROLLDELTA_LINE)
|
||||
{
|
||||
// Only apply delta multipliers if we're increasing the delta.
|
||||
double hfactor = double(gfxPrefs::MouseWheelRootHScrollDeltaFactor()) / 100;
|
||||
double vfactor = double(gfxPrefs::MouseWheelRootVScrollDeltaFactor()) / 100;
|
||||
@@ -1576,6 +1587,21 @@ AsyncPanZoomController::GetScrollWheelDelta(const ScrollWheelInput& aEvent) cons
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a line scroll, and this event was part of a scroll series, then
|
||||
// it might need extra acceleration. See WheelHandlingHelper.cpp.
|
||||
if (aEvent.mDeltaType == ScrollWheelInput::SCROLLDELTA_LINE &&
|
||||
aEvent.mScrollSeriesNumber > 0)
|
||||
{
|
||||
int32_t start = gfxPrefs::MouseWheelAccelerationStart();
|
||||
if (start >= 0 && aEvent.mScrollSeriesNumber >= uint32_t(start)) {
|
||||
int32_t factor = gfxPrefs::MouseWheelAccelerationFactor();
|
||||
if (factor > 0) {
|
||||
delta.x = ComputeAcceleratedWheelDelta(delta.x, aEvent.mScrollSeriesNumber, factor);
|
||||
delta.y = ComputeAcceleratedWheelDelta(delta.y, aEvent.mScrollSeriesNumber, factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Abs(delta.x) > pageScrollSize.width) {
|
||||
delta.x = (delta.x >= 0)
|
||||
? pageScrollSize.width
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "InputBlockState.h"
|
||||
#include "AsyncPanZoomController.h" // for AsyncPanZoomController
|
||||
#include "AsyncScrollBase.h" // for kScrollSeriesTimeoutMs
|
||||
#include "gfxPrefs.h" // for gfxPrefs
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/SizePrintfMacros.h" // for PRIuSIZE
|
||||
@@ -246,6 +247,7 @@ WheelBlockState::WheelBlockState(const RefPtr<AsyncPanZoomController>& aTargetAp
|
||||
bool aTargetConfirmed,
|
||||
const ScrollWheelInput& aInitialEvent)
|
||||
: CancelableBlockState(aTargetApzc, aTargetConfirmed)
|
||||
, mScrollSeriesCounter(0)
|
||||
, mTransactionEnded(false)
|
||||
{
|
||||
sLastWheelBlockId = GetBlockId();
|
||||
@@ -297,7 +299,7 @@ WheelBlockState::SetConfirmedTargetApzc(const RefPtr<AsyncPanZoomController>& aT
|
||||
}
|
||||
|
||||
void
|
||||
WheelBlockState::Update(const ScrollWheelInput& aEvent)
|
||||
WheelBlockState::Update(ScrollWheelInput& aEvent)
|
||||
{
|
||||
// We might not be in a transaction if the block never started in a
|
||||
// transaction - for example, if nothing was scrollable.
|
||||
@@ -305,6 +307,18 @@ WheelBlockState::Update(const ScrollWheelInput& aEvent)
|
||||
return;
|
||||
}
|
||||
|
||||
// The current "scroll series" is a like a sub-transaction. It has a separate
|
||||
// timeout of 80ms. Since we need to compute wheel deltas at different phases
|
||||
// of a transaction (for example, when it is updated, and later when the
|
||||
// event action is taken), we affix the scroll series counter to the event.
|
||||
// This makes GetScrollWheelDelta() consistent.
|
||||
if (!mLastEventTime.IsNull() &&
|
||||
(aEvent.mTimeStamp - mLastEventTime).ToMilliseconds() > kScrollSeriesTimeoutMs)
|
||||
{
|
||||
mScrollSeriesCounter = 0;
|
||||
}
|
||||
aEvent.mScrollSeriesNumber = ++mScrollSeriesCounter;
|
||||
|
||||
// If we can't scroll in the direction of the wheel event, we don't update
|
||||
// the last move time. This allows us to timeout a transaction even if the
|
||||
// mouse isn't moving.
|
||||
|
||||
@@ -244,7 +244,7 @@ public:
|
||||
/**
|
||||
* Update the wheel transaction state for a new event.
|
||||
*/
|
||||
void Update(const ScrollWheelInput& aEvent);
|
||||
void Update(ScrollWheelInput& aEvent);
|
||||
|
||||
protected:
|
||||
void UpdateTargetApzc(const RefPtr<AsyncPanZoomController>& aTargetApzc) override;
|
||||
@@ -253,6 +253,7 @@ private:
|
||||
nsTArray<ScrollWheelInput> mEvents;
|
||||
TimeStamp mLastEventTime;
|
||||
TimeStamp mLastMouseMove;
|
||||
uint32_t mScrollSeriesCounter;
|
||||
bool mTransactionEnded;
|
||||
};
|
||||
|
||||
|
||||
@@ -269,15 +269,17 @@ InputQueue::ReceiveScrollWheelInput(const RefPtr<AsyncPanZoomController>& aTarge
|
||||
*aOutInputBlockId = block->GetBlockId();
|
||||
}
|
||||
|
||||
block->Update(aEvent);
|
||||
// Copy the event, since WheelBlockState needs to affix a counter.
|
||||
ScrollWheelInput event(aEvent);
|
||||
block->Update(event);
|
||||
|
||||
// Note that the |aTarget| the APZCTM sent us may contradict the confirmed
|
||||
// target set on the block. In this case the confirmed target (which may be
|
||||
// null) should take priority. This is equivalent to just always using the
|
||||
// target (confirmed or not) from the block, which is what
|
||||
// MaybeHandleCurrentBlock() does.
|
||||
if (!MaybeHandleCurrentBlock(block, aEvent)) {
|
||||
block->AddEvent(aEvent.AsScrollWheelInput());
|
||||
if (!MaybeHandleCurrentBlock(block, event)) {
|
||||
block->AddEvent(event);
|
||||
}
|
||||
|
||||
return nsEventStatus_eConsumeDoDefault;
|
||||
|
||||
@@ -204,24 +204,73 @@ LayerManagerComposite::BeginTransactionWithDrawTarget(DrawTarget* aTarget, const
|
||||
mTargetBounds = aRect;
|
||||
}
|
||||
|
||||
template<typename RectType>
|
||||
Maybe<RectType>
|
||||
IntersectMaybeRects(const Maybe<RectType>& aRect1, const Maybe<RectType>& aRect2)
|
||||
{
|
||||
if (aRect1) {
|
||||
if (aRect2) {
|
||||
return Some(aRect1->Intersect(*aRect2));
|
||||
}
|
||||
return aRect1;
|
||||
}
|
||||
return aRect2;
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerComposite::PostProcessLayers(Layer* aLayer,
|
||||
nsIntRegion& aOpaqueRegion,
|
||||
LayerIntRegion& aVisibleRegion)
|
||||
LayerIntRegion& aVisibleRegion,
|
||||
const Maybe<ParentLayerIntRect>& aClipFromAncestors)
|
||||
{
|
||||
nsIntRegion localOpaque;
|
||||
Matrix4x4 transform = aLayer->GetLocalTransform();
|
||||
Matrix transform2d;
|
||||
Maybe<nsIntPoint> integerTranslation;
|
||||
// If aLayer has a simple transform (only an integer translation) then we
|
||||
// can easily convert aOpaqueRegion into pre-transform coordinates and include
|
||||
// that region.
|
||||
if (aLayer->GetLocalTransform().Is2D(&transform2d)) {
|
||||
if (transform.Is2D(&transform2d)) {
|
||||
if (transform2d.IsIntegerTranslation()) {
|
||||
integerTranslation = Some(TruncatedToInt(transform2d.GetTranslation()));
|
||||
localOpaque = aOpaqueRegion;
|
||||
localOpaque.MoveBy(-*integerTranslation);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute a clip that's the combination of our layer clip with the clip
|
||||
// from our ancestors.
|
||||
LayerComposite* composite = aLayer->AsLayerComposite();
|
||||
Maybe<ParentLayerIntRect> layerClip = composite->GetShadowClipRect();
|
||||
Maybe<ParentLayerIntRect> outsideClip =
|
||||
IntersectMaybeRects(layerClip, aClipFromAncestors);
|
||||
|
||||
// Convert the combined clip into our pre-transform coordinate space, so
|
||||
// that it can later be intersected with our visible region.
|
||||
// If our transform is a perspective, there's no meaningful insideClip rect
|
||||
// we can compute (it would need to be a cone).
|
||||
Maybe<LayerIntRect> insideClip;
|
||||
if (outsideClip && !transform.HasPerspectiveComponent()) {
|
||||
Matrix4x4 inverse = transform;
|
||||
if (inverse.Invert()) {
|
||||
Maybe<LayerRect> insideClipFloat =
|
||||
UntransformTo<LayerPixel>(inverse, ParentLayerRect(*outsideClip),
|
||||
LayerRect::MaxIntRect());
|
||||
if (insideClipFloat) {
|
||||
insideClipFloat->RoundOut();
|
||||
LayerIntRect insideClipInt;
|
||||
if (insideClipFloat->ToIntRect(&insideClipInt)) {
|
||||
insideClip = Some(insideClipInt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<ParentLayerIntRect> ancestorClipForChildren;
|
||||
if (insideClip) {
|
||||
ancestorClipForChildren =
|
||||
Some(ViewAs<ParentLayerPixel>(*insideClip, PixelCastJustification::MovingDownToChildren));
|
||||
}
|
||||
|
||||
// Save the value of localOpaque, which currently stores the region obscured
|
||||
// by siblings (and uncles and such), before our descendants contribute to it.
|
||||
@@ -229,15 +278,14 @@ LayerManagerComposite::PostProcessLayers(Layer* aLayer,
|
||||
|
||||
// Recurse on our descendants, in front-to-back order. In this process:
|
||||
// - Occlusions are computed for them, and they contribute to localOpaque.
|
||||
// - They recalculate their visible regions, and accumulate them into
|
||||
// descendantsVisibleRegion.
|
||||
// - They recalculate their visible regions, taking ancestorClipForChildren
|
||||
// into account, and accumulate them into descendantsVisibleRegion.
|
||||
LayerIntRegion descendantsVisibleRegion;
|
||||
for (Layer* child = aLayer->GetLastChild(); child; child = child->GetPrevSibling()) {
|
||||
PostProcessLayers(child, localOpaque, descendantsVisibleRegion);
|
||||
PostProcessLayers(child, localOpaque, descendantsVisibleRegion, ancestorClipForChildren);
|
||||
}
|
||||
|
||||
// Recalculate our visible region.
|
||||
LayerComposite* composite = aLayer->AsLayerComposite();
|
||||
LayerIntRegion visible = composite->GetShadowVisibleRegion();
|
||||
|
||||
// If we have descendants, throw away the visible region stored on this
|
||||
@@ -251,13 +299,17 @@ LayerManagerComposite::PostProcessLayers(Layer* aLayer,
|
||||
visible.SubOut(LayerIntRegion::FromUnknownRegion(obscured));
|
||||
}
|
||||
|
||||
// Clip the visible region using the combined clip.
|
||||
if (insideClip) {
|
||||
visible.AndWith(*insideClip);
|
||||
}
|
||||
composite->SetShadowVisibleRegion(visible);
|
||||
|
||||
// Transform the newly calculated visible region into our parent's space,
|
||||
// apply our clip to it (if any), and accumulate it into |aVisibleRegion|
|
||||
// for the caller to use.
|
||||
ParentLayerIntRegion visibleParentSpace = TransformTo<ParentLayerPixel>(
|
||||
aLayer->GetLocalTransform(), visible);
|
||||
ParentLayerIntRegion visibleParentSpace =
|
||||
TransformTo<ParentLayerPixel>(transform, visible);
|
||||
if (const Maybe<ParentLayerIntRect>& clipRect = composite->GetShadowClipRect()) {
|
||||
visibleParentSpace.AndWith(*clipRect);
|
||||
}
|
||||
@@ -273,9 +325,8 @@ LayerManagerComposite::PostProcessLayers(Layer* aLayer,
|
||||
localOpaque.OrWith(composite->GetFullyRenderedRegion());
|
||||
}
|
||||
localOpaque.MoveBy(*integerTranslation);
|
||||
const Maybe<ParentLayerIntRect>& clip = aLayer->GetEffectiveClipRect();
|
||||
if (clip) {
|
||||
localOpaque.AndWith(clip->ToUnknownRect());
|
||||
if (layerClip) {
|
||||
localOpaque.AndWith(layerClip->ToUnknownRect());
|
||||
}
|
||||
aOpaqueRegion.OrWith(localOpaque);
|
||||
}
|
||||
@@ -390,7 +441,7 @@ LayerManagerComposite::UpdateAndRender()
|
||||
|
||||
nsIntRegion opaque;
|
||||
LayerIntRegion visible;
|
||||
PostProcessLayers(mRoot, opaque, visible);
|
||||
PostProcessLayers(mRoot, opaque, visible, Nothing());
|
||||
|
||||
Render(invalid);
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
|
||||
@@ -1047,7 +1098,7 @@ LayerManagerComposite::RenderToPresentationSurface()
|
||||
mRoot->ComputeEffectiveTransforms(matrix);
|
||||
nsIntRegion opaque;
|
||||
LayerIntRegion visible;
|
||||
PostProcessLayers(mRoot, opaque, visible);
|
||||
PostProcessLayers(mRoot, opaque, visible, Nothing());
|
||||
|
||||
nsIntRegion invalid;
|
||||
Rect bounds(0.0f, 0.0f, scale * pageWidth, (float)actualHeight);
|
||||
|
||||
@@ -182,7 +182,8 @@ public:
|
||||
*/
|
||||
void PostProcessLayers(Layer* aLayer,
|
||||
nsIntRegion& aOpaqueRegion,
|
||||
LayerIntRegion& aVisibleRegion);
|
||||
LayerIntRegion& aVisibleRegion,
|
||||
const Maybe<ParentLayerIntRect>& aClipFromAncestors);
|
||||
|
||||
/**
|
||||
* RAII helper class to add a mask effect with the compositable from aMaskLayer
|
||||
|
||||
@@ -387,6 +387,10 @@ private:
|
||||
// This and code dependent on it should be removed once containerless scrolling looks stable.
|
||||
DECL_GFX_PREF(Once, "layout.scroll.root-frame-containers", LayoutUseContainersForRootFrames, bool, true);
|
||||
|
||||
// These affect how line scrolls from wheel events will be accelerated.
|
||||
DECL_GFX_PREF(Live, "mousewheel.acceleration.factor", MouseWheelAccelerationFactor, int32_t, -1);
|
||||
DECL_GFX_PREF(Live, "mousewheel.acceleration.start", MouseWheelAccelerationStart, int32_t, -1);
|
||||
|
||||
// This affects whether events will be routed through APZ or not.
|
||||
DECL_GFX_PREF(Live, "mousewheel.system_scroll_override_on_root_content.enabled",
|
||||
MouseWheelHasRootScrollDeltaOverride, bool, false);
|
||||
|
||||
@@ -256,6 +256,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
|
||||
CFLAGS += CONFIG['MOZ_ICU_CFLAGS']
|
||||
LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
|
||||
USE_LIBS += [
|
||||
'icu',
|
||||
]
|
||||
|
||||
@@ -10,6 +10,7 @@ SOURCES += [
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
|
||||
LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
|
||||
LOCAL_INCLUDES += [
|
||||
'../locale',
|
||||
'../lwbrk',
|
||||
|
||||
@@ -12,6 +12,7 @@ UNIFIED_SOURCES += [
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
|
||||
LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
|
||||
LOCAL_INCLUDES += [
|
||||
'..',
|
||||
]
|
||||
|
||||
@@ -20,5 +20,6 @@ LOCAL_INCLUDES += [
|
||||
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
|
||||
LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
|
||||
|
||||
DIST_INSTALL = True
|
||||
|
||||
@@ -41,6 +41,7 @@ if CONFIG['_MSC_VER']:
|
||||
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
|
||||
LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
|
||||
USE_LIBS += ['icu']
|
||||
|
||||
DIST_INSTALL = True
|
||||
|
||||
@@ -13,6 +13,7 @@ UNIFIED_SOURCES += [
|
||||
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
|
||||
LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
|
||||
USE_LIBS += ['icu']
|
||||
|
||||
for var in ('MOZILLA_INTERNAL_API', 'MOZILLA_XPCOMRT_API', 'MOZILLA_EXTERNAL_LINKAGE',
|
||||
|
||||
@@ -242,6 +242,7 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
|
||||
triggeringPrincipalInfo,
|
||||
aLoadInfo->GetSecurityFlags(),
|
||||
aLoadInfo->InternalContentPolicyType(),
|
||||
static_cast<uint32_t>(aLoadInfo->GetTainting()),
|
||||
aLoadInfo->GetUpgradeInsecureRequests(),
|
||||
aLoadInfo->GetUpgradeInsecurePreloads(),
|
||||
aLoadInfo->GetInnerWindowID(),
|
||||
@@ -252,7 +253,10 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
|
||||
aLoadInfo->GetIsInThirdPartyContext(),
|
||||
aLoadInfo->GetOriginAttributes(),
|
||||
redirectChainIncludingInternalRedirects,
|
||||
redirectChain);
|
||||
redirectChain,
|
||||
aLoadInfo->CorsUnsafeHeaders(),
|
||||
aLoadInfo->GetForcePreflight(),
|
||||
aLoadInfo->GetIsPreflight());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -298,6 +302,7 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs,
|
||||
triggeringPrincipal,
|
||||
loadInfoArgs.securityFlags(),
|
||||
loadInfoArgs.contentPolicyType(),
|
||||
static_cast<LoadTainting>(loadInfoArgs.tainting()),
|
||||
loadInfoArgs.upgradeInsecureRequests(),
|
||||
loadInfoArgs.upgradeInsecurePreloads(),
|
||||
loadInfoArgs.innerWindowID(),
|
||||
@@ -308,7 +313,10 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs,
|
||||
loadInfoArgs.isInThirdPartyContext(),
|
||||
loadInfoArgs.originAttributes(),
|
||||
redirectChainIncludingInternalRedirects,
|
||||
redirectChain);
|
||||
redirectChain,
|
||||
loadInfoArgs.corsUnsafeHeaders(),
|
||||
loadInfoArgs.forcePreflight(),
|
||||
loadInfoArgs.isPreflight());
|
||||
|
||||
loadInfo.forget(outLoadInfo);
|
||||
return NS_OK;
|
||||
|
||||
@@ -675,6 +675,7 @@ if CONFIG['OS_ARCH'] == 'SunOS':
|
||||
|
||||
CFLAGS += CONFIG['MOZ_ICU_CFLAGS']
|
||||
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
|
||||
LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
|
||||
|
||||
if not CONFIG['GNU_CXX']:
|
||||
ALLOW_COMPILER_WARNINGS = True
|
||||
|
||||
@@ -1986,8 +1986,8 @@ VerifySameTree(nsStyleContext* aContext1, nsStyleContext* aContext2)
|
||||
}
|
||||
|
||||
static void
|
||||
VerifyContextParent(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
nsStyleContext* aContext, nsStyleContext* aParentContext)
|
||||
VerifyContextParent(nsIFrame* aFrame, nsStyleContext* aContext,
|
||||
nsStyleContext* aParentContext)
|
||||
{
|
||||
// get the contexts not provided
|
||||
if (!aContext) {
|
||||
@@ -2047,11 +2047,10 @@ VerifyContextParent(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
}
|
||||
|
||||
static void
|
||||
VerifyStyleTree(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
nsStyleContext* aParentContext)
|
||||
VerifyStyleTree(nsIFrame* aFrame, nsStyleContext* aParentContext)
|
||||
{
|
||||
nsStyleContext* context = aFrame->StyleContext();
|
||||
VerifyContextParent(aPresContext, aFrame, context, nullptr);
|
||||
VerifyContextParent(aFrame, context, nullptr);
|
||||
|
||||
nsIFrame::ChildListIterator lists(aFrame);
|
||||
for (; !lists.IsDone(); lists.Next()) {
|
||||
@@ -2066,15 +2065,15 @@ VerifyStyleTree(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
|
||||
// recurse to out of flow frame, letting the parent context get resolved
|
||||
do {
|
||||
VerifyStyleTree(aPresContext, outOfFlowFrame, nullptr);
|
||||
VerifyStyleTree(outOfFlowFrame, nullptr);
|
||||
} while ((outOfFlowFrame = outOfFlowFrame->GetNextContinuation()));
|
||||
|
||||
// verify placeholder using the parent frame's context as
|
||||
// parent context
|
||||
VerifyContextParent(aPresContext, child, nullptr, nullptr);
|
||||
VerifyContextParent(child, nullptr, nullptr);
|
||||
}
|
||||
else { // regular frame
|
||||
VerifyStyleTree(aPresContext, child, nullptr);
|
||||
VerifyStyleTree(child, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2085,7 +2084,7 @@ VerifyStyleTree(nsPresContext* aPresContext, nsIFrame* aFrame,
|
||||
for (nsStyleContext* extraContext;
|
||||
(extraContext = aFrame->GetAdditionalStyleContext(contextIndex));
|
||||
++contextIndex) {
|
||||
VerifyContextParent(aPresContext, aFrame, extraContext, context);
|
||||
VerifyContextParent(aFrame, extraContext, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2095,7 +2094,7 @@ RestyleManager::DebugVerifyStyleTree(nsIFrame* aFrame)
|
||||
if (aFrame) {
|
||||
nsStyleContext* context = aFrame->StyleContext();
|
||||
nsStyleContext* parentContext = context->GetParent();
|
||||
VerifyStyleTree(mPresContext, aFrame, parentContext);
|
||||
VerifyStyleTree(aFrame, parentContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2513,7 +2512,7 @@ RestyleManager::ReparentStyleContext(nsIFrame* aFrame)
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
VerifyStyleTree(mPresContext, aFrame, newParentContext);
|
||||
VerifyStyleTree(aFrame, newParentContext);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1431,8 +1431,7 @@ nsFrameConstructorSaveState::~nsFrameConstructorSaveState()
|
||||
// relevant part of ReparentFrameViewList, I suppose... Or just get rid of
|
||||
// views, which would make most of this function go away.
|
||||
static void
|
||||
MoveChildrenTo(nsPresContext* aPresContext,
|
||||
nsIFrame* aOldParent,
|
||||
MoveChildrenTo(nsIFrame* aOldParent,
|
||||
nsContainerFrame* aNewParent,
|
||||
nsFrameList& aFrameList)
|
||||
{
|
||||
@@ -2819,8 +2818,7 @@ nsCSSFrameConstructor::SetUpDocElementContainingBlock(nsIContent* aDocElement)
|
||||
// Set the initial child lists
|
||||
nsContainerFrame* canvasFrame;
|
||||
nsContainerFrame* pageFrame =
|
||||
ConstructPageFrame(mPresShell, presContext, rootFrame, nullptr,
|
||||
canvasFrame);
|
||||
ConstructPageFrame(mPresShell, rootFrame, nullptr, canvasFrame);
|
||||
SetInitialSingleChild(rootFrame, pageFrame);
|
||||
|
||||
// The eventual parent of the document element frame.
|
||||
@@ -2861,7 +2859,6 @@ nsCSSFrameConstructor::ConstructAnonymousContentForCanvas(nsFrameConstructorStat
|
||||
|
||||
nsContainerFrame*
|
||||
nsCSSFrameConstructor::ConstructPageFrame(nsIPresShell* aPresShell,
|
||||
nsPresContext* aPresContext,
|
||||
nsContainerFrame* aParentFrame,
|
||||
nsIFrame* aPrevPageFrame,
|
||||
nsContainerFrame*& aCanvasFrame)
|
||||
@@ -6317,7 +6314,7 @@ nsCSSFrameConstructor::AppendFramesToParent(nsFrameConstructorState& aStat
|
||||
prevBlock = static_cast<nsContainerFrame*>(prevBlock->LastContinuation());
|
||||
NS_ASSERTION(prevBlock, "Should have previous block here");
|
||||
|
||||
MoveChildrenTo(aState.mPresContext, aParentFrame, prevBlock, blockKids);
|
||||
MoveChildrenTo(aParentFrame, prevBlock, blockKids);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7261,8 +7258,7 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
|
||||
|
||||
if (haveFirstLetterStyle) {
|
||||
// Before we get going, remove the current letter frames
|
||||
RemoveLetterFrames(state.mPresContext, state.mPresShell,
|
||||
containingBlock);
|
||||
RemoveLetterFrames(state.mPresShell, containingBlock);
|
||||
}
|
||||
|
||||
nsIAtom* frameType = parentFrame->GetType();
|
||||
@@ -7425,7 +7421,7 @@ bool NotifyListBoxBody(nsPresContext* aPresContext,
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
listBoxBodyFrame->OnContentInserted(aPresContext, aChild);
|
||||
listBoxBodyFrame->OnContentInserted(aChild);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -7773,8 +7769,7 @@ nsCSSFrameConstructor::ContentRangeInserted(nsIContent* aContainer,
|
||||
}
|
||||
|
||||
// Remove the old letter frames before doing the insertion
|
||||
RemoveLetterFrames(state.mPresContext, mPresShell,
|
||||
state.mFloatedItems.containingBlock);
|
||||
RemoveLetterFrames(mPresShell, state.mFloatedItems.containingBlock);
|
||||
|
||||
// Removing the letterframes messes around with the frame tree, removing
|
||||
// and creating frames. We need to reget our prevsibling, parent frame,
|
||||
@@ -8273,7 +8268,7 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer,
|
||||
// First update the containing blocks structure by removing the
|
||||
// existing letter frames. This makes the subsequent logic
|
||||
// simpler.
|
||||
RemoveLetterFrames(presContext, mPresShell, containingBlock);
|
||||
RemoveLetterFrames(mPresShell, containingBlock);
|
||||
|
||||
// Recover childFrame and parentFrame
|
||||
childFrame = aChild->GetPrimaryFrame();
|
||||
@@ -8487,8 +8482,7 @@ nsCSSFrameConstructor::CharacterDataChanged(nsIContent* aContent,
|
||||
// See if the block has first-letter style applied to it.
|
||||
haveFirstLetterStyle = HasFirstLetterStyle(block);
|
||||
if (haveFirstLetterStyle) {
|
||||
RemoveLetterFrames(mPresShell->GetPresContext(), mPresShell,
|
||||
block);
|
||||
RemoveLetterFrames(mPresShell, block);
|
||||
// Reget |frame|, since we might have killed it.
|
||||
// Do we really need to call CharacterDataChanged in this case, though?
|
||||
frame = aContent->GetPrimaryFrame();
|
||||
@@ -8642,7 +8636,6 @@ nsCSSFrameConstructor::CreateContinuingOuterTableFrame(nsIPresShell* aPresSh
|
||||
|
||||
nsIFrame*
|
||||
nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
|
||||
nsPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsContainerFrame* aParentFrame,
|
||||
nsIContent* aContent,
|
||||
@@ -8695,7 +8688,7 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
|
||||
headerFooterFrame->SetRepeatable(true);
|
||||
|
||||
// Table specific initialization
|
||||
headerFooterFrame->InitRepeatedFrame(aPresContext, rowGroupFrame);
|
||||
headerFooterFrame->InitRepeatedFrame(rowGroupFrame);
|
||||
|
||||
// XXX Deal with absolute and fixed frames...
|
||||
childFrames.AddChild(headerFooterFrame);
|
||||
@@ -8750,8 +8743,7 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
|
||||
newFrame->Init(content, aParentFrame, aFrame);
|
||||
} else if (nsGkAtoms::pageFrame == frameType) {
|
||||
nsContainerFrame* canvasFrame;
|
||||
newFrame = ConstructPageFrame(shell, aPresContext, aParentFrame, aFrame,
|
||||
canvasFrame);
|
||||
newFrame = ConstructPageFrame(shell, aParentFrame, aFrame, canvasFrame);
|
||||
} else if (nsGkAtoms::tableOuterFrame == frameType) {
|
||||
newFrame =
|
||||
CreateContinuingOuterTableFrame(shell, aPresContext, aFrame, aParentFrame,
|
||||
@@ -8759,7 +8751,7 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
|
||||
|
||||
} else if (nsGkAtoms::tableFrame == frameType) {
|
||||
newFrame =
|
||||
CreateContinuingTableFrame(shell, aPresContext, aFrame, aParentFrame,
|
||||
CreateContinuingTableFrame(shell, aFrame, aParentFrame,
|
||||
content, styleContext);
|
||||
|
||||
} else if (nsGkAtoms::tableRowGroupFrame == frameType) {
|
||||
@@ -11210,7 +11202,6 @@ FindFirstLetterFrame(nsIFrame* aFrame, nsIFrame::ChildListID aListID)
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames(
|
||||
nsPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIFrame* aBlockFrame,
|
||||
bool* aStopLooking)
|
||||
@@ -11301,8 +11292,7 @@ nsCSSFrameConstructor::RemoveFloatingFirstLetterFrames(
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::RemoveFirstLetterFrames(nsPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsCSSFrameConstructor::RemoveFirstLetterFrames(nsIPresShell* aPresShell,
|
||||
nsContainerFrame* aFrame,
|
||||
nsContainerFrame* aBlockFrame,
|
||||
bool* aStopLooking)
|
||||
@@ -11364,8 +11354,7 @@ nsCSSFrameConstructor::RemoveFirstLetterFrames(nsPresContext* aPresContext,
|
||||
nsContainerFrame* kidAsContainerFrame = do_QueryFrame(kid);
|
||||
if (kidAsContainerFrame) {
|
||||
// Look inside child inline frame for the letter frame.
|
||||
RemoveFirstLetterFrames(aPresContext, aPresShell,
|
||||
kidAsContainerFrame,
|
||||
RemoveFirstLetterFrames(aPresShell, kidAsContainerFrame,
|
||||
aBlockFrame, aStopLooking);
|
||||
if (*aStopLooking) {
|
||||
break;
|
||||
@@ -11380,8 +11369,7 @@ nsCSSFrameConstructor::RemoveFirstLetterFrames(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::RemoveLetterFrames(nsPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsCSSFrameConstructor::RemoveLetterFrames(nsIPresShell* aPresShell,
|
||||
nsContainerFrame* aBlockFrame)
|
||||
{
|
||||
aBlockFrame =
|
||||
@@ -11391,10 +11379,10 @@ nsCSSFrameConstructor::RemoveLetterFrames(nsPresContext* aPresContext,
|
||||
bool stopLooking = false;
|
||||
nsresult rv;
|
||||
do {
|
||||
rv = RemoveFloatingFirstLetterFrames(aPresContext, aPresShell,
|
||||
rv = RemoveFloatingFirstLetterFrames(aPresShell,
|
||||
continuation, &stopLooking);
|
||||
if (NS_SUCCEEDED(rv) && !stopLooking) {
|
||||
rv = RemoveFirstLetterFrames(aPresContext, aPresShell,
|
||||
rv = RemoveFirstLetterFrames(aPresShell,
|
||||
continuation, aBlockFrame, &stopLooking);
|
||||
}
|
||||
if (stopLooking) {
|
||||
@@ -11447,8 +11435,7 @@ nsCSSFrameConstructor::RecoverLetterFrames(nsContainerFrame* aBlockFrame)
|
||||
// listbox Widget Routines
|
||||
|
||||
nsresult
|
||||
nsCSSFrameConstructor::CreateListBoxContent(nsPresContext* aPresContext,
|
||||
nsContainerFrame* aParentFrame,
|
||||
nsCSSFrameConstructor::CreateListBoxContent(nsContainerFrame* aParentFrame,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIContent* aChild,
|
||||
nsIFrame** aNewFrame,
|
||||
@@ -11768,7 +11755,7 @@ nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState& aState,
|
||||
FindFirstNonBlock(aChildItems);
|
||||
nsFrameList blockKids = aChildItems.ExtractHead(firstNonBlock);
|
||||
|
||||
MoveChildrenTo(aState.mPresContext, aInitialInline, blockFrame, blockKids);
|
||||
MoveChildrenTo(aInitialInline, blockFrame, blockKids);
|
||||
|
||||
SetFrameIsIBSplit(lastNewInline, blockFrame);
|
||||
aSiblings.AddChild(blockFrame);
|
||||
@@ -11788,8 +11775,7 @@ nsCSSFrameConstructor::CreateIBSiblings(nsFrameConstructorState& aState,
|
||||
FindFirstBlock(firstBlock);
|
||||
nsFrameList inlineKids = aChildItems.ExtractHead(firstBlock);
|
||||
|
||||
MoveChildrenTo(aState.mPresContext, aInitialInline, inlineFrame,
|
||||
inlineKids);
|
||||
MoveChildrenTo(aInitialInline, inlineFrame, inlineKids);
|
||||
}
|
||||
|
||||
SetFrameIsIBSplit(blockFrame, inlineFrame);
|
||||
|
||||
@@ -300,8 +300,7 @@ public:
|
||||
*/
|
||||
InsertionPoint GetInsertionPoint(nsIContent* aContainer, nsIContent* aChild);
|
||||
|
||||
nsresult CreateListBoxContent(nsPresContext* aPresContext,
|
||||
nsContainerFrame* aParentFrame,
|
||||
nsresult CreateListBoxContent(nsContainerFrame* aParentFrame,
|
||||
nsIFrame* aPrevFrame,
|
||||
nsIContent* aChild,
|
||||
nsIFrame** aResult,
|
||||
@@ -336,7 +335,6 @@ private:
|
||||
class FrameConstructionItemList;
|
||||
|
||||
nsContainerFrame* ConstructPageFrame(nsIPresShell* aPresShell,
|
||||
nsPresContext* aPresContext,
|
||||
nsContainerFrame* aParentFrame,
|
||||
nsIFrame* aPrevPageFrame,
|
||||
nsContainerFrame*& aCanvasFrame);
|
||||
@@ -1755,7 +1753,6 @@ private:
|
||||
nsStyleContext* aStyleContext);
|
||||
|
||||
nsIFrame* CreateContinuingTableFrame(nsIPresShell* aPresShell,
|
||||
nsPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsContainerFrame* aParentFrame,
|
||||
nsIContent* aContent,
|
||||
@@ -1932,20 +1929,17 @@ private:
|
||||
void RecoverLetterFrames(nsContainerFrame* aBlockFrame);
|
||||
|
||||
//
|
||||
nsresult RemoveLetterFrames(nsPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsresult RemoveLetterFrames(nsIPresShell* aPresShell,
|
||||
nsContainerFrame* aBlockFrame);
|
||||
|
||||
// Recursive helper for RemoveLetterFrames
|
||||
nsresult RemoveFirstLetterFrames(nsPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsresult RemoveFirstLetterFrames(nsIPresShell* aPresShell,
|
||||
nsContainerFrame* aFrame,
|
||||
nsContainerFrame* aBlockFrame,
|
||||
bool* aStopLooking);
|
||||
|
||||
// Special remove method for those pesky floating first-letter frames
|
||||
nsresult RemoveFloatingFirstLetterFrames(nsPresContext* aPresContext,
|
||||
nsIPresShell* aPresShell,
|
||||
nsresult RemoveFloatingFirstLetterFrames(nsIPresShell* aPresShell,
|
||||
nsIFrame* aBlockFrame,
|
||||
bool* aStopLooking);
|
||||
|
||||
|
||||
@@ -2721,7 +2721,6 @@ nsDisplayBackgroundImage::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
/* static */ nsRegion
|
||||
nsDisplayBackgroundImage::GetInsideClipRegion(nsDisplayItem* aItem,
|
||||
nsPresContext* aPresContext,
|
||||
uint8_t aClip, const nsRect& aRect,
|
||||
bool* aSnap)
|
||||
{
|
||||
@@ -2779,8 +2778,7 @@ nsDisplayBackgroundImage::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||
if (layer.mImage.IsOpaque() && layer.mBlendMode == NS_STYLE_BLEND_NORMAL &&
|
||||
layer.mRepeat.mXRepeat != NS_STYLE_BG_REPEAT_SPACE &&
|
||||
layer.mRepeat.mYRepeat != NS_STYLE_BG_REPEAT_SPACE) {
|
||||
nsPresContext* presContext = mFrame->PresContext();
|
||||
result = GetInsideClipRegion(this, presContext, layer.mClip, mBounds, aSnap);
|
||||
result = GetInsideClipRegion(this, layer.mClip, mBounds, aSnap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3187,8 +3185,8 @@ nsDisplayBackgroundColor::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
const nsStyleBackground::Layer& bottomLayer = mBackgroundStyle->BottomLayer();
|
||||
nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
||||
nsPresContext* presContext = mFrame->PresContext();
|
||||
return nsDisplayBackgroundImage::GetInsideClipRegion(this, presContext, bottomLayer.mClip, borderBox, aSnap);
|
||||
return nsDisplayBackgroundImage::GetInsideClipRegion(this, bottomLayer.mClip,
|
||||
borderBox, aSnap);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -2682,7 +2682,7 @@ public:
|
||||
virtual void ConfigureLayer(ImageLayer* aLayer,
|
||||
const ContainerLayerParameters& aParameters) override;
|
||||
|
||||
static nsRegion GetInsideClipRegion(nsDisplayItem* aItem, nsPresContext* aPresContext, uint8_t aClip,
|
||||
static nsRegion GetInsideClipRegion(nsDisplayItem* aItem, uint8_t aClip,
|
||||
const nsRect& aRect, bool* aSnap);
|
||||
|
||||
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) override;
|
||||
|
||||
@@ -1278,7 +1278,6 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
|
||||
{ NS_PARENTPROCESSMESSAGEMANAGER_CONTRACTID, &kNS_PARENTPROCESSMESSAGEMANAGER_CID },
|
||||
{ NS_CHILDPROCESSMESSAGEMANAGER_CONTRACTID, &kNS_CHILDPROCESSMESSAGEMANAGER_CID },
|
||||
{ NS_SCRIPTSECURITYMANAGER_CONTRACTID, &kNS_SCRIPTSECURITYMANAGER_CID },
|
||||
{ NS_GLOBAL_CHANNELEVENTSINK_CONTRACTID, &kNS_SCRIPTSECURITYMANAGER_CID },
|
||||
{ NS_PRINCIPAL_CONTRACTID, &kNS_PRINCIPAL_CID },
|
||||
{ NS_SYSTEMPRINCIPAL_CONTRACTID, &kNS_SYSTEMPRINCIPAL_CID },
|
||||
{ NS_NULLPRINCIPAL_CONTRACTID, &kNS_NULLPRINCIPAL_CID },
|
||||
|
||||
@@ -57,3 +57,4 @@ if CONFIG['ENABLE_INTL_API']:
|
||||
# nsNumberControlFrame.cpp requires ICUUtils.h which in turn requires
|
||||
# i18n/unum.h
|
||||
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
|
||||
LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
|
||||
|
||||
@@ -87,6 +87,19 @@ protected:
|
||||
nsSMILKeySpline mTimingFunctionY;
|
||||
};
|
||||
|
||||
// Helper for accelerated wheel deltas. This can be called from the main thread
|
||||
// or the APZ Controller thread.
|
||||
static inline double
|
||||
ComputeAcceleratedWheelDelta(double aDelta, int32_t aCounter, int32_t aFactor)
|
||||
{
|
||||
if (!aDelta) {
|
||||
return aDelta;
|
||||
}
|
||||
return (aDelta * aCounter * double(aFactor) / 10);
|
||||
}
|
||||
|
||||
static const uint32_t kScrollSeriesTimeoutMs = 80; // in milliseconds
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layout_AsyncScrollBase_h_
|
||||
|
||||
@@ -3164,8 +3164,7 @@ nsFrame::SelectByTypeAtPoint(nsPresContext* aPresContext,
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsFrame* frame = static_cast<nsFrame*>(theFrame);
|
||||
return frame->PeekBackwardAndForward(aBeginAmountType, aEndAmountType,
|
||||
offset, aPresContext,
|
||||
return frame->PeekBackwardAndForward(aBeginAmountType, aEndAmountType, offset,
|
||||
aBeginAmountType != eSelectWord,
|
||||
aSelectFlags);
|
||||
}
|
||||
@@ -3224,7 +3223,6 @@ nsresult
|
||||
nsFrame::PeekBackwardAndForward(nsSelectionAmount aAmountBack,
|
||||
nsSelectionAmount aAmountForward,
|
||||
int32_t aStartPos,
|
||||
nsPresContext* aPresContext,
|
||||
bool aJumpLines,
|
||||
uint32_t aSelectFlags)
|
||||
{
|
||||
|
||||
@@ -394,7 +394,6 @@ public:
|
||||
nsresult PeekBackwardAndForward(nsSelectionAmount aAmountBack,
|
||||
nsSelectionAmount aAmountForward,
|
||||
int32_t aStartPos,
|
||||
nsPresContext* aPresContext,
|
||||
bool aJumpLines,
|
||||
uint32_t aSelectFlags);
|
||||
|
||||
|
||||
@@ -715,7 +715,7 @@ nsGlyphTableList::GetGlyphTableFor(const nsAString& aFamily)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static nsresult
|
||||
InitGlobals(nsPresContext* aPresContext)
|
||||
InitCharGlobals()
|
||||
{
|
||||
NS_ASSERTION(!gGlyphTableInitialized, "Error -- already initialized");
|
||||
gGlyphTableInitialized = true;
|
||||
@@ -776,11 +776,10 @@ nsMathMLChar::SetStyleContext(nsStyleContext* aStyleContext)
|
||||
}
|
||||
|
||||
void
|
||||
nsMathMLChar::SetData(nsPresContext* aPresContext,
|
||||
nsString& aData)
|
||||
nsMathMLChar::SetData(nsString& aData)
|
||||
{
|
||||
if (!gGlyphTableInitialized) {
|
||||
InitGlobals(aPresContext);
|
||||
InitCharGlobals();
|
||||
}
|
||||
mData = aData;
|
||||
// some assumptions until proven otherwise
|
||||
@@ -878,7 +877,7 @@ nsMathMLChar::SetData(nsPresContext* aPresContext,
|
||||
#define NS_MATHML_DELIMITER_SHORTFALL_POINTS 5.0f
|
||||
|
||||
static bool
|
||||
IsSizeOK(nsPresContext* aPresContext, nscoord a, nscoord b, uint32_t aHint)
|
||||
IsSizeOK(nscoord a, nscoord b, uint32_t aHint)
|
||||
{
|
||||
// Normal: True if 'a' is around +/-10% of the target 'b' (10% is
|
||||
// 1-DelimiterFactor). This often gives a chance to the base size to
|
||||
@@ -1243,8 +1242,7 @@ StretchEnumContext::TryVariants(nsGlyphTable* aGlyphTable,
|
||||
}
|
||||
|
||||
return haveBetter &&
|
||||
(largeopOnly ||
|
||||
IsSizeOK(mPresContext, bestSize, mTargetSize, mStretchHint));
|
||||
(largeopOnly || IsSizeOK(bestSize, mTargetSize, mStretchHint));
|
||||
}
|
||||
|
||||
// 3. Build by parts.
|
||||
@@ -1415,7 +1413,7 @@ nsMathMLChar::StretchEnumContext::TryParts(nsGlyphTable* aGlyphTable,
|
||||
mChar->mBmData[i] = bmdata[i];
|
||||
}
|
||||
|
||||
return IsSizeOK(mPresContext, computedSize, mTargetSize, mStretchHint);
|
||||
return IsSizeOK(computedSize, mTargetSize, mStretchHint);
|
||||
}
|
||||
|
||||
// This is called for each family, whether it exists or not
|
||||
@@ -1640,7 +1638,7 @@ nsMathMLChar::StretchInternal(nsPresContext* aPresContext,
|
||||
// and not a largeop in display mode; we're done if size fits
|
||||
if ((targetSize <= 0) ||
|
||||
((isVertical && charSize >= targetSize) ||
|
||||
IsSizeOK(aPresContext, charSize, targetSize, aStretchHint)))
|
||||
IsSizeOK(charSize, targetSize, aStretchHint)))
|
||||
done = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,8 +123,7 @@ public:
|
||||
bool aRTL);
|
||||
|
||||
void
|
||||
SetData(nsPresContext* aPresContext,
|
||||
nsString& aData);
|
||||
SetData(nsString& aData);
|
||||
|
||||
void
|
||||
GetData(nsString& aData) {
|
||||
|
||||
@@ -292,7 +292,7 @@ InitOperators(void)
|
||||
}
|
||||
|
||||
static nsresult
|
||||
InitGlobals()
|
||||
InitOperatorGlobals()
|
||||
{
|
||||
gGlobalsInitialized = true;
|
||||
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
@@ -348,7 +348,7 @@ nsMathMLOperators::LookupOperator(const nsString& aOperator,
|
||||
float* aTrailingSpace)
|
||||
{
|
||||
if (!gGlobalsInitialized) {
|
||||
InitGlobals();
|
||||
InitOperatorGlobals();
|
||||
}
|
||||
if (gOperatorTable) {
|
||||
NS_ASSERTION(aFlags && aLeadingSpace && aTrailingSpace, "bad usage");
|
||||
@@ -393,7 +393,7 @@ nsMathMLOperators::LookupOperators(const nsString& aOperator,
|
||||
float* aTrailingSpace)
|
||||
{
|
||||
if (!gGlobalsInitialized) {
|
||||
InitGlobals();
|
||||
InitOperatorGlobals();
|
||||
}
|
||||
|
||||
aFlags[NS_MATHML_OPERATOR_FORM_INFIX] = 0;
|
||||
|
||||
@@ -82,7 +82,7 @@ nsresult nsMathMLmencloseFrame::AllocateMathMLChar(nsMencloseNotation mask)
|
||||
}
|
||||
|
||||
nsPresContext *presContext = PresContext();
|
||||
mMathMLChar[i].SetData(presContext, Char);
|
||||
mMathMLChar[i].SetData(Char);
|
||||
ResolveMathMLCharStyle(presContext, mContent, mStyleContext, &mMathMLChar[i]);
|
||||
|
||||
return NS_OK;
|
||||
|
||||
@@ -108,7 +108,7 @@ nsMathMLmfencedFrame::CreateFencesAndSeparators(nsPresContext* aPresContext)
|
||||
|
||||
if (!value.IsEmpty()) {
|
||||
mOpenChar = new nsMathMLChar;
|
||||
mOpenChar->SetData(aPresContext, value);
|
||||
mOpenChar->SetData(value);
|
||||
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mOpenChar);
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ nsMathMLmfencedFrame::CreateFencesAndSeparators(nsPresContext* aPresContext)
|
||||
|
||||
if (!value.IsEmpty()) {
|
||||
mCloseChar = new nsMathMLChar;
|
||||
mCloseChar->SetData(aPresContext, value);
|
||||
mCloseChar->SetData(value);
|
||||
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, mCloseChar);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ nsMathMLmfencedFrame::CreateFencesAndSeparators(nsPresContext* aPresContext)
|
||||
else {
|
||||
sepChar = value[mSeparatorsCount-1];
|
||||
}
|
||||
mSeparatorsChar[i].SetData(aPresContext, sepChar);
|
||||
mSeparatorsChar[i].SetData(sepChar);
|
||||
ResolveMathMLCharStyle(aPresContext, mContent, mStyleContext, &mSeparatorsChar[i]);
|
||||
}
|
||||
mSeparatorsCount = sepCount;
|
||||
|
||||
@@ -133,7 +133,7 @@ nsMathMLmoFrame::ProcessTextData()
|
||||
nsPresContext* presContext = PresContext();
|
||||
if (mFrames.GetLength() != 1) {
|
||||
data.Truncate(); // empty data to reset the char
|
||||
mMathMLChar.SetData(presContext, data);
|
||||
mMathMLChar.SetData(data);
|
||||
ResolveMathMLCharStyle(presContext, mContent, mStyleContext, &mMathMLChar);
|
||||
return;
|
||||
}
|
||||
@@ -177,7 +177,7 @@ nsMathMLmoFrame::ProcessTextData()
|
||||
}
|
||||
|
||||
// cache the operator
|
||||
mMathMLChar.SetData(presContext, data);
|
||||
mMathMLChar.SetData(data);
|
||||
|
||||
// cache the native direction -- beware of bug 133429...
|
||||
// mEmbellishData.direction must always retain our native direction, whereas
|
||||
|
||||
@@ -51,7 +51,7 @@ nsMathMLmrootFrame::Init(nsIContent* aContent,
|
||||
// The Style System will use Get/SetAdditionalStyleContext() to keep it
|
||||
// up-to-date if dynamic changes arise.
|
||||
nsAutoString sqrChar; sqrChar.Assign(kSqrChar);
|
||||
mSqrChar.SetData(presContext, sqrChar);
|
||||
mSqrChar.SetData(sqrChar);
|
||||
ResolveMathMLCharStyle(presContext, mContent, mStyleContext, &mSqrChar);
|
||||
}
|
||||
|
||||
|
||||
@@ -781,8 +781,7 @@ nsMathMLmtableOuterFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsMathMLmtableOuterFrame::GetRowFrameAt(nsPresContext* aPresContext,
|
||||
int32_t aRowIndex)
|
||||
nsMathMLmtableOuterFrame::GetRowFrameAt(int32_t aRowIndex)
|
||||
{
|
||||
int32_t rowCount = GetRowCount();
|
||||
|
||||
@@ -846,7 +845,7 @@ nsMathMLmtableOuterFrame::Reflow(nsPresContext* aPresContext,
|
||||
nscoord blockSize = aDesiredSize.BSize(wm);
|
||||
nsIFrame* rowFrame = nullptr;
|
||||
if (rowIndex) {
|
||||
rowFrame = GetRowFrameAt(aPresContext, rowIndex);
|
||||
rowFrame = GetRowFrameAt(rowIndex);
|
||||
if (rowFrame) {
|
||||
// translate the coordinates to be relative to us and in our writing mode
|
||||
nsIFrame* frame = rowFrame;
|
||||
|
||||
@@ -53,8 +53,7 @@ protected:
|
||||
// 1..n means the first row down to the last row, -1..-n means the last row
|
||||
// up to the first row. Used for alignments that are relative to a given row
|
||||
nsIFrame*
|
||||
GetRowFrameAt(nsPresContext* aPresContext,
|
||||
int32_t aRowIndex);
|
||||
GetRowFrameAt(int32_t aRowIndex);
|
||||
}; // class nsMathMLmtableOuterFrame
|
||||
|
||||
// --------------
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
== clipPath-html-04-extref.xhtml clipPath-html-04-ref.xhtml
|
||||
fuzzy-if(true,140,70) == clipPath-html-05.xhtml clipPath-html-05-ref.xhtml # Bug 776089
|
||||
fuzzy-if(true,140,70) == clipPath-html-05-extref.xhtml clipPath-html-05-ref.xhtml # Bug 776089
|
||||
== clipPath-html-06.xhtml clipPath-html-06-ref.xhtml
|
||||
== clipPath-html-06-extref.xhtml clipPath-html-06-ref.xhtml
|
||||
fuzzy-if(Android&&AndroidVersion==18,255,30) == clipPath-html-06.xhtml clipPath-html-06-ref.xhtml
|
||||
fuzzy-if(Android&&AndroidVersion==18,255,30) == clipPath-html-06-extref.xhtml clipPath-html-06-ref.xhtml
|
||||
== clipPath-html-07.xhtml clipPath-html-07-ref.svg
|
||||
== clipPath-html-08.xhtml clipPath-html-07-ref.svg # reuse 07-ref.svg
|
||||
== clipPath-html-zoomed-01.xhtml clipPath-html-01-ref.svg
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>#inner should not be clipped</title>
|
||||
|
||||
<style>
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: lime;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<title>#inner should not be clipped</title>
|
||||
|
||||
<style>
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: red;
|
||||
}
|
||||
|
||||
#perspective {
|
||||
perspective: 300px;
|
||||
perspective-origin: top left;
|
||||
}
|
||||
|
||||
#inner {
|
||||
height: 100vh;
|
||||
transform-origin: top left;
|
||||
transform: translateZ(-300px) scale(2);
|
||||
z-index: 2;
|
||||
background: lime;
|
||||
border: 1px solid lime;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div id="perspective">
|
||||
<div id="inner"></div>
|
||||
</div>
|
||||
@@ -37,6 +37,7 @@ fuzzy-if(winWidget,102,580) fuzzy-if(d2d,143,681) fuzzy-if(OSX>=1008,224,924) ==
|
||||
== backface-visibility-1c.html about:blank
|
||||
fuzzy-if(winWidget&&!layersGPUAccelerated,1,251) == backface-visibility-2.html backface-visibility-2-ref.html
|
||||
== backface-visibility-3.html backface-visibility-3-ref.html
|
||||
== perspective-clipping-1.html perspective-clipping-1-ref.html
|
||||
!= perspective-origin-1a.html rotatex-perspective-1a.html
|
||||
random-if(Android&&AndroidVersion==17) == perspective-origin-1b.html perspective-origin-1a.html
|
||||
fuzzy(3,99) random-if(Android&&!browserIsRemote) == perspective-origin-2a.html perspective-origin-2-ref.html # subpixel AA, bug 732568
|
||||
|
||||
@@ -586,8 +586,7 @@ void
|
||||
AnimationCollection::UpdateCheckGeneration(
|
||||
nsPresContext* aPresContext)
|
||||
{
|
||||
mCheckGeneration =
|
||||
aPresContext->RestyleManager()->GetAnimationGeneration();
|
||||
mCheckGeneration = aPresContext->RestyleManager()->GetAnimationGeneration();
|
||||
}
|
||||
|
||||
nsPresContext*
|
||||
|
||||
@@ -471,13 +471,16 @@ nsMediaQuery::AppendToString(nsAString& aString) const
|
||||
aString.Append('(');
|
||||
|
||||
const nsMediaExpression &expr = mExpressions[i];
|
||||
const nsMediaFeature *feature = expr.mFeature;
|
||||
if (feature->mReqFlags & nsMediaFeature::eHasWebkitPrefix) {
|
||||
aString.AppendLiteral("-webkit-");
|
||||
}
|
||||
if (expr.mRange == nsMediaExpression::eMin) {
|
||||
aString.AppendLiteral("min-");
|
||||
} else if (expr.mRange == nsMediaExpression::eMax) {
|
||||
aString.AppendLiteral("max-");
|
||||
}
|
||||
|
||||
const nsMediaFeature *feature = expr.mFeature;
|
||||
aString.Append(nsDependentAtomString(*feature->mName));
|
||||
|
||||
if (expr.mValue.GetUnit() != eCSSUnit_Null) {
|
||||
|
||||
@@ -3412,6 +3412,14 @@ CSSParserImpl::ParseMediaQueryExpression(nsMediaQuery* aQuery)
|
||||
// case insensitive from CSS - must be lower cased
|
||||
nsContentUtils::ASCIIToLower(mToken.mIdent);
|
||||
nsDependentString featureString(mToken.mIdent, 0);
|
||||
uint8_t satisfiedReqFlags = 0;
|
||||
|
||||
// Strip off "-webkit-" prefix from featureString:
|
||||
if (sWebkitPrefixedAliasesEnabled &&
|
||||
StringBeginsWith(featureString, NS_LITERAL_STRING("-webkit-"))) {
|
||||
satisfiedReqFlags |= nsMediaFeature::eHasWebkitPrefix;
|
||||
featureString.Rebind(featureString, 8);
|
||||
}
|
||||
|
||||
// Strip off "min-"/"max-" prefix from featureString:
|
||||
if (StringBeginsWith(featureString, NS_LITERAL_STRING("min-"))) {
|
||||
@@ -3427,7 +3435,11 @@ CSSParserImpl::ParseMediaQueryExpression(nsMediaQuery* aQuery)
|
||||
nsCOMPtr<nsIAtom> mediaFeatureAtom = do_GetAtom(featureString);
|
||||
const nsMediaFeature *feature = nsMediaFeatures::features;
|
||||
for (; feature->mName; ++feature) {
|
||||
if (*(feature->mName) == mediaFeatureAtom) {
|
||||
// See if name matches & all requirement flags are satisfied:
|
||||
// (We check requirements by turning off all of the flags that have been
|
||||
// satisfied, and then see if the result is 0.)
|
||||
if (*(feature->mName) == mediaFeatureAtom &&
|
||||
!(feature->mReqFlags & ~satisfiedReqFlags)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,7 +372,7 @@ GetWindowsTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetOperatinSystemVersion(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
|
||||
GetOperatingSystemVersion(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
|
||||
nsCSSValue& aResult)
|
||||
{
|
||||
aResult.Reset();
|
||||
@@ -420,6 +420,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::width,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eLength,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetWidth
|
||||
},
|
||||
@@ -427,6 +428,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::height,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eLength,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetHeight
|
||||
},
|
||||
@@ -434,6 +436,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::deviceWidth,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eLength,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetDeviceWidth
|
||||
},
|
||||
@@ -441,6 +444,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::deviceHeight,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eLength,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetDeviceHeight
|
||||
},
|
||||
@@ -448,6 +452,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::orientation,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eEnumerated,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ kOrientationKeywords },
|
||||
GetOrientation
|
||||
},
|
||||
@@ -455,6 +460,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::aspectRatio,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eIntRatio,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetAspectRatio
|
||||
},
|
||||
@@ -462,6 +468,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::deviceAspectRatio,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eIntRatio,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetDeviceAspectRatio
|
||||
},
|
||||
@@ -469,6 +476,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::color,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetColor
|
||||
},
|
||||
@@ -476,6 +484,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::colorIndex,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetColorIndex
|
||||
},
|
||||
@@ -483,6 +492,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::monochrome,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetMonochrome
|
||||
},
|
||||
@@ -490,6 +500,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::resolution,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eResolution,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetResolution
|
||||
},
|
||||
@@ -497,6 +508,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::scan,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eEnumerated,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ kScanKeywords },
|
||||
GetScan
|
||||
},
|
||||
@@ -504,15 +516,28 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::grid,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetGrid
|
||||
},
|
||||
|
||||
// Webkit extensions that we support for de-facto web compatibility
|
||||
// -webkit-{min|max}-device-pixel-ratio:
|
||||
{
|
||||
&nsGkAtoms::devicePixelRatio,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eFloat,
|
||||
nsMediaFeature::eHasWebkitPrefix,
|
||||
{ nullptr },
|
||||
GetDevicePixelRatio
|
||||
},
|
||||
|
||||
// Mozilla extensions
|
||||
{
|
||||
&nsGkAtoms::_moz_device_pixel_ratio,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eFloat,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetDevicePixelRatio
|
||||
},
|
||||
@@ -520,6 +545,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_device_orientation,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eEnumerated,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ kOrientationKeywords },
|
||||
GetDeviceOrientation
|
||||
},
|
||||
@@ -527,6 +553,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_is_resource_document,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetIsResourceDocument
|
||||
},
|
||||
@@ -534,6 +561,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_color_picker_available,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::color_picker_available },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -541,6 +569,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_scrollbar_start_backward,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::scrollbar_start_backward },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -548,6 +577,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_scrollbar_start_forward,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::scrollbar_start_forward },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -555,6 +585,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_scrollbar_end_backward,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::scrollbar_end_backward },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -562,6 +593,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_scrollbar_end_forward,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::scrollbar_end_forward },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -569,6 +601,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_scrollbar_thumb_proportional,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::scrollbar_thumb_proportional },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -576,6 +609,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_images_in_menus,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::images_in_menus },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -583,6 +617,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_images_in_buttons,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::images_in_buttons },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -590,6 +625,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_overlay_scrollbars,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::overlay_scrollbars },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -597,6 +633,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_windows_default_theme,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::windows_default_theme },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -604,6 +641,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_mac_graphite_theme,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::mac_graphite_theme },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -611,6 +649,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_mac_lion_theme,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::mac_lion_theme },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -618,6 +657,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_mac_yosemite_theme,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::mac_yosemite_theme },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -625,6 +665,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_windows_accent_color_applies,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::windows_accent_color_applies },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -632,6 +673,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_windows_accent_color_is_dark,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::windows_accent_color_is_dark },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -639,6 +681,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_windows_compositor,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::windows_compositor },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -646,6 +689,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_windows_classic,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::windows_classic },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -653,6 +697,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_windows_glass,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::windows_glass },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -660,6 +705,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_touch_enabled,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::touch_enabled },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -667,6 +713,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_menubar_drag,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::menubar_drag },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -674,6 +721,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_windows_theme,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eIdent,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetWindowsTheme
|
||||
},
|
||||
@@ -681,14 +729,16 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_os_version,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eIdent,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetOperatinSystemVersion
|
||||
GetOperatingSystemVersion
|
||||
},
|
||||
|
||||
{
|
||||
&nsGkAtoms::_moz_swipe_animation_enabled,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::swipe_animation_enabled },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -697,6 +747,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_physical_home_button,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ &nsGkAtoms::physical_home_button },
|
||||
GetSystemMetric
|
||||
},
|
||||
@@ -708,6 +759,7 @@ nsMediaFeatures::features[] = {
|
||||
&nsGkAtoms::_moz_is_glyph,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetIsGlyph
|
||||
},
|
||||
@@ -716,6 +768,7 @@ nsMediaFeatures::features[] = {
|
||||
nullptr,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
nsMediaFeature::eInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
nullptr
|
||||
},
|
||||
|
||||
@@ -46,6 +46,15 @@ struct nsMediaFeature {
|
||||
};
|
||||
ValueType mValueType;
|
||||
|
||||
enum RequirementFlags : uint8_t {
|
||||
// Bitfield of requirements that must be satisfied in order for this
|
||||
// media feature to be active.
|
||||
eNoRequirements = 0,
|
||||
eHasWebkitPrefix = 1 // Feature name must start w/ "-webkit-", even
|
||||
// before any "min-"/"max-" qualifier.
|
||||
};
|
||||
uint8_t mReqFlags;
|
||||
|
||||
union {
|
||||
// In static arrays, it's the first member that's initialized. We
|
||||
// need that to be void* so we can initialize both other types.
|
||||
|
||||
@@ -283,3 +283,4 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262,
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support)
|
||||
[test_visited_reftests.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' #TIMED_OUT # b2g(bug 870262, :visited support) b2g-debug(bug 870262, :visited support) b2g-desktop(bug 870262, :visited support)
|
||||
[test_webkit_device_pixel_ratio.html]
|
||||
|
||||
@@ -113,6 +113,29 @@ function run() {
|
||||
"expression " + e + " should not be parseable");
|
||||
}
|
||||
|
||||
// Helper to share code between -moz & -webkit device-pixel-ratio versions:
|
||||
function test_device_pixel_ratio(equal_name, min_name, max_name) {
|
||||
var real_dpr = 1.0 * getScreenPixelsPerCSSPixel();
|
||||
var high_dpr = 1.1 * getScreenPixelsPerCSSPixel();
|
||||
var low_dpr = 0.9 * getScreenPixelsPerCSSPixel();
|
||||
should_apply("all and (" + max_name + ": " + real_dpr + ")");
|
||||
should_apply("all and (" + min_name + ": " + real_dpr + ")");
|
||||
should_not_apply("not all and (" + max_name + ": " + real_dpr + ")");
|
||||
should_not_apply("not all and (" + min_name + ": " + real_dpr + ")");
|
||||
should_apply("all and (" + min_name + ": " + low_dpr + ")");
|
||||
should_apply("all and (" + max_name + ": " + high_dpr + ")");
|
||||
should_not_apply("all and (" + max_name + ": " + low_dpr + ")");
|
||||
should_not_apply("all and (" + min_name + ": " + high_dpr + ")");
|
||||
should_apply("not all and (" + max_name + ": " + low_dpr + ")");
|
||||
should_apply("not all and (" + min_name + ": " + high_dpr + ")");
|
||||
should_apply("(" + equal_name + ": " + real_dpr + ")");
|
||||
should_not_apply("(" + equal_name + ": " + high_dpr + ")");
|
||||
should_not_apply("(" + equal_name + ": " + low_dpr + ")");
|
||||
should_apply("(" + equal_name + ")");
|
||||
expression_should_not_be_parseable(min_name);
|
||||
expression_should_not_be_parseable(max_name);
|
||||
}
|
||||
|
||||
function test_serialization(q, test_application, should_apply) {
|
||||
style.setAttribute("media", q);
|
||||
var ser1 = style.sheet.media.mediaText;
|
||||
@@ -398,25 +421,23 @@ function run() {
|
||||
should_apply("not all and (max-device-aspect-ratio: " + low_dar_2 + ")");
|
||||
expression_should_not_be_parseable("max-device-aspect-ratio");
|
||||
|
||||
var real_dpr = 1.0 * getScreenPixelsPerCSSPixel();
|
||||
var high_dpr = 1.1 * getScreenPixelsPerCSSPixel();
|
||||
var low_dpr = 0.9 * getScreenPixelsPerCSSPixel();
|
||||
should_apply("all and (max--moz-device-pixel-ratio: " + real_dpr + ")");
|
||||
should_apply("all and (min--moz-device-pixel-ratio: " + real_dpr + ")");
|
||||
should_not_apply("not all and (max--moz-device-pixel-ratio: " + real_dpr + ")");
|
||||
should_not_apply("not all and (min--moz-device-pixel-ratio: " + real_dpr + ")");
|
||||
should_apply("all and (min--moz-device-pixel-ratio: " + low_dpr + ")");
|
||||
should_apply("all and (max--moz-device-pixel-ratio: " + high_dpr + ")");
|
||||
should_not_apply("all and (max--moz-device-pixel-ratio: " + low_dpr + ")");
|
||||
should_not_apply("all and (min--moz-device-pixel-ratio: " + high_dpr + ")");
|
||||
should_apply("not all and (max--moz-device-pixel-ratio: " + low_dpr + ")");
|
||||
should_apply("not all and (min--moz-device-pixel-ratio: " + high_dpr + ")");
|
||||
should_apply("(-moz-device-pixel-ratio: " + real_dpr + ")");
|
||||
should_not_apply("(-moz-device-pixel-ratio: " + high_dpr + ")");
|
||||
should_not_apply("(-moz-device-pixel-ratio: " + low_dpr + ")");
|
||||
should_apply("(-moz-device-pixel-ratio)");
|
||||
expression_should_not_be_parseable("min--moz-device-pixel-ratio");
|
||||
expression_should_not_be_parseable("max--moz-device-pixel-ratio");
|
||||
// Tests for -moz- & -webkit versions of "device-pixel-ratio"
|
||||
// (Note that the vendor prefixes go in different places.)
|
||||
test_device_pixel_ratio("-moz-device-pixel-ratio",
|
||||
"min--moz-device-pixel-ratio",
|
||||
"max--moz-device-pixel-ratio");
|
||||
test_device_pixel_ratio("-webkit-device-pixel-ratio",
|
||||
"-webkit-min-device-pixel-ratio",
|
||||
"-webkit-max-device-pixel-ratio");
|
||||
|
||||
// Make sure that we don't accidentally start accepting *unprefixed*
|
||||
// "device-pixel-ratio" expressions:
|
||||
expression_should_be_parseable("-webkit-device-pixel-ratio: 1.0");
|
||||
expression_should_not_be_parseable("device-pixel-ratio: 1.0");
|
||||
expression_should_be_parseable("-webkit-min-device-pixel-ratio: 1.0");
|
||||
expression_should_not_be_parseable("min-device-pixel-ratio: 1.0");
|
||||
expression_should_be_parseable("-webkit-max-device-pixel-ratio: 1.0");
|
||||
expression_should_not_be_parseable("max-device-pixel-ratio: 1.0");
|
||||
|
||||
features = [ "max-aspect-ratio", "device-aspect-ratio" ];
|
||||
for (i in features) {
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1176968
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1176968</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<style>.zoom-test { visibility: hidden; }</style>
|
||||
<style><!-- placeholder for dynamic additions --></style>
|
||||
</head>
|
||||
<body onload="run()">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1176968">Mozilla Bug 1176968</a>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
<pre id="test">
|
||||
<div id="zoom1" class="zoom-test"></div>
|
||||
<div id="zoom2" class="zoom-test"></div>
|
||||
<div id="zoom3" class="zoom-test"></div>
|
||||
<script class="testbody" type="application/javascript">
|
||||
|
||||
/** Test for Bug 1176968 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function run() {
|
||||
function zoom(factor) {
|
||||
var previous = SpecialPowers.getFullZoom(window);
|
||||
SpecialPowers.setFullZoom(window, factor);
|
||||
return previous;
|
||||
}
|
||||
|
||||
function isVisible(divName) {
|
||||
return window.getComputedStyle(document.getElementById(divName), null).visibility == "visible";
|
||||
}
|
||||
|
||||
function getScreenPixelsPerCSSPixel() {
|
||||
return SpecialPowers.DOMWindowUtils.screenPixelsPerCSSPixel;
|
||||
}
|
||||
|
||||
var screenPixelsPerCSSPixel = getScreenPixelsPerCSSPixel();
|
||||
var baseRatio = 1.0 * screenPixelsPerCSSPixel;
|
||||
var doubleRatio = 2.0 * screenPixelsPerCSSPixel;
|
||||
var halfRatio = 0.5 * screenPixelsPerCSSPixel;
|
||||
var styleElem = document.getElementsByTagName("style")[1];
|
||||
styleElem.textContent =
|
||||
["@media all and (-webkit-device-pixel-ratio: " + baseRatio + ") {",
|
||||
"#zoom1 { visibility: visible; }",
|
||||
"}",
|
||||
"@media all and (-webkit-device-pixel-ratio: " + doubleRatio + ") {",
|
||||
"#zoom2 { visibility: visible; }",
|
||||
"}",
|
||||
"@media all and (-webkit-device-pixel-ratio: " + halfRatio + ") {",
|
||||
"#zoom3 { visibility: visible; }",
|
||||
"}"
|
||||
].join("\n");
|
||||
|
||||
ok(isVisible("zoom1"), "Base ratio rule should apply at base zoom level");
|
||||
ok(!isVisible("zoom2") && !isVisible("zoom3"), "no other rules should apply");
|
||||
var origZoom = zoom(2);
|
||||
ok(isVisible("zoom2"), "Double ratio rule should apply at double zoom level");
|
||||
ok(!isVisible("zoom1") && !isVisible("zoom3"), "no other rules should apply");
|
||||
zoom(0.5);
|
||||
ok(isVisible("zoom3"), "Half ratio rule should apply at half zoom level");
|
||||
ok(!isVisible("zoom1") && !isVisible("zoom2"), "no other rules should apply");
|
||||
zoom(origZoom);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -825,10 +825,9 @@ void DebugCheckChildSize(nsIFrame* aChild,
|
||||
// it is the bsize (minus border, padding) of the cell's first in flow during its final
|
||||
// reflow without an unconstrained bsize.
|
||||
static nscoord
|
||||
CalcUnpaginatedBSize(nsPresContext* aPresContext,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
nsTableFrame& aTableFrame,
|
||||
nscoord aBlockDirBorderPadding)
|
||||
CalcUnpaginatedBSize(nsTableCellFrame& aCellFrame,
|
||||
nsTableFrame& aTableFrame,
|
||||
nscoord aBlockDirBorderPadding)
|
||||
{
|
||||
const nsTableCellFrame* firstCellInFlow =
|
||||
static_cast<nsTableCellFrame*>(aCellFrame.FirstInFlow());
|
||||
@@ -852,7 +851,7 @@ CalcUnpaginatedBSize(nsPresContext* aPresContext,
|
||||
break;
|
||||
}
|
||||
else if (rowX >= rowIndex) {
|
||||
computedBSize += row->GetUnpaginatedBSize(aPresContext);
|
||||
computedBSize += row->GetUnpaginatedBSize();
|
||||
}
|
||||
}
|
||||
return computedBSize;
|
||||
@@ -910,7 +909,7 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
|
||||
}
|
||||
else if (aPresContext->IsPaginated()) {
|
||||
nscoord computedUnpaginatedBSize =
|
||||
CalcUnpaginatedBSize(aPresContext, (nsTableCellFrame&)*this,
|
||||
CalcUnpaginatedBSize((nsTableCellFrame&)*this,
|
||||
*tableFrame, borderPadding.BStartEnd(wm));
|
||||
if (computedUnpaginatedBSize > 0) {
|
||||
const_cast<nsHTMLReflowState&>(aReflowState).SetComputedBSize(computedUnpaginatedBSize);
|
||||
|
||||
@@ -775,15 +775,14 @@ GetSpaceBetween(int32_t aPrevColIndex,
|
||||
|
||||
// subtract the bsizes of aRow's prev in flows from the unpaginated bsize
|
||||
static
|
||||
nscoord CalcBSizeFromUnpaginatedBSize(nsPresContext* aPresContext,
|
||||
nsTableRowFrame& aRow,
|
||||
nscoord CalcBSizeFromUnpaginatedBSize(nsTableRowFrame& aRow,
|
||||
WritingMode aWM)
|
||||
{
|
||||
nscoord bsize = 0;
|
||||
nsTableRowFrame* firstInFlow =
|
||||
static_cast<nsTableRowFrame*>(aRow.FirstInFlow());
|
||||
if (firstInFlow->HasUnpaginatedBSize()) {
|
||||
bsize = firstInFlow->GetUnpaginatedBSize(aPresContext);
|
||||
bsize = firstInFlow->GetUnpaginatedBSize();
|
||||
for (nsIFrame* prevInFlow = aRow.GetPrevInFlow(); prevInFlow;
|
||||
prevInFlow = prevInFlow->GetPrevInFlow()) {
|
||||
bsize -= prevInFlow->BSize(aWM);
|
||||
@@ -1038,7 +1037,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
|
||||
} else if (NS_UNCONSTRAINEDSIZE == aReflowState.AvailableBSize()) {
|
||||
aDesiredSize.BSize(wm) = CalcBSize(aReflowState);
|
||||
if (GetPrevInFlow()) {
|
||||
nscoord bsize = CalcBSizeFromUnpaginatedBSize(aPresContext, *this, wm);
|
||||
nscoord bsize = CalcBSizeFromUnpaginatedBSize(*this, wm);
|
||||
aDesiredSize.BSize(wm) = std::max(aDesiredSize.BSize(wm), bsize);
|
||||
} else {
|
||||
if (isPaginated && HasStyleBSize()) {
|
||||
@@ -1048,14 +1047,13 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
|
||||
}
|
||||
if (isPaginated && HasUnpaginatedBSize()) {
|
||||
aDesiredSize.BSize(wm) = std::max(aDesiredSize.BSize(wm),
|
||||
GetUnpaginatedBSize(aPresContext));
|
||||
GetUnpaginatedBSize());
|
||||
}
|
||||
}
|
||||
} else { // constrained bsize, paginated
|
||||
// Compute the bsize we should have from style (subtracting the
|
||||
// bsize from our prev-in-flows from the style bsize)
|
||||
nscoord styleBSize = CalcBSizeFromUnpaginatedBSize(aPresContext, *this,
|
||||
wm);
|
||||
nscoord styleBSize = CalcBSizeFromUnpaginatedBSize(*this, wm);
|
||||
if (styleBSize > aReflowState.AvailableBSize()) {
|
||||
styleBSize = aReflowState.AvailableBSize();
|
||||
NS_FRAME_SET_INCOMPLETE(aStatus);
|
||||
@@ -1432,7 +1430,7 @@ nsTableRowFrame::SetUnpaginatedBSize(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
nscoord
|
||||
nsTableRowFrame::GetUnpaginatedBSize(nsPresContext* aPresContext)
|
||||
nsTableRowFrame::GetUnpaginatedBSize()
|
||||
{
|
||||
FrameProperties props = FirstInFlow()->Properties();
|
||||
return NS_PTR_TO_INT32(props.Get(RowUnpaginatedHeightProperty()));
|
||||
|
||||
@@ -209,7 +209,7 @@ public:
|
||||
|
||||
bool HasUnpaginatedBSize();
|
||||
void SetHasUnpaginatedBSize(bool aValue);
|
||||
nscoord GetUnpaginatedBSize(nsPresContext* aPresContext);
|
||||
nscoord GetUnpaginatedBSize();
|
||||
void SetUnpaginatedBSize(nsPresContext* aPresContext, nscoord aValue);
|
||||
|
||||
nscoord GetBStartBCBorderWidth() const { return mBStartBorderWidth; }
|
||||
|
||||
@@ -92,8 +92,7 @@ void nsTableRowGroupFrame::AdjustRowIndices(int32_t aRowIndex,
|
||||
}
|
||||
}
|
||||
nsresult
|
||||
nsTableRowGroupFrame::InitRepeatedFrame(nsPresContext* aPresContext,
|
||||
nsTableRowGroupFrame* aHeaderFooterFrame)
|
||||
nsTableRowGroupFrame::InitRepeatedFrame(nsTableRowGroupFrame* aHeaderFooterFrame)
|
||||
{
|
||||
nsTableRowFrame* copyRowFrame = GetFirstRow();
|
||||
nsTableRowFrame* originalRowFrame = aHeaderFooterFrame->GetFirstRow();
|
||||
|
||||
@@ -155,8 +155,7 @@ public:
|
||||
* @param aHeaderFooterFrame the original header or footer row group frame
|
||||
* that was repeated
|
||||
*/
|
||||
nsresult InitRepeatedFrame(nsPresContext* aPresContext,
|
||||
nsTableRowGroupFrame* aHeaderFooterFrame);
|
||||
nsresult InitRepeatedFrame(nsTableRowGroupFrame* aHeaderFooterFrame);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
+12
-11
@@ -185,8 +185,9 @@ nsBoxFrame::Init(nsIContent* aContent,
|
||||
|
||||
#ifdef DEBUG_LAYOUT
|
||||
// if we are root and this
|
||||
if (mState & NS_STATE_IS_ROOT)
|
||||
GetDebugPref(GetPresContext());
|
||||
if (mState & NS_STATE_IS_ROOT) {
|
||||
GetDebugPref();
|
||||
}
|
||||
#endif
|
||||
|
||||
UpdateMouseThrough();
|
||||
@@ -1259,9 +1260,9 @@ nsBoxFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
|
||||
#ifdef DEBUG_LAYOUT
|
||||
void
|
||||
nsBoxFrame::GetDebugPref(nsPresContext* aPresContext)
|
||||
nsBoxFrame::GetDebugPref()
|
||||
{
|
||||
gDebug = Preferences::GetBool("xul.debug.box");
|
||||
gDebug = Preferences::GetBool("xul.debug.box");
|
||||
}
|
||||
|
||||
class nsDisplayXULDebug : public nsDisplayItem {
|
||||
@@ -1408,13 +1409,13 @@ nsBoxFrame::PaintXULDebugBackground(nsRenderingContext& aRenderingContext,
|
||||
bool isHorizontal = IsHorizontal();
|
||||
|
||||
GetDebugBorder(debugBorder);
|
||||
PixelMarginToTwips(GetPresContext(), debugBorder);
|
||||
PixelMarginToTwips(debugBorder);
|
||||
|
||||
GetDebugMargin(debugMargin);
|
||||
PixelMarginToTwips(GetPresContext(), debugMargin);
|
||||
PixelMarginToTwips(debugMargin);
|
||||
|
||||
GetDebugPadding(debugPadding);
|
||||
PixelMarginToTwips(GetPresContext(), debugPadding);
|
||||
PixelMarginToTwips(debugPadding);
|
||||
|
||||
nsRect inner(mRect);
|
||||
inner.MoveTo(aPt);
|
||||
@@ -1468,7 +1469,7 @@ nsBoxFrame::PaintXULDebugOverlay(DrawTarget& aDrawTarget, nsPoint aPt)
|
||||
|
||||
nsMargin debugMargin;
|
||||
GetDebugMargin(debugMargin);
|
||||
PixelMarginToTwips(GetPresContext(), debugMargin);
|
||||
PixelMarginToTwips(debugMargin);
|
||||
|
||||
nsRect inner(mRect);
|
||||
inner.MoveTo(aPt);
|
||||
@@ -1671,7 +1672,7 @@ nsBoxFrame::GetDebugPadding(nsMargin& aPadding)
|
||||
}
|
||||
|
||||
void
|
||||
nsBoxFrame::PixelMarginToTwips(nsPresContext* aPresContext, nsMargin& aMarginPixels)
|
||||
nsBoxFrame::PixelMarginToTwips(nsMargin& aMarginPixels)
|
||||
{
|
||||
nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);
|
||||
aMarginPixels.left *= onePixel;
|
||||
@@ -1742,10 +1743,10 @@ nsBoxFrame::DisplayDebugInfoFor(nsIFrame* aBox,
|
||||
nsMargin m;
|
||||
nsMargin m2;
|
||||
GetDebugBorder(m);
|
||||
PixelMarginToTwips(aPresContext, m);
|
||||
PixelMarginToTwips(m);
|
||||
|
||||
GetDebugMargin(m2);
|
||||
PixelMarginToTwips(aPresContext, m2);
|
||||
PixelMarginToTwips(m2);
|
||||
|
||||
m += m2;
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ private:
|
||||
#ifdef DEBUG_LAYOUT
|
||||
nsresult SetDebug(nsPresContext* aPresContext, bool aDebug);
|
||||
bool GetInitialDebug(bool& aDebug);
|
||||
void GetDebugPref(nsPresContext* aPresContext);
|
||||
void GetDebugPref();
|
||||
|
||||
void GetDebugBorder(nsMargin& aInset);
|
||||
void GetDebugPadding(nsMargin& aInset);
|
||||
@@ -230,7 +230,7 @@ private:
|
||||
|
||||
nsresult GetFrameSizeWithMargin(nsIFrame* aBox, nsSize& aSize);
|
||||
|
||||
void PixelMarginToTwips(nsPresContext* aPresContext, nsMargin& aMarginPixels);
|
||||
void PixelMarginToTwips(nsMargin& aMarginPixels);
|
||||
|
||||
void GetValue(nsPresContext* aPresContext, const nsSize& a, const nsSize& b, char* value);
|
||||
void GetValue(nsPresContext* aPresContext, int32_t a, int32_t b, char* value);
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
virtual bool GetInitialVAlignment(Valignment& aValign) override { aValign = vAlign_Top; return true; }
|
||||
virtual bool GetInitialAutoStretch(bool& aStretch) override { aStretch = true; return true; }
|
||||
|
||||
nsIFrame* GetCaptionBox(nsPresContext* aPresContext, nsRect& aCaptionRect);
|
||||
nsIFrame* GetCaptionBox(nsRect& aCaptionRect);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -172,7 +172,7 @@ nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext,
|
||||
nsPresContext* presContext = PresContext();
|
||||
|
||||
nsRect groupRect;
|
||||
nsIFrame* groupBox = GetCaptionBox(presContext, groupRect);
|
||||
nsIFrame* groupBox = GetCaptionBox(groupRect);
|
||||
|
||||
if (groupBox) {
|
||||
// if the border is smaller than the legend. Move the border down
|
||||
@@ -253,7 +253,7 @@ nsGroupBoxFrame::PaintBorderBackground(nsRenderingContext& aRenderingContext,
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsGroupBoxFrame::GetCaptionBox(nsPresContext* aPresContext, nsRect& aCaptionRect)
|
||||
nsGroupBoxFrame::GetCaptionBox(nsRect& aCaptionRect)
|
||||
{
|
||||
// first child is our grouped area
|
||||
nsIFrame* box = nsBox::GetChildBox(this);
|
||||
|
||||
@@ -1179,7 +1179,7 @@ nsListBoxBodyFrame::GetFirstItemBox(int32_t aOffset, bool* aCreated)
|
||||
nsPresContext* presContext = PresContext();
|
||||
nsCSSFrameConstructor* fc = presContext->PresShell()->FrameConstructor();
|
||||
nsIFrame* topFrame = nullptr;
|
||||
fc->CreateListBoxContent(presContext, this, nullptr, startContent,
|
||||
fc->CreateListBoxContent(this, nullptr, startContent,
|
||||
&topFrame, isAppend, false, nullptr);
|
||||
mTopFrame = topFrame;
|
||||
if (mTopFrame) {
|
||||
@@ -1232,7 +1232,7 @@ nsListBoxBodyFrame::GetNextItemBox(nsIFrame* aBox, int32_t aOffset,
|
||||
|
||||
nsPresContext* presContext = PresContext();
|
||||
nsCSSFrameConstructor* fc = presContext->PresShell()->FrameConstructor();
|
||||
fc->CreateListBoxContent(presContext, this, prevFrame, nextContent,
|
||||
fc->CreateListBoxContent(this, prevFrame, nextContent,
|
||||
&result, isAppend, false, nullptr);
|
||||
|
||||
if (result) {
|
||||
@@ -1339,8 +1339,8 @@ nsListBoxBodyFrame::ListBoxInsertFrames(nsIFrame* aPrevFrame,
|
||||
//
|
||||
// Called by nsCSSFrameConstructor when a new listitem content is inserted.
|
||||
//
|
||||
void
|
||||
nsListBoxBodyFrame::OnContentInserted(nsPresContext* aPresContext, nsIContent* aChildContent)
|
||||
void
|
||||
nsListBoxBodyFrame::OnContentInserted(nsIContent* aChildContent)
|
||||
{
|
||||
if (mRowCount >= 0)
|
||||
++mRowCount;
|
||||
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
bool ContinueReflow(nscoord height);
|
||||
NS_IMETHOD ListBoxAppendFrames(nsFrameList& aFrameList);
|
||||
NS_IMETHOD ListBoxInsertFrames(nsIFrame* aPrevFrame, nsFrameList& aFrameList);
|
||||
void OnContentInserted(nsPresContext* aPresContext, nsIContent* aContent);
|
||||
void OnContentInserted(nsIContent* aContent);
|
||||
void OnContentRemoved(nsPresContext* aPresContext, nsIContent* aContainer,
|
||||
nsIFrame* aChildFrame, nsIContent* aOldNextSibling);
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ nsMenuBarFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent)
|
||||
nsIContent* current = currFrame->GetContent();
|
||||
|
||||
// See if it's a menu item.
|
||||
if (nsXULPopupManager::IsValidMenuItem(PresContext(), current, false)) {
|
||||
if (nsXULPopupManager::IsValidMenuItem(current, false)) {
|
||||
// Get the shortcut attribute.
|
||||
nsAutoString shortcutKey;
|
||||
current->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, shortcutKey);
|
||||
|
||||
@@ -125,7 +125,7 @@ public:
|
||||
nsMenuFrame* frame = static_cast<nsMenuFrame*>(mFrame.GetFrame());
|
||||
NS_ENSURE_STATE(frame);
|
||||
if (mAttr == nsGkAtoms::checked) {
|
||||
frame->UpdateMenuSpecialState(frame->PresContext());
|
||||
frame->UpdateMenuSpecialState();
|
||||
} else if (mAttr == nsGkAtoms::acceltext) {
|
||||
// someone reset the accelText attribute,
|
||||
// so clear the bit that says *we* set it
|
||||
@@ -135,7 +135,7 @@ public:
|
||||
else if (mAttr == nsGkAtoms::key) {
|
||||
frame->BuildAcceleratorText(true);
|
||||
} else if (mAttr == nsGkAtoms::type || mAttr == nsGkAtoms::name) {
|
||||
frame->UpdateMenuType(frame->PresContext());
|
||||
frame->UpdateMenuType();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -211,7 +211,7 @@ public:
|
||||
bool shouldFlush = false;
|
||||
nsMenuFrame* menu = do_QueryFrame(mWeakFrame.GetFrame());
|
||||
if (menu) {
|
||||
menu->UpdateMenuType(menu->PresContext());
|
||||
menu->UpdateMenuType();
|
||||
shouldFlush = true;
|
||||
}
|
||||
delete this;
|
||||
@@ -912,7 +912,7 @@ nsMenuFrame::IsDisabled()
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuFrame::UpdateMenuType(nsPresContext* aPresContext)
|
||||
nsMenuFrame::UpdateMenuType()
|
||||
{
|
||||
static nsIContent::AttrValuesArray strings[] =
|
||||
{&nsGkAtoms::checkbox, &nsGkAtoms::radio, nullptr};
|
||||
@@ -934,12 +934,12 @@ nsMenuFrame::UpdateMenuType(nsPresContext* aPresContext)
|
||||
mType = eMenuType_Normal;
|
||||
break;
|
||||
}
|
||||
UpdateMenuSpecialState(aPresContext);
|
||||
UpdateMenuSpecialState();
|
||||
}
|
||||
|
||||
/* update checked-ness for type="checkbox" and type="radio" */
|
||||
void
|
||||
nsMenuFrame::UpdateMenuSpecialState(nsPresContext* aPresContext)
|
||||
nsMenuFrame::UpdateMenuSpecialState()
|
||||
{
|
||||
bool newChecked =
|
||||
mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::checked,
|
||||
|
||||
@@ -235,10 +235,10 @@ protected:
|
||||
|
||||
// Update the menu's type (normal, checkbox, radio).
|
||||
// This method can destroy the frame.
|
||||
void UpdateMenuType(nsPresContext* aPresContext);
|
||||
void UpdateMenuType();
|
||||
// Update the checked state of the menu, and for radios, clear any other
|
||||
// checked items. This method can destroy the frame.
|
||||
void UpdateMenuSpecialState(nsPresContext* aPresContext);
|
||||
void UpdateMenuSpecialState();
|
||||
|
||||
// Examines the key node and builds the accelerator.
|
||||
void BuildAcceleratorText(bool aNotify);
|
||||
|
||||
@@ -1724,7 +1724,7 @@ void nsMenuPopupFrame::ChangeByPage(bool aIsUp)
|
||||
// Only consider menu frames.
|
||||
nsMenuFrame* menuFrame = do_QueryFrame(currentMenu);
|
||||
if (menuFrame &&
|
||||
nsXULPopupManager::IsValidMenuItem(PresContext(), menuFrame->GetContent(), true)) {
|
||||
nsXULPopupManager::IsValidMenuItem(menuFrame->GetContent(), true)) {
|
||||
|
||||
// If the right position was found, break out. Otherwise, look for another item.
|
||||
if ((!aIsUp && currentMenu->GetRect().YMost() > targetPosition) ||
|
||||
|
||||
@@ -230,8 +230,7 @@ nsScrollbarButtonFrame::MouseClicked(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScrollbarButtonFrame::GetChildWithTag(nsPresContext* aPresContext,
|
||||
nsIAtom* atom, nsIFrame* start,
|
||||
nsScrollbarButtonFrame::GetChildWithTag(nsIAtom* atom, nsIFrame* start,
|
||||
nsIFrame*& result)
|
||||
{
|
||||
// recursively search our children
|
||||
@@ -252,7 +251,7 @@ nsScrollbarButtonFrame::GetChildWithTag(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
// recursive search the child
|
||||
GetChildWithTag(aPresContext, atom, childFrame, result);
|
||||
GetChildWithTag(atom, childFrame, result);
|
||||
if (result != nullptr)
|
||||
return NS_OK;
|
||||
|
||||
|
||||
@@ -35,8 +35,7 @@ public:
|
||||
mozilla::WidgetGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus) override;
|
||||
|
||||
static nsresult GetChildWithTag(nsPresContext* aPresContext,
|
||||
nsIAtom* atom, nsIFrame* start, nsIFrame*& result);
|
||||
static nsresult GetChildWithTag(nsIAtom* atom, nsIFrame* start, nsIFrame*& result);
|
||||
static nsresult GetParentWithTag(nsIAtom* atom, nsIFrame* start, nsIFrame*& result);
|
||||
|
||||
bool HandleButtonPress(nsPresContext* aPresContext,
|
||||
|
||||
@@ -84,17 +84,16 @@ public:
|
||||
int32_t aCount,
|
||||
int32_t& aSpaceLeft);
|
||||
|
||||
void ResizeChildTo(nsPresContext* aPresContext,
|
||||
nscoord& aDiff,
|
||||
nsSplitterInfo* aChildrenBeforeInfos,
|
||||
nsSplitterInfo* aChildrenAfterInfos,
|
||||
int32_t aChildrenBeforeCount,
|
||||
int32_t aChildrenAfterCount,
|
||||
bool aBounded);
|
||||
void ResizeChildTo(nscoord& aDiff,
|
||||
nsSplitterInfo* aChildrenBeforeInfos,
|
||||
nsSplitterInfo* aChildrenAfterInfos,
|
||||
int32_t aChildrenBeforeCount,
|
||||
int32_t aChildrenAfterCount,
|
||||
bool aBounded);
|
||||
|
||||
void UpdateState();
|
||||
|
||||
void AddListener(nsPresContext* aPresContext);
|
||||
void AddListener();
|
||||
void RemoveListener();
|
||||
|
||||
enum ResizeType { Closest, Farthest, Flex, Grow };
|
||||
@@ -249,7 +248,7 @@ nsSplitterFrame::AttributeChanged(int32_t aNameSpaceID,
|
||||
// tell the slider its attribute changed so it can
|
||||
// update itself
|
||||
nsIFrame* grippy = nullptr;
|
||||
nsScrollbarButtonFrame::GetChildWithTag(PresContext(), nsGkAtoms::grippy, this, grippy);
|
||||
nsScrollbarButtonFrame::GetChildWithTag(nsGkAtoms::grippy, this, grippy);
|
||||
if (grippy)
|
||||
grippy->AttributeChanged(aNameSpaceID, aAttribute, aModType);
|
||||
} else if (aAttribute == nsGkAtoms::state) {
|
||||
@@ -295,7 +294,7 @@ nsSplitterFrame::Init(nsIContent* aContent,
|
||||
nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
|
||||
|
||||
mInner->mState = nsSplitterFrameInner::Open;
|
||||
mInner->AddListener(PresContext());
|
||||
mInner->AddListener();
|
||||
mInner->mParentBox = nullptr;
|
||||
}
|
||||
|
||||
@@ -410,7 +409,7 @@ nsSplitterFrameInner::MouseUp(nsPresContext* aPresContext,
|
||||
{
|
||||
if (mDragging && mOuter) {
|
||||
AdjustChildren(aPresContext);
|
||||
AddListener(aPresContext);
|
||||
AddListener();
|
||||
nsIPresShell::SetCapturingContent(nullptr, 0); // XXXndeakin is this needed?
|
||||
mDragging = false;
|
||||
State newState = GetState();
|
||||
@@ -475,7 +474,7 @@ nsSplitterFrameInner::MouseDrag(nsPresContext* aPresContext,
|
||||
|
||||
nscoord oldPos = pos;
|
||||
|
||||
ResizeChildTo(aPresContext, pos,
|
||||
ResizeChildTo(pos,
|
||||
mChildInfosBefore.get(), mChildInfosAfter.get(),
|
||||
mChildInfosBeforeCount, mChildInfosAfterCount, bounded);
|
||||
|
||||
@@ -542,7 +541,7 @@ nsSplitterFrameInner::MouseDrag(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
void
|
||||
nsSplitterFrameInner::AddListener(nsPresContext* aPresContext)
|
||||
nsSplitterFrameInner::AddListener()
|
||||
{
|
||||
mOuter->GetContent()->
|
||||
AddEventListener(NS_LITERAL_STRING("mouseup"), this, false, false);
|
||||
@@ -1023,14 +1022,13 @@ nsSplitterFrameInner::AddRemoveSpace(nscoord aDiff,
|
||||
*/
|
||||
|
||||
void
|
||||
nsSplitterFrameInner::ResizeChildTo(nsPresContext* aPresContext,
|
||||
nscoord& aDiff,
|
||||
nsSplitterInfo* aChildrenBeforeInfos,
|
||||
nsSplitterInfo* aChildrenAfterInfos,
|
||||
int32_t aChildrenBeforeCount,
|
||||
int32_t aChildrenAfterCount,
|
||||
bool aBounded)
|
||||
{
|
||||
nsSplitterFrameInner::ResizeChildTo(nscoord& aDiff,
|
||||
nsSplitterInfo* aChildrenBeforeInfos,
|
||||
nsSplitterInfo* aChildrenAfterInfos,
|
||||
int32_t aChildrenBeforeCount,
|
||||
int32_t aChildrenAfterCount,
|
||||
bool aBounded)
|
||||
{
|
||||
nscoord spaceLeft;
|
||||
AddRemoveSpace(aDiff, aChildrenBeforeInfos,aChildrenBeforeCount,spaceLeft);
|
||||
|
||||
|
||||
@@ -620,8 +620,7 @@ nsTextBoxFrame::CalculateUnderline(nsRenderingContext& aRenderingContext,
|
||||
}
|
||||
|
||||
nscoord
|
||||
nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
nsTextBoxFrame::CalculateTitleForWidth(nsRenderingContext& aRenderingContext,
|
||||
nscoord aWidth)
|
||||
{
|
||||
if (mTitle.IsEmpty()) {
|
||||
@@ -1016,8 +1015,7 @@ nsTextBoxFrame::MarkIntrinsicISizesDirty()
|
||||
}
|
||||
|
||||
void
|
||||
nsTextBoxFrame::GetTextSize(nsPresContext* aPresContext,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
nsTextBoxFrame::GetTextSize(nsRenderingContext& aRenderingContext,
|
||||
const nsString& aString,
|
||||
nsSize& aSize, nscoord& aAscent)
|
||||
{
|
||||
@@ -1033,14 +1031,11 @@ nsTextBoxFrame::GetTextSize(nsPresContext* aPresContext,
|
||||
void
|
||||
nsTextBoxFrame::CalcTextSize(nsBoxLayoutState& aBoxLayoutState)
|
||||
{
|
||||
if (mNeedsRecalc)
|
||||
{
|
||||
if (mNeedsRecalc) {
|
||||
nsSize size;
|
||||
nsPresContext* presContext = aBoxLayoutState.PresContext();
|
||||
nsRenderingContext* rendContext = aBoxLayoutState.GetRenderingContext();
|
||||
if (rendContext) {
|
||||
GetTextSize(presContext, *rendContext,
|
||||
mTitle, size, mAscent);
|
||||
GetTextSize(*rendContext, mTitle, size, mAscent);
|
||||
if (GetWritingMode().IsVertical()) {
|
||||
Swap(size.width, size.height);
|
||||
}
|
||||
@@ -1061,13 +1056,11 @@ nsTextBoxFrame::CalcDrawRect(nsRenderingContext &aRenderingContext)
|
||||
textRect.Deflate(wm, LogicalMargin(wm, borderPadding));
|
||||
|
||||
// determine (cropped) title and underline position
|
||||
nsPresContext* presContext = PresContext();
|
||||
// determine (cropped) title which fits in aRect, and its width
|
||||
// (where "width" is the text measure along its baseline, i.e. actually
|
||||
// a physical height in vertical writing modes)
|
||||
nscoord titleWidth =
|
||||
CalculateTitleForWidth(presContext, aRenderingContext,
|
||||
textRect.ISize(wm));
|
||||
CalculateTitleForWidth(aRenderingContext, textRect.ISize(wm));
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
// Make sure to update the accessible tree in case when cropped title is
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user