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:
John Schoenick 2015-05-20 15:30:05 +02:00
Родитель ec17d16219
Коммит 4ce6580106
9 изменённых файлов: 278 добавлений и 83 удалений

Просмотреть файл

@ -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;