Bug 1332956 part 3. Implement the same behavior for <object>-inside-<object> and <object>-inside-mediaelement as we do for <embed> already. r=qdot

This commit is contained in:
Boris Zbarsky
2017-02-08 18:19:01 -05:00
parent 6de9ae9d5d
commit e5460d8ba1
10 changed files with 181 additions and 77 deletions

View File

@@ -88,6 +88,7 @@
#include "mozilla/Telemetry.h"
#include "mozilla/dom/HTMLObjectElementBinding.h"
#include "mozilla/dom/HTMLSharedObjectElement.h"
#include "mozilla/dom/HTMLObjectElement.h"
#include "nsChannelClassifier.h"
#ifdef XP_WIN
@@ -97,13 +98,6 @@
#endif
#endif // XP_WIN
#ifdef XP_MACOSX
// HandlePluginCrashed() and HandlePluginInstantiated() needed from here to
// fix bug 1147521. Should later be replaced by proper interface methods,
// maybe on nsIObjectLoadingContext.
#include "mozilla/dom/HTMLObjectElement.h"
#endif
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
static const char *kPrefJavaMIME = "plugin.java.mime";
@@ -3018,7 +3012,7 @@ nsObjectLoadingContent::LoadFallback(FallbackType aType, bool aNotify) {
// Fixup mFallbackType
//
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
NS_ASSERTION(thisContent, "must be a content");
if (!thisContent->IsHTMLElement() || mContentType.IsEmpty()) {
@@ -3031,8 +3025,10 @@ nsObjectLoadingContent::LoadFallback(FallbackType aType, bool aNotify) {
// child embeds as we find them in the upcoming loop.
mType = eType_Null;
// Do a breadth-first traverse of node tree with the current element as root,
// looking for the first embed we can find.
bool thisIsObject = thisContent->IsHTMLElement(nsGkAtoms::object);
// Do a depth-first traverse of node tree with the current element as root,
// looking for <embed> or <object> elements that might now need to load.
nsTArray<nsINodeList*> childNodes;
if ((thisContent->IsHTMLElement(nsGkAtoms::object) ||
thisContent->IsHTMLElement(nsGkAtoms::applet)) &&
@@ -3048,10 +3044,11 @@ nsObjectLoadingContent::LoadFallback(FallbackType aType, bool aNotify) {
nsStyleUtil::IsSignificantChild(child, true, false)) {
aType = eFallbackAlternate;
}
if (child->IsHTMLElement(nsGkAtoms::embed) &&
thisContent->IsHTMLElement(nsGkAtoms::object)) {
HTMLSharedObjectElement* object = static_cast<HTMLSharedObjectElement*>(child);
if (object) {
if (thisIsObject) {
if (child->IsHTMLElement(nsGkAtoms::embed)) {
HTMLSharedObjectElement* embed = static_cast<HTMLSharedObjectElement*>(child);
embed->StartObjectLoad(true, true);
} else if (auto object = HTMLObjectElement::FromContent(child)) {
object->StartObjectLoad(true, true);
}
}
@@ -3817,6 +3814,38 @@ nsObjectLoadingContent::MaybeFireErrorEvent()
}
}
bool
nsObjectLoadingContent::BlockEmbedOrObjectContentLoading()
{
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
if (!thisContent->IsHTMLElement(nsGkAtoms::embed) &&
!thisContent->IsHTMLElement(nsGkAtoms::object)) {
// Doesn't apply to other elements (i.e. <applet>)
return false;
}
// Traverse up the node tree to see if we have any ancestors that may block us
// from loading
for (nsIContent* parent = thisContent->GetParent();
parent;
parent = parent->GetParent()) {
if (parent->IsAnyOfHTMLElements(nsGkAtoms::video, nsGkAtoms::audio)) {
return true;
}
// If we have an ancestor that is an object with a source, it'll have an
// associated displayed type. If that type is not null, don't load content
// for the embed.
if (HTMLObjectElement* object = HTMLObjectElement::FromContent(parent)) {
uint32_t type = object->DisplayedType();
if (type != eType_Null) {
return true;
}
}
}
return false;
}
// SetupProtoChainRunner implementation
nsObjectLoadingContent::SetupProtoChainRunner::SetupProtoChainRunner(
nsObjectLoadingContent* aContent)