Back out bug 771666 and bug 745030.

This commit is contained in:
Ms2ger 2012-07-25 22:39:01 +02:00
parent d7a8ecf988
commit 3941714312
9 changed files with 1366 additions and 1663 deletions

View File

@ -24,9 +24,6 @@ interface nsIURI;
[scriptable, uuid(e3e284a3-b4a8-49ef-af6b-c8c4a158db86)]
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;

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,36 @@ class AutoFallback;
class AutoSetInstantiatingToFalse;
class nsObjectFrame;
enum PluginSupportState {
ePluginUnsupported, // The plugin is not supported (e.g. not installed)
ePluginDisabled, // The plugin has been explicitly disabled by the user
ePluginBlocklisted, // The plugin is blocklisted and disabled
ePluginOutdated, // The plugin is considered outdated, but not disabled
ePluginOtherState, // Something else (e.g. uninitialized or not a plugin)
ePluginCrashed,
ePluginClickToPlay, // The plugin is disabled until the user clicks on it
ePluginVulnerableUpdatable, // The plugin is vulnerable (update available)
ePluginVulnerableNoUpdate // The plugin is vulnerable (no update available)
};
/**
* INVARIANTS OF THIS CLASS
* - mChannel is non-null between asyncOpen and onStopRequest (NOTE: Only needs
* to be valid until onStopRequest is called on mFinalListener, not
* necessarily until the channel calls onStopRequest on us)
* - mChannel corresponds to the channel that gets passed to the
* nsIRequestObserver/nsIStreamListener methods
* - mChannel can be cancelled and ODA calls will stop
* - mFinalListener is non-null (only) after onStartRequest has been called on
* it and before onStopRequest has been called on it
* (i.e. calling onStopRequest doesn't violate the nsIRequestObserver
* contract)
* - mFrameLoader is null while this node is not in a document (XXX this
* invariant only exists due to nsFrameLoader suckage and needs to go away)
* - mInstantiating is true while in LoadObject (it may be true in other
* cases as well). Only the function that set mInstantiating should trigger
* frame construction or notifications like ContentStatesChanged or flushes.
*/
class nsObjectLoadingContent : public nsImageLoadingContent
, public nsIStreamListener
, public nsIFrameLoaderOwner
@ -38,9 +68,9 @@ class nsObjectLoadingContent : public nsImageLoadingContent
, public nsIInterfaceRequestor
, public nsIChannelEventSink
{
friend class AutoNotifier;
friend class AutoFallback;
friend class AutoSetInstantiatingToFalse;
friend class AutoSetLoadingToFalse;
friend class InDocCheckEvent;
friend class nsStopPluginRunnable;
friend class nsAsyncInstantiateEvent;
@ -48,33 +78,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent
// This enum's values must be the same as the constants on
// nsIObjectLoadingContent
enum ObjectType {
// Loading, type not yet known. We may be waiting for a channel to open.
eType_Loading = TYPE_LOADING,
// Content is a *non-svg* image
eType_Image = TYPE_IMAGE,
// Content is a plugin
eType_Plugin = TYPE_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 {
eFallbackUnsupported, // The content type is not supported (e.g. plugin
// not installed)
eFallbackAlternate, // Showing alternate content
eFallbackDisabled, // The plugin exists, but is disabled
eFallbackBlocklisted, // The plugin is blocklisted and disabled
eFallbackOutdated, // The plugin is considered outdated, but not
// disabled
eFallbackCrashed, // The plugin has crashed
eFallbackSuppressed, // Suppressed by security policy
eFallbackUserDisabled, // Blocked by content policy
eFallbackClickToPlay, // The plugin is disabled until the user clicks on
// it
eFallbackVulnerableUpdatable, // The plugin is vulnerable (update avail)
eFallbackVulnerableNoUpdate // The plugin is vulnerable (no update avail)
eType_Loading = TYPE_LOADING, ///< Type not yet known
eType_Image = TYPE_IMAGE, ///< This content is an image
eType_Plugin = TYPE_PLUGIN, ///< This content is a plugin
eType_Document = TYPE_DOCUMENT, ///< This is a document type (e.g. HTML)
eType_Null = TYPE_NULL ///< Type can't be handled
};
nsObjectLoadingContent();
@ -94,106 +102,110 @@ class nsObjectLoadingContent : public nsImageLoadingContent
using nsImageLoadingContent::OnStopRequest;
#endif
ObjectType Type() { return mType; }
/**
* Object state. This is a bitmask of NS_EVENT_STATEs epresenting the
* current state of the object.
* Object state. This is a bitmask consisting of a subset of
* NS_EVENT_STATE_BROKEN, NS_EVENT_STATE_USERDISABLED and
* NS_EVENT_STATE_SUPPRESSED representing the current state of the object.
*/
nsEventStates ObjectState() const;
ObjectType Type() { return mType; }
void SetIsNetworkCreated(bool aNetworkCreated)
{
mNetworkCreated = aNetworkCreated;
}
/**
* Immediately instantiate a plugin instance. This is a no-op if
* mType != eType_Plugin or a plugin is already running.
*/
nsresult InstantiatePluginInstance();
// Can flush layout.
nsresult InstantiatePluginInstance(const char* aMimeType, nsIURI* aURI);
/**
* Notify this class the document state has changed
* Called by nsDocument so we may suspend plugins in inactive documents)
*/
void NotifyOwnerDocumentActivityChanged();
/**
* Used by pluginHost to know if we're loading with a channel, so it
* will not open its own.
*/
bool SrcStreamLoading() { return mSrcStreamLoading; };
protected:
/**
* Begins loading the object when called
* Load the object from the given URI.
* @param aURI The URI to load.
* @param aNotify If true, nsIDocumentObserver state change notifications
* will be sent as needed.
* @param aTypeHint MIME Type hint. Overridden by the server unless this
* class has the eOverrideServerType capability.
* @param aForceLoad If true, the object will be refetched even if the URI
* is the same as the currently-loaded object.
* @note Prefer the nsIURI-taking version of this function if a URI object
* is already available.
* @see the URI-taking version of this function for a detailed description
* of how a plugin will be found.
*/
nsresult LoadObject(const nsAString& aURI,
bool aNotify,
const nsCString& aTypeHint = EmptyCString(),
bool aForceLoad = false);
/**
* Loads the object from the given URI.
*
* Attributes of |this| QI'd to nsIContent will be inspected, depending on
* the node type. This function currently assumes it is a <applet>,
* <object>, or <embed> tag.
* The URI and type can both be null; if the URI is null a plugin will be
* instantiated in the hope that there is a <param> with a useful URI
* somewhere around. Other attributes of |this| QI'd to nsIContent will be
* inspected. This function attempts hard to find a suitable plugin.
*
* The instantiated plugin depends on:
* - The URI (<embed src>, <object data>)
* - The type 'hint' (type attribute)
* - The mime type returned by opening the URI
* - Enabled plugins claiming the ultimate mime type
* - The capabilities returned by GetCapabilities
* The instantiated plugin depends on three values:
* - The passed-in URI
* - The passed-in type hint
* - The classid attribute, if eSupportClassID is among the capabilities
* and such an attribute is present..
*
* If eAllowPluginSkipChannel is true, we may skip opening the URI if our
* type hint points to a valid plugin, deferring that responsibility to the
* plugin.
* Similarly, if no URI is provided, but a type hint for a valid plugin is
* present, that plugin will be instantiated
* Supported class ID attributes override any other value.
*
* If no class ID is present and aForceType is true, the handler given by
* aTypeHint will be instantiated for this content.
* If the URI is null or not supported, and a type hint is given, the plugin
* corresponding to that type is instantiated.
*
* Otherwise a request to that URI is made and the type sent by the server
* is used to find a suitable handler, EXCEPT when:
* - The type hint refers to a *supported* plugin, in which case that
* plugin will be instantiated regardless of the server provided type
* - The server returns a binary-stream type, and our type hint refers to
* a valid non-document type, we will use the type hint
* is used to find a suitable handler.
*
* @param aNotify If we should send notifications. If false, content
* loading may be deferred while appropriate frames are
* created
* @param aForceLoad If we should reload this content (and re-attempt the
* channel open) even if our parameters did not change
* @param aForceLoad If true, the object will be refetched even if the URI
* is the same as the currently-loaded object.
*/
nsresult LoadObject(bool aNotify,
nsresult LoadObject(nsIURI* aURI,
bool aNotify,
const nsCString& aTypeHint = EmptyCString(),
bool aForceLoad = false);
enum Capabilities {
eSupportImages = PR_BIT(0), // Images are supported (imgILoader)
eSupportPlugins = PR_BIT(1), // Plugins are supported (nsIPluginHost)
eSupportDocuments = PR_BIT(2), // Documents are supported
// (nsIDocumentLoaderFactory)
// This flag always includes SVG
eSupportSVG = PR_BIT(3), // SVG is supported (image/svg+xml)
eSupportClassID = PR_BIT(4), // The classid attribute is supported
// Allows us to load a plugin if it matches a MIME type or file extension
// registered to a plugin without opening its specified URI first. Can
// result in launching plugins for URIs that return differing content
// types. Plugins without URIs may instantiate regardless.
// XXX(johns) this is our legacy behavior on <embed> tags, whereas object
// will always open a channel and check its MIME if a URI is present.
eAllowPluginSkipChannel = PR_BIT(5)
eSupportImages = PR_BIT(0), // Images are supported (imgILoader)
eSupportPlugins = PR_BIT(1), // Plugins are supported (nsIPluginHost)
eSupportDocuments = PR_BIT(2), // Documents are supported
// (nsIDocumentLoaderFactory)
// This flag always includes SVG
eSupportSVG = PR_BIT(3), // SVG is supported (image/svg+xml)
eSupportClassID = PR_BIT(4), // The classid attribute is supported
eOverrideServerType = PR_BIT(5) // The server-sent MIME type is ignored
// (ignored if no type is specified)
};
/**
* Returns the list of capabilities this content node supports. This is a
* bitmask consisting of flags from the Capabilities enum.
*
* The default implementation supports all types but not
* eSupportClassID or eAllowPluginSkipChannel
* The default implementation supports all types but no classids.
*/
virtual PRUint32 GetCapabilities() const;
/**
* Destroys all loaded documents/plugins and releases references
* Fall back to rendering the alternative content.
*/
void DestroyContent();
void Fallback(bool aNotify);
/**
* Subclasses must call this function when they are removed from the
* document.
*
* XXX This is a temporary workaround for docshell suckyness
*/
void RemovedFromDocument();
static void Traverse(nsObjectLoadingContent *tmp,
nsCycleCollectionTraversalCallback &cb);
@ -210,127 +222,30 @@ class nsObjectLoadingContent : public nsImageLoadingContent
bool aNullParent = true);
private:
// Object parameter changes returned by UpdateObjectParameters
enum ParameterUpdateFlags {
eParamNoChange = 0,
// Parameters that potentially affect the channel changed
// - mOriginalURI, mOriginalContentType
eParamChannelChanged = PR_BIT(0),
// Parameters that affect displayed content changed
// - mURI, mContentType, mType, mBaseURI
eParamStateChanged = PR_BIT(1)
};
/**
* Loads fallback content with the specified FallbackType
*
* @param aType FallbackType value for type of fallback we're loading
* @param aNotify Send notifications and events. If false, caller is
* responsible for doing so
*/
void LoadFallback(FallbackType aType, bool aNotify);
/**
* Internal version of LoadObject that should only be used by this class
* aLoadingChannel is passed by the LoadObject call from OnStartRequest,
* primarily for sanity-preservation
*/
nsresult LoadObject(bool aNotify,
bool aForceLoad,
nsIRequest *aLoadingChannel);
/**
* Introspects the object and sets the following member variables:
* - mOriginalContentType : This is the type attribute on the element
* - mOriginalURI : The src or data attribute on the element
* - mURI : The final URI, considering mChannel if
* mChannelLoaded is set
* - mContentType : The final content type, considering mChannel if
* mChannelLoaded is set
* - mBaseURI : The object's base URI, which may be set by the
* object (codebase attribute)
* - mType : The type the object is determined to be based
* on the above
*
* NOTE The class assumes that mType is the currently loaded type at various
* points, so the caller of this function must take the appropriate
* actions to ensure this
*
* NOTE This function does not perform security checks, only determining the
* requested type and parameters of the object.
*
* @return Returns a bitmask of ParameterUpdateFlags values
*/
ParameterUpdateFlags UpdateObjectParameters();
void NotifyContentObjectWrapper();
/**
* Opens the channel pointed to by mURI into mChannel.
*
* @param aPolicyType The value to be passed to channelPolicy->SetLoadType
* Check whether the given request represents a successful load.
*/
nsresult OpenChannel(PRInt32 aPolicyType);
static bool IsSuccessfulRequest(nsIRequest* aRequest);
/**
* Closes and releases references to mChannel and, if opened, mFinalListener
* Check whether the URI can be handled internally.
*/
nsresult CloseChannel();
static bool CanHandleURI(nsIURI* aURI);
/**
* 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
*/
bool ShouldPlay(FallbackType &aReason);
/**
* Checks if a URI passes security checks and content policy, relative to
* the current document's principal
*
* @param aURI The URI to consider
* @param aContentPolicy [in/out] A pointer to the initial content
* policy, that will be updated to contain the
* final determined policy
* @param aContentPolicyType The 'contentType' parameter passed to
* NS_CheckContentLoadPolicy
*
* @return true if this URI is acceptable for loading
*/
bool CheckURILoad(nsIURI *aURI,
PRInt16 *aContentPolicy,
PRInt32 aContentPolicyType);
/**
* Checks if the current mURI and mBaseURI pass content policy and security
* checks for loading
*
* @param aContentPolicy [in/out] A pointer to the initial content
* policy, that will be updated to contain the
* final determined policy if a URL is rejected
* @param aContentPolicyType The 'contentType' parameter passed to
* NS_CheckContentLoadPolicy
*
* @return true if the URIs are acceptable for loading
*/
bool CheckObjectURIs(PRInt16 *aContentPolicy, PRInt32 aContentPolicyType);
/**
* Checks whether the given type is a supported document type
*
* NOTE Does not take content policy or capabilities into account
* Checks whether the given type is a supported document type.
*/
bool IsSupportedDocument(const nsCString& aType);
/**
* Unloads all content and resets the object to a completely unloaded state
*
* NOTE Calls StopPluginInstance() and may spin the event loop
*
* @param aResetState Reset the object type to 'loading' and destroy channel
* as well
* Unload the currently loaded content. This removes all state related to
* the displayed content and sets the type to eType_Null.
* Note: This does not send any notifications.
*/
void UnloadObject(bool aResetState = true);
void UnloadContent();
/**
* Notifies document observes about a new type/state of this object.
@ -346,112 +261,141 @@ class nsObjectLoadingContent : public nsImageLoadingContent
bool aSync, bool aNotify);
/**
* Fires the nsPluginErrorEvent. This function doesn't do any checks
* whether it should be fired, or whether the given state translates to a
* meaningful event
* Fires the "Plugin not found" event. This function doesn't do any checks
* whether it should be fired, the caller should do that.
*/
void FirePluginError(FallbackType aFallbackType);
static void FirePluginError(nsIContent* thisContent, PluginSupportState state);
/**
* Returns a ObjectType value corresponding to the type of content we would
* support the given MIME type as, taking capabilities and plugin state
* into account
*
* 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);
/**
* For a classid, returns the MIME type that can be used to instantiate
* a plugin for this ID.
*
* @param aClassID The class ID in question
* @param aType [out] The corresponding type, if the call is successful
* @return NS_ERROR_NOT_AVAILABLE Unsupported class ID.
*/
nsresult TypeForClassID(const nsAString& aClassID, nsACString& aType);
/**
* Gets the base URI to be used for this object. This differs from
* nsIContent::GetBaseURI in that it takes codebase attributes into
* account.
*/
void GetObjectBaseURI(nsIContent* thisContent, nsIURI** aURI);
/**
* Gets the frame that's associated with this content node.
* Does not flush.
*/
nsObjectFrame* GetExistingFrame();
// The final listener for mChannel (uriloader, pluginstreamlistener, etc.)
/**
* Handle being blocked by a content policy. aStatus is the nsresult
* return value of the Should* call, while aRetval is what it returned in
* its out parameter.
*/
void HandleBeingBlockedByContentPolicy(nsresult aStatus,
PRInt16 aRetval);
/**
* Get the plugin support state for the given content node and MIME type.
* This is used for purposes of determining whether to fire PluginNotFound
* events etc. aContentType is the MIME type we ended up with.
*
* This should only be called if the type of this content is eType_Null.
*/
PluginSupportState GetPluginSupportState(nsIContent* aContent, const nsCString& aContentType);
/**
* If the plugin for aContentType is disabled, return ePluginDisabled.
* Otherwise (including if there is no plugin for aContentType at all),
* return ePluginUnsupported.
*
* This should only be called if the type of this content is eType_Null.
*/
PluginSupportState GetPluginDisabledState(const nsCString& aContentType);
/**
* When there is no usable plugin available this will send UI events and
* update the AutoFallback object appropriate to the reason for there being
* no plugin available.
*/
void UpdateFallbackState(nsIContent* aContent, AutoFallback& fallback, const nsCString& aTypeHint);
nsresult IsPluginEnabledForType(const nsCString& aMIMEType);
bool IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType);
/**
* The final listener to ship the data to (imagelib, uriloader, etc)
*/
nsCOMPtr<nsIStreamListener> mFinalListener;
// Frame loader, for content documents we load.
/**
* Frame loader, for content documents we load.
*/
nsRefPtr<nsFrameLoader> mFrameLoader;
// A pending nsAsyncInstantiateEvent (may be null). This is a weak ref.
/**
* A pending nsAsyncInstantiateEvent (may be null). This is a weak ref.
*/
nsIRunnable *mPendingInstantiateEvent;
// The content type of our current load target, updated by
// UpdateObjectParameters(). Takes the channel's type into account once
// opened.
//
// May change if a channel is opened, does not imply a loaded state
/**
* The content type of the resource we were last asked to load.
*/
nsCString mContentType;
// The content type 'hint' provided by the element's type attribute. May
// or may not be used as a final type
nsCString mOriginalContentType;
/**
* The channel that's currently being loaded. This is a weak reference.
* Non-null between asyncOpen and onStopRequest.
*/
nsIChannel* mChannel;
// The channel that's currently being loaded. If set, but mChannelLoaded is
// false, has not yet reached OnStartRequest
nsCOMPtr<nsIChannel> mChannel;
// The URI of the current content.
// May change as we open channels and encounter redirects - does not imply
// a loaded type
// The data we were last asked to load
nsCOMPtr<nsIURI> mURI;
// The original URI obtained from inspecting the element (codebase, and
// src/data). May differ from mURI due to redirects
nsCOMPtr<nsIURI> mOriginalURI;
/**
* Type of the currently-loaded content.
*/
ObjectType mType : 16;
// The baseURI used for constructing mURI, and used by some plugins (java)
// as a root for other resource requests.
nsCOMPtr<nsIURI> mBaseURI;
// Type of the currently-loaded content.
ObjectType mType : 8;
// The type of fallback content we're showing (see ObjectState())
FallbackType mFallbackType : 8;
// If true, the current load has finished opening a channel. Does not imply
// mChannel -- mChannelLoaded && !mChannel may occur for a load that failed
bool mChannelLoaded : 1;
// Whether we are about to call instantiate on our frame. If we aren't,
// SetFrame needs to asynchronously call Instantiate.
/**
* Whether we are about to call instantiate on our frame. If we aren't,
* SetFrame needs to asynchronously call Instantiate.
*/
bool mInstantiating : 1;
// Blocking status from content policy
bool mUserDisabled : 1;
bool mSuppressed : 1;
// True when the object is created for an element which the parser has
// created using NS_FROM_PARSER_NETWORK flag. If the element is modified,
// it may lose the flag.
bool mNetworkCreated : 1;
// Used to keep track of whether or not a plugin has been explicitly
// activated by PlayPlugin(). (see ShouldPlay())
// Used to keep track of if a plugin is blocked by click-to-play.
// True indicates the plugin is not click-to-play or it has been clicked by
// the user.
// False indicates the plugin is click-to-play and has not yet been clicked.
bool mCTPPlayable : 1;
// Used to keep track of whether or not a plugin has been played.
// This is used for click-to-play plugins.
bool mActivated : 1;
// Protects DoStopPlugin from reentry (bug 724781).
bool mIsStopping : 1;
// Protects LoadObject from re-entry
bool mIsLoading : 1;
// Used to track when we might try to instantiate a plugin instance based on
// a src data stream being delivered to this object. When this is true we
// don't want plugin instance instantiation code to attempt to load src data
// again or we'll deliver duplicate streams. Should be cleared when we are
// not loading src data.
// a src data stream being delivered to this object. When this is true we don't
// want plugin instance instantiation code to attempt to load src data again or
// we'll deliver duplicate streams. Should be cleared when we are not loading
// src data.
bool mSrcStreamLoading;
// A specific state that caused us to fallback
PluginSupportState mFallbackReason;
nsWeakFrame mPrintFrame;

View File

@ -268,6 +268,7 @@ void
nsHTMLObjectElement::UnbindFromTree(bool aDeep,
bool aNullParent)
{
RemovedFromDocument();
nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
}
@ -279,12 +280,10 @@ nsHTMLObjectElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
nsIAtom *aPrefix, const nsAString &aValue,
bool aNotify)
{
nsresult rv = nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
NS_ENSURE_SUCCESS(rv, rv);
// if aNotify is false, we are coming from the parser or some such place;
// we'll get bound after all the attributes have been set, so we'll do the
// If we plan to call LoadObject, we want to do it first so that the
// object load kicks off _before_ the reflow triggered by the SetAttr. But if
// aNotify is false, we are coming from the parser or some such place; we'll
// get bound after all the attributes have been set, so we'll do the
// object load from BindToTree/DoneAddingChildren.
// Skip the LoadObject call in that case.
// We also don't want to start loading the object when we're not yet in
@ -292,27 +291,24 @@ nsHTMLObjectElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
// attributes before inserting the node into the document.
if (aNotify && IsInDoc() && mIsDoneAddingChildren &&
aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data) {
return LoadObject(aNotify, true);
nsAutoString type;
GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
LoadObject(aValue, aNotify, NS_ConvertUTF16toUTF8(type), true);
}
return NS_OK;
return nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
}
nsresult
nsHTMLObjectElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
bool aNotify)
{
nsresult rv = nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID,
aAttribute, aNotify);
NS_ENSURE_SUCCESS(rv, rv);
// See comment in SetAttr
if (aNotify && IsInDoc() && mIsDoneAddingChildren &&
aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data) {
return LoadObject(aNotify, true);
if (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data) {
Fallback(aNotify);
}
return NS_OK;
return nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
}
bool
@ -517,7 +513,20 @@ nsHTMLObjectElement::GetAttributeMappingFunction() const
void
nsHTMLObjectElement::StartObjectLoad(bool aNotify)
{
LoadObject(aNotify);
nsAutoString type;
GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
NS_ConvertUTF16toUTF8 ctype(type);
nsAutoString uri;
if (GetAttr(kNameSpaceID_None, nsGkAtoms::data, uri)) {
LoadObject(uri, aNotify, ctype);
}
else {
// Be sure to call the nsIURI version if we have no attribute
// That handles the case where no URI is specified. An empty string would
// get interpreted as the page itself, instead of absence of URI.
LoadObject(nsnull, aNotify, ctype);
}
SetIsNetworkCreated(false);
}
@ -536,7 +545,7 @@ nsHTMLObjectElement::GetCapabilities() const
void
nsHTMLObjectElement::DestroyContent()
{
nsObjectLoadingContent::DestroyContent();
RemovedFromDocument();
nsGenericHTMLFormElement::DestroyContent();
}

View File

@ -298,22 +298,22 @@ void
nsHTMLSharedObjectElement::UnbindFromTree(bool aDeep,
bool aNullParent)
{
RemovedFromDocument();
nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
nsresult
nsHTMLSharedObjectElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
nsIAtom *aPrefix, const nsAString &aValue,
bool aNotify)
{
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
NS_ENSURE_SUCCESS(rv, rv);
// if aNotify is false, we are coming from the parser or some such place;
// we'll get bound after all the attributes have been set, so we'll do the
// If we plan to call LoadObject, we want to do it first so that the
// object load kicks off _before_ the reflow triggered by the SetAttr. But if
// aNotify is false, we are coming from the parser or some such place; we'll
// get bound after all the attributes have been set, so we'll do the
// object load from BindToTree/DoneAddingChildren.
// Skip the LoadObject call in that case.
// We also don't want to start loading the object when we're not yet in
@ -321,10 +321,13 @@ nsHTMLSharedObjectElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom *aName,
// attributes before inserting the node into the document.
if (aNotify && IsInDoc() && mIsDoneAddingChildren &&
aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()) {
return LoadObject(aNotify, true);
nsCAutoString type;
GetTypeAttrValue(type);
LoadObject(aValue, aNotify, type, true);
}
return NS_OK;
return nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
aNotify);
}
bool
@ -465,7 +468,19 @@ nsHTMLSharedObjectElement::GetAttributeMappingFunction() const
void
nsHTMLSharedObjectElement::StartObjectLoad(bool aNotify)
{
LoadObject(aNotify);
nsCAutoString type;
GetTypeAttrValue(type);
nsAutoString uri;
if (!GetAttr(kNameSpaceID_None, URIAttrName(), uri)) {
// Be sure to call the nsIURI version if we have no attribute
// That handles the case where no URI is specified. An empty string would
// get interpreted as the page itself, instead of absence of URI.
LoadObject(nsnull, aNotify, type);
}
else {
LoadObject(uri, aNotify, type);
}
SetIsNetworkCreated(false);
}
@ -478,7 +493,7 @@ nsHTMLSharedObjectElement::IntrinsicState() const
PRUint32
nsHTMLSharedObjectElement::GetCapabilities() const
{
PRUint32 capabilities = eSupportPlugins | eAllowPluginSkipChannel;
PRUint32 capabilities = eSupportPlugins | eOverrideServerType;
if (mNodeInfo->Equals(nsGkAtoms::embed)) {
capabilities |= eSupportSVG | eSupportImages;
}
@ -489,7 +504,7 @@ nsHTMLSharedObjectElement::GetCapabilities() const
void
nsHTMLSharedObjectElement::DestroyContent()
{
nsObjectLoadingContent::DestroyContent();
RemovedFromDocument();
nsGenericHTMLElement::DestroyContent();
}

View File

@ -120,7 +120,8 @@ PluginStreamListener::SetupPlugin()
return NS_ERROR_UNEXPECTED;
}
nsObjectLoadingContent* olcc = static_cast<nsObjectLoadingContent*>(olc.get());
nsresult rv = olcc->InstantiatePluginInstance();
nsresult rv = olcc->InstantiatePluginInstance(mPluginDoc->GetType().get(),
mDocument->nsIDocument::GetDocumentURI());
if (NS_FAILED(rv)) {
return rv;
}

View File

@ -601,7 +601,7 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
// if we have a mime type now.
if (!mPluginInstance && mContent && !aContentType.IsEmpty()) {
nsObjectLoadingContent *olc = static_cast<nsObjectLoadingContent*>(mContent.get());
rv = olc->InstantiatePluginInstance();
rv = olc->InstantiatePluginInstance(aContentType.get(), aURL.get());
if (NS_SUCCEEDED(rv)) {
rv = olc->GetPluginInstance(getter_AddRefs(mPluginInstance));
if (NS_FAILED(rv)) {

View File

@ -21,8 +21,8 @@
<audio src="sandbox_content.sjs?audio/ogg" autoplay="true"></audio>
<!-- plugins -->
<embed src="sandbox_content.sjs?application/x-test"/>
<object data="sandbox_content.sjs?application/x-test"></object>
<embed src="sandbox_content.sjs?test/embed"/>
<object data="sandbox_content.sjs?test/object"></object>
<applet code="sandbox_content.sjs?application/x-java-applet"></applet>
<iframe src="sandbox_content.sjs?text/html"></iframe>

View File

@ -119,7 +119,7 @@ function test_url_normalization() {
/**
* Check with the server's state to see what content was loaded then reset it.
*/
function check_loaded_content(aSandbox, aNothingShouldLoad, aCallback) {
function check_loaded_content(aNothingShouldLoad, aCallback) {
let xhr = new XMLHttpRequest();
xhr.open("GET", STATE_URL + "?get_loaded", true);
@ -129,32 +129,16 @@ function check_loaded_content(aSandbox, aNothingShouldLoad, aCallback) {
if (aNothingShouldLoad) {
is(xhr.responseText, "NOTHING", "Check that nothing was loaded on the server");
} else if (!OSX_10_5) {
let allowedTypes = [ "application/javascript", "text/html", "video/webm",
"audio/ogg", "application/x-test" ];
let loadedTypes = xhr.responseText == "NOTHING" ? [] : xhr.responseText.split(",");
for (let loadedType of loadedTypes) {
isnot(allowedTypes.indexOf(loadedType), -1, "Check that " + loadedType + " was expected to load");
}
// TODO: Media should be disabled after bug 759964.
is(loadedTypes.length, 4, "Check number of loaded content types: " + xhr.responseText)
todo_is(loadedTypes.length, 2, "Check number of loaded content types: " + xhr.responseText)
isnot(loadedTypes.indexOf("application/javascript"), -1, "Check JS was loaded");
isnot(loadedTypes.indexOf("text/html"), -1, "Check iframe was loaded");
todo_is(loadedTypes.indexOf("video/webm"), -1, "Check webm was not loaded");
todo_is(loadedTypes.indexOf("audio/ogg"), -1, "Check ogg was not loaded");
// Check that no plugin tags have a type other than TYPE_NULL (failed load)
// --
// Checking if a channel was opened is not sufficient for plugin tags --
// An object tag may still be allowed to load a sub-document, but not a
// plugin, so it will open a channel but then abort when it gets a
// plugin-type.
let doc = aSandbox._frame.contentDocument;
let nullType = Components.interfaces.nsIObjectLoadingContent.TYPE_NULL;
for (let tag of doc.querySelectorAll("embed, object, applet")) {
tag instanceof Components.interfaces.nsIObjectLoadingContent;
is(tag.displayedType, nullType, "Check that plugin did not load content");
}
}
reset_server_state();
@ -173,7 +157,7 @@ function check_disabled_content(aSandboxURL, aNothingShouldLoad = false) {
let originalId = aSandbox.id;
setTimeout(function() {
check_loaded_content(aSandbox, aNothingShouldLoad, function checkFinished() {
check_loaded_content(aNothingShouldLoad, function checkFinished() {
info("reload the sandbox content");
aSandbox.reload(function sandboxReloadCB(aSandbox) {
@ -181,7 +165,7 @@ function check_disabled_content(aSandboxURL, aNothingShouldLoad = false) {
is(aSandbox.id, originalId, "Sandbox ID should be the same after reload");
setTimeout(function() {
check_loaded_content(aSandbox, aNothingShouldLoad, function reloadCheckFinished() {
check_loaded_content(aNothingShouldLoad, function reloadCheckFinished() {
free_and_check_sandbox(aSandbox);
});
}, 5000);