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:
2023-05-12 10:38:28 +08:00
parent 61b14e0f32
commit bb3c92a4bb
137 changed files with 1780 additions and 1216 deletions
+2 -2
View File
@@ -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,
-1
View File
@@ -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',
-36
View File
@@ -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 //
/////////////////////////////////////
-3
View File
@@ -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*
+3 -7
View File
@@ -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());
}
+1 -1
View File
@@ -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
View File
@@ -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);
+1
View File
@@ -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")
+1 -1
View File
@@ -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
View File
@@ -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)
+5 -12
View File
@@ -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 -1
View File
@@ -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);
}
+7 -13
View File
@@ -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();
}
-4
View File
@@ -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() {
+19 -16
View File
@@ -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
+9 -9
View File
@@ -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
+4 -8
View File
@@ -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
-2
View File
@@ -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
View File
@@ -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();
-5
View File
@@ -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>
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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));
+1
View File
@@ -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;
+143 -63
View File
@@ -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 =====
+5
View File
@@ -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);
}
+155 -1
View File
@@ -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",
+1 -12
View File
@@ -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"];
+3 -5
View File
@@ -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,
+1
View File
@@ -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>
+160 -2
View File
@@ -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.
}
+13 -5
View File
@@ -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;
+27 -1
View File
@@ -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
+15 -1
View File
@@ -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.
+2 -1
View File
@@ -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;
};
+5 -3
View File
@@ -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;
+64 -13
View File
@@ -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);
+2 -1
View File
@@ -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
+4
View File
@@ -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);
+1
View File
@@ -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',
]
+1
View File
@@ -10,6 +10,7 @@ SOURCES += [
FINAL_LIBRARY = 'xul'
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
LOCAL_INCLUDES += [
'../locale',
'../lwbrk',
+1
View File
@@ -12,6 +12,7 @@ UNIFIED_SOURCES += [
FINAL_LIBRARY = 'xul'
CXXFLAGS += CONFIG['MOZ_ICU_CFLAGS']
LOCAL_INCLUDES += CONFIG['MOZ_ICU_INCLUDES']
LOCAL_INCLUDES += [
'..',
]
+1
View File
@@ -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
+1
View File
@@ -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',
+10 -2
View File
@@ -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;
+1
View File
@@ -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
+10 -11
View File
@@ -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
}
}
+19 -33
View File
@@ -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);
+4 -10
View File
@@ -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);
+3 -5
View File
@@ -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
+1 -1
View File
@@ -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;
-1
View File
@@ -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 },
+1
View File
@@ -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']
+13
View File
@@ -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_
+1 -3
View File
@@ -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)
{
-1
View File
@@ -394,7 +394,6 @@ public:
nsresult PeekBackwardAndForward(nsSelectionAmount aAmountBack,
nsSelectionAmount aAmountForward,
int32_t aStartPos,
nsPresContext* aPresContext,
bool aJumpLines,
uint32_t aSelectFlags);
+7 -9
View File
@@ -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;
}
+1 -2
View File
@@ -123,8 +123,7 @@ public:
bool aRTL);
void
SetData(nsPresContext* aPresContext,
nsString& aData);
SetData(nsString& aData);
void
GetData(nsString& aData) {
+3 -3
View File
@@ -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;
+1 -1
View File
@@ -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;
+3 -3
View File
@@ -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;
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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);
}
+2 -3
View File
@@ -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;
+1 -2
View File
@@ -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
+1 -2
View File
@@ -586,8 +586,7 @@ void
AnimationCollection::UpdateCheckGeneration(
nsPresContext* aPresContext)
{
mCheckGeneration =
aPresContext->RestyleManager()->GetAnimationGeneration();
mCheckGeneration = aPresContext->RestyleManager()->GetAnimationGeneration();
}
nsPresContext*
+4 -1
View File
@@ -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) {
+13 -1
View File
@@ -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;
}
}
+55 -2
View File
@@ -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
},
+9
View File
@@ -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.
+1
View File
@@ -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]
+40 -19
View File
@@ -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>
+5 -6
View File
@@ -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);
+6 -8
View File
@@ -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()));
+1 -1
View File
@@ -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; }
+1 -2
View File
@@ -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();
+1 -2
View File
@@ -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
View File
@@ -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;
+2 -2
View File
@@ -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);
+3 -3
View File
@@ -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);
+4 -4
View File
@@ -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;
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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);
+6 -6
View File
@@ -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,
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -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) ||
+2 -3
View File
@@ -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;
+1 -2
View File
@@ -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,
+19 -21
View File
@@ -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);
+5 -12
View File
@@ -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