Bug 1456435: Make UpdateStyleSheet less bool-happy. r=heycam
MozReview-Commit-ID: FlTD390lMhg
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "nsISupports.h"
|
#include "nsISupports.h"
|
||||||
#include "mozilla/StyleSheet.h"
|
#include "mozilla/StyleSheet.h"
|
||||||
|
#include "mozilla/Result.h"
|
||||||
|
|
||||||
class nsICSSLoaderObserver;
|
class nsICSSLoaderObserver;
|
||||||
class nsIURI;
|
class nsIURI;
|
||||||
@@ -19,6 +20,57 @@ class nsIURI;
|
|||||||
|
|
||||||
class nsIStyleSheetLinkingElement : public nsISupports {
|
class nsIStyleSheetLinkingElement : public nsISupports {
|
||||||
public:
|
public:
|
||||||
|
enum class ForceUpdate
|
||||||
|
{
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class IsAlternate
|
||||||
|
{
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class WillNotify
|
||||||
|
{
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Update
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool mWillNotify;
|
||||||
|
bool mIsAlternate;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Update()
|
||||||
|
: mWillNotify(false)
|
||||||
|
, mIsAlternate(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Update(WillNotify aWillNotify, IsAlternate aIsAlternate)
|
||||||
|
: mWillNotify(aWillNotify == WillNotify::Yes)
|
||||||
|
, mIsAlternate(aIsAlternate == IsAlternate::Yes)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool WillNotify() const
|
||||||
|
{
|
||||||
|
return mWillNotify;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShouldBlock() const
|
||||||
|
{
|
||||||
|
if (!mWillNotify) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !mIsAlternate;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISTYLESHEETLINKINGELEMENT_IID)
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISTYLESHEETLINKINGELEMENT_IID)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,21 +102,12 @@ public:
|
|||||||
*
|
*
|
||||||
* @param aObserver observer to notify once the stylesheet is loaded.
|
* @param aObserver observer to notify once the stylesheet is loaded.
|
||||||
* This will be passed to the CSSLoader
|
* This will be passed to the CSSLoader
|
||||||
* @param [out] aWillNotify whether aObserver will be notified when the sheet
|
|
||||||
* loads. If this is false, then either we didn't
|
|
||||||
* start the sheet load at all, the load failed, or
|
|
||||||
* this was an inline sheet that completely finished
|
|
||||||
* loading. In the case when the load failed the
|
|
||||||
* failure code will be returned.
|
|
||||||
* @param [out] whether the sheet is an alternate sheet. This value is only
|
|
||||||
* meaningful if aWillNotify is true.
|
|
||||||
* @param aForceUpdate whether we wand to force the update, flushing the
|
* @param aForceUpdate whether we wand to force the update, flushing the
|
||||||
* cached version if any.
|
* cached version if any.
|
||||||
*/
|
*/
|
||||||
virtual nsresult UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
|
virtual mozilla::Result<Update, nsresult>
|
||||||
bool *aWillNotify,
|
UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
|
||||||
bool *aIsAlternate,
|
ForceUpdate = ForceUpdate::No) = 0;
|
||||||
bool aForceUpdate = false) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells this element whether to update the stylesheet when the
|
* Tells this element whether to update the stylesheet when the
|
||||||
|
|||||||
@@ -176,13 +176,11 @@ uint32_t nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
|
|||||||
return linkMask;
|
return linkMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
Result<nsStyleLinkElement::Update, nsresult>
|
||||||
nsStyleLinkElement::UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
|
nsStyleLinkElement::UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
|
||||||
bool* aWillNotify,
|
ForceUpdate aForceUpdate)
|
||||||
bool* aIsAlternate,
|
|
||||||
bool aForceReload)
|
|
||||||
{
|
{
|
||||||
if (aForceReload) {
|
if (aForceUpdate == ForceUpdate::Yes) {
|
||||||
// We remove this stylesheet from the cache to load a new version.
|
// We remove this stylesheet from the cache to load a new version.
|
||||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
|
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
|
||||||
nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
|
nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
|
||||||
@@ -192,30 +190,24 @@ nsStyleLinkElement::UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
|
|||||||
doc->CSSLoader()->ObsoleteSheet(mStyleSheet->GetOriginalURI());
|
doc->CSSLoader()->ObsoleteSheet(mStyleSheet->GetOriginalURI());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DoUpdateStyleSheet(nullptr, nullptr, aObserver, aWillNotify,
|
return DoUpdateStyleSheet(nullptr, nullptr, aObserver, aForceUpdate);
|
||||||
aIsAlternate, aForceReload);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
Result<nsStyleLinkElement::Update, nsresult>
|
||||||
nsStyleLinkElement::UpdateStyleSheetInternal(nsIDocument *aOldDocument,
|
nsStyleLinkElement::UpdateStyleSheetInternal(nsIDocument* aOldDocument,
|
||||||
ShadowRoot *aOldShadowRoot,
|
ShadowRoot* aOldShadowRoot,
|
||||||
bool aForceUpdate)
|
ForceUpdate aForceUpdate)
|
||||||
{
|
{
|
||||||
bool notify, alternate;
|
return DoUpdateStyleSheet(
|
||||||
return DoUpdateStyleSheet(aOldDocument, aOldShadowRoot, nullptr, ¬ify,
|
aOldDocument, aOldShadowRoot, nullptr, aForceUpdate);
|
||||||
&alternate, aForceUpdate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
Result<nsStyleLinkElement::Update, nsresult>
|
||||||
nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
||||||
ShadowRoot* aOldShadowRoot,
|
ShadowRoot* aOldShadowRoot,
|
||||||
nsICSSLoaderObserver* aObserver,
|
nsICSSLoaderObserver* aObserver,
|
||||||
bool* aWillNotify,
|
ForceUpdate aForceUpdate)
|
||||||
bool* aIsAlternate,
|
|
||||||
bool aForceUpdate)
|
|
||||||
{
|
{
|
||||||
*aWillNotify = false;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
|
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(this);
|
||||||
// All instances of nsStyleLinkElement should implement nsIContent.
|
// All instances of nsStyleLinkElement should implement nsIContent.
|
||||||
MOZ_ASSERT(thisContent);
|
MOZ_ASSERT(thisContent);
|
||||||
@@ -224,7 +216,7 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
|||||||
thisContent->IsAnonymousContentInSVGUseSubtree()) {
|
thisContent->IsAnonymousContentInSVGUseSubtree()) {
|
||||||
// Stylesheets in <use>-cloned subtrees are disabled until we figure out
|
// Stylesheets in <use>-cloned subtrees are disabled until we figure out
|
||||||
// how they should behave.
|
// how they should behave.
|
||||||
return NS_OK;
|
return Update { };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for a ShadowRoot because link elements are inert in a
|
// Check for a ShadowRoot because link elements are inert in a
|
||||||
@@ -232,7 +224,7 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
|||||||
ShadowRoot* containingShadow = thisContent->GetContainingShadow();
|
ShadowRoot* containingShadow = thisContent->GetContainingShadow();
|
||||||
if (thisContent->IsHTMLElement(nsGkAtoms::link) &&
|
if (thisContent->IsHTMLElement(nsGkAtoms::link) &&
|
||||||
(aOldShadowRoot || containingShadow)) {
|
(aOldShadowRoot || containingShadow)) {
|
||||||
return NS_OK;
|
return Update { };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mStyleSheet && (aOldDocument || aOldShadowRoot)) {
|
if (mStyleSheet && (aOldDocument || aOldShadowRoot)) {
|
||||||
@@ -259,26 +251,25 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
|||||||
// When static documents are created, stylesheets are cloned manually.
|
// When static documents are created, stylesheets are cloned manually.
|
||||||
if (mDontLoadStyle || !mUpdatesEnabled ||
|
if (mDontLoadStyle || !mUpdatesEnabled ||
|
||||||
thisContent->OwnerDoc()->IsStaticDocument()) {
|
thisContent->OwnerDoc()->IsStaticDocument()) {
|
||||||
return NS_OK;
|
return Update { };
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
|
nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
|
||||||
thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
|
thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
|
||||||
if (!doc || !doc->CSSLoader()->GetEnabled()) {
|
if (!doc || !doc->CSSLoader()->GetEnabled()) {
|
||||||
return NS_OK;
|
return Update { };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInline;
|
bool isInline;
|
||||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
|
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
|
||||||
nsCOMPtr<nsIURI> uri = GetStyleSheetURL(&isInline, getter_AddRefs(triggeringPrincipal));
|
nsCOMPtr<nsIURI> uri = GetStyleSheetURL(&isInline, getter_AddRefs(triggeringPrincipal));
|
||||||
|
|
||||||
if (!aForceUpdate && mStyleSheet && !isInline && uri) {
|
if (aForceUpdate == ForceUpdate::No && mStyleSheet && !isInline && uri) {
|
||||||
nsIURI* oldURI = mStyleSheet->GetSheetURI();
|
if (nsIURI* oldURI = mStyleSheet->GetSheetURI()) {
|
||||||
if (oldURI) {
|
|
||||||
bool equal;
|
bool equal;
|
||||||
nsresult rv = oldURI->Equals(uri, &equal);
|
nsresult rv = oldURI->Equals(uri, &equal);
|
||||||
if (NS_SUCCEEDED(rv) && equal) {
|
if (NS_SUCCEEDED(rv) && equal) {
|
||||||
return NS_OK; // We already loaded this stylesheet
|
return Update { };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,20 +288,18 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!uri && !isInline) {
|
if (!uri && !isInline) {
|
||||||
return NS_OK; // If href is empty and this is not inline style then just bail
|
// If href is empty and this is not inline style then just bail
|
||||||
|
return Update { };
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString title, type, media;
|
nsAutoString title, type, media;
|
||||||
bool isAlternate;
|
bool hasAlternateRel;
|
||||||
|
GetStyleSheetInfo(title, type, media, &hasAlternateRel);
|
||||||
GetStyleSheetInfo(title, type, media, &isAlternate);
|
|
||||||
|
|
||||||
if (!type.LowerCaseEqualsLiteral("text/css")) {
|
if (!type.LowerCaseEqualsLiteral("text/css")) {
|
||||||
return NS_OK;
|
return Update { };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool doneLoading = false;
|
bool doneLoading = false;
|
||||||
nsresult rv = NS_OK;
|
|
||||||
|
|
||||||
// Load the link's referrerpolicy attribute. If the link does not provide a
|
// Load the link's referrerpolicy attribute. If the link does not provide a
|
||||||
// referrerpolicy attribute, ignore this and use the document's referrer
|
// referrerpolicy attribute, ignore this and use the document's referrer
|
||||||
@@ -321,27 +310,37 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
|||||||
referrerPolicy = doc->GetReferrerPolicy();
|
referrerPolicy = doc->GetReferrerPolicy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isAlternate;
|
||||||
if (isInline) {
|
if (isInline) {
|
||||||
nsAutoString text;
|
nsAutoString text;
|
||||||
if (!nsContentUtils::GetNodeTextContent(thisContent, false, text, fallible)) {
|
if (!nsContentUtils::GetNodeTextContent(thisContent, false, text, fallible)) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return Err(NS_ERROR_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MOZ_ASSERT(thisContent->NodeInfo()->NameAtom() != nsGkAtoms::link,
|
MOZ_ASSERT(thisContent->NodeInfo()->NameAtom() != nsGkAtoms::link,
|
||||||
"<link> is not 'inline', and needs different CSP checks");
|
"<link> is not 'inline', and needs different CSP checks");
|
||||||
MOZ_ASSERT(thisContent->IsElement());
|
MOZ_ASSERT(thisContent->IsElement());
|
||||||
|
nsresult rv = NS_OK;
|
||||||
if (!nsStyleUtil::CSPAllowsInlineStyle(thisContent->AsElement(),
|
if (!nsStyleUtil::CSPAllowsInlineStyle(thisContent->AsElement(),
|
||||||
thisContent->NodePrincipal(),
|
thisContent->NodePrincipal(),
|
||||||
triggeringPrincipal,
|
triggeringPrincipal,
|
||||||
doc->GetDocumentURI(),
|
doc->GetDocumentURI(),
|
||||||
mLineNumber, text, &rv))
|
mLineNumber, text, &rv)) {
|
||||||
return rv;
|
if (NS_FAILED(rv)) {
|
||||||
|
return Err(rv);
|
||||||
|
}
|
||||||
|
return Update { };
|
||||||
|
}
|
||||||
|
|
||||||
// Parse the style sheet.
|
// Parse the style sheet.
|
||||||
rv = doc->CSSLoader()->
|
rv = doc->CSSLoader()->
|
||||||
LoadInlineStyle(thisContent, text, triggeringPrincipal, mLineNumber,
|
LoadInlineStyle(thisContent, text, triggeringPrincipal, mLineNumber,
|
||||||
title, media, referrerPolicy,
|
title, media, referrerPolicy,
|
||||||
aObserver, &doneLoading, &isAlternate);
|
aObserver, &doneLoading, &isAlternate);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return Err(rv);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
nsAutoString integrity;
|
nsAutoString integrity;
|
||||||
if (thisContent->IsElement()) {
|
if (thisContent->IsElement()) {
|
||||||
@@ -354,24 +353,19 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
|||||||
NS_ConvertUTF16toUTF8(integrity).get()));
|
NS_ConvertUTF16toUTF8(integrity).get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = doc->CSSLoader()->
|
nsresult rv = doc->CSSLoader()->
|
||||||
LoadStyleLink(thisContent, uri, triggeringPrincipal, title, media,
|
LoadStyleLink(thisContent, uri, triggeringPrincipal, title, media,
|
||||||
isAlternate, GetCORSMode(), referrerPolicy, integrity,
|
hasAlternateRel, GetCORSMode(), referrerPolicy, integrity,
|
||||||
aObserver, &isAlternate);
|
aObserver, &isAlternate);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
// Don't propagate LoadStyleLink() errors further than this, since some
|
// Don't propagate LoadStyleLink() errors further than this, since some
|
||||||
// consumers (e.g. nsXMLContentSink) will completely abort on innocuous
|
// consumers (e.g. nsXMLContentSink) will completely abort on innocuous
|
||||||
// things like a stylesheet load being blocked by the security system.
|
// things like a stylesheet load being blocked by the security system.
|
||||||
doneLoading = true;
|
return Update { };
|
||||||
isAlternate = false;
|
|
||||||
rv = NS_OK;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
auto willNotify = doneLoading ? WillNotify::No : WillNotify::Yes;
|
||||||
|
auto alternate = isAlternate ? IsAlternate::Yes : IsAlternate::No;
|
||||||
*aWillNotify = !doneLoading;
|
return Update { willNotify, alternate };
|
||||||
*aIsAlternate = isAlternate;
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/CORSMode.h"
|
#include "mozilla/CORSMode.h"
|
||||||
#include "mozilla/StyleSheetInlines.h"
|
#include "mozilla/StyleSheetInlines.h"
|
||||||
|
#include "mozilla/Unused.h"
|
||||||
#include "mozilla/net/ReferrerPolicy.h"
|
#include "mozilla/net/ReferrerPolicy.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIStyleSheetLinkingElement.h"
|
#include "nsIStyleSheetLinkingElement.h"
|
||||||
@@ -45,16 +46,16 @@ public:
|
|||||||
void SetStyleSheet(mozilla::StyleSheet* aStyleSheet) override;
|
void SetStyleSheet(mozilla::StyleSheet* aStyleSheet) override;
|
||||||
mozilla::StyleSheet* GetStyleSheet() override;
|
mozilla::StyleSheet* GetStyleSheet() override;
|
||||||
void InitStyleLinkElement(bool aDontLoadStyle) override;
|
void InitStyleLinkElement(bool aDontLoadStyle) override;
|
||||||
nsresult UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
|
|
||||||
bool* aWillNotify,
|
mozilla::Result<Update, nsresult>
|
||||||
bool* aIsAlternate,
|
UpdateStyleSheet(nsICSSLoaderObserver*, ForceUpdate) override;
|
||||||
bool aForceReload) override;
|
|
||||||
void SetEnableUpdates(bool aEnableUpdates) override;
|
void SetEnableUpdates(bool aEnableUpdates) override;
|
||||||
void GetCharset(nsAString& aCharset) override;
|
void GetCharset(nsAString& aCharset) override;
|
||||||
|
|
||||||
virtual void OverrideBaseURI(nsIURI* aNewBaseURI) override;
|
void OverrideBaseURI(nsIURI* aNewBaseURI) override;
|
||||||
virtual void SetLineNumber(uint32_t aLineNumber) override;
|
void SetLineNumber(uint32_t aLineNumber) override;
|
||||||
virtual uint32_t GetLineNumber() override;
|
uint32_t GetLineNumber() override;
|
||||||
|
|
||||||
enum RelValue {
|
enum RelValue {
|
||||||
ePREFETCH = 0x00000001,
|
ePREFETCH = 0x00000001,
|
||||||
@@ -72,20 +73,25 @@ public:
|
|||||||
|
|
||||||
void UpdateStyleSheetInternal()
|
void UpdateStyleSheetInternal()
|
||||||
{
|
{
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr);
|
mozilla::Unused << UpdateStyleSheetInternal(nullptr, nullptr);
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @param aOldDocument should be non-null only if we're updating because we
|
* @param aOldDocument should be non-null only if we're updating because we
|
||||||
* removed the node from the document.
|
* removed the node from the document.
|
||||||
|
* @param aOldShadowRoot should be non-null only if we're updating because we
|
||||||
|
* removed the node from a shadow tree.
|
||||||
* @param aForceUpdate true will force the update even if the URI has not
|
* @param aForceUpdate true will force the update even if the URI has not
|
||||||
* changed. This should be used in cases when something
|
* changed. This should be used in cases when something
|
||||||
* about the content that affects the resulting sheet
|
* about the content that affects the resulting sheet
|
||||||
* changed but the URI may not have changed.
|
* changed but the URI may not have changed.
|
||||||
|
*
|
||||||
|
* TODO(emilio): Should probably pass a single DocumentOrShadowRoot.
|
||||||
*/
|
*/
|
||||||
nsresult UpdateStyleSheetInternal(nsIDocument *aOldDocument,
|
mozilla::Result<Update, nsresult> UpdateStyleSheetInternal(
|
||||||
mozilla::dom::ShadowRoot *aOldShadowRoot,
|
nsIDocument* aOldDocument,
|
||||||
bool aForceUpdate = false);
|
mozilla::dom::ShadowRoot* aOldShadowRoot,
|
||||||
|
ForceUpdate = ForceUpdate::No);
|
||||||
|
|
||||||
virtual already_AddRefed<nsIURI> GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal) = 0;
|
virtual already_AddRefed<nsIURI> GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal) = 0;
|
||||||
virtual void GetStyleSheetInfo(nsAString& aTitle,
|
virtual void GetStyleSheetInfo(nsAString& aTitle,
|
||||||
@@ -121,12 +127,11 @@ private:
|
|||||||
* about the content that affects the resulting sheet
|
* about the content that affects the resulting sheet
|
||||||
* changed but the URI may not have changed.
|
* changed but the URI may not have changed.
|
||||||
*/
|
*/
|
||||||
nsresult DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
mozilla::Result<Update, nsresult>
|
||||||
mozilla::dom::ShadowRoot* aOldShadowRoot,
|
DoUpdateStyleSheet(nsIDocument* aOldDocument,
|
||||||
nsICSSLoaderObserver* aObserver,
|
mozilla::dom::ShadowRoot* aOldShadowRoot,
|
||||||
bool* aWillNotify,
|
nsICSSLoaderObserver* aObserver,
|
||||||
bool* aIsAlternate,
|
ForceUpdate);
|
||||||
bool aForceUpdate);
|
|
||||||
|
|
||||||
RefPtr<mozilla::StyleSheet> mStyleSheet;
|
RefPtr<mozilla::StyleSheet> mStyleSheet;
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ HTMLLinkElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||||||
CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMLinkRemoved"));
|
CreateAndDispatchEvent(oldDoc, NS_LITERAL_STRING("DOMLinkRemoved"));
|
||||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||||
|
|
||||||
UpdateStyleSheetInternal(oldDoc, oldShadowRoot);
|
Unused << UpdateStyleSheetInternal(oldDoc, oldShadowRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -328,11 +328,13 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
|||||||
UpdatePreload(aName, aValue, aOldValue);
|
UpdatePreload(aName, aValue, aOldValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr,
|
const bool forceUpdate = dropSheet ||
|
||||||
dropSheet ||
|
aName == nsGkAtoms::title ||
|
||||||
(aName == nsGkAtoms::title ||
|
aName == nsGkAtoms::media ||
|
||||||
aName == nsGkAtoms::media ||
|
aName == nsGkAtoms::type;
|
||||||
aName == nsGkAtoms::type));
|
|
||||||
|
Unused << UpdateStyleSheetInternal(
|
||||||
|
nullptr, nullptr, forceUpdate ? ForceUpdate::Yes : ForceUpdate::No);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Since removing href or rel makes us no longer link to a
|
// Since removing href or rel makes us no longer link to a
|
||||||
@@ -343,7 +345,7 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
|||||||
aName == nsGkAtoms::title ||
|
aName == nsGkAtoms::title ||
|
||||||
aName == nsGkAtoms::media ||
|
aName == nsGkAtoms::media ||
|
||||||
aName == nsGkAtoms::type) {
|
aName == nsGkAtoms::type) {
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr, true);
|
Unused << UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes);
|
||||||
}
|
}
|
||||||
if ((aName == nsGkAtoms::as || aName == nsGkAtoms::type ||
|
if ((aName == nsGkAtoms::as || aName == nsGkAtoms::type ||
|
||||||
aName == nsGkAtoms::crossorigin || aName == nsGkAtoms::media) &&
|
aName == nsGkAtoms::crossorigin || aName == nsGkAtoms::media) &&
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ HTMLStyleElement::ContentChanged(nsIContent* aContent)
|
|||||||
{
|
{
|
||||||
mTriggeringPrincipal = nullptr;
|
mTriggeringPrincipal = nullptr;
|
||||||
if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
|
if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr);
|
Unused << UpdateStyleSheetInternal(nullptr, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ HTMLStyleElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateStyleSheetInternal(oldDoc, oldShadow);
|
Unused << UpdateStyleSheetInternal(oldDoc, oldShadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
@@ -144,7 +144,7 @@ HTMLStyleElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
|||||||
if (aName == nsGkAtoms::title ||
|
if (aName == nsGkAtoms::title ||
|
||||||
aName == nsGkAtoms::media ||
|
aName == nsGkAtoms::media ||
|
||||||
aName == nsGkAtoms::type) {
|
aName == nsGkAtoms::type) {
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr, true);
|
Unused << UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ HTMLStyleElement::SetTextContentInternal(const nsAString& aTextContent,
|
|||||||
|
|
||||||
mTriggeringPrincipal = aScriptedPrincipal;
|
mTriggeringPrincipal = aScriptedPrincipal;
|
||||||
|
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr);
|
Unused << UpdateStyleSheetInternal(nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIURI>
|
already_AddRefed<nsIURI>
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ SVGStyleElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||||||
nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc();
|
nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc();
|
||||||
ShadowRoot* oldShadow = GetContainingShadow();
|
ShadowRoot* oldShadow = GetContainingShadow();
|
||||||
SVGStyleElementBase::UnbindFromTree(aDeep, aNullParent);
|
SVGStyleElementBase::UnbindFromTree(aDeep, aNullParent);
|
||||||
UpdateStyleSheetInternal(oldDoc, oldShadow);
|
Unused << UpdateStyleSheetInternal(oldDoc, oldShadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
@@ -100,7 +100,7 @@ SVGStyleElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
|||||||
if (aName == nsGkAtoms::title ||
|
if (aName == nsGkAtoms::title ||
|
||||||
aName == nsGkAtoms::media ||
|
aName == nsGkAtoms::media ||
|
||||||
aName == nsGkAtoms::type) {
|
aName == nsGkAtoms::type) {
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr, true);
|
Unused << UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ void
|
|||||||
SVGStyleElement::ContentChanged(nsIContent* aContent)
|
SVGStyleElement::ContentChanged(nsIContent* aContent)
|
||||||
{
|
{
|
||||||
if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
|
if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr);
|
Unused << UpdateStyleSheetInternal(nullptr, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ XMLStylesheetProcessingInstruction::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||||||
nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc();
|
nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc();
|
||||||
|
|
||||||
ProcessingInstruction::UnbindFromTree(aDeep, aNullParent);
|
ProcessingInstruction::UnbindFromTree(aDeep, aNullParent);
|
||||||
UpdateStyleSheetInternal(oldDoc, nullptr);
|
Unused << UpdateStyleSheetInternal(oldDoc, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsIDOMNode
|
// nsIDOMNode
|
||||||
@@ -80,7 +80,7 @@ XMLStylesheetProcessingInstruction::SetNodeValueInternal(const nsAString& aNodeV
|
|||||||
{
|
{
|
||||||
CharacterData::SetNodeValueInternal(aNodeValue, aError);
|
CharacterData::SetNodeValueInternal(aNodeValue, aError);
|
||||||
if (!aError.Failed()) {
|
if (!aError.Failed()) {
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr, true);
|
Unused << UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#define mozilla_dom_XMLStylesheetProcessingInstruction_h
|
#define mozilla_dom_XMLStylesheetProcessingInstruction_h
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/Unused.h"
|
||||||
#include "mozilla/dom/ProcessingInstruction.h"
|
#include "mozilla/dom/ProcessingInstruction.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsStyleLinkElement.h"
|
#include "nsStyleLinkElement.h"
|
||||||
@@ -68,7 +69,7 @@ public:
|
|||||||
if (rv.Failed()) {
|
if (rv.Failed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UpdateStyleSheetInternal(nullptr, nullptr, true);
|
Unused << UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -603,12 +603,11 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
|
|||||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aContent));
|
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aContent));
|
||||||
if (ssle) {
|
if (ssle) {
|
||||||
ssle->SetEnableUpdates(true);
|
ssle->SetEnableUpdates(true);
|
||||||
bool willNotify;
|
auto updateOrError =
|
||||||
bool isAlternate;
|
ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this);
|
||||||
rv = ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this,
|
if (updateOrError.isErr()) {
|
||||||
&willNotify,
|
rv = updateOrError.unwrapErr();
|
||||||
&isAlternate);
|
} else if (updateOrError.unwrap().ShouldBlock() && !mRunsToCompletion) {
|
||||||
if (NS_SUCCEEDED(rv) && willNotify && !isAlternate && !mRunsToCompletion) {
|
|
||||||
++mPendingSheetCount;
|
++mPendingSheetCount;
|
||||||
mScriptLoader->AddParserBlockingScriptExecutionBlocker();
|
mScriptLoader->AddParserBlockingScriptExecutionBlocker();
|
||||||
}
|
}
|
||||||
@@ -1268,20 +1267,19 @@ nsXMLContentSink::HandleProcessingInstruction(const char16_t *aTarget,
|
|||||||
// This is an xml-stylesheet processing instruction... but it might not be
|
// This is an xml-stylesheet processing instruction... but it might not be
|
||||||
// a CSS one if the type is set to something else.
|
// a CSS one if the type is set to something else.
|
||||||
ssle->SetEnableUpdates(true);
|
ssle->SetEnableUpdates(true);
|
||||||
bool willNotify;
|
auto updateOrError =
|
||||||
bool isAlternate;
|
ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this);
|
||||||
rv = ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this,
|
if (updateOrError.isErr()) {
|
||||||
&willNotify,
|
return updateOrError.unwrapErr();
|
||||||
&isAlternate);
|
}
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (willNotify) {
|
auto update = updateOrError.unwrap();
|
||||||
|
if (update.WillNotify()) {
|
||||||
// Successfully started a stylesheet load
|
// Successfully started a stylesheet load
|
||||||
if (!isAlternate && !mRunsToCompletion) {
|
if (update.ShouldBlock() && !mRunsToCompletion) {
|
||||||
++mPendingSheetCount;
|
++mPendingSheetCount;
|
||||||
mScriptLoader->AddParserBlockingScriptExecutionBlocker();
|
mScriptLoader->AddParserBlockingScriptExecutionBlocker();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,11 +322,10 @@ txMozillaXMLOutput::endElement()
|
|||||||
do_QueryInterface(mCurrentNode);
|
do_QueryInterface(mCurrentNode);
|
||||||
if (ssle) {
|
if (ssle) {
|
||||||
ssle->SetEnableUpdates(true);
|
ssle->SetEnableUpdates(true);
|
||||||
bool willNotify;
|
auto updateOrError = ssle->UpdateStyleSheet(mNotifier);
|
||||||
bool isAlternate;
|
if (mNotifier &&
|
||||||
nsresult rv = ssle->UpdateStyleSheet(mNotifier, &willNotify,
|
updateOrError.isOk() &&
|
||||||
&isAlternate);
|
updateOrError.unwrap().ShouldBlock()) {
|
||||||
if (mNotifier && NS_SUCCEEDED(rv) && willNotify && !isAlternate) {
|
|
||||||
mNotifier->AddPendingStylesheet();
|
mNotifier->AddPendingStylesheet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -400,10 +399,10 @@ txMozillaXMLOutput::processingInstruction(const nsString& aTarget, const nsStrin
|
|||||||
|
|
||||||
if (ssle) {
|
if (ssle) {
|
||||||
ssle->SetEnableUpdates(true);
|
ssle->SetEnableUpdates(true);
|
||||||
bool willNotify;
|
auto updateOrError = ssle->UpdateStyleSheet(mNotifier);
|
||||||
bool isAlternate;
|
if (mNotifier &&
|
||||||
rv = ssle->UpdateStyleSheet(mNotifier, &willNotify, &isAlternate);
|
updateOrError.isOk() &&
|
||||||
if (mNotifier && NS_SUCCEEDED(rv) && willNotify && !isAlternate) {
|
updateOrError.unwrap().ShouldBlock()) {
|
||||||
mNotifier->AddPendingStylesheet();
|
mNotifier->AddPendingStylesheet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2104,18 +2104,20 @@ XULDocument::InsertXMLStylesheetPI(const nsXULPrototypePI* aProtoPI,
|
|||||||
|
|
||||||
// load the stylesheet if necessary, passing ourselves as
|
// load the stylesheet if necessary, passing ourselves as
|
||||||
// nsICSSObserver
|
// nsICSSObserver
|
||||||
bool willNotify;
|
auto result = ssle->UpdateStyleSheet(this);
|
||||||
bool isAlternate;
|
if (result.isErr()) {
|
||||||
rv = ssle->UpdateStyleSheet(this, &willNotify, &isAlternate);
|
// Ignore errors from UpdateStyleSheet; we don't want failure to
|
||||||
if (NS_SUCCEEDED(rv) && willNotify && !isAlternate) {
|
// do that to break the XUL document load. But do propagate out
|
||||||
++mPendingSheets;
|
// NS_ERROR_OUT_OF_MEMORY.
|
||||||
|
if (result.unwrapErr() == NS_ERROR_OUT_OF_MEMORY) {
|
||||||
|
return result.unwrapErr();
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore errors from UpdateStyleSheet; we don't want failure to
|
auto update = result.unwrap();
|
||||||
// do that to break the XUL document load. But do propagate out
|
if (update.ShouldBlock()) {
|
||||||
// NS_ERROR_OUT_OF_MEMORY.
|
++mPendingSheets;
|
||||||
if (rv == NS_ERROR_OUT_OF_MEMORY) {
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@@ -2492,10 +2494,7 @@ XULDocument::ResumeWalk()
|
|||||||
do_QueryInterface(element);
|
do_QueryInterface(element);
|
||||||
NS_ASSERTION(ssle, "<html:style> doesn't implement "
|
NS_ASSERTION(ssle, "<html:style> doesn't implement "
|
||||||
"nsIStyleSheetLinkingElement?");
|
"nsIStyleSheetLinkingElement?");
|
||||||
bool willNotify;
|
Unused << ssle->UpdateStyleSheet(nullptr);
|
||||||
bool isAlternate;
|
|
||||||
ssle->UpdateStyleSheet(nullptr, &willNotify,
|
|
||||||
&isAlternate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -840,6 +840,9 @@ Loader::IsAlternate(const nsAString& aTitle, bool aHasAlternateRel)
|
|||||||
// style set, the sheet wasn't marked as an alternate explicitly, and aTitle
|
// style set, the sheet wasn't marked as an alternate explicitly, and aTitle
|
||||||
// is nonempty, we should select the style set corresponding to aTitle, since
|
// is nonempty, we should select the style set corresponding to aTitle, since
|
||||||
// that's a preferred sheet.
|
// that's a preferred sheet.
|
||||||
|
//
|
||||||
|
// FIXME(emilio): This should return false for Shadow DOM regardless of the
|
||||||
|
// document.
|
||||||
if (aTitle.IsEmpty()) {
|
if (aTitle.IsEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,11 +79,12 @@ nsHtml5DocumentBuilder::UpdateStyleSheet(nsIContent* aElement)
|
|||||||
|
|
||||||
ssle->SetEnableUpdates(true);
|
ssle->SetEnableUpdates(true);
|
||||||
|
|
||||||
bool willNotify;
|
auto updateOrError =
|
||||||
bool isAlternate;
|
ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this);
|
||||||
nsresult rv = ssle->UpdateStyleSheet(
|
|
||||||
mRunsToCompletion ? nullptr : this, &willNotify, &isAlternate);
|
if (updateOrError.isOk() &&
|
||||||
if (NS_SUCCEEDED(rv) && willNotify && !isAlternate && !mRunsToCompletion) {
|
updateOrError.unwrap().ShouldBlock() &&
|
||||||
|
!mRunsToCompletion) {
|
||||||
++mPendingSheetCount;
|
++mPendingSheetCount;
|
||||||
mScriptLoader->AddParserBlockingScriptExecutionBlocker();
|
mScriptLoader->AddParserBlockingScriptExecutionBlocker();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user