зеркало из https://github.com/mozilla/gecko-dev.git
Bug 558184 - Part 4.3 - Load fake plugin handlers as eType_FakePlugin in nsObjectLoadingContent. r=peterv.
--HG-- extra : rebase_source : 4683568e90fd65a38c974aa755dd5f6f94479ee3 extra : source : 8e4be859c1a1ec73b29df98422d5ee6935cd9aa9
This commit is contained in:
Родитель
ec17d16219
Коммит
4ce6580106
|
@ -10351,8 +10351,26 @@ HtmlObjectContentSupportsDocument(const nsCString& aMimeType,
|
|||
return NS_SUCCEEDED(rv) && canConvert;
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsIPluginTag>
|
||||
nsContentUtils::PluginTagForType(const nsCString& aMIMEType, bool aNoFakePlugin)
|
||||
{
|
||||
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
|
||||
nsCOMPtr<nsIPluginTag> tag;
|
||||
NS_ENSURE_TRUE(pluginHost, nullptr);
|
||||
|
||||
// ShouldPlay will handle the case where the plugin is disabled
|
||||
pluginHost->GetPluginTagForType(aMIMEType,
|
||||
aNoFakePlugin ? nsPluginHost::eExcludeFake
|
||||
: nsPluginHost::eExcludeNone,
|
||||
getter_AddRefs(tag));
|
||||
|
||||
return tag.forget();
|
||||
}
|
||||
|
||||
/* static */ uint32_t
|
||||
nsContentUtils::HtmlObjectContentTypeForMIMEType(const nsCString& aMIMEType,
|
||||
bool aNoFakePlugin,
|
||||
nsIContent* aContent)
|
||||
{
|
||||
if (aMIMEType.IsEmpty()) {
|
||||
|
@ -10375,10 +10393,17 @@ nsContentUtils::HtmlObjectContentTypeForMIMEType(const nsCString& aMIMEType,
|
|||
}
|
||||
|
||||
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
|
||||
if (pluginHost &&
|
||||
pluginHost->HavePluginForType(aMIMEType, nsPluginHost::eExcludeNone)) {
|
||||
// ShouldPlay will handle checking for disabled plugins
|
||||
return nsIObjectLoadingContent::TYPE_PLUGIN;
|
||||
if (pluginHost) {
|
||||
nsCOMPtr<nsIPluginTag> tag = PluginTagForType(aMIMEType, aNoFakePlugin);
|
||||
if (tag) {
|
||||
if (!aNoFakePlugin &&
|
||||
nsCOMPtr<nsIFakePluginTag>(do_QueryInterface(tag))) {
|
||||
return nsIObjectLoadingContent::TYPE_FAKE_PLUGIN;
|
||||
}
|
||||
|
||||
// ShouldPlay will handle checking for disabled plugins
|
||||
return nsIObjectLoadingContent::TYPE_PLUGIN;
|
||||
}
|
||||
}
|
||||
|
||||
return nsIObjectLoadingContent::TYPE_NULL;
|
||||
|
|
|
@ -83,6 +83,7 @@ class nsNameSpaceManager;
|
|||
class nsIObserver;
|
||||
class nsIParser;
|
||||
class nsIParserService;
|
||||
class nsIPluginTag;
|
||||
class nsIPresShell;
|
||||
class nsIPrincipal;
|
||||
class nsIRequest;
|
||||
|
@ -2904,6 +2905,16 @@ public:
|
|||
*/
|
||||
static Element* GetClosestNonNativeAnonymousAncestor(Element* aElement);
|
||||
|
||||
/**
|
||||
* Returns the nsIPluginTag for the plugin we should try to use for a given
|
||||
* MIME type.
|
||||
*
|
||||
* @param aMIMEType The MIME type of the document being loaded.
|
||||
* @param aNoFakePlugin If false then this method should consider JS plugins.
|
||||
*/
|
||||
static already_AddRefed<nsIPluginTag>
|
||||
PluginTagForType(const nsCString& aMIMEType, bool aNoFakePlugin);
|
||||
|
||||
/**
|
||||
* Returns one of the nsIObjectLoadingContent::TYPE_ values describing the
|
||||
* content type which will be used for the given MIME type when loaded within
|
||||
|
@ -2913,12 +2924,14 @@ public:
|
|||
* take that into account.
|
||||
*
|
||||
* @param aMIMEType The MIME type of the document being loaded.
|
||||
* @param aNoFakePlugin If false then this method should consider JS plugins.
|
||||
* @param aContent The nsIContent object which is performing the load. May be
|
||||
* nullptr in which case the docshell's plugin permissions
|
||||
* will not be checked.
|
||||
*/
|
||||
static uint32_t
|
||||
HtmlObjectContentTypeForMIMEType(const nsCString& aMIMEType,
|
||||
bool aNoFakePlugin,
|
||||
nsIContent* aContent);
|
||||
|
||||
static already_AddRefed<nsIEventTarget>
|
||||
|
|
|
@ -31,11 +31,12 @@ interface nsIObjectLoadingContent : nsISupports
|
|||
/**
|
||||
* See notes in nsObjectLoadingContent.h
|
||||
*/
|
||||
const unsigned long TYPE_LOADING = 0;
|
||||
const unsigned long TYPE_IMAGE = 1;
|
||||
const unsigned long TYPE_PLUGIN = 2;
|
||||
const unsigned long TYPE_DOCUMENT = 3;
|
||||
const unsigned long TYPE_NULL = 4;
|
||||
const unsigned long TYPE_LOADING = 0;
|
||||
const unsigned long TYPE_IMAGE = 1;
|
||||
const unsigned long TYPE_PLUGIN = 2;
|
||||
const unsigned long TYPE_FAKE_PLUGIN = 3;
|
||||
const unsigned long TYPE_DOCUMENT = 4;
|
||||
const unsigned long TYPE_NULL = 5;
|
||||
|
||||
const unsigned long PLUGIN_ACTIVE = 0xFF;
|
||||
|
||||
|
@ -163,4 +164,9 @@ interface nsIObjectLoadingContent : nsISupports
|
|||
* an <embed> with no src).
|
||||
*/
|
||||
readonly attribute nsIURI srcURI;
|
||||
|
||||
/**
|
||||
* Disable the use of fake plugins and reload the tag if necessary.
|
||||
*/
|
||||
void skipFakePlugins();
|
||||
};
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "nsIContent.h"
|
||||
#include "nsIContentInlines.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellLoadInfo.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMCustomEvent.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
|
@ -146,6 +147,13 @@ InActiveDocument(nsIContent *aContent)
|
|||
return (doc && doc->IsActive());
|
||||
}
|
||||
|
||||
static bool
|
||||
IsPluginType(nsObjectLoadingContent::ObjectType type)
|
||||
{
|
||||
return type == nsObjectLoadingContent::eType_Plugin ||
|
||||
type == nsObjectLoadingContent::eType_FakePlugin;
|
||||
}
|
||||
|
||||
///
|
||||
/// Runnables and helper classes
|
||||
///
|
||||
|
@ -548,6 +556,44 @@ nsObjectLoadingContent::MakePluginListener()
|
|||
return true;
|
||||
}
|
||||
|
||||
// Helper to spawn the frameloader and return a pointer to its docshell
|
||||
already_AddRefed<nsIDocShell>
|
||||
nsObjectLoadingContent::SetupFrameLoader(nsIURI *aRecursionCheckURI)
|
||||
{
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
NS_ASSERTION(thisContent, "must be a content");
|
||||
|
||||
mFrameLoader = nsFrameLoader::Create(thisContent->AsElement(),
|
||||
/* aOpener = */ nullptr,
|
||||
mNetworkCreated);
|
||||
if (!mFrameLoader) {
|
||||
NS_NOTREACHED("nsFrameLoader::Create failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
|
||||
if (aRecursionCheckURI) {
|
||||
nsresult rv = mFrameLoader->CheckForRecursiveLoad(aRecursionCheckURI);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mFrameLoader->GetDocShell(getter_AddRefs(docShell));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_NOTREACHED("Could not get DocShell from mFrameLoader?");
|
||||
}
|
||||
} else {
|
||||
LOG(("OBJLC [%p]: Aborting recursive load", this));
|
||||
}
|
||||
}
|
||||
|
||||
if (!docShell) {
|
||||
mFrameLoader->Destroy();
|
||||
mFrameLoader = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return docShell.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsObjectLoadingContent::BindToTree(nsIDocument* aDocument,
|
||||
|
@ -575,6 +621,8 @@ nsObjectLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent)
|
|||
nsIDocument* ownerDoc = thisContent->OwnerDoc();
|
||||
ownerDoc->RemovePlugin(this);
|
||||
|
||||
/// XXX(johns): Do we want to somehow propogate the reparenting behavior to
|
||||
/// FakePlugin types as well?
|
||||
if (mType == eType_Plugin && (mInstanceOwner || mInstantiating)) {
|
||||
// we'll let the plugin continue to run at least until we get back to
|
||||
// the event loop. If we get back to the event loop and the node
|
||||
|
@ -608,6 +656,7 @@ nsObjectLoadingContent::nsObjectLoadingContent()
|
|||
, mNetworkCreated(true)
|
||||
, mActivated(false)
|
||||
, mContentBlockingEnabled(false)
|
||||
, mSkipFakePlugins(false)
|
||||
, mIsStopping(false)
|
||||
, mIsLoading(false)
|
||||
, mScriptRequested(false)
|
||||
|
@ -1199,7 +1248,7 @@ NS_IMETHODIMP
|
|||
nsObjectLoadingContent::GetContentTypeForMIMEType(const nsACString& aMIMEType,
|
||||
uint32_t* aType)
|
||||
{
|
||||
*aType = GetTypeOfContent(PromiseFlatCString(aMIMEType));
|
||||
*aType = GetTypeOfContent(PromiseFlatCString(aMIMEType), false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1294,6 +1343,7 @@ nsObjectLoadingContent::ObjectState() const
|
|||
case eType_Image:
|
||||
return ImageState();
|
||||
case eType_Plugin:
|
||||
case eType_FakePlugin:
|
||||
case eType_Document:
|
||||
// These are OK. If documents start to load successfully, they display
|
||||
// something, and are thus not broken in this sense. The same goes for
|
||||
|
@ -1537,6 +1587,9 @@ nsObjectLoadingContent::CheckProcessPolicy(int16_t *aContentPolicy)
|
|||
case eType_Document:
|
||||
objectType = nsIContentPolicy::TYPE_DOCUMENT;
|
||||
break;
|
||||
// FIXME Fake plugins look just like real plugins to CSP, should they use
|
||||
// the fake plugin's handler URI and look like documents instead?
|
||||
case eType_FakePlugin:
|
||||
case eType_Plugin:
|
||||
objectType = GetContentPolicyType();
|
||||
break;
|
||||
|
@ -1750,7 +1803,7 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
|
|||
|
||||
// For eAllowPluginSkipChannel tags, if we have a non-plugin type, but can get
|
||||
// a plugin type from the extension, prefer that to falling back to a channel.
|
||||
if (GetTypeOfContent(newMime) != eType_Plugin && newURI &&
|
||||
if (!IsPluginType(GetTypeOfContent(newMime, mSkipFakePlugins)) && newURI &&
|
||||
(caps & eAllowPluginSkipChannel) &&
|
||||
IsPluginEnabledByExtension(newURI, newMime)) {
|
||||
LOG(("OBJLC [%p]: Using extension as type hint (%s)", this, newMime.get()));
|
||||
|
@ -1816,8 +1869,8 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
|
|||
stateInvalid = true;
|
||||
}
|
||||
|
||||
ObjectType typeHint = newMime.IsEmpty() ?
|
||||
eType_Null : GetTypeOfContent(newMime);
|
||||
ObjectType typeHint = newMime.IsEmpty() ? eType_Null
|
||||
: GetTypeOfContent(newMime, mSkipFakePlugins);
|
||||
|
||||
//
|
||||
// In order of preference:
|
||||
|
@ -1838,7 +1891,7 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
|
|||
if (!typeAttr.LowerCaseEqualsASCII(channelType.get())) {
|
||||
stateInvalid = true;
|
||||
}
|
||||
} else if (typeHint == eType_Plugin) {
|
||||
} else if (IsPluginType(typeHint)) {
|
||||
LOG(("OBJLC [%p]: Using plugin type hint in favor of any channel type",
|
||||
this));
|
||||
overrideChannelType = true;
|
||||
|
@ -1900,16 +1953,18 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
|
|||
// 6) Otherwise, type null to indicate unloadable content (fallback)
|
||||
//
|
||||
|
||||
ObjectType newMime_Type = GetTypeOfContent(newMime, mSkipFakePlugins);
|
||||
|
||||
if (stateInvalid) {
|
||||
newType = eType_Null;
|
||||
newMime.Truncate();
|
||||
} else if (newChannel) {
|
||||
// If newChannel is set above, we considered it in setting newMime
|
||||
newType = GetTypeOfContent(newMime);
|
||||
newType = newMime_Type;
|
||||
LOG(("OBJLC [%p]: Using channel type", this));
|
||||
} else if (((caps & eAllowPluginSkipChannel) || !newURI) &&
|
||||
GetTypeOfContent(newMime) == eType_Plugin) {
|
||||
newType = eType_Plugin;
|
||||
IsPluginType(newMime_Type)) {
|
||||
newType = newMime_Type;
|
||||
LOG(("OBJLC [%p]: Plugin type with no URI, skipping channel load", this));
|
||||
} else if (newURI) {
|
||||
// We could potentially load this if we opened a channel on mURI, indicate
|
||||
|
@ -2081,10 +2136,13 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
|||
// NOTE LoadFallback can override this in some cases
|
||||
FallbackType fallbackType = eFallbackAlternate;
|
||||
|
||||
// mType can differ with GetTypeOfContent(mContentType) if we support this
|
||||
// type, but the parameters are invalid e.g. a embed tag with type "image/png"
|
||||
// but no URI -- don't show a plugin error or unknown type error in that case.
|
||||
if (mType == eType_Null && GetTypeOfContent(mContentType) == eType_Null) {
|
||||
// If GetTypeOfContent(mContentType) is null we truly have no handler for the
|
||||
// type -- otherwise, we have a handler but UpdateObjectParameters rejected
|
||||
// the configuration for another reason (e.g. an embed tag with type
|
||||
// "image/png" but no URI). Don't show a plugin error or unknown type error in
|
||||
// the latter case.
|
||||
if (mType == eType_Null &&
|
||||
GetTypeOfContent(mContentType, mSkipFakePlugins) == eType_Null) {
|
||||
fallbackType = eFallbackUnsupported;
|
||||
}
|
||||
|
||||
|
@ -2097,7 +2155,7 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
|||
// We synchronously start/stop plugin instances below, which may spin the
|
||||
// event loop. Re-entering into the load is fine, but at that point the
|
||||
// original load call needs to abort when unwinding
|
||||
// NOTE this is located *after* the state change check, a subseqent load
|
||||
// NOTE this is located *after* the state change check, a subsequent load
|
||||
// with no subsequently changed state will be a no-op.
|
||||
if (mIsLoading) {
|
||||
LOG(("OBJLC [%p]: Re-entering into LoadObject", this));
|
||||
|
@ -2212,7 +2270,7 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
|||
|
||||
// Items resolved as Image/Document are no candidates for content blocking,
|
||||
// as well as invalid plugins (they will not have the mContentType set).
|
||||
if ((mType == eType_Null || mType == eType_Plugin) && ShouldBlockContent()) {
|
||||
if ((mType == eType_Null || IsPluginType(mType)) && ShouldBlockContent()) {
|
||||
LOG(("OBJLC [%p]: Enable content blocking", this));
|
||||
mType = eType_Loading;
|
||||
}
|
||||
|
@ -2222,14 +2280,13 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
|||
// will not be checked for previews, as well as invalid plugins
|
||||
// (they will not have the mContentType set).
|
||||
FallbackType clickToPlayReason;
|
||||
if (!mActivated && (mType == eType_Null || mType == eType_Plugin) &&
|
||||
!ShouldPlay(clickToPlayReason, false)) {
|
||||
if (!mActivated && IsPluginType(mType) && !ShouldPlay(clickToPlayReason)) {
|
||||
LOG(("OBJLC [%p]: Marking plugin as click-to-play", this));
|
||||
mType = eType_Null;
|
||||
fallbackType = clickToPlayReason;
|
||||
}
|
||||
|
||||
if (!mActivated && mType == eType_Plugin) {
|
||||
if (!mActivated && IsPluginType(mType)) {
|
||||
// Object passed ShouldPlay, so it should be considered
|
||||
// activated until it changes content type
|
||||
LOG(("OBJLC [%p]: Object implicitly activated", this));
|
||||
|
@ -2306,31 +2363,81 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case eType_FakePlugin:
|
||||
{
|
||||
if (mChannel) {
|
||||
/// XXX(johns): Ideally we'd have some way to pass the channel to the
|
||||
/// fake plugin handler, but for now handlers will need to
|
||||
/// request element.srcURI themselves if they want it
|
||||
LOG(("OBJLC [%p]: Closing unused channel for fake plugin type", this));
|
||||
CloseChannel();
|
||||
}
|
||||
|
||||
/// XXX(johns) Bug FIXME - We need to cleanup the various plugintag
|
||||
/// classes to be more sane and avoid this dance
|
||||
nsCOMPtr<nsIPluginTag> basetag =
|
||||
nsContentUtils::PluginTagForType(mContentType, false);
|
||||
nsCOMPtr<nsIFakePluginTag> tag = do_QueryInterface(basetag);
|
||||
nsCOMPtr<nsIURI> handlerURI;
|
||||
if (tag) {
|
||||
tag->GetHandlerURI(getter_AddRefs(handlerURI));
|
||||
}
|
||||
|
||||
if (!handlerURI) {
|
||||
NS_NOTREACHED("Selected type is not a proper fake plugin handler");
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = SetupFrameLoader(handlerURI);
|
||||
if (!docShell) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
nsCString spec;
|
||||
handlerURI->GetSpec(spec);
|
||||
LOG(("OBJLC [%p]: Loading fake plugin handler (%s)", this, spec.get()));
|
||||
|
||||
// XXX(johns): This and moreso the document case below are
|
||||
// sidestepping/duplicating nsFrameLoader's LoadURI code,
|
||||
// which is not great.
|
||||
|
||||
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
|
||||
docShell->CreateLoadInfo(getter_AddRefs(loadInfo));
|
||||
if (loadInfo) {
|
||||
loadInfo->SetTriggeringPrincipal(thisContent->NodePrincipal());
|
||||
nsCOMPtr<nsIURI> referrer;
|
||||
thisContent->NodePrincipal()->GetURI(getter_AddRefs(referrer));
|
||||
loadInfo->SetReferrer(referrer);
|
||||
|
||||
rv = docShell->LoadURI(handlerURI, loadInfo,
|
||||
nsIWebNavigation::LOAD_FLAGS_NONE, false);
|
||||
} else {
|
||||
NS_NOTREACHED("CreateLoadInfo failed");
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("OBJLC [%p]: LoadURI() failed for fake handler", this));
|
||||
mFrameLoader->Destroy();
|
||||
mFrameLoader = nullptr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eType_Document:
|
||||
{
|
||||
if (!mChannel) {
|
||||
// We could mFrameLoader->LoadURI(mURI), but UpdateObjectParameters
|
||||
// requires documents have a channel, so this is not a valid state.
|
||||
NS_NOTREACHED("Attempting to load a document without a channel");
|
||||
mType = eType_Null;
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
mFrameLoader = nsFrameLoader::Create(thisContent->AsElement(),
|
||||
/* aOpener = */ nullptr,
|
||||
mNetworkCreated);
|
||||
if (!mFrameLoader) {
|
||||
NS_NOTREACHED("nsFrameLoader::Create failed");
|
||||
mType = eType_Null;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = mFrameLoader->CheckForRecursiveLoad(mURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("OBJLC [%p]: Aborting recursive load", this));
|
||||
mFrameLoader->Destroy();
|
||||
mFrameLoader = nullptr;
|
||||
mType = eType_Null;
|
||||
nsCOMPtr<nsIDocShell> docShell = SetupFrameLoader(mURI);
|
||||
if (!docShell) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2341,14 +2448,6 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
|||
flags |= nsIChannel::LOAD_DOCUMENT_URI;
|
||||
mChannel->SetLoadFlags(flags);
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
rv = mFrameLoader->GetDocShell(getter_AddRefs(docShell));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_NOTREACHED("Could not get DocShell from mFrameLoader?");
|
||||
mType = eType_Null;
|
||||
break;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> req(do_QueryInterface(docShell));
|
||||
NS_ASSERTION(req, "Docshell must be an ifreq");
|
||||
|
||||
|
@ -2356,9 +2455,11 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
|||
uriLoader(do_GetService(NS_URI_LOADER_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_NOTREACHED("Failed to get uriLoader service");
|
||||
mType = eType_Null;
|
||||
mFrameLoader->Destroy();
|
||||
mFrameLoader = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = uriLoader->OpenChannel(mChannel, nsIURILoader::DONT_RETARGET, req,
|
||||
getter_AddRefs(finalListener));
|
||||
// finalListener will receive OnStartRequest below
|
||||
|
@ -2712,14 +2813,16 @@ nsObjectLoadingContent::NotifyStateChanged(ObjectType aOldType,
|
|||
}
|
||||
|
||||
nsObjectLoadingContent::ObjectType
|
||||
nsObjectLoadingContent::GetTypeOfContent(const nsCString& aMIMEType)
|
||||
nsObjectLoadingContent::GetTypeOfContent(const nsCString& aMIMEType,
|
||||
bool aNoFakePlugin)
|
||||
{
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
NS_ASSERTION(thisContent, "must be a content");
|
||||
|
||||
ObjectType type = static_cast<ObjectType>(
|
||||
nsContentUtils::HtmlObjectContentTypeForMIMEType(aMIMEType, thisContent));
|
||||
nsContentUtils::HtmlObjectContentTypeForMIMEType(aMIMEType, aNoFakePlugin,
|
||||
thisContent));
|
||||
|
||||
// Switch the result type to eType_Null ic the capability is not present.
|
||||
uint32_t caps = GetCapabilities();
|
||||
|
@ -2729,7 +2832,8 @@ nsObjectLoadingContent::GetTypeOfContent(const nsCString& aMIMEType)
|
|||
if (!(caps & eSupportDocuments) && type == eType_Document) {
|
||||
type = eType_Null;
|
||||
}
|
||||
if (!(caps & eSupportPlugins) && type == eType_Plugin) {
|
||||
if (!(caps & eSupportPlugins) &&
|
||||
(type == eType_Plugin || type == eType_FakePlugin)) {
|
||||
type = eType_Null;
|
||||
}
|
||||
|
||||
|
@ -3124,6 +3228,7 @@ nsObjectLoadingContent::Reload(bool aClearActivation)
|
|||
{
|
||||
if (aClearActivation) {
|
||||
mActivated = false;
|
||||
mSkipFakePlugins = false;
|
||||
}
|
||||
|
||||
return LoadObject(true, true);
|
||||
|
@ -3140,13 +3245,28 @@ uint32_t
|
|||
nsObjectLoadingContent::DefaultFallbackType()
|
||||
{
|
||||
FallbackType reason;
|
||||
bool go = ShouldPlay(reason, true);
|
||||
if (go) {
|
||||
if (ShouldPlay(reason)) {
|
||||
return PLUGIN_ACTIVE;
|
||||
}
|
||||
return reason;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::SkipFakePlugins()
|
||||
{
|
||||
if (!nsContentUtils::IsCallerChrome())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
mSkipFakePlugins = true;
|
||||
|
||||
// If we're showing a fake plugin now, reload
|
||||
if (mType == eType_FakePlugin) {
|
||||
return LoadObject(true, true);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nsObjectLoadingContent::GetRunID(SystemCallerGuarantee, ErrorResult& aRv)
|
||||
{
|
||||
|
@ -3193,7 +3313,7 @@ nsObjectLoadingContent::ShouldBlockContent()
|
|||
}
|
||||
|
||||
bool
|
||||
nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentType)
|
||||
nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
|
@ -3216,11 +3336,6 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentTyp
|
|||
|
||||
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
|
||||
|
||||
// at this point if it's not a plugin, we let it play/fallback
|
||||
if (!aIgnoreCurrentType && mType != eType_Plugin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Order of checks:
|
||||
// * Assume a default of click-to-play
|
||||
// * If globally disabled, per-site permissions cannot override.
|
||||
|
@ -3256,8 +3371,7 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentTyp
|
|||
|
||||
if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE) {
|
||||
aReason = eFallbackVulnerableUpdatable;
|
||||
}
|
||||
else if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
|
||||
} else if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_NO_UPDATE) {
|
||||
aReason = eFallbackVulnerableNoUpdate;
|
||||
}
|
||||
|
||||
|
@ -3291,10 +3405,10 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentTyp
|
|||
NS_ENSURE_TRUE(permissionManager, false);
|
||||
|
||||
// For now we always say that the system principal uses click-to-play since
|
||||
// that maintains current behavior and we have tests that expect this.
|
||||
// What we really should do is disable plugins entirely in pages that use
|
||||
// the system principal, i.e. in chrome pages. That way the click-to-play
|
||||
// code here wouldn't matter at all. Bug 775301 is tracking this.
|
||||
// that maintains current behavior and we have tests that expect this. What
|
||||
// we really should do is disable plugins entirely in pages that use the
|
||||
// system principal, i.e. in chrome pages. That way the click-to-play code
|
||||
// here wouldn't matter at all. Bug 775301 is tracking this.
|
||||
if (!nsContentUtils::IsSystemPrincipal(topDoc->NodePrincipal())) {
|
||||
nsAutoCString permissionString;
|
||||
rv = pluginHost->GetPermissionStringForType(mContentType,
|
||||
|
|
|
@ -64,12 +64,16 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
eType_Image = TYPE_IMAGE,
|
||||
// Content is a plugin
|
||||
eType_Plugin = TYPE_PLUGIN,
|
||||
// Content is a fake plugin, which loads as a document but behaves as a
|
||||
// plugin (see nsPluginHost::CreateFakePlugin)
|
||||
eType_FakePlugin = TYPE_FAKE_PLUGIN,
|
||||
// Content is a subdocument, possibly SVG
|
||||
eType_Document = TYPE_DOCUMENT,
|
||||
// No content loaded (fallback). May be showing alternate content or
|
||||
// a custom error handler - *including* click-to-play dialogs
|
||||
eType_Null = TYPE_NULL
|
||||
};
|
||||
|
||||
enum FallbackType {
|
||||
// The content type is not supported (e.g. plugin not installed)
|
||||
eFallbackUnsupported = nsIObjectLoadingContent::PLUGIN_UNSUPPORTED,
|
||||
|
@ -192,7 +196,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
}
|
||||
uint32_t GetContentTypeForMIMEType(const nsAString& aMIMEType)
|
||||
{
|
||||
return GetTypeOfContent(NS_ConvertUTF16toUTF8(aMIMEType));
|
||||
return GetTypeOfContent(NS_ConvertUTF16toUTF8(aMIMEType), false);
|
||||
}
|
||||
void PlayPlugin(mozilla::dom::SystemCallerGuarantee,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
@ -223,6 +227,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
{
|
||||
return !!mInstanceOwner;
|
||||
}
|
||||
// FIXME rename this
|
||||
void SkipFakePlugins(mozilla::ErrorResult& aRv)
|
||||
{
|
||||
aRv = SkipFakePlugins();
|
||||
}
|
||||
void SwapFrameLoaders(mozilla::dom::HTMLIFrameElement& aOtherLoaderOwner,
|
||||
mozilla::ErrorResult& aRv)
|
||||
{
|
||||
|
@ -461,9 +470,10 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
* If this object is allowed to play plugin content, or if it would display
|
||||
* click-to-play instead.
|
||||
* NOTE that this does not actually check if the object is a loadable plugin
|
||||
* NOTE This ignores the current activated state. The caller should check this if appropriate.
|
||||
* NOTE This ignores the current activated state. The caller should check
|
||||
* this if appropriate.
|
||||
*/
|
||||
bool ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentType);
|
||||
bool ShouldPlay(FallbackType &aReason);
|
||||
|
||||
/**
|
||||
* This method tells if the fallback content should be attempted to be used
|
||||
|
@ -521,6 +531,14 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
*/
|
||||
bool MakePluginListener();
|
||||
|
||||
/**
|
||||
* Helper to spawn mFrameLoader and return a pointer to its docshell
|
||||
*
|
||||
* @param aURI URI we intend to load for the recursive load check (does not
|
||||
* actually load anything)
|
||||
*/
|
||||
already_AddRefed<nsIDocShell> SetupFrameLoader(nsIURI *aRecursionCheckURI);
|
||||
|
||||
/**
|
||||
* Unloads all content and resets the object to a completely unloaded state
|
||||
*
|
||||
|
@ -550,10 +568,14 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
* support the given MIME type as, taking capabilities and plugin state
|
||||
* into account
|
||||
*
|
||||
* @param aNoFakePlugin Don't select a fake plugin handler as a valid type,
|
||||
* as when SkipFakePlugins() is called.
|
||||
* @return The ObjectType enum value that we would attempt to load
|
||||
*
|
||||
* NOTE this does not consider whether the content would be suppressed by
|
||||
* click-to-play or other content policy checks
|
||||
*/
|
||||
ObjectType GetTypeOfContent(const nsCString& aMIMEType);
|
||||
ObjectType GetTypeOfContent(const nsCString& aMIMEType, bool aNoFakePlugin);
|
||||
|
||||
/**
|
||||
* Gets the frame that's associated with this content node.
|
||||
|
@ -687,14 +709,17 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
// Whether content blocking is enabled or not for this object.
|
||||
bool mContentBlockingEnabled : 1;
|
||||
|
||||
// If we should not use fake plugins until the next type change
|
||||
bool mSkipFakePlugins : 1;
|
||||
|
||||
// Protects DoStopPlugin from reentry (bug 724781).
|
||||
bool mIsStopping : 1;
|
||||
|
||||
// Protects LoadObject from re-entry
|
||||
bool mIsLoading : 1;
|
||||
|
||||
// For plugin stand-in types (click-to-play) tracks
|
||||
// whether content js has tried to access the plugin script object.
|
||||
// For plugin stand-in types (click-to-play) tracks whether content js has
|
||||
// tried to access the plugin script object.
|
||||
bool mScriptRequested : 1;
|
||||
|
||||
// True if object represents an object/embed tag pointing to a flash embed
|
||||
|
|
|
@ -345,7 +345,7 @@ HTMLObjectElement::IsFocusableForTabIndex()
|
|||
}
|
||||
|
||||
return IsEditableRoot() ||
|
||||
(Type() == eType_Document &&
|
||||
((Type() == eType_Document || Type() == eType_FakePlugin) &&
|
||||
nsContentUtils::IsSubDocumentTabbable(this));
|
||||
}
|
||||
|
||||
|
@ -369,7 +369,8 @@ HTMLObjectElement::IsHTMLFocusable(bool aWithMouse,
|
|||
// This method doesn't call nsGenericHTMLFormElement intentionally.
|
||||
// TODO: It should probably be changed when bug 597242 will be fixed.
|
||||
if (Type() == eType_Plugin || IsEditableRoot() ||
|
||||
(Type() == eType_Document && nsContentUtils::IsSubDocumentTabbable(this))) {
|
||||
((Type() == eType_Document || Type() == eType_FakePlugin) &&
|
||||
nsContentUtils::IsSubDocumentTabbable(this))) {
|
||||
// Has plugin content: let the plugin decide what to do in terms of
|
||||
// internal focus from mouse clicks
|
||||
if (aTabIndex) {
|
||||
|
@ -400,7 +401,7 @@ HTMLObjectElement::GetDesiredIMEState()
|
|||
if (Type() == eType_Plugin) {
|
||||
return IMEState(IMEState::PLUGIN);
|
||||
}
|
||||
|
||||
|
||||
return nsGenericHTMLFormElement::GetDesiredIMEState();
|
||||
}
|
||||
|
||||
|
|
|
@ -83,15 +83,17 @@ interface MozObjectLoadingContent {
|
|||
// make sure to update this list if nsIObjectLoadingContent changes. Also,
|
||||
// make sure everything on here is [ChromeOnly].
|
||||
[ChromeOnly]
|
||||
const unsigned long TYPE_LOADING = 0;
|
||||
const unsigned long TYPE_LOADING = 0;
|
||||
[ChromeOnly]
|
||||
const unsigned long TYPE_IMAGE = 1;
|
||||
const unsigned long TYPE_IMAGE = 1;
|
||||
[ChromeOnly]
|
||||
const unsigned long TYPE_PLUGIN = 2;
|
||||
const unsigned long TYPE_PLUGIN = 2;
|
||||
[ChromeOnly]
|
||||
const unsigned long TYPE_DOCUMENT = 3;
|
||||
const unsigned long TYPE_FAKE_PLUGIN = 3;
|
||||
[ChromeOnly]
|
||||
const unsigned long TYPE_NULL = 4;
|
||||
const unsigned long TYPE_DOCUMENT = 4;
|
||||
[ChromeOnly]
|
||||
const unsigned long TYPE_NULL = 5;
|
||||
|
||||
// The content type is not supported (e.g. plugin not installed)
|
||||
[ChromeOnly]
|
||||
|
@ -204,6 +206,12 @@ interface MozObjectLoadingContent {
|
|||
[ChromeOnly]
|
||||
readonly attribute boolean hasRunningPlugin;
|
||||
|
||||
/**
|
||||
* Disable the use of fake plugins and reload the tag if necessary
|
||||
*/
|
||||
[ChromeOnly, Throws]
|
||||
void skipFakePlugins();
|
||||
|
||||
[ChromeOnly, Throws, NeedsCallerType]
|
||||
readonly attribute unsigned long runID;
|
||||
};
|
||||
|
|
|
@ -3809,6 +3809,9 @@ nsCSSFrameConstructor::FindObjectData(Element* aElement,
|
|||
SIMPLE_INT_CREATE(nsIObjectLoadingContent::TYPE_IMAGE,
|
||||
NS_NewImageFrame),
|
||||
SIMPLE_INT_CREATE(nsIObjectLoadingContent::TYPE_DOCUMENT,
|
||||
NS_NewSubDocumentFrame),
|
||||
// Fake plugin handlers load as documents
|
||||
SIMPLE_INT_CREATE(nsIObjectLoadingContent::TYPE_FAKE_PLUGIN,
|
||||
NS_NewSubDocumentFrame)
|
||||
// Nothing for TYPE_NULL so we'll construct frames by display there
|
||||
};
|
||||
|
|
|
@ -384,7 +384,7 @@ NS_GetIsDocumentChannel(nsIChannel * aChannel, bool *aIsDocument)
|
|||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (nsContentUtils::HtmlObjectContentTypeForMIMEType(mimeType, nullptr) ==
|
||||
if (nsContentUtils::HtmlObjectContentTypeForMIMEType(mimeType, false, nullptr) ==
|
||||
nsIObjectLoadingContent::TYPE_DOCUMENT) {
|
||||
*aIsDocument = true;
|
||||
return NS_OK;
|
||||
|
|
Загрузка…
Ссылка в новой задаче