зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. r=merge a=merge CLOSED TREE
This commit is contained in:
Коммит
da2beafe7e
|
@ -500,7 +500,7 @@ public:
|
|||
AutoSetContext Asc(this, D);
|
||||
return Super::TraverseRecordDecl(D);
|
||||
}
|
||||
bool TraverseCxxRecordDecl(CXXRecordDecl *D) {
|
||||
bool TraverseCXXRecordDecl(CXXRecordDecl *D) {
|
||||
AutoSetContext Asc(this, D);
|
||||
return Super::TraverseCXXRecordDecl(D);
|
||||
}
|
||||
|
@ -516,7 +516,7 @@ public:
|
|||
}
|
||||
return Super::TraverseFunctionDecl(D);
|
||||
}
|
||||
bool TraverseCxxMethodDecl(CXXMethodDecl *D) {
|
||||
bool TraverseCXXMethodDecl(CXXMethodDecl *D) {
|
||||
AutoSetContext Asc(this, D);
|
||||
const FunctionDecl *Def;
|
||||
// See TraverseFunctionDecl.
|
||||
|
@ -525,7 +525,7 @@ public:
|
|||
}
|
||||
return Super::TraverseCXXMethodDecl(D);
|
||||
}
|
||||
bool TraverseCxxConstructorDecl(CXXConstructorDecl *D) {
|
||||
bool TraverseCXXConstructorDecl(CXXConstructorDecl *D) {
|
||||
AutoSetContext Asc(this, D);
|
||||
const FunctionDecl *Def;
|
||||
// See TraverseFunctionDecl.
|
||||
|
@ -534,7 +534,7 @@ public:
|
|||
}
|
||||
return Super::TraverseCXXConstructorDecl(D);
|
||||
}
|
||||
bool TraverseCxxConversionDecl(CXXConversionDecl *D) {
|
||||
bool TraverseCXXConversionDecl(CXXConversionDecl *D) {
|
||||
AutoSetContext Asc(this, D);
|
||||
const FunctionDecl *Def;
|
||||
// See TraverseFunctionDecl.
|
||||
|
@ -543,7 +543,7 @@ public:
|
|||
}
|
||||
return Super::TraverseCXXConversionDecl(D);
|
||||
}
|
||||
bool TraverseCxxDestructorDecl(CXXDestructorDecl *D) {
|
||||
bool TraverseCXXDestructorDecl(CXXDestructorDecl *D) {
|
||||
AutoSetContext Asc(this, D);
|
||||
const FunctionDecl *Def;
|
||||
// See TraverseFunctionDecl.
|
||||
|
@ -1143,7 +1143,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool VisitCxxConstructExpr(CXXConstructExpr *E) {
|
||||
bool VisitCXXConstructExpr(CXXConstructExpr *E) {
|
||||
SourceLocation Loc = E->getLocStart();
|
||||
normalizeLocation(&Loc);
|
||||
if (!isInterestingLocation(Loc)) {
|
||||
|
@ -1313,7 +1313,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool VisitCxxConstructorDecl(CXXConstructorDecl *D) {
|
||||
bool VisitCXXConstructorDecl(CXXConstructorDecl *D) {
|
||||
if (!isInterestingLocation(D->getLocation())) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1356,7 +1356,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool VisitCxxDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
|
||||
bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
|
||||
SourceLocation Loc = E->getMemberLoc();
|
||||
normalizeLocation(&Loc);
|
||||
if (!isInterestingLocation(Loc)) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
This clang plugin code generates a JSON file for each compiler input
|
||||
file. The JSON file contains information about the C++ symbols that
|
||||
are referenced by the input file. The data is eventually consumed by
|
||||
Searchfox. See https://github.com/bill-mccloskey/mozsearch for more
|
||||
Searchfox. See https://github.com/mozsearch/mozsearch for more
|
||||
information.
|
||||
|
||||
This plugin is enabled with the --enable-clang-plugin and
|
||||
|
|
|
@ -4733,6 +4733,8 @@ nsDocument::SetStyleSheetApplicableState(StyleSheet* aSheet,
|
|||
NS_PRECONDITION(aSheet, "null arg");
|
||||
|
||||
// If we're actually in the document style sheet list
|
||||
//
|
||||
// FIXME(emilio): Shadow DOM.
|
||||
MOZ_DIAGNOSTIC_ASSERT(aSheet->IsServo() == IsStyledByServo());
|
||||
if (mStyleSheets.IndexOf(aSheet) != mStyleSheets.NoIndex) {
|
||||
if (aApplicable) {
|
||||
|
@ -5755,45 +5757,42 @@ nsDocument::DocumentStatesChanged(EventStates aStateMask)
|
|||
}
|
||||
|
||||
void
|
||||
nsDocument::StyleRuleChanged(StyleSheet* aSheet,
|
||||
css::Rule* aStyleRule)
|
||||
nsDocument::StyleRuleChanged(StyleSheet* aSheet, css::Rule* aStyleRule)
|
||||
{
|
||||
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleChanged, (aSheet, aStyleRule));
|
||||
|
||||
if (StyleSheetChangeEventsEnabled()) {
|
||||
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
|
||||
"StyleRuleChanged",
|
||||
mRule,
|
||||
aStyleRule);
|
||||
if (!StyleSheetChangeEventsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
|
||||
"StyleRuleChanged",
|
||||
mRule,
|
||||
aStyleRule);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::StyleRuleAdded(StyleSheet* aSheet,
|
||||
css::Rule* aStyleRule)
|
||||
nsDocument::StyleRuleAdded(StyleSheet* aSheet, css::Rule* aStyleRule)
|
||||
{
|
||||
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleAdded, (aSheet, aStyleRule));
|
||||
|
||||
if (StyleSheetChangeEventsEnabled()) {
|
||||
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
|
||||
"StyleRuleAdded",
|
||||
mRule,
|
||||
aStyleRule);
|
||||
if (!StyleSheetChangeEventsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
|
||||
"StyleRuleAdded",
|
||||
mRule,
|
||||
aStyleRule);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::StyleRuleRemoved(StyleSheet* aSheet,
|
||||
css::Rule* aStyleRule)
|
||||
nsDocument::StyleRuleRemoved(StyleSheet* aSheet, css::Rule* aStyleRule)
|
||||
{
|
||||
NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleRemoved, (aSheet, aStyleRule));
|
||||
|
||||
if (StyleSheetChangeEventsEnabled()) {
|
||||
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
|
||||
"StyleRuleRemoved",
|
||||
mRule,
|
||||
aStyleRule);
|
||||
if (!StyleSheetChangeEventsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
|
||||
"StyleRuleRemoved",
|
||||
mRule,
|
||||
aStyleRule);
|
||||
}
|
||||
|
||||
#undef DO_STYLESHEET_NOTIFICATION
|
||||
|
|
|
@ -794,6 +794,10 @@ nsGlobalWindowInner::RequestIdleCallback(JSContext* aCx,
|
|||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (mInnerObjectsFreed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t handle = mIdleRequestCallbackCounter++;
|
||||
|
||||
RefPtr<IdleRequest> request =
|
||||
|
|
|
@ -14,12 +14,6 @@
|
|||
class nsIContent;
|
||||
class nsIDocument;
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
class Rule;
|
||||
} // namespace css
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_IDOCUMENT_OBSERVER_IID \
|
||||
{ 0x71041fa3, 0x6dd7, 0x4cde, \
|
||||
{ 0xbb, 0x76, 0xae, 0xcc, 0x69, 0xe1, 0x75, 0x78 } }
|
||||
|
@ -126,45 +120,6 @@ public:
|
|||
* @param aStyleSheet the StyleSheet that has changed state
|
||||
*/
|
||||
virtual void StyleSheetApplicableStateChanged(mozilla::StyleSheet* aStyleSheet) = 0;
|
||||
|
||||
/**
|
||||
* A StyleRule has just been modified within a style sheet.
|
||||
* This method is called automatically when the rule gets
|
||||
* modified. The style sheet passes this notification to
|
||||
* the document. The notification is passed on to all of
|
||||
* the document observers.
|
||||
*
|
||||
* @param aStyleSheet the StyleSheet that contians the rule
|
||||
* @param aStyleRule the changed rule
|
||||
*/
|
||||
virtual void StyleRuleChanged(mozilla::StyleSheet* aStyleSheet,
|
||||
mozilla::css::Rule* aStyleRule) = 0;
|
||||
|
||||
/**
|
||||
* A StyleRule has just been added to a style sheet.
|
||||
* This method is called automatically when the rule gets
|
||||
* added to the sheet. The style sheet passes this
|
||||
* notification to the document. The notification is passed on
|
||||
* to all of the document observers.
|
||||
*
|
||||
* @param aStyleSheet the StyleSheet that has been modified
|
||||
* @param aStyleRule the added rule
|
||||
*/
|
||||
virtual void StyleRuleAdded(mozilla::StyleSheet* aStyleSheet,
|
||||
mozilla::css::Rule* aStyleRule) = 0;
|
||||
|
||||
/**
|
||||
* A StyleRule has just been removed from a style sheet.
|
||||
* This method is called automatically when the rule gets
|
||||
* removed from the sheet. The style sheet passes this
|
||||
* notification to the document. The notification is passed on
|
||||
* to all of the document observers.
|
||||
*
|
||||
* @param aStyleSheet the StyleSheet that has been modified
|
||||
* @param aStyleRule the removed rule
|
||||
*/
|
||||
virtual void StyleRuleRemoved(mozilla::StyleSheet* aStyleSheet,
|
||||
mozilla::css::Rule* aStyleRule) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
|
||||
|
@ -203,18 +158,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
|
|||
virtual void StyleSheetApplicableStateChanged( \
|
||||
mozilla::StyleSheet* aStyleSheet) override;
|
||||
|
||||
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED \
|
||||
virtual void StyleRuleChanged(mozilla::StyleSheet* aStyleSheet, \
|
||||
mozilla::css::Rule* aStyleRule) override;
|
||||
|
||||
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED \
|
||||
virtual void StyleRuleAdded(mozilla::StyleSheet* aStyleSheet, \
|
||||
mozilla::css::Rule* aStyleRule) override;
|
||||
|
||||
#define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED \
|
||||
virtual void StyleRuleRemoved(mozilla::StyleSheet* aStyleSheet, \
|
||||
mozilla::css::Rule* aStyleRule) override;
|
||||
|
||||
#define NS_DECL_NSIDOCUMENTOBSERVER \
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE \
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE \
|
||||
|
@ -225,9 +168,6 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
|
|||
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED \
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED \
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETAPPLICABLESTATECHANGED \
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED \
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED \
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED \
|
||||
NS_DECL_NSIMUTATIONOBSERVER
|
||||
|
||||
|
||||
|
@ -284,20 +224,5 @@ void \
|
|||
_class::StyleSheetApplicableStateChanged(mozilla::StyleSheet* aStyleSheet)\
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
_class::StyleRuleChanged(mozilla::StyleSheet* aStyleSheet, \
|
||||
mozilla::css::Rule* aStyleRule) \
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
_class::StyleRuleAdded(mozilla::StyleSheet* aStyleSheet, \
|
||||
mozilla::css::Rule* aStyleRule) \
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
_class::StyleRuleRemoved(mozilla::StyleSheet* aStyleSheet, \
|
||||
mozilla::css::Rule* aStyleRule) \
|
||||
{ \
|
||||
}
|
||||
|
||||
#endif /* nsIDocumentObserver_h___ */
|
||||
|
|
|
@ -195,6 +195,8 @@ NavigatorGetUserMediaWarning=navigator.mozGetUserMedia has been replaced by navi
|
|||
RTCPeerConnectionGetStreamsWarning=RTCPeerConnection.getLocalStreams/getRemoteStreams are deprecated. Use RTCPeerConnection.getSenders/getReceivers instead.
|
||||
# LOCALIZATION NOTE: Do not translate "ServiceWorker". %S is a URL.
|
||||
InterceptionFailedWithURL=Failed to load ‘%S’. A ServiceWorker intercepted the request and encountered an unexpected error.
|
||||
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "cors", "Response", "same-origin" or "Request". %1$S is a URL, %2$S is a URL.
|
||||
CorsResponseForSameOriginRequest=Failed to load ‘%1$S’ by responding ‘%2$S’. A ServiceWorker is not allowed to synthesize a cors Response for a same-origin Request.
|
||||
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "FetchEvent.respondWith()", "FetchEvent", "no-cors", "opaque", "Response", or "RequestMode". %1$S is a URL. %2$S is a RequestMode value.
|
||||
BadOpaqueInterceptionRequestModeWithURL=Failed to load ‘%1$S’. A ServiceWorker passed an opaque Response to FetchEvent.respondWith() while handling a ‘%2$S’ FetchEvent. Opaque Response objects are only valid when the RequestMode is ‘no-cors’.
|
||||
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "Error", "Response", "FetchEvent.respondWith()", or "fetch()". %S is a URL.
|
||||
|
|
|
@ -12,8 +12,7 @@ function testURL() {
|
|||
ok(res.type !== "error", "Response should not be an error for " + entry[0]);
|
||||
is(res.status, entry[2], "Status should match expected for " + entry[0]);
|
||||
is(res.statusText, entry[3], "Status text should match expected for " + entry[0]);
|
||||
// This file redirects to pass2, but that is invisible if a SW is present.
|
||||
if (entry[0] != "file_XHR_pass3.txt" || isSWPresent)
|
||||
if (entry[0] != "file_XHR_pass3.txt")
|
||||
ok(res.url.endsWith(path + entry[0]), "Response url should match request for simple fetch for " + entry[0]);
|
||||
else
|
||||
ok(res.url.endsWith(path + "file_XHR_pass2.txt"), "Response url should match request for simple fetch for " + entry[0]);
|
||||
|
@ -49,8 +48,7 @@ function testRequestGET() {
|
|||
ok(res.type !== "error", "Response should not be an error for " + entry[0]);
|
||||
is(res.status, entry[2], "Status should match expected for " + entry[0]);
|
||||
is(res.statusText, entry[3], "Status text should match expected for " + entry[0]);
|
||||
// This file redirects to pass2, but that is invisible if a SW is present.
|
||||
if (entry[0] != "file_XHR_pass3.txt" || isSWPresent)
|
||||
if (entry[0] != "file_XHR_pass3.txt")
|
||||
ok(res.url.endsWith(path + entry[0]), "Response url should match request for simple fetch for " + entry[0]);
|
||||
else
|
||||
ok(res.url.endsWith(path + "file_XHR_pass2.txt"), "Response url should match request for simple fetch for " + entry[0]);
|
||||
|
|
|
@ -342,8 +342,8 @@ public:
|
|||
RefPtr<BodyCopyHandle> copyHandle;
|
||||
copyHandle = new BodyCopyHandle(Move(mClosure));
|
||||
|
||||
rv = mChannel->StartSynthesizedResponse(body, copyHandle,
|
||||
mResponseURLSpec);
|
||||
rv = mChannel->StartSynthesizedResponse(body, copyHandle, mResponseURLSpec,
|
||||
mInternalResponse->IsRedirected());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mChannel->CancelInterception(NS_ERROR_INTERCEPTION_FAILED);
|
||||
return NS_OK;
|
||||
|
@ -658,15 +658,14 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
|||
if (NS_WARN_IF(!ir)) {
|
||||
return;
|
||||
}
|
||||
// When an opaque response is encountered, we need the original channel's principal
|
||||
// to reflect the final URL. Non-opaque responses are either same-origin or CORS-enabled
|
||||
// cross-origin responses, which are treated as same-origin by consumers.
|
||||
nsCString responseURL;
|
||||
if (response->Type() == ResponseType::Opaque) {
|
||||
responseURL = ir->GetUnfilteredURL();
|
||||
if (NS_WARN_IF(responseURL.IsEmpty())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// An extra safety check to make sure our invariant that opaque and cors
|
||||
// responses always have a URL does not break.
|
||||
if (NS_WARN_IF((response->Type() == ResponseType::Opaque ||
|
||||
response->Type() == ResponseType::Cors) &&
|
||||
ir->GetUnfilteredURL().IsEmpty())) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(false, "Cors or opaque Response without a URL");
|
||||
return;
|
||||
}
|
||||
|
||||
Telemetry::ScalarAdd(Telemetry::ScalarID::SW_SYNTHESIZED_RES_COUNT, 1);
|
||||
|
@ -674,6 +673,23 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
|||
if (mRequestMode == RequestMode::Same_origin &&
|
||||
response->Type() == ResponseType::Cors) {
|
||||
Telemetry::ScalarAdd(Telemetry::ScalarID::SW_CORS_RES_FOR_SO_REQ_COUNT, 1);
|
||||
|
||||
// XXXtt: Will have a pref to enable the quirk response in bug 1419684.
|
||||
// The variadic template provided by StringArrayAppender requires exactly
|
||||
// an nsString.
|
||||
NS_ConvertUTF8toUTF16 responseURL(ir->GetUnfilteredURL());
|
||||
autoCancel.SetCancelMessage(
|
||||
NS_LITERAL_CSTRING("CorsResponseForSameOriginRequest"), mRequestURL,
|
||||
responseURL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Propagate the URL to the content if the request mode is not "navigate".
|
||||
// Note that, we only reflect the final URL if the response.redirected is
|
||||
// false. We propagate all the URLs if the response.redirected is true.
|
||||
nsCString responseURL;
|
||||
if (mRequestMode != RequestMode::Navigate) {
|
||||
responseURL = ir->GetUnfilteredURL();
|
||||
}
|
||||
|
||||
UniquePtr<RespondWithClosure> closure(new RespondWithClosure(mInterceptedChannel,
|
||||
|
|
|
@ -22,11 +22,9 @@ async function checkObserverInContent(aInput) {
|
|||
// We always get two channels which receive the "http-on-stop-request"
|
||||
// notification if the service worker hijacks the request and respondWith an
|
||||
// another fetch. One is for the "outer" window request when the other one is
|
||||
// for the "inner" service worker request. We used to distinguish them by the
|
||||
// channel.URI.spec, but it doesn't work fine with internal redirect case. The
|
||||
// reason is that the two different channels will have the same channel.URI
|
||||
// if it's an internal redirect. Therefore, distinguish them by the order.
|
||||
let waitForSecondOnStopRequest = aInput.redirect;
|
||||
// for the "inner" service worker request. Therefore, distinguish them by the
|
||||
// order.
|
||||
let waitForSecondOnStopRequest = aInput.intercepted;
|
||||
|
||||
let promiseResolve;
|
||||
|
||||
|
@ -35,8 +33,7 @@ async function checkObserverInContent(aInput) {
|
|||
// Since we cannot make sure that the network event triggered by the fetch()
|
||||
// in this testcase is the very next event processed by ObserverService, we
|
||||
// have to wait until we catch the one we want.
|
||||
if (!(aInput.redirect && channel.URI.spec.includes(aInput.redirect)) &&
|
||||
!(!aInput.redirect && channel.URI.spec.includes(aInput.url))) {
|
||||
if (!channel.URI.spec.includes(aInput.expectedURL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -197,24 +194,28 @@ add_task(async function test_serivce_worker_interception() {
|
|||
let testcases = [
|
||||
{
|
||||
url: helloDoc,
|
||||
expectedURL: helloDoc,
|
||||
swPresent: false,
|
||||
intercepted: false,
|
||||
fetch: true
|
||||
},
|
||||
{
|
||||
url: fakeDoc,
|
||||
expectedURL: helloDoc,
|
||||
swPresent: true,
|
||||
intercepted: true,
|
||||
fetch: false // should use HTTP cache
|
||||
},
|
||||
{ // Bypass http cache
|
||||
url: helloDoc + "?ForBypassingHttpCache=" + Date.now(),
|
||||
expectedURL: helloDoc,
|
||||
swPresent: true,
|
||||
intercepted: false,
|
||||
fetch: true
|
||||
},
|
||||
{ // no-cors mode redirect to no-cors mode (trigger internal redirect)
|
||||
url: crossRedirect + "?url=" + crossHelloDoc + "&mode=no-cors",
|
||||
expectedURL: crossHelloDoc,
|
||||
swPresent: true,
|
||||
redirect: "hello.html",
|
||||
intercepted: true,
|
||||
|
|
|
@ -140,7 +140,8 @@
|
|||
xmlDoc.load('load_cross_origin_xml_document_cors.xml');
|
||||
xmlDoc.onload = function(evt) {
|
||||
var content = new XMLSerializer().serializeToString(evt.target);
|
||||
my_ok(!content.includes('parsererror'), "Load CORS cross origin XML Document should be allowed");
|
||||
// issue: https://github.com/whatwg/fetch/issues/629
|
||||
my_ok(content.includes('parsererror'), "Load CORS cross origin XML Document should not be allowed");
|
||||
finish();
|
||||
};
|
||||
|
||||
|
|
|
@ -505,6 +505,7 @@ ContentClient::CalculateBufferForPaint(PaintedLayer* aLayer,
|
|||
canReuseBuffer = false;
|
||||
canKeepBufferContents = false;
|
||||
validRegion.SetEmpty();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ class ThebesBufferData;
|
|||
class TiledContentHost;
|
||||
class CompositableParentManager;
|
||||
class WebRenderImageHost;
|
||||
class ContentHost;
|
||||
class ContentHostTexture;
|
||||
struct EffectChain;
|
||||
|
||||
|
@ -149,6 +150,7 @@ public:
|
|||
Layer* GetLayer() const { return mLayer; }
|
||||
void SetLayer(Layer* aLayer) { mLayer = aLayer; }
|
||||
|
||||
virtual ContentHost* AsContentHost() { return nullptr; }
|
||||
virtual ContentHostTexture* AsContentHostTexture() { return nullptr; }
|
||||
virtual ImageHost* AsImageHost() { return nullptr; }
|
||||
virtual TiledContentHost* AsTiledContentHost() { return nullptr; }
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
MOZ_ASSERT_UNREACHABLE("Must be implemented in derived class");
|
||||
return gfx::IntRect();
|
||||
}
|
||||
virtual ContentHost* AsContentHost() { return this; }
|
||||
|
||||
protected:
|
||||
explicit ContentHost(const TextureInfo& aTextureInfo)
|
||||
|
|
|
@ -48,6 +48,26 @@ TileHost::GetFadeInOpacity(float aOpacity)
|
|||
return aOpacity * (elapsed / duration);
|
||||
}
|
||||
|
||||
RefPtr<TextureSource>
|
||||
TileHost::AcquireTextureSource() const
|
||||
{
|
||||
if (!mTextureHost || !mTextureHost->AcquireTextureSource(mTextureSource)) {
|
||||
return nullptr;
|
||||
}
|
||||
return mTextureSource.get();
|
||||
}
|
||||
|
||||
RefPtr<TextureSource>
|
||||
TileHost::AcquireTextureSourceOnWhite() const
|
||||
{
|
||||
if (!mTextureHostOnWhite ||
|
||||
!mTextureHostOnWhite->AcquireTextureSource(mTextureSourceOnWhite))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return mTextureSourceOnWhite.get();
|
||||
}
|
||||
|
||||
TiledLayerBufferComposite::TiledLayerBufferComposite()
|
||||
: mFrameResolution()
|
||||
{}
|
||||
|
@ -161,15 +181,15 @@ void
|
|||
UseTileTexture(CompositableTextureHostRef& aTexture,
|
||||
CompositableTextureSourceRef& aTextureSource,
|
||||
const IntRect& aUpdateRect,
|
||||
Compositor* aCompositor)
|
||||
TextureSourceProvider* aProvider)
|
||||
{
|
||||
MOZ_ASSERT(aTexture);
|
||||
if (!aTexture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aCompositor) {
|
||||
aTexture->SetTextureSourceProvider(aCompositor);
|
||||
if (aProvider) {
|
||||
aTexture->SetTextureSourceProvider(aProvider);
|
||||
}
|
||||
|
||||
if (!aUpdateRect.IsEmpty()) {
|
||||
|
@ -358,13 +378,13 @@ TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles,
|
|||
UseTileTexture(tile.mTextureHost,
|
||||
tile.mTextureSource,
|
||||
texturedDesc.updateRect(),
|
||||
aLayerManager->GetCompositor());
|
||||
aLayerManager->GetTextureSourceProvider());
|
||||
|
||||
if (tile.mTextureHostOnWhite) {
|
||||
UseTileTexture(tile.mTextureHostOnWhite,
|
||||
tile.mTextureSourceOnWhite,
|
||||
texturedDesc.updateRect(),
|
||||
aLayerManager->GetCompositor());
|
||||
aLayerManager->GetTextureSourceProvider());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,6 +99,9 @@ public:
|
|||
CompositableHost::DumpTextureHost(aStream, mTextureHost);
|
||||
}
|
||||
|
||||
RefPtr<TextureSource> AcquireTextureSource() const;
|
||||
RefPtr<TextureSource> AcquireTextureSourceOnWhite() const;
|
||||
|
||||
/**
|
||||
* This does a linear tween of the passed opacity (which is assumed
|
||||
* to be between 0.0 and 1.0). The duration of the fade is controlled
|
||||
|
@ -234,6 +237,13 @@ public:
|
|||
|
||||
virtual void AddAnimationInvalidation(nsIntRegion& aRegion) override;
|
||||
|
||||
TiledLayerBufferComposite& GetLowResBuffer() {
|
||||
return mLowPrecisionTiledBuffer;
|
||||
}
|
||||
TiledLayerBufferComposite& GetHighResBuffer() {
|
||||
return mTiledBuffer;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,
|
||||
|
|
|
@ -11,8 +11,10 @@
|
|||
#include "gfxConfig.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "LayersLogging.h"
|
||||
#include "ShaderDefinitionsMLGPU.h"
|
||||
#include "SharedBufferMLGPU.h"
|
||||
#include "UtilityMLGPU.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "PaintedLayerMLGPU.h"
|
||||
#include "LayerManagerMLGPU.h"
|
||||
#include "mozilla/layers/LayersHelpers.h"
|
||||
#include "mozilla/layers/TiledContentHost.h"
|
||||
#include "UnitTransforms.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -32,16 +33,11 @@ PaintedLayerMLGPU::~PaintedLayerMLGPU()
|
|||
bool
|
||||
PaintedLayerMLGPU::OnPrepareToRender(FrameBuilder* aBuilder)
|
||||
{
|
||||
if (!mHost) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mTexture = mHost->AcquireTextureSource();
|
||||
if (!mTexture) {
|
||||
return false;
|
||||
}
|
||||
mTextureOnWhite = mHost->AcquireTextureSourceOnWhite();
|
||||
return true;
|
||||
// Reset our cached texture pointers. The next call to AssignToView will
|
||||
// populate them again.
|
||||
mTexture = nullptr;
|
||||
mTextureOnWhite = nullptr;
|
||||
return !!mHost;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -77,9 +73,10 @@ bool
|
|||
PaintedLayerMLGPU::SetCompositableHost(CompositableHost* aHost)
|
||||
{
|
||||
switch (aHost->GetType()) {
|
||||
case CompositableType::CONTENT_TILED:
|
||||
case CompositableType::CONTENT_SINGLE:
|
||||
case CompositableType::CONTENT_DOUBLE:
|
||||
mHost = static_cast<ContentHostBase*>(aHost)->AsContentHostTexture();
|
||||
mHost = aHost->AsContentHost();
|
||||
if (!mHost) {
|
||||
gfxWarning() << "ContentHostBase is not a ContentHostTexture";
|
||||
}
|
||||
|
@ -95,6 +92,123 @@ PaintedLayerMLGPU::GetCompositableHost()
|
|||
return mHost;
|
||||
}
|
||||
|
||||
gfx::Point
|
||||
PaintedLayerMLGPU::GetDestOrigin() const
|
||||
{
|
||||
return mDestOrigin;
|
||||
}
|
||||
|
||||
void
|
||||
PaintedLayerMLGPU::AssignToView(FrameBuilder* aBuilder,
|
||||
RenderViewMLGPU* aView,
|
||||
Maybe<Polygon>&& aGeometry)
|
||||
{
|
||||
if (TiledContentHost* tiles = mHost->AsTiledContentHost()) {
|
||||
// Note: we do not support the low-res buffer yet.
|
||||
MOZ_ASSERT(tiles->GetLowResBuffer().GetTileCount() == 0);
|
||||
AssignHighResTilesToView(aBuilder, aView, tiles, aGeometry);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't have a texture yet, acquire one from the ContentHost now.
|
||||
if (!mTexture) {
|
||||
ContentHostTexture* single = mHost->AsContentHostTexture();
|
||||
if (!single) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTexture = single->AcquireTextureSource();
|
||||
if (!mTexture) {
|
||||
return;
|
||||
}
|
||||
mTextureOnWhite = single->AcquireTextureSourceOnWhite();
|
||||
mDestOrigin = single->GetOriginOffset();
|
||||
}
|
||||
|
||||
// Fall through to the single texture case.
|
||||
LayerMLGPU::AssignToView(aBuilder, aView, Move(aGeometry));
|
||||
}
|
||||
|
||||
void
|
||||
PaintedLayerMLGPU::AssignHighResTilesToView(FrameBuilder* aBuilder,
|
||||
RenderViewMLGPU* aView,
|
||||
TiledContentHost* aTileHost,
|
||||
const Maybe<Polygon>& aGeometry)
|
||||
{
|
||||
TiledLayerBufferComposite& tiles = aTileHost->GetHighResBuffer();
|
||||
|
||||
LayerIntRegion compositeRegion = ViewAs<LayerPixel>(tiles.GetValidRegion());
|
||||
compositeRegion.AndWith(GetShadowVisibleRegion());
|
||||
if (compositeRegion.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AssignTileBufferToView(aBuilder, aView, tiles, compositeRegion, aGeometry);
|
||||
}
|
||||
|
||||
void
|
||||
PaintedLayerMLGPU::AssignTileBufferToView(FrameBuilder* aBuilder,
|
||||
RenderViewMLGPU* aView,
|
||||
TiledLayerBufferComposite& aTiles,
|
||||
const LayerIntRegion& aCompositeRegion,
|
||||
const Maybe<Polygon>& aGeometry)
|
||||
{
|
||||
float resolution = aTiles.GetResolution();
|
||||
|
||||
// Save these so they can be restored at the end.
|
||||
float baseOpacity = mComputedOpacity;
|
||||
LayerIntRegion visible = GetShadowVisibleRegion();
|
||||
|
||||
for (size_t i = 0; i < aTiles.GetTileCount(); i++) {
|
||||
TileHost& tile = aTiles.GetTile(i);
|
||||
if (tile.IsPlaceholderTile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TileIntPoint pos = aTiles.GetPlacement().TilePosition(i);
|
||||
// A sanity check that catches a lot of mistakes.
|
||||
MOZ_ASSERT(pos.x == tile.mTilePosition.x && pos.y == tile.mTilePosition.y);
|
||||
|
||||
IntPoint offset = aTiles.GetTileOffset(pos);
|
||||
|
||||
// Use LayerIntRect here so we don't have to keep re-allocating the region
|
||||
// to change the unit type.
|
||||
LayerIntRect tileRect(ViewAs<LayerPixel>(offset),
|
||||
ViewAs<LayerPixel>(aTiles.GetScaledTileSize()));
|
||||
LayerIntRegion tileDrawRegion = tileRect;
|
||||
tileDrawRegion.AndWith(aCompositeRegion);
|
||||
if (tileDrawRegion.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
tileDrawRegion.ScaleRoundOut(resolution, resolution);
|
||||
|
||||
// Update layer state for this tile - that includes the texture, visible
|
||||
// region, and opacity.
|
||||
mTexture = tile.AcquireTextureSource();
|
||||
if (!mTexture) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mTextureOnWhite = tile.AcquireTextureSourceOnWhite();
|
||||
|
||||
SetShadowVisibleRegion(tileDrawRegion);
|
||||
mComputedOpacity = tile.GetFadeInOpacity(baseOpacity);
|
||||
mDestOrigin = offset;
|
||||
|
||||
// Yes, it's a bit weird that we're assigning the same layer to the same
|
||||
// view multiple times. Note that each time, the texture, computed
|
||||
// opacity, origin, and visible region are updated to match the current
|
||||
// tile, and we restore these properties after we've finished processing
|
||||
// all tiles.
|
||||
Maybe<Polygon> geometry = aGeometry;
|
||||
LayerMLGPU::AssignToView(aBuilder, aView, Move(geometry));
|
||||
}
|
||||
|
||||
// Restore the computed opacity and visible region.
|
||||
mComputedOpacity = baseOpacity;
|
||||
SetShadowVisibleRegion(Move(visible));
|
||||
}
|
||||
|
||||
void
|
||||
PaintedLayerMLGPU::CleanupResources()
|
||||
{
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class TiledLayerBufferComposite;
|
||||
|
||||
class PaintedLayerMLGPU final
|
||||
: public PaintedLayer,
|
||||
public LayerMLGPU
|
||||
|
@ -48,9 +50,8 @@ public:
|
|||
MOZ_ASSERT(HasComponentAlpha());
|
||||
return mTextureOnWhite;
|
||||
}
|
||||
ContentHostTexture* GetContentHost() const {
|
||||
return mHost;
|
||||
}
|
||||
gfx::Point GetDestOrigin() const;
|
||||
|
||||
SamplerMode GetSamplerMode() {
|
||||
// Note that when resamping, we must break the texture coordinates into
|
||||
// no-repeat rects. When we have simple integer translations we can
|
||||
|
@ -75,15 +76,33 @@ protected:
|
|||
void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
|
||||
bool OnPrepareToRender(FrameBuilder* aBuilder) override;
|
||||
|
||||
// We override this to support tiling.
|
||||
void AssignToView(FrameBuilder* aBuilder,
|
||||
RenderViewMLGPU* aView,
|
||||
Maybe<gfx::Polygon>&& aGeometry) override;
|
||||
|
||||
void AssignHighResTilesToView(FrameBuilder* aBuilder,
|
||||
RenderViewMLGPU* aView,
|
||||
TiledContentHost* aTileHost,
|
||||
const Maybe<gfx::Polygon>& aGeometry);
|
||||
|
||||
// Helper for Assign*TilesToView.
|
||||
void AssignTileBufferToView(FrameBuilder* aBuilder,
|
||||
RenderViewMLGPU* aView,
|
||||
TiledLayerBufferComposite& aTiles,
|
||||
const LayerIntRegion& aCompositeRegion,
|
||||
const Maybe<gfx::Polygon>& aGeometry);
|
||||
|
||||
void CleanupResources();
|
||||
|
||||
private:
|
||||
RefPtr<ContentHostTexture> mHost;
|
||||
RefPtr<ContentHost> mHost;
|
||||
RefPtr<TextureSource> mTexture;
|
||||
RefPtr<TextureSource> mTextureOnWhite;
|
||||
#ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE
|
||||
LayerIntRegion mDrawRects;
|
||||
#endif
|
||||
gfx::IntPoint mDestOrigin;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -457,7 +457,7 @@ TexturedRenderPass::TexturedRenderPass(FrameBuilder* aBuilder, const ItemInfo& a
|
|||
TexturedRenderPass::Info::Info(const ItemInfo& aItem, PaintedLayerMLGPU* aLayer)
|
||||
: item(aItem),
|
||||
textureSize(aLayer->GetTexture()->GetSize()),
|
||||
destOrigin(aLayer->GetContentHost()->GetOriginOffset()),
|
||||
destOrigin(aLayer->GetDestOrigin()),
|
||||
decomposeIntoNoRepeatRects(aLayer->MayResample())
|
||||
{
|
||||
}
|
||||
|
@ -676,8 +676,8 @@ SingleTexturePass::SetupPipeline()
|
|||
}
|
||||
|
||||
ComponentAlphaPass::ComponentAlphaPass(FrameBuilder* aBuilder, const ItemInfo& aItem)
|
||||
: TexturedRenderPass(aBuilder, aItem),
|
||||
mAssignedLayer(nullptr)
|
||||
: TexturedRenderPass(aBuilder, aItem),
|
||||
mOpacity(1.0f)
|
||||
{
|
||||
SetDefaultGeometry(aItem);
|
||||
}
|
||||
|
@ -688,11 +688,17 @@ ComponentAlphaPass::AddToPass(LayerMLGPU* aLayer, ItemInfo& aItem)
|
|||
PaintedLayerMLGPU* layer = aLayer->AsPaintedLayerMLGPU();
|
||||
MOZ_ASSERT(layer);
|
||||
|
||||
if (mAssignedLayer && mAssignedLayer != layer) {
|
||||
return false;
|
||||
}
|
||||
if (!mAssignedLayer) {
|
||||
mAssignedLayer = layer;
|
||||
if (mTextureOnBlack) {
|
||||
if (layer->GetTexture() != mTextureOnBlack ||
|
||||
layer->GetTextureOnWhite() != mTextureOnWhite ||
|
||||
layer->GetOpacity() != mOpacity ||
|
||||
layer->GetSamplerMode() != mSamplerMode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
mOpacity = layer->GetComputedOpacity();
|
||||
mSamplerMode = layer->GetSamplerMode();
|
||||
mTextureOnBlack = layer->GetTexture();
|
||||
mTextureOnWhite = layer->GetTextureOnWhite();
|
||||
}
|
||||
|
@ -709,7 +715,7 @@ ComponentAlphaPass::AddToPass(LayerMLGPU* aLayer, ItemInfo& aItem)
|
|||
float
|
||||
ComponentAlphaPass::GetOpacity() const
|
||||
{
|
||||
return mAssignedLayer->GetComputedOpacity();
|
||||
return mOpacity;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -730,7 +736,7 @@ ComponentAlphaPass::SetupPipeline()
|
|||
mDevice->SetPixelShader(PixelShaderID::ComponentAlphaVertex);
|
||||
}
|
||||
|
||||
mDevice->SetSamplerMode(kDefaultSamplerSlot, mAssignedLayer->GetSamplerMode());
|
||||
mDevice->SetSamplerMode(kDefaultSamplerSlot, mSamplerMode);
|
||||
mDevice->SetPSTextures(0, 2, textures);
|
||||
}
|
||||
|
||||
|
|
|
@ -424,7 +424,8 @@ private:
|
|||
}
|
||||
|
||||
private:
|
||||
PaintedLayerMLGPU* mAssignedLayer;
|
||||
float mOpacity;
|
||||
SamplerMode mSamplerMode;
|
||||
RefPtr<TextureSource> mTextureOnBlack;
|
||||
RefPtr<TextureSource> mTextureOnWhite;
|
||||
};
|
||||
|
|
|
@ -398,6 +398,7 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
|
|||
aLoadInfo->GetForcePreflight(),
|
||||
aLoadInfo->GetIsPreflight(),
|
||||
aLoadInfo->GetLoadTriggeredFromExternal(),
|
||||
aLoadInfo->GetServiceWorkerTaintingSynthesized(),
|
||||
aLoadInfo->GetForceHSTSPriming(),
|
||||
aLoadInfo->GetMixedContentWouldBlock(),
|
||||
aLoadInfo->GetIsHSTSPriming(),
|
||||
|
@ -507,6 +508,7 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs,
|
|||
loadInfoArgs.forcePreflight(),
|
||||
loadInfoArgs.isPreflight(),
|
||||
loadInfoArgs.loadTriggeredFromExternal(),
|
||||
loadInfoArgs.serviceWorkerTaintingSynthesized(),
|
||||
loadInfoArgs.forceHSTSPriming(),
|
||||
loadInfoArgs.mixedContentWouldBlock(),
|
||||
loadInfoArgs.isHSTSPriming(),
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "frontend/NameFunctions.h"
|
||||
|
||||
#include "mozilla/MemoryChecking.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
||||
#include "jsfun.h"
|
||||
|
@ -350,7 +351,7 @@ class NameResolver
|
|||
* ParseNode instance given. The prefix is for each subsequent name, and
|
||||
* should initially be nullptr.
|
||||
*/
|
||||
bool resolve(ParseNode* cur, HandleAtom prefixArg = nullptr) {
|
||||
bool resolve(ParseNode* const cur, HandleAtom prefixArg = nullptr) {
|
||||
RootedAtom prefix(cx, prefixArg);
|
||||
if (cur == nullptr)
|
||||
return true;
|
||||
|
@ -370,9 +371,13 @@ class NameResolver
|
|||
if (!isDirectCall(nparents - 1, cur))
|
||||
prefix = prefix2;
|
||||
}
|
||||
|
||||
if (nparents >= MaxParents)
|
||||
return true;
|
||||
parents[nparents++] = cur;
|
||||
|
||||
auto initialParents = nparents;
|
||||
parents[initialParents] = cur;
|
||||
nparents++;
|
||||
|
||||
switch (cur->getKind()) {
|
||||
// Nodes with no children that might require name resolution need no
|
||||
|
@ -815,6 +820,18 @@ class NameResolver
|
|||
}
|
||||
|
||||
nparents--;
|
||||
MOZ_ASSERT(initialParents == nparents, "nparents imbalance detected");
|
||||
|
||||
// It would be nice to common up the repeated |parents[initialParents]|
|
||||
// in a single variable, but the #if condition required to prevent an
|
||||
// unused-variable warning across three separate conditionally-expanded
|
||||
// macros would be super-ugly. :-(
|
||||
MOZ_ASSERT(parents[initialParents] == cur,
|
||||
"pushed child shouldn't change underneath us");
|
||||
|
||||
JS_POISON(&parents[initialParents], 0xFF, sizeof(parents[initialParents]));
|
||||
MOZ_MAKE_MEM_UNDEFINED(&parents[initialParents], sizeof(parents[initialParents]));
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4653,24 +4653,6 @@ PresShell::StyleSheetApplicableStateChanged(StyleSheet* aStyleSheet)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::StyleRuleChanged(StyleSheet* aStyleSheet, css::Rule* aStyleRule)
|
||||
{
|
||||
RecordStyleSheetChange(aStyleSheet, StyleSheet::ChangeType::RuleChanged);
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::StyleRuleAdded(StyleSheet* aStyleSheet, css::Rule* aStyleRule)
|
||||
{
|
||||
RecordStyleSheetChange(aStyleSheet, StyleSheet::ChangeType::RuleAdded);
|
||||
}
|
||||
|
||||
void
|
||||
PresShell::StyleRuleRemoved(StyleSheet* aStyleSheet, css::Rule* aStyleRule)
|
||||
{
|
||||
RecordStyleSheetChange(aStyleSheet, StyleSheet::ChangeType::RuleRemoved);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresShell::RenderDocument(const nsRect& aRect, uint32_t aFlags,
|
||||
nscolor aBackgroundColor,
|
||||
|
|
|
@ -299,9 +299,6 @@ public:
|
|||
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETAPPLICABLESTATECHANGED
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED
|
||||
NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED
|
||||
|
||||
// nsIMutationObserver
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
|
||||
|
|
|
@ -27,8 +27,6 @@ ServoStyleRuleMap::~ServoStyleRuleMap()
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ServoStyleRuleMap, nsIDocumentObserver, nsICSSLoaderObserver)
|
||||
|
||||
void
|
||||
ServoStyleRuleMap::EnsureTable()
|
||||
{
|
||||
|
@ -38,23 +36,21 @@ ServoStyleRuleMap::EnsureTable()
|
|||
mStyleSet->EnumerateStyleSheetArrays(
|
||||
[this](const nsTArray<RefPtr<ServoStyleSheet>>& aArray) {
|
||||
for (auto& sheet : aArray) {
|
||||
FillTableFromStyleSheet(sheet);
|
||||
FillTableFromStyleSheet(*sheet);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleRuleMap::StyleSheetAdded(StyleSheet* aStyleSheet,
|
||||
bool aDocumentSheet)
|
||||
ServoStyleRuleMap::SheetAdded(ServoStyleSheet& aStyleSheet)
|
||||
{
|
||||
if (!IsEmpty()) {
|
||||
FillTableFromStyleSheet(aStyleSheet->AsServo());
|
||||
FillTableFromStyleSheet(aStyleSheet);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleRuleMap::StyleSheetRemoved(StyleSheet* aStyleSheet,
|
||||
bool aDocumentSheet)
|
||||
ServoStyleRuleMap::SheetRemoved(ServoStyleSheet& aStyleSheet)
|
||||
{
|
||||
// Invalidate all data inside. This isn't strictly necessary since
|
||||
// we should always get update from document before new queries come.
|
||||
|
@ -66,18 +62,7 @@ ServoStyleRuleMap::StyleSheetRemoved(StyleSheet* aStyleSheet,
|
|||
}
|
||||
|
||||
void
|
||||
ServoStyleRuleMap::StyleSheetApplicableStateChanged(StyleSheet* aStyleSheet)
|
||||
{
|
||||
// We don't care if the stylesheet is disabled. Not removing no longer
|
||||
// applicable stylesheets wouldn't make anything wrong.
|
||||
if (!IsEmpty() && aStyleSheet->IsApplicable()) {
|
||||
FillTableFromStyleSheet(aStyleSheet->AsServo());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleRuleMap::StyleRuleAdded(StyleSheet* aStyleSheet,
|
||||
css::Rule* aStyleRule)
|
||||
ServoStyleRuleMap::RuleAdded(ServoStyleSheet& aStyleSheet, css::Rule& aStyleRule)
|
||||
{
|
||||
if (!IsEmpty()) {
|
||||
FillTableFromRule(aStyleRule);
|
||||
|
@ -85,17 +70,17 @@ ServoStyleRuleMap::StyleRuleAdded(StyleSheet* aStyleSheet,
|
|||
}
|
||||
|
||||
void
|
||||
ServoStyleRuleMap::StyleRuleRemoved(StyleSheet* aStyleSheet,
|
||||
css::Rule* aStyleRule)
|
||||
ServoStyleRuleMap::RuleRemoved(ServoStyleSheet& aStyleSheet,
|
||||
css::Rule& aStyleRule)
|
||||
{
|
||||
if (IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (aStyleRule->Type()) {
|
||||
switch (aStyleRule.Type()) {
|
||||
case nsIDOMCSSRule::STYLE_RULE: {
|
||||
auto rule = static_cast<ServoStyleRule*>(aStyleRule);
|
||||
mTable.Remove(rule->Raw());
|
||||
auto& rule = static_cast<ServoStyleRule&>(aStyleRule);
|
||||
mTable.Remove(rule.Raw());
|
||||
break;
|
||||
}
|
||||
case nsIDOMCSSRule::IMPORT_RULE:
|
||||
|
@ -119,18 +104,6 @@ ServoStyleRuleMap::StyleRuleRemoved(StyleSheet* aStyleSheet,
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServoStyleRuleMap::StyleSheetLoaded(StyleSheet* aSheet,
|
||||
bool aWasAlternate,
|
||||
nsresult aStatus)
|
||||
{
|
||||
MOZ_ASSERT(aSheet->IsServo());
|
||||
if (!IsEmpty()) {
|
||||
FillTableFromStyleSheet(aSheet->AsServo());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
size_t
|
||||
ServoStyleRuleMap::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
|
@ -140,43 +113,44 @@ ServoStyleRuleMap::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
|||
}
|
||||
|
||||
void
|
||||
ServoStyleRuleMap::FillTableFromRule(css::Rule* aRule)
|
||||
ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule)
|
||||
{
|
||||
switch (aRule->Type()) {
|
||||
switch (aRule.Type()) {
|
||||
case nsIDOMCSSRule::STYLE_RULE: {
|
||||
auto rule = static_cast<ServoStyleRule*>(aRule);
|
||||
mTable.Put(rule->Raw(), rule);
|
||||
auto& rule = static_cast<ServoStyleRule&>(aRule);
|
||||
mTable.Put(rule.Raw(), &rule);
|
||||
break;
|
||||
}
|
||||
case nsIDOMCSSRule::MEDIA_RULE:
|
||||
case nsIDOMCSSRule::SUPPORTS_RULE:
|
||||
case nsIDOMCSSRule::DOCUMENT_RULE: {
|
||||
auto rule = static_cast<css::GroupRule*>(aRule);
|
||||
auto ruleList = static_cast<ServoCSSRuleList*>(rule->CssRules());
|
||||
FillTableFromRuleList(ruleList);
|
||||
auto& rule = static_cast<css::GroupRule&>(aRule);
|
||||
auto ruleList = static_cast<ServoCSSRuleList*>(rule.CssRules());
|
||||
FillTableFromRuleList(*ruleList);
|
||||
break;
|
||||
}
|
||||
case nsIDOMCSSRule::IMPORT_RULE: {
|
||||
auto rule = static_cast<ServoImportRule*>(aRule);
|
||||
FillTableFromStyleSheet(rule->GetStyleSheet()->AsServo());
|
||||
auto& rule = static_cast<ServoImportRule&>(aRule);
|
||||
MOZ_ASSERT(aRule.GetStyleSheet());
|
||||
FillTableFromStyleSheet(*rule.GetStyleSheet()->AsServo());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleRuleMap::FillTableFromRuleList(ServoCSSRuleList* aRuleList)
|
||||
ServoStyleRuleMap::FillTableFromRuleList(ServoCSSRuleList& aRuleList)
|
||||
{
|
||||
for (uint32_t i : IntegerRange(aRuleList->Length())) {
|
||||
FillTableFromRule(aRuleList->GetRule(i));
|
||||
for (uint32_t i : IntegerRange(aRuleList.Length())) {
|
||||
FillTableFromRule(*aRuleList.GetRule(i));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleRuleMap::FillTableFromStyleSheet(ServoStyleSheet* aSheet)
|
||||
ServoStyleRuleMap::FillTableFromStyleSheet(ServoStyleSheet& aSheet)
|
||||
{
|
||||
if (aSheet->IsComplete()) {
|
||||
FillTableFromRuleList(aSheet->GetCssRulesInternal());
|
||||
if (aSheet.IsComplete()) {
|
||||
FillTableFromRuleList(*aSheet.GetCssRulesInternal());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include "mozilla/ServoStyleRule.h"
|
||||
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsICSSLoaderObserver.h"
|
||||
#include "nsStubDocumentObserver.h"
|
||||
|
||||
struct RawServoStyleRule;
|
||||
|
||||
|
@ -22,12 +20,9 @@ namespace css {
|
|||
class Rule;
|
||||
} // namespace css
|
||||
|
||||
class ServoStyleRuleMap final : public nsStubDocumentObserver
|
||||
, public nsICSSLoaderObserver
|
||||
class ServoStyleRuleMap
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit ServoStyleRuleMap(ServoStyleSet* aStyleSet);
|
||||
|
||||
void EnsureTable();
|
||||
|
@ -35,30 +30,25 @@ public:
|
|||
return mTable.Get(aRawRule);
|
||||
}
|
||||
|
||||
// nsIDocumentObserver methods
|
||||
void StyleSheetAdded(StyleSheet* aStyleSheet, bool aDocumentSheet) final;
|
||||
void StyleSheetRemoved(StyleSheet* aStyleSheet, bool aDocumentSheet) final;
|
||||
void StyleSheetApplicableStateChanged(StyleSheet* aStyleSheet) final;
|
||||
void StyleRuleAdded(StyleSheet* aStyleSheet, css::Rule* aStyleRule) final;
|
||||
void StyleRuleRemoved(StyleSheet* aStyleSheet, css::Rule* aStyleRule) final;
|
||||
void SheetAdded(ServoStyleSheet& aStyleSheet);
|
||||
void SheetRemoved(ServoStyleSheet& aStyleSheet);
|
||||
|
||||
// nsICSSLoaderObserver
|
||||
NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet,
|
||||
bool aWasAlternate, nsresult aStatus) final;
|
||||
void RuleAdded(ServoStyleSheet& aStyleSheet, css::Rule&);
|
||||
void RuleRemoved(ServoStyleSheet& aStyleSheet, css::Rule& aStyleRule);
|
||||
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
private:
|
||||
~ServoStyleRuleMap();
|
||||
|
||||
private:
|
||||
// Since we would never have a document which contains no style rule,
|
||||
// we use IsEmpty as an indication whether we need to walk through
|
||||
// all stylesheets to fill the table.
|
||||
bool IsEmpty() const { return mTable.Count() == 0; }
|
||||
|
||||
void FillTableFromRule(css::Rule* aRule);
|
||||
void FillTableFromRuleList(ServoCSSRuleList* aRuleList);
|
||||
void FillTableFromStyleSheet(ServoStyleSheet* aSheet);
|
||||
void FillTableFromRule(css::Rule& aRule);
|
||||
void FillTableFromRuleList(ServoCSSRuleList& aRuleList);
|
||||
void FillTableFromStyleSheet(ServoStyleSheet& aSheet);
|
||||
|
||||
typedef nsDataHashtable<nsPtrHashKey<const RawServoStyleRule>,
|
||||
WeakPtr<ServoStyleRule>> Hashtable;
|
||||
|
|
|
@ -766,9 +766,8 @@ CSSStyleSheet::InsertRuleInternal(const nsAString& aRule,
|
|||
|
||||
// We don't notify immediately for @import rules, but rather when
|
||||
// the sheet the rule is importing is loaded (see StyleSheetLoaded)
|
||||
if ((type != css::Rule::IMPORT_RULE || !RuleHasPendingChildSheet(rule)) &&
|
||||
mDocument) {
|
||||
mDocument->StyleRuleAdded(this, rule);
|
||||
if (type != css::Rule::IMPORT_RULE || !RuleHasPendingChildSheet(rule)) {
|
||||
RuleAdded(*rule);
|
||||
}
|
||||
|
||||
return aIndex;
|
||||
|
@ -795,11 +794,7 @@ CSSStyleSheet::DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv)
|
|||
if (rule) {
|
||||
Inner()->mOrderedRules.RemoveObjectAt(aIndex);
|
||||
rule->SetStyleSheet(nullptr);
|
||||
DidDirty();
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->StyleRuleRemoved(this, rule);
|
||||
}
|
||||
RuleRemoved(*rule);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -865,12 +860,9 @@ CSSStyleSheet::StyleSheetLoaded(StyleSheet* aSheet,
|
|||
NS_ASSERTION(this == sheet->GetParentSheet(),
|
||||
"We are being notified of a sheet load for a sheet that is not our child!");
|
||||
|
||||
if (mDocument && NS_SUCCEEDED(aStatus)) {
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
|
||||
|
||||
// XXXldb @import rules shouldn't even implement nsIStyleRule (but
|
||||
// they do)!
|
||||
mDocument->StyleRuleAdded(this, sheet->GetOwnerRule());
|
||||
RuleAdded(*sheet->GetOwnerRule());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -917,9 +909,7 @@ CSSStyleSheet::ReparseSheet(const nsAString& aInput)
|
|||
reusableSheets.AddReusableSheet(cssSheet);
|
||||
}
|
||||
}
|
||||
if (mDocument) {
|
||||
mDocument->StyleRuleRemoved(this, rule);
|
||||
}
|
||||
RuleRemoved(*rule);
|
||||
}
|
||||
|
||||
// nuke child sheets list and current namespace map
|
||||
|
@ -949,15 +939,13 @@ CSSStyleSheet::ReparseSheet(const nsAString& aInput)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// notify document of all new rules
|
||||
if (mDocument) {
|
||||
for (int32_t index = 0; index < Inner()->mOrderedRules.Count(); ++index) {
|
||||
RefPtr<css::Rule> rule = Inner()->mOrderedRules.ObjectAt(index);
|
||||
if (rule->GetType() == css::Rule::IMPORT_RULE &&
|
||||
RuleHasPendingChildSheet(rule)) {
|
||||
continue; // notify when loaded (see StyleSheetLoaded)
|
||||
}
|
||||
mDocument->StyleRuleAdded(this, rule);
|
||||
for (int32_t index = 0; index < Inner()->mOrderedRules.Count(); ++index) {
|
||||
RefPtr<css::Rule> rule = Inner()->mOrderedRules.ObjectAt(index);
|
||||
if (rule->GetType() == css::Rule::IMPORT_RULE &&
|
||||
RuleHasPendingChildSheet(rule)) {
|
||||
continue; // notify when loaded (see StyleSheetLoaded)
|
||||
}
|
||||
RuleAdded(*rule);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -120,12 +120,6 @@ public:
|
|||
nsIDocument* aCloneDocument,
|
||||
nsINode* aCloneOwningNode) const final;
|
||||
|
||||
void SetModifiedByChildRule() {
|
||||
NS_ASSERTION(mDirty,
|
||||
"sheet must be marked dirty before handing out child rules");
|
||||
DidDirty();
|
||||
}
|
||||
|
||||
nsresult AddRuleProcessor(nsCSSRuleProcessor* aProcessor);
|
||||
nsresult DropRuleProcessor(nsCSSRuleProcessor* aProcessor);
|
||||
|
||||
|
|
|
@ -304,7 +304,7 @@ GroupRule::AppendStyleRule(Rule* aRule)
|
|||
aRule->SetStyleSheet(sheet);
|
||||
aRule->SetParentRule(this);
|
||||
if (sheet) {
|
||||
sheet->AsGecko()->SetModifiedByChildRule();
|
||||
sheet->RuleChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,12 +62,12 @@ MediaList::DoMediaChange(Func aCallback)
|
|||
}
|
||||
|
||||
if (mStyleSheet) {
|
||||
mStyleSheet->DidDirty();
|
||||
}
|
||||
/* XXXldb Pass something meaningful? */
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(mStyleSheet, nullptr);
|
||||
// FIXME(emilio): We should discern between "owned by a rule" (as in @media)
|
||||
// and "owned by a sheet" (as in <style media>), and then pass something
|
||||
// meaningful here.
|
||||
mStyleSheet->RuleChanged(nullptr);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -174,10 +174,7 @@ ServoKeyframeRule::UpdateRule(Func aCallback)
|
|||
aCallback();
|
||||
|
||||
if (StyleSheet* sheet = GetStyleSheet()) {
|
||||
// FIXME sheet->AsGecko()->SetModifiedByChildRule();
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(sheet, this);
|
||||
}
|
||||
sheet->RuleChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -252,10 +252,7 @@ ServoKeyframesRule::UpdateRule(Func aCallback)
|
|||
aCallback();
|
||||
|
||||
if (StyleSheet* sheet = GetStyleSheet()) {
|
||||
// FIXME sheet->AsGecko()->SetModifiedByChildRule();
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(sheet, this);
|
||||
}
|
||||
sheet->RuleChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,9 +81,7 @@ ServoStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
|
|||
mDecls = decls.forget();
|
||||
mDecls->SetOwningRule(rule);
|
||||
}
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(sheet, rule);
|
||||
}
|
||||
sheet->RuleChanged(rule);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -171,19 +171,6 @@ ServoStyleSet::Init(nsPresContext* aPresContext, nsBindingManager* aBindingManag
|
|||
SetStylistStyleSheetsDirty();
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleSet::BeginShutdown()
|
||||
{
|
||||
nsIDocument* doc = mPresContext->Document();
|
||||
|
||||
// Remove the style rule map from document's observer and drop it.
|
||||
if (mStyleRuleMap) {
|
||||
doc->RemoveObserver(mStyleRuleMap);
|
||||
doc->CSSLoader()->RemoveObserver(mStyleRuleMap);
|
||||
mStyleRuleMap = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleSet::Shutdown()
|
||||
{
|
||||
|
@ -191,6 +178,7 @@ ServoStyleSet::Shutdown()
|
|||
// starts going away.
|
||||
ClearNonInheritingStyleContexts();
|
||||
mRawSet = nullptr;
|
||||
mStyleRuleMap = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -685,6 +673,10 @@ ServoStyleSet::AppendStyleSheet(SheetType aType,
|
|||
SetStylistStyleSheetsDirty();
|
||||
}
|
||||
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->SheetAdded(*aSheet);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -709,6 +701,10 @@ ServoStyleSet::PrependStyleSheet(SheetType aType,
|
|||
SetStylistStyleSheetsDirty();
|
||||
}
|
||||
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->SheetAdded(*aSheet);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -726,6 +722,10 @@ ServoStyleSet::RemoveStyleSheet(SheetType aType,
|
|||
SetStylistStyleSheetsDirty();
|
||||
}
|
||||
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->SheetRemoved(*aSheet);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -758,6 +758,9 @@ ServoStyleSet::ReplaceSheets(SheetType aType,
|
|||
}
|
||||
}
|
||||
|
||||
// Just don't bother calling SheetRemoved / SheetAdded, and recreate the rule
|
||||
// map when needed.
|
||||
mStyleRuleMap = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -785,6 +788,10 @@ ServoStyleSet::InsertStyleSheetBefore(SheetType aType,
|
|||
SetStylistStyleSheetsDirty();
|
||||
}
|
||||
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->SheetAdded(*aNewSheet);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -851,6 +858,10 @@ ServoStyleSet::AddDocStyleSheet(ServoStyleSheet* aSheet,
|
|||
}
|
||||
}
|
||||
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->SheetAdded(*aSheet);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1053,24 +1064,32 @@ ServoStyleSet::SetStylistXBLStyleSheetsDirty()
|
|||
}
|
||||
|
||||
void
|
||||
ServoStyleSet::RecordStyleSheetChange(
|
||||
ServoStyleSheet* aSheet,
|
||||
StyleSheet::ChangeType aChangeType)
|
||||
ServoStyleSet::RuleAdded(ServoStyleSheet& aSheet, css::Rule& aRule)
|
||||
{
|
||||
switch (aChangeType) {
|
||||
case StyleSheet::ChangeType::RuleAdded:
|
||||
case StyleSheet::ChangeType::RuleRemoved:
|
||||
case StyleSheet::ChangeType::RuleChanged:
|
||||
case StyleSheet::ChangeType::ReparsedFromInspector:
|
||||
// FIXME(emilio): We can presumably do better in a bunch of these.
|
||||
return MarkOriginsDirty(aSheet->GetOrigin());
|
||||
case StyleSheet::ChangeType::ApplicableStateChanged:
|
||||
case StyleSheet::ChangeType::Added:
|
||||
case StyleSheet::ChangeType::Removed:
|
||||
// Do nothing, we've already recorded the change in the
|
||||
// Append/Remove/Replace methods, etc, and will act consequently.
|
||||
return;
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->RuleAdded(aSheet, aRule);
|
||||
}
|
||||
|
||||
// FIXME(emilio): Could be more granular based on aRule.
|
||||
MarkOriginsDirty(aSheet.GetOrigin());
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleSet::RuleRemoved(ServoStyleSheet& aSheet, css::Rule& aRule)
|
||||
{
|
||||
if (mStyleRuleMap) {
|
||||
mStyleRuleMap->RuleRemoved(aSheet, aRule);
|
||||
}
|
||||
|
||||
// FIXME(emilio): Could be more granular based on aRule.
|
||||
MarkOriginsDirty(aSheet.GetOrigin());
|
||||
}
|
||||
|
||||
void
|
||||
ServoStyleSet::RuleChanged(ServoStyleSheet& aSheet, css::Rule* aRule)
|
||||
{
|
||||
// FIXME(emilio): Could be more granular based on aRule.
|
||||
MarkOriginsDirty(aSheet.GetOrigin());
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -1458,14 +1477,9 @@ ServoStyleRuleMap*
|
|||
ServoStyleSet::StyleRuleMap()
|
||||
{
|
||||
if (!mStyleRuleMap) {
|
||||
mStyleRuleMap = new ServoStyleRuleMap(this);
|
||||
if (mPresContext) {
|
||||
nsIDocument* doc = mPresContext->Document();
|
||||
doc->AddObserver(mStyleRuleMap);
|
||||
doc->CSSLoader()->AddObserver(mStyleRuleMap);
|
||||
}
|
||||
mStyleRuleMap = MakeUnique<ServoStyleRuleMap>(this);
|
||||
}
|
||||
return mStyleRuleMap;
|
||||
return mStyleRuleMap.get();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -133,12 +133,20 @@ public:
|
|||
const nsTArray<RefPtr<ServoStyleSheet>>& aNewSheets);
|
||||
|
||||
void Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager);
|
||||
void BeginShutdown();
|
||||
void BeginShutdown() {}
|
||||
void Shutdown();
|
||||
|
||||
void RecordStyleSheetChange(mozilla::ServoStyleSheet*, StyleSheet::ChangeType);
|
||||
// Called when a rules in a stylesheet in this set, or a child sheet of that,
|
||||
// are mutated from CSSOM.
|
||||
void RuleAdded(ServoStyleSheet&, css::Rule&);
|
||||
void RuleRemoved(ServoStyleSheet&, css::Rule&);
|
||||
void RuleChanged(ServoStyleSheet& aSheet, css::Rule* aRule);
|
||||
|
||||
void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot) {
|
||||
// All the relevant changes are handled in RuleAdded / RuleRemoved / etc, and
|
||||
// the relevant AppendSheet / RemoveSheet...
|
||||
void RecordStyleSheetChange(ServoStyleSheet*, StyleSheet::ChangeType) {}
|
||||
|
||||
void RecordShadowStyleChange(dom::ShadowRoot* aShadowRoot) {
|
||||
// FIXME(emilio): When we properly support shadow dom we'll need to do
|
||||
// better.
|
||||
MarkOriginsDirty(OriginFlags::All);
|
||||
|
@ -286,7 +294,7 @@ public:
|
|||
// check whether there is ::before/::after style for an element
|
||||
already_AddRefed<ServoStyleContext>
|
||||
ProbePseudoElementStyle(dom::Element* aOriginatingElement,
|
||||
mozilla::CSSPseudoElementType aType,
|
||||
CSSPseudoElementType aType,
|
||||
ServoStyleContext* aParentContext);
|
||||
|
||||
/**
|
||||
|
@ -442,7 +450,6 @@ public:
|
|||
// Called by StyleSheet::EnsureUniqueInner to let us know it cloned
|
||||
// its inner.
|
||||
void SetNeedsRestyleAfterEnsureUniqueInner() {
|
||||
MOZ_ASSERT(!IsForXBL(), "Should not be cloning things for XBL stylesheet");
|
||||
mNeedsRestyleAfterEnsureUniqueInner = true;
|
||||
}
|
||||
|
||||
|
@ -625,7 +632,7 @@ private:
|
|||
|
||||
// Map from raw Servo style rule to Gecko's wrapper object.
|
||||
// Constructed lazily when requested by devtools.
|
||||
RefPtr<ServoStyleRuleMap> mStyleRuleMap;
|
||||
UniquePtr<ServoStyleRuleMap> mStyleRuleMap;
|
||||
|
||||
// This can be null if we are used to hold XBL style sheets.
|
||||
RefPtr<nsBindingManager> mBindingManager;
|
||||
|
|
|
@ -281,9 +281,8 @@ ServoStyleSheet::ReparseSheet(const nsAString& aInput)
|
|||
}
|
||||
}
|
||||
|
||||
// Notify mDocument that all our rules are removed.
|
||||
if (mDocument) {
|
||||
// Get the rule list.
|
||||
// Notify to the stylesets about the old rules going away.
|
||||
{
|
||||
ServoCSSRuleList* ruleList = GetCssRulesInternal();
|
||||
MOZ_ASSERT(ruleList);
|
||||
|
||||
|
@ -295,13 +294,7 @@ ServoStyleSheet::ReparseSheet(const nsAString& aInput)
|
|||
RuleHasPendingChildSheet(rule)) {
|
||||
continue; // notify when loaded (see StyleSheetLoaded)
|
||||
}
|
||||
mDocument->StyleRuleRemoved(this, rule);
|
||||
|
||||
// Document observers could possibly detach document from this sheet.
|
||||
if (!mDocument) {
|
||||
// If detached, don't process any more rules.
|
||||
break;
|
||||
}
|
||||
RuleRemoved(*rule);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,8 +311,8 @@ ServoStyleSheet::ReparseSheet(const nsAString& aInput)
|
|||
DidDirty();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Notify mDocument that all our new rules are added.
|
||||
if (mDocument) {
|
||||
// Notify the stylesets about the new rules.
|
||||
{
|
||||
// Get the rule list (which will need to be regenerated after ParseSheet).
|
||||
ServoCSSRuleList* ruleList = GetCssRulesInternal();
|
||||
MOZ_ASSERT(ruleList);
|
||||
|
@ -333,29 +326,10 @@ ServoStyleSheet::ReparseSheet(const nsAString& aInput)
|
|||
continue; // notify when loaded (see StyleSheetLoaded)
|
||||
}
|
||||
|
||||
mDocument->StyleRuleAdded(this, rule);
|
||||
|
||||
// Document observers could possibly detach document from this sheet.
|
||||
if (!mDocument) {
|
||||
// If detached, don't process any more rules.
|
||||
break;
|
||||
}
|
||||
RuleAdded(*rule);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(emilio): This is kind-of a hack for bug 1420713. As you may notice,
|
||||
// there's nothing that triggers a style flush or anything similar (neither
|
||||
// here or in the relevant Gecko path inside DidDirty).
|
||||
//
|
||||
// The tl;dr is: if we want to make sure scripted changes to sheets not
|
||||
// associated with any document get properly reflected, we need to rejigger a
|
||||
// fair amount of stuff. I'm probably doing that work as part of the shadow
|
||||
// DOM stuff.
|
||||
for (StyleSetHandle handle : mStyleSets) {
|
||||
handle->AsServo()->RecordStyleSheetChange(
|
||||
this, StyleSheet::ChangeType::ReparsedFromInspector);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -369,15 +343,15 @@ ServoStyleSheet::StyleSheetLoaded(StyleSheet* aSheet,
|
|||
"why we were called back with a CSSStyleSheet?");
|
||||
|
||||
ServoStyleSheet* sheet = aSheet->AsServo();
|
||||
if (sheet->GetParentSheet() == nullptr) {
|
||||
if (!sheet->GetParentSheet()) {
|
||||
return NS_OK; // ignore if sheet has been detached already
|
||||
}
|
||||
NS_ASSERTION(this == sheet->GetParentSheet(),
|
||||
"We are being notified of a sheet load for a sheet that is not our child!");
|
||||
|
||||
if (mDocument && NS_SUCCEEDED(aStatus)) {
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
|
||||
mDocument->StyleRuleAdded(this, sheet->GetOwnerRule());
|
||||
RuleAdded(*sheet->GetOwnerRule());
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -432,14 +406,15 @@ ServoStyleSheet::InsertRuleInternal(const nsAString& aRule,
|
|||
if (aRv.Failed()) {
|
||||
return 0;
|
||||
}
|
||||
if (mDocument) {
|
||||
if (mRuleList->GetDOMCSSRuleType(aIndex) != nsIDOMCSSRule::IMPORT_RULE ||
|
||||
!RuleHasPendingChildSheet(mRuleList->GetRule(aIndex))) {
|
||||
// XXX We may not want to get the rule when stylesheet change event
|
||||
// is not enabled.
|
||||
mDocument->StyleRuleAdded(this, mRuleList->GetRule(aIndex));
|
||||
}
|
||||
|
||||
// XXX We may not want to get the rule when stylesheet change event
|
||||
// is not enabled.
|
||||
css::Rule* rule = mRuleList->GetRule(aIndex);
|
||||
if (rule->GetType() != css::Rule::IMPORT_RULE ||
|
||||
!RuleHasPendingChildSheet(rule)) {
|
||||
RuleAdded(*rule);
|
||||
}
|
||||
|
||||
return aIndex;
|
||||
}
|
||||
|
||||
|
@ -461,8 +436,8 @@ ServoStyleSheet::DeleteRuleInternal(uint32_t aIndex, ErrorResult& aRv)
|
|||
aRv = mRuleList->DeleteRule(aIndex);
|
||||
MOZ_ASSERT(!aRv.ErrorCodeIs(NS_ERROR_DOM_INDEX_SIZE_ERR),
|
||||
"IndexSizeError should have been handled earlier");
|
||||
if (!aRv.Failed() && mDocument) {
|
||||
mDocument->StyleRuleRemoved(this, rule);
|
||||
if (!aRv.Failed()) {
|
||||
RuleRemoved(*rule);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1162,11 +1162,7 @@ DOMCSSDeclarationImpl::SetCSSDeclaration(DeclarationBlock* aDecl)
|
|||
mRule->SetDeclaration(aDecl->AsGecko());
|
||||
|
||||
if (sheet) {
|
||||
sheet->DidDirty();
|
||||
}
|
||||
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(sheet, mRule);
|
||||
sheet->RuleChanged(mRule);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -18,14 +18,6 @@
|
|||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
class CSSStyleSheet;
|
||||
class ServoStyleSet;
|
||||
namespace dom {
|
||||
class Element;
|
||||
class ShadowRoot;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
class nsBindingManager;
|
||||
class nsCSSCounterStyleRule;
|
||||
struct nsFontFaceRuleContainer;
|
||||
|
@ -41,6 +33,16 @@ struct TreeMatchContext;
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
class CSSStyleSheet;
|
||||
class ServoStyleSet;
|
||||
namespace dom {
|
||||
class Element;
|
||||
class ShadowRoot;
|
||||
} // namespace dom
|
||||
namespace css {
|
||||
class Rule;
|
||||
} // namespace css
|
||||
|
||||
#define SERVO_BIT 0x1
|
||||
|
||||
/**
|
||||
|
@ -166,6 +168,12 @@ public:
|
|||
inline void AppendAllXBLStyleSheets(nsTArray<StyleSheet*>& aArray) const;
|
||||
inline nsresult RemoveDocStyleSheet(StyleSheet* aSheet);
|
||||
inline nsresult AddDocStyleSheet(StyleSheet* aSheet, nsIDocument* aDocument);
|
||||
|
||||
inline void RuleRemoved(StyleSheet&, css::Rule&);
|
||||
inline void RuleAdded(StyleSheet&, css::Rule&);
|
||||
inline void RuleChanged(StyleSheet&, css::Rule*);
|
||||
|
||||
// TODO(emilio): Remove in favor of Rule* methods.
|
||||
inline void RecordStyleSheetChange(StyleSheet* aSheet, StyleSheet::ChangeType);
|
||||
inline void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot);
|
||||
inline bool StyleSheetsHaveChanged() const;
|
||||
|
|
|
@ -249,6 +249,27 @@ StyleSetHandle::Ptr::AddDocStyleSheet(StyleSheet* aSheet,
|
|||
(aSheet->AsServo(), aDocument));
|
||||
}
|
||||
|
||||
void
|
||||
StyleSetHandle::Ptr::RuleRemoved(StyleSheet& aSheet, css::Rule& aRule)
|
||||
{
|
||||
FORWARD_CONCRETE(RuleRemoved, (*aSheet.AsGecko(), aRule),
|
||||
(*aSheet.AsServo(), aRule));
|
||||
}
|
||||
|
||||
void
|
||||
StyleSetHandle::Ptr::RuleAdded(StyleSheet& aSheet, css::Rule& aRule)
|
||||
{
|
||||
FORWARD_CONCRETE(RuleAdded, (*aSheet.AsGecko(), aRule),
|
||||
(*aSheet.AsServo(), aRule));
|
||||
}
|
||||
|
||||
void
|
||||
StyleSetHandle::Ptr::RuleChanged(StyleSheet& aSheet, css::Rule* aRule)
|
||||
{
|
||||
FORWARD_CONCRETE(RuleChanged, (*aSheet.AsGecko(), aRule),
|
||||
(*aSheet.AsServo(), aRule));
|
||||
}
|
||||
|
||||
void
|
||||
StyleSetHandle::Ptr::RecordStyleSheetChange(StyleSheet* aSheet,
|
||||
StyleSheet::ChangeType aChangeType)
|
||||
|
|
|
@ -454,12 +454,18 @@ StyleSheet::EnsureUniqueInner()
|
|||
// already unique
|
||||
return;
|
||||
}
|
||||
|
||||
// If this stylesheet is for XBL with Servo, don't bother cloning
|
||||
// it, as it may break ServoStyleRuleMap. XBL stylesheets are not
|
||||
// supposed to change anyway.
|
||||
//
|
||||
// The mDocument check is used as a fast reject path because no
|
||||
// XBL stylesheets would have associated document, but in normal
|
||||
// cases, content stylesheets should usually have one.
|
||||
//
|
||||
// FIXME(emilio): Shadow DOM definitely modifies stylesheets! Right now all of
|
||||
// them are unique anyway because we don't support <link>, but that needs to
|
||||
// change.
|
||||
if (!mDocument && IsServo() &&
|
||||
mStyleSets.Length() == 1 &&
|
||||
mStyleSets[0]->AsServo()->IsForXBL()) {
|
||||
|
@ -603,14 +609,51 @@ StyleSheet::DeleteRuleFromGroup(css::GroupRule* aGroup, uint32_t aIndex)
|
|||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
rule->SetStyleSheet(nullptr);
|
||||
RuleRemoved(*rule);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define NOTIFY_STYLE_SETS(function_, args_) do { \
|
||||
StyleSheet* current = this; \
|
||||
do { \
|
||||
for (StyleSetHandle handle : current->mStyleSets) { \
|
||||
handle->function_ args_; \
|
||||
} \
|
||||
current = current->mParent; \
|
||||
} while (current); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
StyleSheet::RuleAdded(css::Rule& aRule)
|
||||
{
|
||||
DidDirty();
|
||||
NOTIFY_STYLE_SETS(RuleAdded, (*this, aRule));
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->StyleRuleRemoved(this, rule);
|
||||
mDocument->StyleRuleAdded(this, &aRule);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
void
|
||||
StyleSheet::RuleRemoved(css::Rule& aRule)
|
||||
{
|
||||
DidDirty();
|
||||
NOTIFY_STYLE_SETS(RuleRemoved, (*this, aRule));
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->StyleRuleRemoved(this, &aRule);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StyleSheet::RuleChanged(css::Rule* aRule)
|
||||
{
|
||||
DidDirty();
|
||||
NOTIFY_STYLE_SETS(RuleChanged, (*this, aRule));
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->StyleRuleChanged(this, aRule);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -636,12 +679,7 @@ StyleSheet::InsertRuleIntoGroup(const nsAString& aRule,
|
|||
result = AsServo()->InsertRuleIntoGroupInternal(aRule, aGroup, aIndex);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
DidDirty();
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->StyleRuleAdded(this, aGroup->GetStyleRuleAt(aIndex));
|
||||
}
|
||||
RuleAdded(*aGroup->GetStyleRuleAt(aIndex));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,6 @@ public:
|
|||
RuleAdded,
|
||||
RuleRemoved,
|
||||
RuleChanged,
|
||||
ReparsedFromInspector,
|
||||
};
|
||||
|
||||
void SetOwningNode(nsINode* aOwningNode)
|
||||
|
@ -262,6 +261,12 @@ public:
|
|||
void WillDirty();
|
||||
virtual void DidDirty() {}
|
||||
|
||||
// Called when a rule changes from CSSOM.
|
||||
//
|
||||
// FIXME(emilio): This shouldn't allow null, but MediaList doesn't know about
|
||||
// it's owning media rule, plus it's used for the stylesheet media itself.
|
||||
void RuleChanged(css::Rule*);
|
||||
|
||||
void AddStyleSet(const StyleSetHandle& aStyleSet);
|
||||
void DropStyleSet(const StyleSetHandle& aStyleSet);
|
||||
|
||||
|
@ -293,6 +298,15 @@ private:
|
|||
ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
// Called when a rule is removed from the sheet from CSSOM.
|
||||
void RuleAdded(css::Rule&);
|
||||
|
||||
// Called when a rule is added to the sheet from CSSOM.
|
||||
void RuleRemoved(css::Rule&);
|
||||
|
||||
// Called from SetEnabled when the enabled state changed.
|
||||
void EnabledStateChanged();
|
||||
|
||||
struct ChildSheetListBuilder {
|
||||
RefPtr<StyleSheet>* sheetSlot;
|
||||
StyleSheet* parent;
|
||||
|
@ -317,9 +331,6 @@ protected:
|
|||
// Drop our reference to mMedia
|
||||
void DropMedia();
|
||||
|
||||
// Called from SetEnabled when the enabled state changed.
|
||||
void EnabledStateChanged();
|
||||
|
||||
// Unlink our inner, if needed, for cycle collection
|
||||
virtual void UnlinkInner();
|
||||
// Traverse our inner, if needed, for cycle collection
|
||||
|
|
|
@ -140,12 +140,7 @@ nsCSSCounterStyleRule::SetName(const nsAString& aName)
|
|||
mName = name;
|
||||
|
||||
if (StyleSheet* sheet = GetStyleSheet()) {
|
||||
if (sheet->IsGecko()) {
|
||||
sheet->AsGecko()->SetModifiedByChildRule();
|
||||
}
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(sheet, this);
|
||||
}
|
||||
sheet->RuleChanged(this);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -187,12 +182,7 @@ nsCSSCounterStyleRule::SetDesc(nsCSSCounterDesc aDescID, const nsCSSValue& aValu
|
|||
mGeneration++;
|
||||
|
||||
if (StyleSheet* sheet = GetStyleSheet()) {
|
||||
if (sheet->IsGecko()) {
|
||||
sheet->AsGecko()->SetModifiedByChildRule();
|
||||
}
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(sheet, this);
|
||||
}
|
||||
sheet->RuleChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1037,10 +1037,7 @@ nsCSSKeyframeRule::SetKeyText(const nsAString& aKeyText)
|
|||
newSelectors.SwapElements(mKeys);
|
||||
|
||||
if (StyleSheet* sheet = GetStyleSheet()) {
|
||||
sheet->AsGecko()->SetModifiedByChildRule();
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(sheet, this);
|
||||
}
|
||||
sheet->RuleChanged(this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1071,10 +1068,7 @@ nsCSSKeyframeRule::ChangeDeclaration(css::Declaration* aDeclaration)
|
|||
}
|
||||
|
||||
if (StyleSheet* sheet = GetStyleSheet()) {
|
||||
sheet->AsGecko()->SetModifiedByChildRule();
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(sheet, this);
|
||||
}
|
||||
sheet->RuleChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1174,10 +1168,7 @@ nsCSSKeyframesRule::SetName(const nsAString& aName)
|
|||
mName = NS_Atomize(aName);
|
||||
|
||||
if (StyleSheet* sheet = GetStyleSheet()) {
|
||||
sheet->AsGecko()->SetModifiedByChildRule();
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(sheet, this);
|
||||
}
|
||||
sheet->RuleChanged(this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1201,10 +1192,7 @@ nsCSSKeyframesRule::AppendRule(const nsAString& aRule)
|
|||
AppendStyleRule(rule);
|
||||
|
||||
if (StyleSheet* sheet = GetStyleSheet()) {
|
||||
sheet->AsGecko()->SetModifiedByChildRule();
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(sheet, this);
|
||||
}
|
||||
sheet->RuleChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1248,11 +1236,7 @@ nsCSSKeyframesRule::DeleteRule(const nsAString& aKey)
|
|||
DeleteStyleRuleAt(index);
|
||||
|
||||
if (StyleSheet* sheet = GetStyleSheet()) {
|
||||
sheet->AsGecko()->SetModifiedByChildRule();
|
||||
|
||||
if (doc) {
|
||||
doc->StyleRuleChanged(sheet, this);
|
||||
}
|
||||
sheet->RuleChanged(this);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -1458,8 +1442,10 @@ nsCSSPageRule::ChangeDeclaration(css::Declaration* aDeclaration)
|
|||
mDeclaration->SetOwningRule(this);
|
||||
}
|
||||
|
||||
nsIDocument* doc = GetDocument();
|
||||
MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
|
||||
if (StyleSheet* sheet = GetStyleSheet()) {
|
||||
sheet->AsGecko()->SetModifiedByChildRule();
|
||||
sheet->RuleChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2354,8 +2354,7 @@ nsStyleSet::Shutdown()
|
|||
}
|
||||
|
||||
void
|
||||
nsStyleSet::RecordStyleSheetChange(CSSStyleSheet* aStyleSheet,
|
||||
StyleSheet::ChangeType)
|
||||
nsStyleSet::SheetChanged(CSSStyleSheet& aStyleSheet)
|
||||
{
|
||||
MOZ_ASSERT(mBatching != 0, "Should be in an update");
|
||||
|
||||
|
@ -2363,7 +2362,7 @@ nsStyleSet::RecordStyleSheetChange(CSSStyleSheet* aStyleSheet,
|
|||
return;
|
||||
}
|
||||
|
||||
if (Element* scopeElement = aStyleSheet->GetScopeElement()) {
|
||||
if (Element* scopeElement = aStyleSheet.GetScopeElement()) {
|
||||
mChangedScopeStyleRoots.AppendElement(scopeElement);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -341,9 +341,29 @@ class nsStyleSet final
|
|||
// Free all of the data associated with this style set.
|
||||
void Shutdown();
|
||||
|
||||
void RuleAdded(mozilla::CSSStyleSheet& aSheet, mozilla::css::Rule&)
|
||||
{
|
||||
SheetChanged(aSheet);
|
||||
}
|
||||
|
||||
void RuleRemoved(mozilla::CSSStyleSheet& aSheet, mozilla::css::Rule&)
|
||||
{
|
||||
SheetChanged(aSheet);
|
||||
}
|
||||
|
||||
void RuleChanged(mozilla::CSSStyleSheet& aSheet, mozilla::css::Rule*)
|
||||
{
|
||||
SheetChanged(aSheet);
|
||||
}
|
||||
|
||||
// Notes that a style sheet has changed.
|
||||
void RecordStyleSheetChange(mozilla::CSSStyleSheet* aStyleSheet,
|
||||
mozilla::StyleSheet::ChangeType);
|
||||
void RecordStyleSheetChange(mozilla::CSSStyleSheet* aSheet,
|
||||
mozilla::StyleSheet::ChangeType)
|
||||
{
|
||||
SheetChanged(*aSheet);
|
||||
}
|
||||
|
||||
void SheetChanged(mozilla::CSSStyleSheet&);
|
||||
|
||||
// Notes that style sheets have changed in a shadow root.
|
||||
void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot);
|
||||
|
|
|
@ -73,6 +73,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
|||
, mForcePreflight(false)
|
||||
, mIsPreflight(false)
|
||||
, mLoadTriggeredFromExternal(false)
|
||||
, mServiceWorkerTaintingSynthesized(false)
|
||||
, mForceHSTSPriming(false)
|
||||
, mMixedContentWouldBlock(false)
|
||||
, mIsHSTSPriming(false)
|
||||
|
@ -266,6 +267,7 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
|
|||
, mForcePreflight(false)
|
||||
, mIsPreflight(false)
|
||||
, mLoadTriggeredFromExternal(false)
|
||||
, mServiceWorkerTaintingSynthesized(false)
|
||||
, mForceHSTSPriming(false)
|
||||
, mMixedContentWouldBlock(false)
|
||||
, mIsHSTSPriming(false)
|
||||
|
@ -347,6 +349,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
|
|||
, mForcePreflight(rhs.mForcePreflight)
|
||||
, mIsPreflight(rhs.mIsPreflight)
|
||||
, mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal)
|
||||
, mServiceWorkerTaintingSynthesized(rhs.mServiceWorkerTaintingSynthesized)
|
||||
, mForceHSTSPriming(rhs.mForceHSTSPriming)
|
||||
, mMixedContentWouldBlock(rhs.mMixedContentWouldBlock)
|
||||
, mIsHSTSPriming(rhs.mIsHSTSPriming)
|
||||
|
@ -384,6 +387,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
|||
bool aForcePreflight,
|
||||
bool aIsPreflight,
|
||||
bool aLoadTriggeredFromExternal,
|
||||
bool aServiceWorkerTaintingSynthesized,
|
||||
bool aForceHSTSPriming,
|
||||
bool aMixedContentWouldBlock,
|
||||
bool aIsHSTSPriming,
|
||||
|
@ -415,6 +419,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
|||
, mForcePreflight(aForcePreflight)
|
||||
, mIsPreflight(aIsPreflight)
|
||||
, mLoadTriggeredFromExternal(aLoadTriggeredFromExternal)
|
||||
, mServiceWorkerTaintingSynthesized(aServiceWorkerTaintingSynthesized)
|
||||
, mForceHSTSPriming (aForceHSTSPriming)
|
||||
, mMixedContentWouldBlock(aMixedContentWouldBlock)
|
||||
, mIsHSTSPriming(aIsHSTSPriming)
|
||||
|
@ -1059,6 +1064,14 @@ LoadInfo::GetLoadTriggeredFromExternal(bool* aLoadTriggeredFromExternal)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LoadInfo::GetServiceWorkerTaintingSynthesized(bool* aServiceWorkerTaintingSynthesized)
|
||||
{
|
||||
MOZ_ASSERT(aServiceWorkerTaintingSynthesized);
|
||||
*aServiceWorkerTaintingSynthesized = mServiceWorkerTaintingSynthesized;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LoadInfo::GetForceHSTSPriming(bool* aForceHSTSPriming)
|
||||
{
|
||||
|
@ -1131,6 +1144,12 @@ NS_IMETHODIMP
|
|||
LoadInfo::MaybeIncreaseTainting(uint32_t aTainting)
|
||||
{
|
||||
NS_ENSURE_ARG(aTainting <= TAINTING_OPAQUE);
|
||||
|
||||
// Skip if the tainting has been set by the service worker.
|
||||
if (mServiceWorkerTaintingSynthesized) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LoadTainting tainting = static_cast<LoadTainting>(aTainting);
|
||||
if (tainting > mTainting) {
|
||||
mTainting = tainting;
|
||||
|
@ -1143,6 +1162,9 @@ LoadInfo::SynthesizeServiceWorkerTainting(LoadTainting aTainting)
|
|||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(aTainting <= LoadTainting::Opaque);
|
||||
mTainting = aTainting;
|
||||
|
||||
// Flag to prevent the tainting from being increased.
|
||||
mServiceWorkerTaintingSynthesized = true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -124,6 +124,7 @@ private:
|
|||
bool aForcePreflight,
|
||||
bool aIsPreflight,
|
||||
bool aLoadTriggeredFromExternal,
|
||||
bool aServiceWorkerTaintingSynthesized,
|
||||
bool aForceHSTSPriming,
|
||||
bool aMixedContentWouldBlock,
|
||||
bool aIsHSTSPriming,
|
||||
|
@ -188,6 +189,7 @@ private:
|
|||
bool mForcePreflight;
|
||||
bool mIsPreflight;
|
||||
bool mLoadTriggeredFromExternal;
|
||||
bool mServiceWorkerTaintingSynthesized;
|
||||
|
||||
bool mForceHSTSPriming : 1;
|
||||
bool mMixedContentWouldBlock : 1;
|
||||
|
|
|
@ -633,6 +633,11 @@ interface nsILoadInfo : nsISupports
|
|||
*/
|
||||
[infallible] attribute boolean loadTriggeredFromExternal;
|
||||
|
||||
/**
|
||||
* True if the tainting has been set by the service worker.
|
||||
*/
|
||||
[noscript, infallible] readonly attribute boolean serviceWorkerTaintingSynthesized;
|
||||
|
||||
/**
|
||||
* Whenever a channel gets redirected, append the redirect history entry of
|
||||
* the channel which contains principal referrer and remote address [before
|
||||
|
|
|
@ -78,10 +78,15 @@ interface nsIInterceptedChannel : nsISupports
|
|||
* - The caller may optionally pass a spec for a URL that this response
|
||||
* originates from; an empty string will cause the original
|
||||
* intercepted request's URL to be used instead.
|
||||
* - The responseRedirected flag is false will cause the channel do an
|
||||
* internal redirect when the original intercepted reauest's URL is
|
||||
* different from the response's URL. The flag is true will cause the
|
||||
* chaanel do a non-internal redirect when the URLs are different.
|
||||
*/
|
||||
void startSynthesizedResponse(in nsIInputStream body,
|
||||
in nsIInterceptedBodyCallback callback,
|
||||
in ACString finalURLSpec);
|
||||
in ACString finalURLSpec,
|
||||
in bool responseRedirected);
|
||||
|
||||
/**
|
||||
* Instruct a channel that has been intercepted that response synthesis
|
||||
|
|
|
@ -72,6 +72,7 @@ struct LoadInfoArgs
|
|||
bool forcePreflight;
|
||||
bool isPreflight;
|
||||
bool loadTriggeredFromExternal;
|
||||
bool serviceWorkerTaintingSynthesized;
|
||||
bool forceHSTSPriming;
|
||||
bool mixedContentWouldBlock;
|
||||
bool isHSTSPriming;
|
||||
|
|
|
@ -1728,14 +1728,23 @@ HttpChannelChild::Redirect1Begin(const uint32_t& registrarId,
|
|||
|
||||
void
|
||||
HttpChannelChild::BeginNonIPCRedirect(nsIURI* responseURI,
|
||||
const nsHttpResponseHead* responseHead)
|
||||
const nsHttpResponseHead* responseHead,
|
||||
bool aResponseRedirected)
|
||||
{
|
||||
LOG(("HttpChannelChild::BeginNonIPCRedirect [this=%p]\n", this));
|
||||
|
||||
// If the response has been redirected, propagate all the URLs to content.
|
||||
// Thus, the exact value of the redirect flag does not matter as long as it's
|
||||
// not REDIRECT_INTERNAL.
|
||||
const uint32_t redirectFlag =
|
||||
aResponseRedirected ? nsIChannelEventSink::REDIRECT_TEMPORARY
|
||||
: nsIChannelEventSink::REDIRECT_INTERNAL;
|
||||
|
||||
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
nsresult rv = SetupRedirect(responseURI,
|
||||
responseHead,
|
||||
nsIChannelEventSink::REDIRECT_INTERNAL,
|
||||
redirectFlag,
|
||||
getter_AddRefs(newChannel));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -1754,7 +1763,7 @@ HttpChannelChild::BeginNonIPCRedirect(nsIURI* responseURI,
|
|||
|
||||
rv = gHttpHandler->AsyncOnChannelRedirect(this,
|
||||
newChannel,
|
||||
nsIChannelEventSink::REDIRECT_INTERNAL,
|
||||
redirectFlag,
|
||||
target);
|
||||
}
|
||||
|
||||
|
|
|
@ -432,7 +432,8 @@ private:
|
|||
|
||||
// Perform a redirection without communicating with the parent process at all.
|
||||
void BeginNonIPCRedirect(nsIURI* responseURI,
|
||||
const nsHttpResponseHead* responseHead);
|
||||
const nsHttpResponseHead* responseHead,
|
||||
bool responseRedirected);
|
||||
|
||||
// Override the default security info pointer during a non-IPC redirection.
|
||||
void OverrideSecurityInfoForNonIPCRedirect(nsISupports* securityInfo);
|
||||
|
|
|
@ -318,7 +318,7 @@ public:
|
|||
{
|
||||
// The URL passed as an argument here doesn't matter, since the child will
|
||||
// receive a redirection notification as a result of this synthesized response.
|
||||
mChannel->StartSynthesizedResponse(nullptr, nullptr, EmptyCString());
|
||||
mChannel->StartSynthesizedResponse(nullptr, nullptr, EmptyCString(), false);
|
||||
mChannel->FinishSynthesizedResponse();
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -275,7 +275,8 @@ InterceptedChannelContent::SynthesizeHeader(const nsACString& aName, const nsACS
|
|||
NS_IMETHODIMP
|
||||
InterceptedChannelContent::StartSynthesizedResponse(nsIInputStream* aBody,
|
||||
nsIInterceptedBodyCallback* aBodyCallback,
|
||||
const nsACString& aFinalURLSpec)
|
||||
const nsACString& aFinalURLSpec,
|
||||
bool aResponseRedirected)
|
||||
{
|
||||
if (NS_WARN_IF(mClosed)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
@ -302,7 +303,8 @@ InterceptedChannelContent::StartSynthesizedResponse(nsIInputStream* aBody,
|
|||
originalURI->Equals(responseURI, &equal);
|
||||
if (!equal) {
|
||||
mChannel->ForceIntercepted(aBody, aBodyCallback);
|
||||
mChannel->BeginNonIPCRedirect(responseURI, *mSynthesizedResponseHead.ptr());
|
||||
mChannel->BeginNonIPCRedirect(responseURI, *mSynthesizedResponseHead.ptr(),
|
||||
aResponseRedirected);
|
||||
} else {
|
||||
mChannel->OverrideWithSynthesizedResponse(mSynthesizedResponseHead.ref(),
|
||||
aBody, aBodyCallback,
|
||||
|
|
|
@ -182,7 +182,8 @@ public:
|
|||
NS_IMETHOD ResetInterception() override;
|
||||
NS_IMETHOD StartSynthesizedResponse(nsIInputStream* aBody,
|
||||
nsIInterceptedBodyCallback* aBodyCallback,
|
||||
const nsACString& aFinalURLSpec) override;
|
||||
const nsACString& aFinalURLSpec,
|
||||
bool aResponseRedirected) override;
|
||||
NS_IMETHOD FinishSynthesizedResponse() override;
|
||||
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
|
||||
NS_IMETHOD GetSecureUpgradedChannelURI(nsIURI** aURI) override;
|
||||
|
|
|
@ -229,13 +229,15 @@ InterceptedHttpChannel::FollowSyntheticRedirect()
|
|||
}
|
||||
|
||||
nsresult
|
||||
InterceptedHttpChannel::RedirectForOpaqueResponse(nsIURI* aResponseURI)
|
||||
InterceptedHttpChannel::RedirectForResponseURL(nsIURI* aResponseURI,
|
||||
bool aResponseRedirected)
|
||||
{
|
||||
// Perform an internal redirect to another InterceptedHttpChannel using
|
||||
// the given cross-origin response URL. The resulting channel will then
|
||||
// process the synthetic response as normal. This extra redirect is
|
||||
// performed so that listeners treat the result as unsafe cross-origin
|
||||
// data.
|
||||
// Perform a service worker redirect to another InterceptedHttpChannel using
|
||||
// the given response URL. It allows content to see the final URL where
|
||||
// appropriate and also helps us enforce cross-origin restrictions. The
|
||||
// resulting channel will then process the synthetic response as normal. This
|
||||
// extra redirect is performed so that listeners treat the result as unsafe
|
||||
// cross-origin data.
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -253,7 +255,11 @@ InterceptedHttpChannel::RedirectForOpaqueResponse(nsIURI* aResponseURI)
|
|||
static_cast<nsProxyInfo*>(mProxyInfo.get()),
|
||||
mProxyResolveFlags, mProxyURI, mChannelId);
|
||||
|
||||
uint32_t flags = nsIChannelEventSink::REDIRECT_INTERNAL;
|
||||
// If the response has been redirected, propagate all the URLs to content.
|
||||
// Thus, the exact value of the redirect flag does not matter as long as it's
|
||||
// not REDIRECT_INTERNAL.
|
||||
uint32_t flags = aResponseRedirected ? nsIChannelEventSink::REDIRECT_TEMPORARY
|
||||
: nsIChannelEventSink::REDIRECT_INTERNAL;
|
||||
|
||||
nsCOMPtr<nsILoadInfo> redirectLoadInfo =
|
||||
CloneLoadInfoForRedirect(aResponseURI, flags);
|
||||
|
@ -717,7 +723,8 @@ InterceptedHttpChannel::SynthesizeHeader(const nsACString& aName,
|
|||
NS_IMETHODIMP
|
||||
InterceptedHttpChannel::StartSynthesizedResponse(nsIInputStream* aBody,
|
||||
nsIInterceptedBodyCallback* aBodyCallback,
|
||||
const nsACString& aFinalURLSpec)
|
||||
const nsACString& aFinalURLSpec,
|
||||
bool aResponseRedirected)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -783,7 +790,7 @@ InterceptedHttpChannel::StartSynthesizedResponse(nsIInputStream* aBody,
|
|||
bool equal = false;
|
||||
Unused << mURI->Equals(responseURI, &equal);
|
||||
if (!equal) {
|
||||
rv = RedirectForOpaqueResponse(responseURI);
|
||||
rv = RedirectForResponseURL(responseURI, aResponseRedirected);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -113,8 +113,12 @@ private:
|
|||
nsresult
|
||||
FollowSyntheticRedirect();
|
||||
|
||||
// If the response's URL is different from the request's then do a service
|
||||
// worker redirect. If Response.redirected is false we do an internal
|
||||
// redirect. Otherwise, if Response.redirect is true do a non-internal
|
||||
// redirect so end consumers detect the redirected state.
|
||||
nsresult
|
||||
RedirectForOpaqueResponse(nsIURI* aResponseURI);
|
||||
RedirectForResponseURL(nsIURI* aResponseURI, bool aResponseRedirected);
|
||||
|
||||
nsresult
|
||||
StartPump();
|
||||
|
|
|
@ -63,7 +63,7 @@ function make_channel(url, body, cb) {
|
|||
.createInstance(Ci.nsIStringInputStream);
|
||||
synthesized.data = body;
|
||||
|
||||
channel.startSynthesizedResponse(synthesized, null, '');
|
||||
channel.startSynthesizedResponse(synthesized, null, '', false);
|
||||
channel.finishSynthesizedResponse();
|
||||
}
|
||||
if (cb) {
|
||||
|
@ -152,7 +152,7 @@ add_test(function() {
|
|||
.createInstance(Ci.nsIStringInputStream);
|
||||
synthesized.data = NON_REMOTE_BODY;
|
||||
channel.synthesizeHeader("Content-Length", NON_REMOTE_BODY.length);
|
||||
channel.startSynthesizedResponse(synthesized, null, '');
|
||||
channel.startSynthesizedResponse(synthesized, null, '', false);
|
||||
channel.finishSynthesizedResponse();
|
||||
});
|
||||
});
|
||||
|
@ -179,7 +179,7 @@ add_test(function() {
|
|||
// set the content-type to ensure that the stream converter doesn't hold up notifications
|
||||
// and cause the test to fail
|
||||
intercepted.synthesizeHeader("Content-Type", "text/plain");
|
||||
intercepted.startSynthesizedResponse(synthesized, null, '');
|
||||
intercepted.startSynthesizedResponse(synthesized, null, '', false);
|
||||
intercepted.finishSynthesizedResponse();
|
||||
});
|
||||
chan.asyncOpen2(new ChannelListener(handle_synthesized_response, null,
|
||||
|
@ -219,7 +219,7 @@ add_test(function() {
|
|||
synthesized.data = NON_REMOTE_BODY;
|
||||
|
||||
let channel = intercepted.channel;
|
||||
intercepted.startSynthesizedResponse(synthesized, null, '');
|
||||
intercepted.startSynthesizedResponse(synthesized, null, '', false);
|
||||
intercepted.finishSynthesizedResponse();
|
||||
channel.cancel(Cr.NS_BINDING_ABORTED);
|
||||
});
|
||||
|
@ -238,7 +238,7 @@ add_test(function() {
|
|||
|
||||
// This should not throw, but result in the channel firing callbacks
|
||||
// with an error status.
|
||||
intercepted.startSynthesizedResponse(synthesized, null, '');
|
||||
intercepted.startSynthesizedResponse(synthesized, null, '', false);
|
||||
intercepted.finishSynthesizedResponse();
|
||||
});
|
||||
chan.asyncOpen2(new ChannelListener(run_next_test, null,
|
||||
|
|
|
@ -538,10 +538,16 @@ class DeviceManagerADB(DeviceManager):
|
|||
localDir = os.path.join(tempParent, remoteName)
|
||||
else:
|
||||
localDir = '/'.join(localDir.rstrip('/').split('/')[:-1])
|
||||
self._runCmd(["pull", remoteDir, localDir]).wait()
|
||||
cmd = ["pull", remoteDir, localDir]
|
||||
proc = self._runCmd(cmd)
|
||||
if copyRequired:
|
||||
dir_util.copy_tree(localDir, originalLocal)
|
||||
mozfile.remove(tempParent)
|
||||
try:
|
||||
dir_util.copy_tree(localDir, originalLocal)
|
||||
mozfile.remove(tempParent)
|
||||
except:
|
||||
self._logger.error("getDirectory() failed after %s" % str(cmd))
|
||||
self._logger.error("rc=%d out=%s" % (proc.returncode, str(proc.output)))
|
||||
raise
|
||||
|
||||
def validateFile(self, remoteFile, localFile):
|
||||
md5Remote = self._getRemoteHash(remoteFile)
|
||||
|
@ -678,16 +684,20 @@ class DeviceManagerADB(DeviceManager):
|
|||
self._logger.error("Timeout exceeded for _runCmd call '%s'" % ' '.join(finalArgs))
|
||||
|
||||
retries = 0
|
||||
proc = None
|
||||
while retries < retryLimit:
|
||||
proc = ProcessHandler(finalArgs, storeOutput=True,
|
||||
processOutputLine=self._log, onTimeout=_timeout)
|
||||
proc.run(timeout=timeout)
|
||||
proc.returncode = proc.wait()
|
||||
if proc.returncode is None:
|
||||
proc.kill()
|
||||
retries += 1
|
||||
else:
|
||||
return proc
|
||||
if proc.returncode is not None:
|
||||
break
|
||||
proc.kill()
|
||||
self._logger.warning("_runCmd failed for '%s'" % ' '.join(finalArgs))
|
||||
retries += 1
|
||||
if retries >= retryLimit:
|
||||
self._logger.warning("_runCmd exceeded all retries")
|
||||
return proc
|
||||
|
||||
# timeout is specified in seconds, and if no timeout is given,
|
||||
# we will run until we hit the default_timeout specified in the __init__
|
||||
|
|
|
@ -40,6 +40,9 @@ config = {
|
|||
|
||||
"download_tooltool": True,
|
||||
|
||||
# this would normally be in "exes", but "exes" is clobbered by remove_executables
|
||||
"geckodriver": "%(abs_test_bin_dir)s/geckodriver",
|
||||
|
||||
"verify_category": "web-platform",
|
||||
}
|
||||
|
||||
|
|
|
@ -167,6 +167,17 @@ class WebPlatformTest(TestingMixin, MercurialScript, BlobUploadMixin, CodeCovera
|
|||
self.register_virtualenv_module(requirements=[requirements],
|
||||
two_pass=True)
|
||||
|
||||
def _query_geckodriver(self):
|
||||
path = None
|
||||
c = self.config
|
||||
dirs = self.query_abs_dirs()
|
||||
repl_dict = {}
|
||||
repl_dict.update(dirs)
|
||||
path = c.get("geckodriver", "geckodriver")
|
||||
if path:
|
||||
path = path % repl_dict
|
||||
return path
|
||||
|
||||
def _query_cmd(self, test_types):
|
||||
if not self.binary_path:
|
||||
self.fatal("Binary path could not be determined")
|
||||
|
@ -218,10 +229,10 @@ class WebPlatformTest(TestingMixin, MercurialScript, BlobUploadMixin, CodeCovera
|
|||
cmd.append("--%s=%s" % (opt.replace("_", "-"), val))
|
||||
|
||||
if "wdspec" in test_types:
|
||||
geckodriver_path = os.path.join(dirs["abs_test_bin_dir"], "geckodriver")
|
||||
if not os.path.isfile(geckodriver_path):
|
||||
geckodriver_path = self._query_geckodriver()
|
||||
if not geckodriver_path or not os.path.isfile(geckodriver_path):
|
||||
self.fatal("Unable to find geckodriver binary "
|
||||
"in common test package: %s" % geckodriver_path)
|
||||
"in common test package: %s" % str(geckodriver_path))
|
||||
cmd.append("--webdriver-binary=%s" % geckodriver_path)
|
||||
|
||||
options = list(c.get("options", []))
|
||||
|
@ -325,6 +336,12 @@ class WebPlatformTest(TestingMixin, MercurialScript, BlobUploadMixin, CodeCovera
|
|||
|
||||
if self.config.get("verify") is True:
|
||||
verify_suites = self.query_verify_category_suites(None, None)
|
||||
if "wdspec" in verify_suites:
|
||||
# geckodriver is required for wdspec, but not always available
|
||||
geckodriver_path = self._query_geckodriver()
|
||||
if not geckodriver_path or not os.path.isfile(geckodriver_path):
|
||||
verify_suites.remove("wdspec")
|
||||
self.info("Test verification skipping 'wdspec' tests - no geckodriver")
|
||||
else:
|
||||
test_types = self.config.get("test_type", [])
|
||||
verify_suites = [None]
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
[fetch-event-redirect.https.html]
|
||||
[Non-navigation, follow redirect, cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected]
|
||||
expected: FAIL
|
||||
|
||||
[Non-navigation, follow redirect, cors mode Request redirected to cors without credentials should succeed interception and response should be redirected]
|
||||
expected: FAIL
|
||||
|
||||
[Non-navigation, follow redirect, same-origin mode Request redirected to same-origin without credentials should succeed interception and response should be redirected]
|
||||
expected: FAIL
|
||||
|
||||
[Non-navigation, follow redirect, no-cors mode Request redirected to same-origin without credentials should succeed interception and response should be redirected]
|
||||
expected: FAIL
|
||||
|
||||
[Non-navigation, follow redirect, cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected]
|
||||
expected: FAIL
|
||||
|
||||
[Non-navigation, follow redirect, same-origin mode Request redirected to same-origin with credentials should succeed interception and response should be redirected]
|
||||
expected: FAIL
|
||||
|
||||
[Non-navigation, follow redirect, no-cors mode Request redirected to same-origin with credentials should succeed interception and response should be redirected]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
[fetch-response-taint.https.html]
|
||||
type: testharness
|
||||
[fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"omit" should succeed.]
|
||||
expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629
|
||||
|
||||
[fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"same-origin" should succeed.]
|
||||
expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629
|
||||
|
||||
[fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3D*&mode=cors&credentials=omit&" mode:"same-origin" credentials:"include" should succeed.]
|
||||
expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629
|
||||
|
||||
[fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Fweb-platform.test%3A8443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"omit" should succeed.]
|
||||
expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629
|
||||
|
||||
[fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Fweb-platform.test%3A8443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"same-origin" should succeed.]
|
||||
expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629
|
||||
|
||||
[fetching url:"https://web-platform.test:8443/?url=https%3A%2F%2Fwww1.web-platform.test%3A8443%2Fservice-workers%2Fservice-worker%2Fresources%2Ffetch-access-control.py%3FACAOrigin%3Dhttps%3A%2F%2Fweb-platform.test%3A8443%26ACACredentials%3Dtrue&mode=cors&credentials=include&" mode:"same-origin" credentials:"include" should succeed.]
|
||||
expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[redirected-response.https.html]
|
||||
type: testharness
|
||||
[mode: "follow", no mode change]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[worker-interception.https.html]
|
||||
type: testharness
|
||||
[Verify worker script intercepted by cors response succeeds]
|
||||
expected: FAIL # issue: https://github.com/whatwg/fetch/issues/629
|
||||
|
|
@ -176,47 +176,16 @@ function getMemoryMB() {
|
|||
* Gets the supported CPU instruction set.
|
||||
*/
|
||||
XPCOMUtils.defineLazyGetter(this, "gInstructionSet", function aus_gIS() {
|
||||
if (AppConstants.platform == "win") {
|
||||
const PF_MMX_INSTRUCTIONS_AVAILABLE = 3; // MMX
|
||||
const PF_XMMI_INSTRUCTIONS_AVAILABLE = 6; // SSE
|
||||
const PF_XMMI64_INSTRUCTIONS_AVAILABLE = 10; // SSE2
|
||||
const PF_SSE3_INSTRUCTIONS_AVAILABLE = 13; // SSE3
|
||||
|
||||
let lib = ctypes.open("kernel32.dll");
|
||||
let IsProcessorFeaturePresent = lib.declare("IsProcessorFeaturePresent",
|
||||
ctypes.winapi_abi,
|
||||
ctypes.int32_t, /* success */
|
||||
ctypes.uint32_t); /* DWORD */
|
||||
let instructionSet = "unknown";
|
||||
try {
|
||||
if (IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE)) {
|
||||
instructionSet = "SSE3";
|
||||
} else if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) {
|
||||
instructionSet = "SSE2";
|
||||
} else if (IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE)) {
|
||||
instructionSet = "SSE";
|
||||
} else if (IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE)) {
|
||||
instructionSet = "MMX";
|
||||
}
|
||||
} catch (e) {
|
||||
instructionSet = "error";
|
||||
Cu.reportError("Error getting processor instruction set. " +
|
||||
"Exception: " + e);
|
||||
const CPU_EXTENSIONS = ["hasSSE4_2", "hasSSE4_1", "hasSSE4A", "hasSSSE3",
|
||||
"hasSSE3", "hasSSE2", "hasSSE", "hasMMX",
|
||||
"hasNEON", "hasARMv7", "hasARMv6"];
|
||||
for (let ext of CPU_EXTENSIONS) {
|
||||
if (Services.sysinfo.getProperty(ext)) {
|
||||
return ext.substring(3);
|
||||
}
|
||||
|
||||
lib.close();
|
||||
return instructionSet;
|
||||
}
|
||||
|
||||
if (AppConstants == "linux") {
|
||||
let instructionSet = "unknown";
|
||||
if (navigator.cpuHasSSE2) {
|
||||
instructionSet = "SSE2";
|
||||
}
|
||||
return instructionSet;
|
||||
}
|
||||
|
||||
return "NA";
|
||||
return "unknown";
|
||||
});
|
||||
|
||||
/* Windows only getter that returns the processor architecture. */
|
||||
|
|
|
@ -136,38 +136,16 @@ function getProcArchitecture() {
|
|||
|
||||
// Gets the supported CPU instruction set.
|
||||
function getInstructionSet() {
|
||||
if (AppConstants.platform == "win") {
|
||||
const PF_MMX_INSTRUCTIONS_AVAILABLE = 3; // MMX
|
||||
const PF_XMMI_INSTRUCTIONS_AVAILABLE = 6; // SSE
|
||||
const PF_XMMI64_INSTRUCTIONS_AVAILABLE = 10; // SSE2
|
||||
const PF_SSE3_INSTRUCTIONS_AVAILABLE = 13; // SSE3
|
||||
|
||||
let lib = ctypes.open("kernel32.dll");
|
||||
let IsProcessorFeaturePresent = lib.declare("IsProcessorFeaturePresent",
|
||||
ctypes.winapi_abi,
|
||||
ctypes.int32_t, /* success */
|
||||
ctypes.uint32_t); /* DWORD */
|
||||
let instructionSet = "unknown";
|
||||
try {
|
||||
if (IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE)) {
|
||||
instructionSet = "SSE3";
|
||||
} else if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) {
|
||||
instructionSet = "SSE2";
|
||||
} else if (IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE)) {
|
||||
instructionSet = "SSE";
|
||||
} else if (IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE)) {
|
||||
instructionSet = "MMX";
|
||||
}
|
||||
} catch (e) {
|
||||
Cu.reportError("Error getting processor instruction set. " +
|
||||
"Exception: " + e);
|
||||
const CPU_EXTENSIONS = ["hasSSE4_2", "hasSSE4_1", "hasSSE4A", "hasSSSE3",
|
||||
"hasSSE3", "hasSSE2", "hasSSE", "hasMMX",
|
||||
"hasNEON", "hasARMv7", "hasARMv6"];
|
||||
for (let ext of CPU_EXTENSIONS) {
|
||||
if (Services.sysinfo.getProperty(ext)) {
|
||||
return ext.substring(3);
|
||||
}
|
||||
|
||||
lib.close();
|
||||
return instructionSet;
|
||||
}
|
||||
|
||||
return "NA";
|
||||
return "error";
|
||||
}
|
||||
|
||||
// Gets the RAM size in megabytes. This will round the value because sysinfo
|
||||
|
|
|
@ -65,6 +65,19 @@ GetPixbufFromImgRequest(imgIRequest* aRequest)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t width = 0, height = 0;
|
||||
const int32_t kBytesPerPixel = 4;
|
||||
// DBUS_MAXIMUM_ARRAY_LENGTH is 64M, there is 60 bytes overhead
|
||||
// for the hints array with only the image payload, 256 is used to give
|
||||
// some breathing room.
|
||||
const int32_t kMaxImageBytes = 64*1024*1024 - 256;
|
||||
image->GetWidth(&width);
|
||||
image->GetHeight(&height);
|
||||
if (width * height * kBytesPerPixel > kMaxImageBytes) {
|
||||
// The image won't fit in a dbus array
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIImageToPixbuf> imgToPixbuf =
|
||||
do_GetService("@mozilla.org/widget/image-to-gdk-pixbuf;1");
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче