summaryrefslogtreecommitdiffstats
path: root/dom/base
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base')
-rw-r--r--dom/base/nsContentPolicy.cpp21
-rw-r--r--dom/base/nsContentUtils.cpp9
-rw-r--r--dom/base/nsContentUtils.h6
-rw-r--r--dom/base/nsDocument.cpp57
-rw-r--r--dom/base/nsDocument.h11
-rw-r--r--dom/base/nsDocumentEncoder.cpp39
-rw-r--r--dom/base/nsGkAtomList.h1
-rw-r--r--dom/base/nsGlobalWindow.cpp60
-rw-r--r--dom/base/nsHTMLContentSerializer.cpp1
-rw-r--r--dom/base/nsHTMLContentSerializer.h1
-rw-r--r--dom/base/nsIContentSerializer.h1
-rw-r--r--dom/base/nsIDocument.h10
-rw-r--r--dom/base/nsIImageLoadingContent.idl9
-rw-r--r--dom/base/nsImageLoadingContent.cpp101
-rw-r--r--dom/base/nsImageLoadingContent.h17
-rw-r--r--dom/base/nsObjectLoadingContent.cpp14
-rw-r--r--dom/base/nsPlainTextSerializer.cpp59
-rw-r--r--dom/base/nsPlainTextSerializer.h5
-rw-r--r--dom/base/nsScriptLoader.cpp65
-rw-r--r--dom/base/nsScriptLoader.h2
-rwxr-xr-xdom/base/nsXHTMLContentSerializer.cpp3
-rw-r--r--dom/base/nsXHTMLContentSerializer.h1
-rw-r--r--dom/base/nsXMLContentSerializer.cpp9
-rw-r--r--dom/base/nsXMLContentSerializer.h2
24 files changed, 316 insertions, 188 deletions
diff --git a/dom/base/nsContentPolicy.cpp b/dom/base/nsContentPolicy.cpp
index 5511b9086..534466103 100644
--- a/dom/base/nsContentPolicy.cpp
+++ b/dom/base/nsContentPolicy.cpp
@@ -22,6 +22,7 @@
#include "nsIDOMWindow.h"
#include "nsITabChild.h"
#include "nsIContent.h"
+#include "nsIImageLoadingContent.h"
#include "nsILoadContext.h"
#include "nsCOMArray.h"
#include "nsContentUtils.h"
@@ -145,6 +146,16 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
decision);
if (NS_SUCCEEDED(rv) && NS_CP_REJECTED(*decision)) {
+ // If we are blocking an image, we have to let the
+ // ImageLoadingContent know that we blocked the load.
+ if (externalType == nsIContentPolicy::TYPE_IMAGE ||
+ externalType == nsIContentPolicy::TYPE_IMAGESET) {
+ nsCOMPtr<nsIImageLoadingContent> img =
+ do_QueryInterface(requestingContext);
+ if (img) {
+ img->SetBlockedRequest(*decision);
+ }
+ }
/* policy says no, no point continuing to check */
return NS_OK;
}
@@ -193,6 +204,16 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
decision);
if (NS_SUCCEEDED(rv) && NS_CP_REJECTED(*decision)) {
+ // If we are blocking an image, we have to let the
+ // ImageLoadingContent know that we blocked the load.
+ if (externalType == nsIContentPolicy::TYPE_IMAGE ||
+ externalType == nsIContentPolicy::TYPE_IMAGESET) {
+ nsCOMPtr<nsIImageLoadingContent> img =
+ do_QueryInterface(requestingContext);
+ if (img) {
+ img->SetBlockedRequest(*decision);
+ }
+ }
/* policy says no, no point continuing to check */
return NS_OK;
}
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 1f9c17947..800f40fa1 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -8478,12 +8478,9 @@ nsContentUtils::InternalContentPolicyTypeToExternalOrWorker(nsContentPolicyType
bool
nsContentUtils::IsPreloadType(nsContentPolicyType aType)
{
- if (aType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD ||
- aType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD ||
- aType == nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD) {
- return true;
- }
- return false;
+ return (aType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD ||
+ aType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD ||
+ aType == nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD);
}
nsresult
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index 299a8e859..606d67de9 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -9,10 +9,14 @@
#ifndef nsContentUtils_h___
#define nsContentUtils_h___
-#if defined(XP_WIN)
+#ifdef XP_WIN
#include <float.h>
#endif
+#ifdef XP_SOLARIS
+#include <ieeefp.h>
+#endif
+
#include "js/TypeDecls.h"
#include "js/Value.h"
#include "js/RootingAPI.h"
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index d8abc174f..e2be6b664 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -395,6 +395,21 @@ nsIdentifierMapEntry::FireChangeCallbacks(Element* aOldElement,
}
}
+void
+nsIdentifierMapEntry::ClearAndNotify()
+{
+ Element* currentElement = mIdContentList.SafeElementAt(0);
+ mIdContentList.Clear();
+ if (currentElement) {
+ FireChangeCallbacks(currentElement, nullptr);
+ }
+ mNameContentList = nullptr;
+ if (mImageElement) {
+ SetImageElement(nullptr);
+ }
+ mChangeCallbacks = nullptr;
+}
+
namespace {
struct PositionComparator
@@ -1422,12 +1437,12 @@ nsDocument::~nsDocument()
delete mSubDocuments;
mSubDocuments = nullptr;
+ nsAutoScriptBlocker scriptBlocker;
+
// Destroy link map now so we don't waste time removing
// links one by one
DestroyElementMaps();
- nsAutoScriptBlocker scriptBlocker;
-
for (uint32_t indx = mChildren.ChildCount(); indx-- != 0; ) {
mChildren.ChildAt(indx)->UnbindFromTree();
mChildren.RemoveChildAt(indx);
@@ -1972,15 +1987,16 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
delete mSubDocuments;
mSubDocuments = nullptr;
- // Destroy link map now so we don't waste time removing
- // links one by one
- DestroyElementMaps();
-
bool oldVal = mInUnlinkOrDeletion;
mInUnlinkOrDeletion = true;
uint32_t count = mChildren.ChildCount();
{ // Scope for update
MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_MODEL, true);
+
+ // Destroy link map now so we don't waste time removing
+ // links one by one
+ DestroyElementMaps();
+
for (int32_t i = int32_t(count) - 1; i >= 0; i--) {
nsCOMPtr<nsIContent> content = mChildren.ChildAt(i);
@@ -8955,7 +8971,14 @@ nsDocument::DestroyElementMaps()
mStyledLinksCleared = true;
#endif
mStyledLinks.Clear();
+
+ // Notify ID change listeners before clearing the identifier map.
+ for (auto iter = mIdentifierMap.Iter(); !iter.Done(); iter.Next()) {
+ iter.Get()->ClearAndNotify();
+ }
+
mIdentifierMap.Clear();
+
++mExpandoAndGeneration.generation;
}
@@ -9222,19 +9245,23 @@ already_AddRefed<nsIURI>
nsDocument::ResolvePreloadImage(nsIURI *aBaseURI,
const nsAString& aSrcAttr,
const nsAString& aSrcsetAttr,
- const nsAString& aSizesAttr)
+ const nsAString& aSizesAttr,
+ bool *aIsImgSet)
{
nsString sourceURL;
+ bool isImgSet;
if (mPreloadPictureDepth == 1 && !mPreloadPictureFoundSource.IsVoid()) {
// We're in a <picture> element and found a URI from a source previous to
// this image, use it.
sourceURL = mPreloadPictureFoundSource;
+ isImgSet = true;
} else {
// Otherwise try to use this <img> as a source
HTMLImageElement::SelectSourceForTagWithAttrs(this, false, aSrcAttr,
aSrcsetAttr, aSizesAttr,
NullString(), NullString(),
sourceURL);
+ isImgSet = !aSrcsetAttr.IsEmpty();
}
// Empty sources are not loaded by <img> (i.e. not resolved to the baseURI)
@@ -9252,6 +9279,8 @@ nsDocument::ResolvePreloadImage(nsIURI *aBaseURI,
return nullptr;
}
+ *aIsImgSet = isImgSet;
+
// We don't clear mPreloadPictureFoundSource because subsequent <img> tags in
// this this <picture> share the same <sources> (though this is not valid per
// spec)
@@ -9260,16 +9289,12 @@ nsDocument::ResolvePreloadImage(nsIURI *aBaseURI,
void
nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr,
- ReferrerPolicy aReferrerPolicy)
+ ReferrerPolicy aReferrerPolicy, bool aIsImgSet)
{
// Early exit if the img is already present in the img-cache
// which indicates that the "real" load has already started and
// that we shouldn't preload it.
- int16_t blockingStatus;
- if (nsContentUtils::IsImageInCache(uri, static_cast<nsIDocument *>(this)) ||
- !nsContentUtils::CanLoadImage(uri, static_cast<nsIDocument *>(this),
- this, NodePrincipal(), &blockingStatus,
- nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD)) {
+ if (nsContentUtils::IsImageInCache(uri, static_cast<nsIDocument *>(this))) {
return;
}
@@ -9288,6 +9313,10 @@ nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr,
MOZ_CRASH("Unknown CORS mode!");
}
+ nsContentPolicyType policyType =
+ aIsImgSet ? nsIContentPolicy::TYPE_IMAGESET :
+ nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD;
+
// Image not in cache - trigger preload
RefPtr<imgRequestProxy> request;
nsresult rv =
@@ -9301,7 +9330,7 @@ nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr,
loadFlags,
NS_LITERAL_STRING("img"),
getter_AddRefs(request),
- nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD);
+ policyType);
// Pin image-reference to avoid evicting it from the img-cache before
// the "real" load occurs. Unpinned in DispatchContentLoadedEvents and
diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h
index 95fd57545..ac600eb43 100644
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -216,6 +216,11 @@ public:
void RemoveContentChangeCallback(nsIDocument::IDTargetObserver aCallback,
void* aData, bool aForImage);
+ /**
+ * Remove all elements and notify change listeners.
+ */
+ void ClearAndNotify();
+
void Traverse(nsCycleCollectionTraversalCallback* aCallback);
struct ChangeCallback {
@@ -948,11 +953,13 @@ public:
ResolvePreloadImage(nsIURI *aBaseURI,
const nsAString& aSrcAttr,
const nsAString& aSrcsetAttr,
- const nsAString& aSizesAttr) override;
+ const nsAString& aSizesAttr,
+ bool *aIsImgSet) override;
virtual void MaybePreLoadImage(nsIURI* uri,
const nsAString &aCrossOriginAttr,
- ReferrerPolicy aReferrerPolicy) override;
+ ReferrerPolicy aReferrerPolicy,
+ bool aIsImgSet) override;
virtual void ForgetImagePreload(nsIURI* aURI) override;
virtual void MaybePreconnect(nsIURI* uri,
diff --git a/dom/base/nsDocumentEncoder.cpp b/dom/base/nsDocumentEncoder.cpp
index 84b128b15..34eb6ed38 100644
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -82,7 +82,9 @@ protected:
nsAString& aStr,
bool aDontSerializeRoot,
uint32_t aMaxLength = 0);
- nsresult SerializeNodeEnd(nsINode* aNode, nsAString& aStr);
+ nsresult SerializeNodeEnd(nsINode* aOriginalNode,
+ nsAString& aStr,
+ nsINode* aFixupNode = nullptr);
// This serializes the content of aNode.
nsresult SerializeToStringIterative(nsINode* aNode,
nsAString& aStr);
@@ -405,14 +407,37 @@ nsDocumentEncoder::SerializeNodeStart(nsINode* aNode,
}
nsresult
-nsDocumentEncoder::SerializeNodeEnd(nsINode* aNode,
- nsAString& aStr)
+nsDocumentEncoder::SerializeNodeEnd(nsINode* aOriginalNode,
+ nsAString& aStr,
+ nsINode* aFixupNode)
{
- if (!IsVisibleNode(aNode))
+ if (!IsVisibleNode(aOriginalNode))
return NS_OK;
- if (aNode->IsElement()) {
- mSerializer->AppendElementEnd(aNode->AsElement(), aStr);
+ nsINode* node = nullptr;
+ nsCOMPtr<nsINode> fixedNodeKungfuDeathGrip;
+
+ // Caller didn't do fixup, so we'll do it ourselves
+ if (!aFixupNode) {
+ aFixupNode = aOriginalNode;
+ if (mNodeFixup) {
+ bool dummy;
+ nsCOMPtr<nsIDOMNode> domNodeIn = do_QueryInterface(aOriginalNode);
+ nsCOMPtr<nsIDOMNode> domNodeOut;
+ mNodeFixup->FixupNode(domNodeIn, &dummy, getter_AddRefs(domNodeOut));
+ fixedNodeKungfuDeathGrip = do_QueryInterface(domNodeOut);
+ node = fixedNodeKungfuDeathGrip;
+ }
+ }
+
+ // Fall back to original node if needed.
+ if (!node)
+ node = aOriginalNode;
+
+ if (node->IsElement()) {
+ mSerializer->AppendElementEnd(node->AsElement(),
+ aOriginalNode->AsElement(),
+ aStr);
}
return NS_OK;
}
@@ -481,7 +506,7 @@ nsDocumentEncoder::SerializeToStringRecursive(nsINode* aNode,
}
if (!aDontSerializeRoot) {
- rv = SerializeNodeEnd(maybeFixedNode, aStr);
+ rv = SerializeNodeEnd(aNode, aStr, maybeFixedNode);
NS_ENSURE_SUCCESS(rv, rv);
}
diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h
index 8fefa0e02..73a3a02b1 100644
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -665,6 +665,7 @@ GK_ATOM(noembed, "noembed")
GK_ATOM(noframes, "noframes")
GK_ATOM(nohref, "nohref")
GK_ATOM(noisolation, "noisolation")
+GK_ATOM(nomodule, "nomodule")
GK_ATOM(nonce, "nonce")
GK_ATOM(none, "none")
GK_ATOM(noresize, "noresize")
diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
index afaa24f09..47b46dda0 100644
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -1026,11 +1026,6 @@ public:
return false;
}
- virtual bool watch(JSContext *cx, JS::Handle<JSObject*> proxy,
- JS::Handle<jsid> id, JS::Handle<JSObject*> callable) const override;
- virtual bool unwatch(JSContext *cx, JS::Handle<JSObject*> proxy,
- JS::Handle<jsid> id) const override;
-
static void ObjectMoved(JSObject *obj, const JSObject *old);
static const nsOuterWindowProxy singleton;
@@ -1398,20 +1393,6 @@ nsOuterWindowProxy::AppendIndexedPropertyNames(JSContext *cx, JSObject *proxy,
return true;
}
-bool
-nsOuterWindowProxy::watch(JSContext *cx, JS::Handle<JSObject*> proxy,
- JS::Handle<jsid> id, JS::Handle<JSObject*> callable) const
-{
- return js::WatchGuts(cx, proxy, id, callable);
-}
-
-bool
-nsOuterWindowProxy::unwatch(JSContext *cx, JS::Handle<JSObject*> proxy,
- JS::Handle<jsid> id) const
-{
- return js::UnwatchGuts(cx, proxy, id);
-}
-
void
nsOuterWindowProxy::ObjectMoved(JSObject *obj, const JSObject *old)
{
@@ -3224,6 +3205,12 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
newInnerWindow->mLocalStorage = nullptr;
newInnerWindow->mSessionStorage = nullptr;
+ newInnerWindow->mPerformance = nullptr;
+
+ // This must be called after nulling the internal objects because
+ // we might recreate them here by calling the getter methods, and
+ // store them into the JS slots. If we null them after, the slot
+ // values and the objects will be out of sync.
newInnerWindow->ClearDocumentDependentSlots(cx);
}
} else {
@@ -3364,10 +3351,16 @@ nsGlobalWindow::InnerSetNewDocument(JSContext* aCx, nsIDocument* aDocument)
}
mDoc = aDocument;
- ClearDocumentDependentSlots(aCx);
mFocusedNode = nullptr;
mLocalStorage = nullptr;
mSessionStorage = nullptr;
+ mPerformance = nullptr;
+
+ // This must be called after nulling the internal objects because we might
+ // recreate them here by calling the getter methods, and store them into the JS
+ // slots. If we null them after, the slot values and the objects will be
+ // out of sync.
+ ClearDocumentDependentSlots(aCx);
#ifdef DEBUG
mLastOpenedURI = aDocument->GetDocumentURI();
@@ -10957,35 +10950,12 @@ nsGlobalWindow::GetComputedStyleHelperOuter(Element& aElt,
{
MOZ_RELEASE_ASSERT(IsOuterWindow());
- if (!mDocShell) {
+ if (!mDoc) {
return nullptr;
}
- nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell();
-
- if (!presShell) {
- // Try flushing frames on our parent in case there's a pending
- // style change that will create the presshell.
- auto* parent = nsGlobalWindow::Cast(GetPrivateParent());
- if (!parent) {
- return nullptr;
- }
-
- parent->FlushPendingNotifications(Flush_Frames);
-
- // Might have killed mDocShell
- if (!mDocShell) {
- return nullptr;
- }
-
- presShell = mDocShell->GetPresShell();
- if (!presShell) {
- return nullptr;
- }
- }
-
RefPtr<nsComputedDOMStyle> compStyle =
- NS_NewComputedDOMStyle(&aElt, aPseudoElt, presShell,
+ NS_NewComputedDOMStyle(&aElt, aPseudoElt, mDoc,
aDefaultStylesOnly ? nsComputedDOMStyle::eDefaultOnly :
nsComputedDOMStyle::eAll);
diff --git a/dom/base/nsHTMLContentSerializer.cpp b/dom/base/nsHTMLContentSerializer.cpp
index ab8b4f2b2..c135c4cf8 100644
--- a/dom/base/nsHTMLContentSerializer.cpp
+++ b/dom/base/nsHTMLContentSerializer.cpp
@@ -301,6 +301,7 @@ nsHTMLContentSerializer::AppendElementStart(Element* aElement,
NS_IMETHODIMP
nsHTMLContentSerializer::AppendElementEnd(Element* aElement,
+ Element* aOriginalElement /* unused */,
nsAString& aStr)
{
NS_ENSURE_ARG(aElement);
diff --git a/dom/base/nsHTMLContentSerializer.h b/dom/base/nsHTMLContentSerializer.h
index 6f3500e01..8e23d54ca 100644
--- a/dom/base/nsHTMLContentSerializer.h
+++ b/dom/base/nsHTMLContentSerializer.h
@@ -31,6 +31,7 @@ class nsHTMLContentSerializer final : public nsXHTMLContentSerializer {
nsAString& aStr) override;
NS_IMETHOD AppendElementEnd(mozilla::dom::Element* aElement,
+ mozilla::dom::Element* aOriginalElement,
nsAString& aStr) override;
NS_IMETHOD AppendDocumentStart(nsIDocument *aDocument,
diff --git a/dom/base/nsIContentSerializer.h b/dom/base/nsIContentSerializer.h
index f023cbc90..35014bd2c 100644
--- a/dom/base/nsIContentSerializer.h
+++ b/dom/base/nsIContentSerializer.h
@@ -55,6 +55,7 @@ class nsIContentSerializer : public nsISupports {
nsAString& aStr) = 0;
NS_IMETHOD AppendElementEnd(mozilla::dom::Element* aElement,
+ mozilla::dom::Element* aOriginalElement,
nsAString& aStr) = 0;
NS_IMETHOD Flush(nsAString& aStr) = 0;
diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h
index e5d12ab8f..d76a12d71 100644
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2260,21 +2260,27 @@ public:
* nesting and possible sources, which are used to inform URL selection
* responsive <picture> or <img srcset> images. Unset attributes are expected
* to be marked void.
+ * If this image is for <picture> or <img srcset>, aIsImgSet will be set to
+ * true, false otherwise.
*/
virtual already_AddRefed<nsIURI>
ResolvePreloadImage(nsIURI *aBaseURI,
const nsAString& aSrcAttr,
const nsAString& aSrcsetAttr,
- const nsAString& aSizesAttr) = 0;
+ const nsAString& aSizesAttr,
+ bool *aIsImgSet) = 0;
/**
* Called by nsParser to preload images. Can be removed and code moved
* to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
* parser-module is linked with gklayout-module. aCrossOriginAttr should
* be a void string if the attr is not present.
+ * aIsImgSet is the value got from calling ResolvePreloadImage, it is true
+ * when this image is for loading <picture> or <img srcset> images.
*/
virtual void MaybePreLoadImage(nsIURI* uri,
const nsAString& aCrossOriginAttr,
- ReferrerPolicyEnum aReferrerPolicy) = 0;
+ ReferrerPolicyEnum aReferrerPolicy,
+ bool aIsImgSet) = 0;
/**
* Called by images to forget an image preload when they start doing
diff --git a/dom/base/nsIImageLoadingContent.idl b/dom/base/nsIImageLoadingContent.idl
index fea261a34..eacc4ac3a 100644
--- a/dom/base/nsIImageLoadingContent.idl
+++ b/dom/base/nsIImageLoadingContent.idl
@@ -104,6 +104,15 @@ interface nsIImageLoadingContent : imgINotificationObserver
imgIRequest getRequest(in long aRequestType);
/**
+ * Call this function when the request was blocked by any of the
+ * security policies enforced.
+ *
+ * @param aContentDecision the decision returned from nsIContentPolicy
+ * (any of the types REJECT_*)
+ */
+ void setBlockedRequest(in int16_t aContentDecision);
+
+ /**
* @return true if the current request's size is available.
*/
[noscript, notxpcom] boolean currentRequestHasSize();
diff --git a/dom/base/nsImageLoadingContent.cpp b/dom/base/nsImageLoadingContent.cpp
index 0c6c37b44..4aad55941 100644
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -44,6 +44,7 @@
#include "mozAutoDocUpdate.h"
#include "mozilla/AsyncEventDispatcher.h"
+#include "mozilla/AutoRestore.h"
#include "mozilla/EventStates.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ImageTracker.h"
@@ -94,7 +95,8 @@ nsImageLoadingContent::nsImageLoadingContent()
mNewRequestsWillNeedAnimationReset(false),
mStateChangerDepth(0),
mCurrentRequestRegistered(false),
- mPendingRequestRegistered(false)
+ mPendingRequestRegistered(false),
+ mIsStartingImageLoad(false)
{
if (!nsContentUtils::GetImgLoaderForChannel(nullptr, nullptr)) {
mLoadingEnabled = false;
@@ -785,6 +787,11 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
nsIDocument* aDocument,
nsLoadFlags aLoadFlags)
{
+ MOZ_ASSERT(!mIsStartingImageLoad, "some evil code is reentering LoadImage.");
+ if (mIsStartingImageLoad) {
+ return NS_OK;
+ }
+
// Pending load/error events need to be canceled in some situations. This
// is not documented in the spec, but can cause site compat problems if not
// done. See bug 1309461 and https://github.com/whatwg/html/issues/1872.
@@ -814,6 +821,21 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
}
}
+ AutoRestore<bool> guard(mIsStartingImageLoad);
+ mIsStartingImageLoad = true;
+
+ // Data documents, or documents from DOMParser shouldn't perform image loading.
+ if (aDocument->IsLoadedAsData()) {
+ // This is the only codepath on which we can reach SetBlockedRequest while
+ // our pending request exists. Just clear it out here if we do have one.
+ ClearPendingRequest(NS_BINDING_ABORTED,
+ Some(OnNonvisible::DISCARD_IMAGES));
+ SetBlockedRequest(nsIContentPolicy::REJECT_REQUEST);
+ FireEvent(NS_LITERAL_STRING("error"));
+ FireEvent(NS_LITERAL_STRING("loadend"));
+ return NS_OK;
+ }
+
// URI equality check.
//
// We skip the equality check if our current image was blocked, since in that
@@ -844,23 +866,8 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
"Principal mismatch?");
#endif
- // Are we blocked?
- int16_t cpDecision = nsIContentPolicy::REJECT_REQUEST;
nsContentPolicyType policyType = PolicyTypeForLoad(aImageLoadType);
- nsContentUtils::CanLoadImage(aNewURI,
- static_cast<nsIImageLoadingContent*>(this),
- aDocument,
- aDocument->NodePrincipal(),
- &cpDecision,
- policyType);
- if (!NS_CP_ACCEPTED(cpDecision)) {
- FireEvent(NS_LITERAL_STRING("error"));
- FireEvent(NS_LITERAL_STRING("loadend"));
- SetBlockedRequest(aNewURI, cpDecision);
- return NS_OK;
- }
-
nsLoadFlags loadFlags = aLoadFlags;
int32_t corsmode = GetCORSMode();
if (corsmode == CORS_ANONYMOUS) {
@@ -878,7 +885,6 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
referrerPolicy = imgReferrerPolicy;
}
- // Not blocked. Do the load.
RefPtr<imgRequestProxy>& req = PrepareNextRequest(aImageLoadType);
nsCOMPtr<nsIContent> content =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
@@ -932,7 +938,6 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
FireEvent(NS_LITERAL_STRING("error"));
FireEvent(NS_LITERAL_STRING("loadend"));
- return NS_OK;
}
return NS_OK;
@@ -1212,46 +1217,42 @@ nsImageLoadingContent::PrepareNextRequest(ImageLoadType aImageLoadType)
mMostRecentRequestChange = now;
}
- // If we don't have a usable current request, get rid of any half-baked
- // request that might be sitting there and make this one current.
- if (!HaveSize(mCurrentRequest))
- return PrepareCurrentRequest(aImageLoadType);
- // Otherwise, make it pending.
- return PreparePendingRequest(aImageLoadType);
+ // We only want to cancel the existing current request if size is not
+ // available. bz says the web depends on this behavior.
+ // Otherwise, we get rid of any half-baked request that might be sitting there
+ // and make this one current.
+ // TODO: Bug 583491
+ // Investigate/Cleanup NS_ERROR_IMAGE_SRC_CHANGED use in nsImageFrame.cpp
+ return HaveSize(mCurrentRequest) ?
+ PreparePendingRequest(aImageLoadType) :
+ PrepareCurrentRequest(aImageLoadType);
}
-void
-nsImageLoadingContent::SetBlockedRequest(nsIURI* aURI, int16_t aContentDecision)
+nsresult
+nsImageLoadingContent::SetBlockedRequest(int16_t aContentDecision)
{
+ // If this is not calling from LoadImage, for example, from ServiceWorker,
+ // bail out.
+ if (!mIsStartingImageLoad) {
+ return NS_OK;
+ }
+
// Sanity
MOZ_ASSERT(!NS_CP_ACCEPTED(aContentDecision), "Blocked but not?");
- // We do some slightly illogical stuff here to maintain consistency with
- // old behavior that people probably depend on. Even in the case where the
- // new image is blocked, the old one should really be canceled with the
- // reason "image source changed". However, apparently there's some abuse
- // over in nsImageFrame where the displaying of the "broken" icon for the
- // next image depends on the cancel reason of the previous image. ugh.
- // XXX(seth): So shouldn't we fix nsImageFrame?!
- ClearPendingRequest(NS_ERROR_IMAGE_BLOCKED,
- Some(OnNonvisible::DISCARD_IMAGES));
-
- // For the blocked case, we only want to cancel the existing current request
- // if size is not available. bz says the web depends on this behavior.
- if (!HaveSize(mCurrentRequest)) {
+ // We should never have a pending request after we got blocked.
+ MOZ_ASSERT(!mPendingRequest, "mPendingRequest should be null.");
+ if (HaveSize(mCurrentRequest)) {
+ // PreparePendingRequest set mPendingRequestFlags, now since we've decided
+ // to block it, we reset it back to 0.
+ mPendingRequestFlags = 0;
+ } else {
mImageBlockingStatus = aContentDecision;
- uint32_t keepFlags = mCurrentRequestFlags & REQUEST_IS_IMAGESET;
- ClearCurrentRequest(NS_ERROR_IMAGE_BLOCKED,
- Some(OnNonvisible::DISCARD_IMAGES));
-
- // We still want to remember what URI we were and if it was an imageset,
- // despite not having an actual request. These are both cleared as part of
- // ClearCurrentRequest() before a new request is started.
- mCurrentURI = aURI;
- mCurrentRequestFlags = keepFlags;
}
+
+ return NS_OK;
}
RefPtr<imgRequestProxy>&
@@ -1262,7 +1263,7 @@ nsImageLoadingContent::PrepareCurrentRequest(ImageLoadType aImageLoadType)
mImageBlockingStatus = nsIContentPolicy::ACCEPT;
// Get rid of anything that was there previously.
- ClearCurrentRequest(NS_ERROR_IMAGE_SRC_CHANGED,
+ ClearCurrentRequest(NS_BINDING_ABORTED,
Some(OnNonvisible::DISCARD_IMAGES));
if (mNewRequestsWillNeedAnimationReset) {
@@ -1281,7 +1282,7 @@ RefPtr<imgRequestProxy>&
nsImageLoadingContent::PreparePendingRequest(ImageLoadType aImageLoadType)
{
// Get rid of anything that was there previously.
- ClearPendingRequest(NS_ERROR_IMAGE_SRC_CHANGED,
+ ClearPendingRequest(NS_BINDING_ABORTED,
Some(OnNonvisible::DISCARD_IMAGES));
if (mNewRequestsWillNeedAnimationReset) {
diff --git a/dom/base/nsImageLoadingContent.h b/dom/base/nsImageLoadingContent.h
index 5f7daff72..cfb2a6207 100644
--- a/dom/base/nsImageLoadingContent.h
+++ b/dom/base/nsImageLoadingContent.h
@@ -303,17 +303,10 @@ protected:
RefPtr<imgRequestProxy>& PrepareNextRequest(ImageLoadType aImageLoadType);
/**
- * Called when we would normally call PrepareNextRequest(), but the request was
- * blocked.
- */
- void SetBlockedRequest(nsIURI* aURI, int16_t aContentDecision);
-
- /**
* Returns a COMPtr reference to the current/pending image requests, cleaning
* up and canceling anything that was there before. Note that if you just want
* to get rid of one of the requests, you should call
- * Clear*Request(NS_BINDING_ABORTED) instead, since it passes a more appropriate
- * aReason than Prepare*Request() does (NS_ERROR_IMAGE_SRC_CHANGED).
+ * Clear*Request(NS_BINDING_ABORTED) instead.
*
* @param aImageLoadType The ImageLoadType for this request
*/
@@ -459,6 +452,14 @@ private:
// registered with the refresh driver.
bool mCurrentRequestRegistered;
bool mPendingRequestRegistered;
+
+ // This member is used in SetBlockedRequest, if it's true, then this call is
+ // triggered from LoadImage.
+ // If this is false, it means this call is from other places like
+ // ServiceWorker, then we will ignore call to SetBlockedRequest for now.
+ //
+ // Also we use this variable to check if some evil code is reentering LoadImage.
+ bool mIsStartingImageLoad;
};
#endif // nsImageLoadingContent_h__
diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp
index 3c850c4cd..4978744e8 100644
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -718,9 +718,9 @@ nsObjectLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent)
if (mType == eType_Plugin) {
nsIDocument* doc = thisContent->GetComposedDoc();
if (doc && doc->IsActive()) {
- nsCOMPtr<nsIRunnable> ev = new nsSimplePluginEvent(doc,
- NS_LITERAL_STRING("PluginRemoved"));
- NS_DispatchToCurrentThread(ev);
+ nsCOMPtr<nsIRunnable> ev = new nsSimplePluginEvent(doc,
+ NS_LITERAL_STRING("PluginRemoved"));
+ NS_DispatchToCurrentThread(ev);
}
}
}
@@ -3628,6 +3628,14 @@ nsObjectLoadingContent::HasGoodFallback() {
}
}
+ // RULE "nosrc":
+ // Use fallback content if the object has not specified a src URI.
+ if (rulesList[i].EqualsLiteral("nosrc")) {
+ if (!mOriginalURI) {
+ return true;
+ }
+ }
+
// RULE "adobelink":
// Don't use fallback content when it has a link to adobe's website.
if (rulesList[i].EqualsLiteral("adobelink")) {
diff --git a/dom/base/nsPlainTextSerializer.cpp b/dom/base/nsPlainTextSerializer.cpp
index ef6bdcac7..98c9cfe32 100644
--- a/dom/base/nsPlainTextSerializer.cpp
+++ b/dom/base/nsPlainTextSerializer.cpp
@@ -53,7 +53,6 @@ static int32_t GetUnicharStringWidth(const char16_t* pwcs, int32_t n);
// Someday may want to make this non-const:
static const uint32_t TagStackSize = 500;
-static const uint32_t OLStackSize = 100;
nsresult
NS_NewPlainTextSerializer(nsIContentSerializer** aSerializer)
@@ -100,10 +99,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
mTagStackIndex = 0;
mIgnoreAboveIndex = (uint32_t)kNotFound;
- // initialize the OL stack, where numbers for ordered lists are kept
- mOLStack = new int32_t[OLStackSize];
- mOLStackIndex = 0;
-
mULCount = 0;
mIgnoredChildNodeLevel = 0;
@@ -112,7 +107,6 @@ nsPlainTextSerializer::nsPlainTextSerializer()
nsPlainTextSerializer::~nsPlainTextSerializer()
{
delete[] mTagStack;
- delete[] mOLStack;
NS_WARNING_ASSERTION(mHeadLevel == 0, "Wrong head level!");
}
@@ -189,6 +183,8 @@ nsPlainTextSerializer::Init(uint32_t aFlags, uint32_t aWrapColumn,
// XXX We should let the caller decide whether to do this or not
mFlags &= ~nsIDocumentEncoder::OutputNoFramesContent;
+ MOZ_ASSERT(mOLStack.IsEmpty());
+
return NS_OK;
}
@@ -390,6 +386,7 @@ nsPlainTextSerializer::AppendElementStart(Element* aElement,
NS_IMETHODIMP
nsPlainTextSerializer::AppendElementEnd(Element* aElement,
+ Element* aOriginalElement /* unused */,
nsAString& aStr)
{
NS_ENSURE_ARG(aElement);
@@ -437,6 +434,8 @@ nsPlainTextSerializer::AppendDocumentStart(nsIDocument *aDocument,
return NS_OK;
}
+int32_t kOlStackDummyValue = 0;
+
nsresult
nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
{
@@ -615,44 +614,45 @@ nsPlainTextSerializer::DoOpenContainer(nsIAtom* aTag)
}
else if (aTag == nsGkAtoms::ul) {
// Indent here to support nested lists, which aren't included in li :-(
- EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0);
- // Must end the current line before we change indention
+ EnsureVerticalSpace(IsInOLOrUL() ? 0 : 1);
+ // Must end the current line before we change indention
mIndent += kIndentSizeList;
mULCount++;
}
else if (aTag == nsGkAtoms::ol) {
- EnsureVerticalSpace(mULCount + mOLStackIndex == 0 ? 1 : 0);
+ EnsureVerticalSpace(IsInOLOrUL() ? 0 : 1);
if (mFlags & nsIDocumentEncoder::OutputFormatted) {
// Must end the current line before we change indention
- if (mOLStackIndex < OLStackSize) {
- nsAutoString startAttr;
- int32_t startVal = 1;
- if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::start, startAttr))) {
- nsresult rv = NS_OK;
- startVal = startAttr.ToInteger(&rv);
- if (NS_FAILED(rv))
- startVal = 1;
+ nsAutoString startAttr;
+ int32_t startVal = 1;
+ if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::start, startAttr))) {
+ nsresult rv = NS_OK;
+ startVal = startAttr.ToInteger(&rv);
+ if (NS_FAILED(rv)) {
+ startVal = 1;
}
- mOLStack[mOLStackIndex++] = startVal;
}
+ mOLStack.AppendElement(startVal);
} else {
- mOLStackIndex++;
+ mOLStack.AppendElement(kOlStackDummyValue);
}
mIndent += kIndentSizeList; // see ul
}
else if (aTag == nsGkAtoms::li &&
(mFlags & nsIDocumentEncoder::OutputFormatted)) {
if (mTagStackIndex > 1 && IsInOL()) {
- if (mOLStackIndex > 0) {
+ if (!mOLStack.IsEmpty()) {
nsAutoString valueAttr;
if (NS_SUCCEEDED(GetAttributeValue(nsGkAtoms::value, valueAttr))) {
nsresult rv = NS_OK;
int32_t valueAttrVal = valueAttr.ToInteger(&rv);
- if (NS_SUCCEEDED(rv))
- mOLStack[mOLStackIndex-1] = valueAttrVal;
+ if (NS_SUCCEEDED(rv)) {
+ mOLStack.LastElement() = valueAttrVal;
+ }
}
// This is what nsBulletFrame does for OLs:
- mInIndentString.AppendInt(mOLStack[mOLStackIndex-1]++, 10);
+ mInIndentString.AppendInt(mOLStack.LastElement(), 10);
+ mOLStack.LastElement()++;
}
else {
mInIndentString.Append(char16_t('#'));
@@ -877,7 +877,8 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
else if (aTag == nsGkAtoms::ul) {
FlushLine();
mIndent -= kIndentSizeList;
- if (--mULCount + mOLStackIndex == 0) {
+ --mULCount;
+ if (!IsInOLOrUL()) {
mFloatingLines = 1;
mLineBreakDue = true;
}
@@ -885,9 +886,9 @@ nsPlainTextSerializer::DoCloseContainer(nsIAtom* aTag)
else if (aTag == nsGkAtoms::ol) {
FlushLine(); // Doing this after decreasing OLStackIndex would be wrong.
mIndent -= kIndentSizeList;
- NS_ASSERTION(mOLStackIndex, "Wrong OLStack level!");
- mOLStackIndex--;
- if (mULCount + mOLStackIndex == 0) {
+ NS_ASSERTION(!mOLStack.IsEmpty(), "Wrong OLStack level!");
+ mOLStack.RemoveElementAt(mOLStack.Length() - 1);
+ if (!IsInOLOrUL()) {
mFloatingLines = 1;
mLineBreakDue = true;
}
@@ -1860,6 +1861,10 @@ nsPlainTextSerializer::IsInOL()
return false;
}
+bool nsPlainTextSerializer::IsInOLOrUL() const {
+ return (mULCount > 0) || !mOLStack.IsEmpty();
+}
+
/*
@return 0 = no header, 1 = h1, ..., 6 = h6
*/
diff --git a/dom/base/nsPlainTextSerializer.h b/dom/base/nsPlainTextSerializer.h
index 95cf5590c..650a8e3e7 100644
--- a/dom/base/nsPlainTextSerializer.h
+++ b/dom/base/nsPlainTextSerializer.h
@@ -61,6 +61,7 @@ public:
mozilla::dom::Element* aOriginalElement,
nsAString& aStr) override;
NS_IMETHOD AppendElementEnd(mozilla::dom::Element* aElement,
+ mozilla::dom::Element* aOriginalElement,
nsAString& aStr) override;
NS_IMETHOD Flush(nsAString& aStr) override;
@@ -80,6 +81,7 @@ private:
void Write(const nsAString& aString);
bool IsInPre();
bool IsInOL();
+ bool IsInOLOrUL() const;
bool IsCurrentNodeConverted();
bool MustSuppressLeaf();
@@ -217,8 +219,7 @@ private:
uint32_t mIgnoreAboveIndex;
// The stack for ordered lists
- int32_t *mOLStack;
- uint32_t mOLStackIndex;
+ AutoTArray<int32_t, 100> mOLStack;
uint32_t mULCount;
diff --git a/dom/base/nsScriptLoader.cpp b/dom/base/nsScriptLoader.cpp
index 1e23d6c5f..3ac00142d 100644
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -654,6 +654,19 @@ nsScriptLoader::CheckContentPolicy(nsIDocument* aDocument,
}
bool
+nsScriptLoader::ModuleScriptsEnabled()
+{
+ static bool sEnabledForContent = false;
+ static bool sCachedPref = false;
+ if (!sCachedPref) {
+ sCachedPref = true;
+ Preferences::AddBoolVarCache(&sEnabledForContent, "dom.moduleScripts.enabled", false);
+ }
+
+ return nsContentUtils::IsChromeDoc(mDocument) || sEnabledForContent;
+}
+
+bool
nsScriptLoader::ModuleMapContainsModule(nsModuleLoadRequest *aRequest) const
{
// Returns whether we have fetched, or are currently fetching, a module script
@@ -1230,15 +1243,27 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType,
nsCOMPtr<nsIInterfaceRequestor> prompter(do_QueryInterface(docshell));
nsSecurityFlags securityFlags;
- // TODO: the spec currently gives module scripts different CORS behaviour to
- // classic scripts.
- securityFlags = aRequest->mCORSMode == CORS_NONE
- ? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL
- : nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
- if (aRequest->mCORSMode == CORS_ANONYMOUS) {
- securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
- } else if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) {
- securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
+ if (aRequest->IsModuleRequest()) {
+ // According to the spec, module scripts have different behaviour to classic
+ // scripts and always use CORS.
+ securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
+ if (aRequest->mCORSMode == CORS_NONE) {
+ securityFlags |= nsILoadInfo::SEC_COOKIES_OMIT;
+ } else if (aRequest->mCORSMode == CORS_ANONYMOUS) {
+ securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
+ } else {
+ MOZ_ASSERT(aRequest->mCORSMode == CORS_USE_CREDENTIALS);
+ securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
+ }
+ } else {
+ securityFlags = aRequest->mCORSMode == CORS_NONE
+ ? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL
+ : nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
+ if (aRequest->mCORSMode == CORS_ANONYMOUS) {
+ securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
+ } else if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) {
+ securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
+ }
}
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
@@ -1434,7 +1459,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
nsCOMPtr<nsIContent> scriptContent = do_QueryInterface(aElement);
- // Step 12. Check that the script is not an eventhandler
+ // Step 13. Check that the script is not an eventhandler
if (IsScriptEventHandler(scriptContent)) {
return false;
}
@@ -1448,8 +1473,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
nsScriptKind scriptKind = nsScriptKind::Classic;
if (!type.IsEmpty()) {
- // Support type="module" only for chrome documents.
- if (nsContentUtils::IsChromeDoc(mDocument) && type.LowerCaseEqualsASCII("module")) {
+ if (ModuleScriptsEnabled() && type.LowerCaseEqualsASCII("module")) {
scriptKind = nsScriptKind::Module;
} else {
NS_ENSURE_TRUE(ParseTypeAttribute(type, &version), false);
@@ -1469,7 +1493,18 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
}
}
- // Step 14. in the HTML5 spec
+ // "In modern user agents that support module scripts, the script element with
+ // the nomodule attribute will be ignored".
+ // "The nomodule attribute must not be specified on module scripts (and will
+ // be ignored if it is)."
+ if (ModuleScriptsEnabled() &&
+ scriptKind == nsScriptKind::Classic &&
+ scriptContent->IsHTMLElement() &&
+ scriptContent->HasAttr(kNameSpaceID_None, nsGkAtoms::nomodule)) {
+ return false;
+ }
+
+ // Step 15. and later in the HTML5 spec
nsresult rv = NS_OK;
RefPtr<nsScriptLoadRequest> request;
if (aElement->GetScriptExternal()) {
@@ -1577,7 +1612,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
}
return false;
}
- if (!aElement->GetParserCreated() && !request->IsModuleRequest()) {
+ if (!aElement->GetParserCreated()) {
// Violate the HTML5 spec in order to make LABjs and the "order" plug-in
// for RequireJS work with their Gecko-sniffed code path. See
// http://lists.w3.org/Archives/Public/public-html/2010Oct/0088.html
@@ -2768,7 +2803,7 @@ nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
}
// TODO: Preload module scripts.
- if (nsContentUtils::IsChromeDoc(mDocument) && aType.LowerCaseEqualsASCII("module")) {
+ if (ModuleScriptsEnabled() && aType.LowerCaseEqualsASCII("module")) {
return;
}
diff --git a/dom/base/nsScriptLoader.h b/dom/base/nsScriptLoader.h
index d30a58441..a00239be5 100644
--- a/dom/base/nsScriptLoader.h
+++ b/dom/base/nsScriptLoader.h
@@ -568,6 +568,8 @@ private:
JS::SourceBufferHolder GetScriptSource(nsScriptLoadRequest* aRequest,
nsAutoString& inlineData);
+ bool ModuleScriptsEnabled();
+
void SetModuleFetchStarted(nsModuleLoadRequest *aRequest);
void SetModuleFetchFinishedAndResumeWaitingRequests(nsModuleLoadRequest *aRequest,
nsresult aResult);
diff --git a/dom/base/nsXHTMLContentSerializer.cpp b/dom/base/nsXHTMLContentSerializer.cpp
index 111ed46c7..0a39ef663 100755
--- a/dom/base/nsXHTMLContentSerializer.cpp
+++ b/dom/base/nsXHTMLContentSerializer.cpp
@@ -514,6 +514,7 @@ nsXHTMLContentSerializer::CheckElementStart(nsIContent * aContent,
bool
nsXHTMLContentSerializer::CheckElementEnd(mozilla::dom::Element* aElement,
+ mozilla::dom::Element* aOriginalElement,
bool& aForceFormat,
nsAString& aStr)
{
@@ -532,7 +533,7 @@ nsXHTMLContentSerializer::CheckElementEnd(mozilla::dom::Element* aElement,
}
bool dummyFormat;
- return nsXMLContentSerializer::CheckElementEnd(aElement, dummyFormat, aStr);
+ return nsXMLContentSerializer::CheckElementEnd(aElement, aOriginalElement, dummyFormat, aStr);
}
bool
diff --git a/dom/base/nsXHTMLContentSerializer.h b/dom/base/nsXHTMLContentSerializer.h
index 7473ba074..79ecf28f1 100644
--- a/dom/base/nsXHTMLContentSerializer.h
+++ b/dom/base/nsXHTMLContentSerializer.h
@@ -53,6 +53,7 @@ class nsXHTMLContentSerializer : public nsXMLContentSerializer {
nsAString& aStr) override;
virtual bool CheckElementEnd(mozilla::dom::Element* aContent,
+ mozilla::dom::Element* aOriginalElement,
bool& aForceFormat,
nsAString& aStr) override;
diff --git a/dom/base/nsXMLContentSerializer.cpp b/dom/base/nsXMLContentSerializer.cpp
index 54fadaa94..f12bb8fdc 100644
--- a/dom/base/nsXMLContentSerializer.cpp
+++ b/dom/base/nsXMLContentSerializer.cpp
@@ -1028,6 +1028,7 @@ nsXMLContentSerializer::AppendEndOfElementStart(Element* aElement,
NS_IMETHODIMP
nsXMLContentSerializer::AppendElementEnd(Element* aElement,
+ Element* aOriginalElement,
nsAString& aStr)
{
NS_ENSURE_ARG(aElement);
@@ -1035,7 +1036,7 @@ nsXMLContentSerializer::AppendElementEnd(Element* aElement,
nsIContent* content = aElement;
bool forceFormat = false, outputElementEnd;
- outputElementEnd = CheckElementEnd(aElement, forceFormat, aStr);
+ outputElementEnd = CheckElementEnd(aElement, aOriginalElement, forceFormat, aStr);
nsIAtom *name = content->NodeInfo()->NameAtom();
@@ -1161,16 +1162,14 @@ nsXMLContentSerializer::CheckElementStart(nsIContent * aContent,
bool
nsXMLContentSerializer::CheckElementEnd(Element* aElement,
+ Element* aOriginalElement,
bool& aForceFormat,
nsAString& aStr)
{
// We don't output a separate end tag for empty element
aForceFormat = false;
- // XXXbz this is a bit messed up, but by now we don't have our fixed-up
- // version of aElement anymore. Let's hope fixup never changes the localName
- // or namespace...
- return ElementNeedsSeparateEndTag(aElement, aElement);
+ return ElementNeedsSeparateEndTag(aElement, aOriginalElement);
}
bool
diff --git a/dom/base/nsXMLContentSerializer.h b/dom/base/nsXMLContentSerializer.h
index 941acb179..2f76b0892 100644
--- a/dom/base/nsXMLContentSerializer.h
+++ b/dom/base/nsXMLContentSerializer.h
@@ -59,6 +59,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
nsAString& aStr) override;
NS_IMETHOD AppendElementEnd(mozilla::dom::Element* aElement,
+ mozilla::dom::Element* aOriginalElement,
nsAString& aStr) override;
NS_IMETHOD Flush(nsAString& aStr) override { return NS_OK; }
@@ -263,6 +264,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
* @return boolean true if the element can be output
*/
virtual bool CheckElementEnd(mozilla::dom::Element* aElement,
+ mozilla::dom::Element* aOriginalElement,
bool& aForceFormat,
nsAString& aStr);