- Make object frames have no children
  - Make the frame constructor construct a subdocumentframe, object frame or
    image frame as appropriate
- start the load of <applet>, <embed> and <object> in content code
- fallback to alternate rendering correctly

NOTE: This checkin will break the plugin finder. This will be fixed soon.

r+sr=bz


git-svn-id: svn://10.0.0.236/trunk@180762 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
cbiesinger%web.de 2005-09-21 19:14:30 +00:00
parent af56274377
commit 054912c09e
26 changed files with 2261 additions and 665 deletions

View File

@ -5801,7 +5801,8 @@ function getPluginInfo(pluginElement)
pluginsPage = "";
}
tagMimetype = pluginElement.QueryInterface(Components.interfaces.nsIPluginElement).actualType;
tagMimetype = pluginElement.QueryInterface(Components.interfaces.nsIObjectLoadingContent)
.actualType;
if (tagMimetype == "") {
tagMimetype = pluginElement.type;

View File

@ -93,6 +93,7 @@ XPIDLSRCS = \
nsIScriptEventHandler.idl \
nsIScriptEventManager.idl \
nsIImageLoadingContent.idl \
nsIObjectLoadingContent.idl \
nsIFrameLoader.idl \
$(NULL)

View File

@ -40,8 +40,9 @@
#include "nsISupports.idl"
interface nsIDocShell;
interface nsIURI;
[scriptable, uuid(88800e93-c6af-4d69-9ee0-29c1100ff431)]
[scriptable, uuid(d675c531-6bdc-417c-b176-635060105f07)]
interface nsIFrameLoader : nsISupports
{
/**
@ -55,6 +56,12 @@ interface nsIFrameLoader : nsISupports
*/
void loadFrame();
/**
* Loads the specified URI in this frame. Behaves identically to loadFrame,
* except that this method allows specifying the URI to load.
*/
void loadURI(in nsIURI aURI);
/**
* Destroy the frame loader and everything inside it. This will
* clear the weak owner content reference.

View File

@ -63,11 +63,9 @@ interface nsIURI;
* missed. We should NOT freeze this interface without considering
* this issue. (It could be that the image status on imgIRequest is
* sufficient, when combined with the imageBlockingStatus information.)
*
* XXXbz Do not freeze without removing imageURIChanged!
*/
[scriptable, uuid(da19c86d-08aa-421c-8c37-12ec2ba5a2c3)]
[scriptable, uuid(49b02654-5f96-48a0-bf99-0fe467a3fa52)]
interface nsIImageLoadingContent : imgIDecoderObserver
{
/**
@ -163,15 +161,4 @@ interface nsIImageLoadingContent : imgIDecoderObserver
* @throws NS_ERROR_NULL_POINTER if aChannel is null
*/
nsIStreamListener loadImageWithChannel(in nsIChannel aChannel);
/**
* ImageURIChanged is called when the appropriate attributes (eg
* 'src' for <img> tags) change. The string passed in is the new
* uri string.
*/
// XXXbz The only reason this is not a protected method is that
// XXXbz <object> and <embed> do everything from frames, not content.
// XXXbz Once those are moved to content, this method should become
// XXXbz a protected method on nsImageLoadingContent!
[noscript] void imageURIChanged(in AString aNewURI);
};

View File

@ -0,0 +1,84 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org object loading code.
*
* The Initial Developer of the Original Code is
* Christian Biesinger <cbiesinger@web.de>.
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIObjectFrame;
/**
* This interface represents a content node that loads objects.
*/
[scriptable, uuid(3e78c950-24d2-4fcc-b0b9-751686e89b8f)]
interface nsIObjectLoadingContent : nsISupports
{
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;
/**
* The actual mime type (the one we got back from the network
* request) for the element.
*/
readonly attribute ACString actualType;
/**
* Gets the type of the content that's currently loaded. See
* the constants above for the list of possible values.
*/
readonly attribute unsigned long displayedType;
/**
* For a classid, returns the MIME type that can be used to instantiate
* a plugin for this ID.
*
* @throw NS_ERROR_NOT_AVAILABLE Unsupported class ID.
*/
ACString typeForClassID(in AString aClassID);
/**
* Tells the content about an associated object frame.
* This can be called multiple times for different frames.
*
* This is noscript because this is an internal method that will go away, and
* because nsIObjectFrame is unscriptable.
*/
[noscript] void hasNewFrame(in nsIObjectFrame aFrame);
};

View File

@ -69,6 +69,7 @@ REQUIRES = xpcom \
intl \
webbrowserpersist \
imglib2 \
plugin \
prefetch \
xuldoc \
$(NULL)
@ -115,6 +116,7 @@ CPPSRCS = \
nsNameSpaceManager.cpp \
nsNodeInfo.cpp \
nsNodeInfoManager.cpp \
nsObjectLoadingContent.cpp \
nsParserUtils.cpp \
nsPlainTextSerializer.cpp \
nsPropertyTable.cpp \

View File

@ -91,14 +91,6 @@ nsFrameLoader::LoadFrame()
{
NS_ENSURE_TRUE(mOwnerContent, NS_ERROR_NOT_INITIALIZED);
nsresult rv = EnsureDocShell();
NS_ENSURE_SUCCESS(rv, rv);
nsIDocument* doc = mOwnerContent->GetDocument();
if (!doc) {
return NS_OK;
}
nsAutoString src;
GetURL(src);
@ -108,13 +100,35 @@ nsFrameLoader::LoadFrame()
src.AssignLiteral("about:blank");
}
nsIDocument* doc = mOwnerContent->GetOwnerDoc();
if (!doc) {
return NS_OK;
}
nsCOMPtr<nsIURI> base_uri = mOwnerContent->GetBaseURI();
const nsAFlatCString &doc_charset = doc->GetDocumentCharacterSet();
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), src,
doc_charset.IsEmpty() ? nsnull : doc_charset.get(),
base_uri);
nsresult rv = NS_NewURI(getter_AddRefs(uri), src,
doc_charset.IsEmpty() ? nsnull : doc_charset.get(),
base_uri);
NS_ENSURE_SUCCESS(rv, rv);
return LoadURI(uri);
}
NS_IMETHODIMP
nsFrameLoader::LoadURI(nsIURI* aURI)
{
NS_PRECONDITION(aURI, "Null URI?");
if (!aURI)
return NS_ERROR_INVALID_POINTER;
nsIDocument* doc = mOwnerContent->GetOwnerDoc();
if (!doc) {
return NS_OK;
}
nsresult rv = EnsureDocShell();
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
@ -137,7 +151,7 @@ nsFrameLoader::LoadFrame()
loadInfo->SetOwner(principal);
} else {
// We're not being called form script, tell the docshell
// We're not being called from script, tell the docshell
// to inherit an owner from the current document.
loadInfo->SetInheritOwner(PR_TRUE);
@ -149,7 +163,7 @@ nsFrameLoader::LoadFrame()
}
// Check if we are allowed to load absURL
rv = secMan->CheckLoadURIWithPrincipal(principal, uri,
rv = secMan->CheckLoadURIWithPrincipal(principal, aURI,
nsIScriptSecurityManager::STANDARD);
if (NS_FAILED(rv)) {
return rv; // We're not
@ -161,11 +175,11 @@ nsFrameLoader::LoadFrame()
loadInfo->SetReferrer(referrer);
// Bail out if this is an infinite recursion scenario
rv = CheckForRecursiveLoad(uri);
rv = CheckForRecursiveLoad(aURI);
NS_ENSURE_SUCCESS(rv, rv);
// Kick off the load...
rv = mDocShell->LoadURI(uri, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE,
rv = mDocShell->LoadURI(aURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE,
PR_FALSE);
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to load URL");

View File

@ -21,6 +21,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Christian Biesinger <cbiesinger@web.de>
*
*
* Alternatively, the contents of this file may be used under the terms of
@ -103,8 +104,9 @@ nsImageLoadingContent::nsImageLoadingContent()
mUserDisabled(PR_FALSE),
mSuppressed(PR_FALSE)
{
if (!nsContentUtils::GetImgLoader())
if (!nsContentUtils::GetImgLoader()) {
mLoadingEnabled = PR_FALSE;
}
}
nsImageLoadingContent::~nsImageLoadingContent()
@ -242,8 +244,9 @@ nsImageLoadingContent::GetLoadingEnabled(PRBool *aLoadingEnabled)
NS_IMETHODIMP
nsImageLoadingContent::SetLoadingEnabled(PRBool aLoadingEnabled)
{
if (nsContentUtils::GetImgLoader())
if (nsContentUtils::GetImgLoader()) {
mLoadingEnabled = aLoadingEnabled;
}
return NS_OK;
}
@ -361,8 +364,9 @@ nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
NS_IMETHODIMP
nsImageLoadingContent::GetCurrentURI(nsIURI** aURI)
{
if (mCurrentRequest)
if (mCurrentRequest) {
return mCurrentRequest->GetURI(aURI);
}
NS_IF_ADDREF(*aURI = mCurrentURI);
return NS_OK;
@ -376,11 +380,13 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
NS_ENSURE_ARG_POINTER(aChannel);
if (!nsContentUtils::GetImgLoader())
if (!nsContentUtils::GetImgLoader()) {
return NS_ERROR_NULL_POINTER;
}
// XXX what should we do with content policies here, if anything?
// Shouldn't that be done before the start of the load?
// XXX what about shouldProcess?
nsCOMPtr<nsIDocument> doc = GetOurDocument();
if (!doc) {
@ -405,12 +411,6 @@ nsImageLoadingContent::LoadImageWithChannel(nsIChannel* aChannel,
return rv;
}
// XXX This should be a protected method, not an interface method!!!
NS_IMETHODIMP
nsImageLoadingContent::ImageURIChanged(const nsAString& aNewURI) {
return ImageURIChanged(aNewURI, PR_TRUE, PR_FALSE);
}
/*
* Non-interface methods
*/
@ -426,17 +426,43 @@ nsImageLoadingContent::ImageURIChanged(const nsAString& aNewURI,
}
// First, get a document (needed for security checks and the like)
nsCOMPtr<nsIDocument> doc = GetOurDocument();
nsIDocument* doc = GetOurDocument();
if (!doc) {
// No reason to bother, I think...
return NS_OK;
}
nsresult rv; // XXXbz Should failures in this method fire onerror?
nsCOMPtr<nsIURI> imageURI;
rv = StringToURI(aNewURI, doc, getter_AddRefs(imageURI));
nsresult rv = StringToURI(aNewURI, doc, getter_AddRefs(imageURI));
NS_ENSURE_SUCCESS(rv, rv);
// XXXbiesi fire onerror if that failed?
return ImageURIChanged(imageURI, aForce, aNotify, doc);
}
nsresult
nsImageLoadingContent::ImageURIChanged(nsIURI* aNewURI,
PRBool aForce,
PRBool aNotify,
nsIDocument* aDocument)
{
if (!mLoadingEnabled) {
return NS_OK;
}
NS_ASSERTION(!aDocument || aDocument == GetOurDocument(),
"Bogus document passed in");
// First, get a document (needed for security checks and the like)
if (!aDocument) {
aDocument = GetOurDocument();
if (!aDocument) {
// No reason to bother, I think...
return NS_OK;
}
}
nsresult rv; // XXXbz Should failures in this method fire onerror?
// Skip the URI equality check if our current image was blocked. If
// that happened, we really do want to try loading again.
@ -445,7 +471,7 @@ nsImageLoadingContent::ImageURIChanged(const nsAString& aNewURI,
GetCurrentURI(getter_AddRefs(currentURI));
PRBool equal;
if (currentURI &&
NS_SUCCEEDED(currentURI->Equals(imageURI, &equal)) &&
NS_SUCCEEDED(currentURI->Equals(aNewURI, &equal)) &&
equal) {
// Nothing to do here.
return NS_OK;
@ -465,7 +491,7 @@ nsImageLoadingContent::ImageURIChanged(const nsAString& aNewURI,
// the error code from those.
PRInt16 newImageStatus;
PRBool loadImage = nsContentUtils::CanLoadImage(imageURI, this, doc,
PRBool loadImage = nsContentUtils::CanLoadImage(aNewURI, this, aDocument,
&newImageStatus);
NS_ASSERTION(loadImage || !NS_CP_ACCEPTED(newImageStatus),
"CanLoadImage lied");
@ -479,8 +505,9 @@ nsImageLoadingContent::ImageURIChanged(const nsAString& aNewURI,
// But this only matters if we are affecting the current request. Need to do
// this after CancelImageRequests, since that affects the value of
// mCurrentRequest.
if (!mCurrentRequest)
mCurrentURI = imageURI;
if (!mCurrentRequest) {
mCurrentURI = aNewURI;
}
if (!loadImage) {
// Don't actually load anything! This was blocked by CanLoadImage.
@ -490,7 +517,8 @@ nsImageLoadingContent::ImageURIChanged(const nsAString& aNewURI,
nsCOMPtr<imgIRequest> & req = mCurrentRequest ? mPendingRequest : mCurrentRequest;
rv = nsContentUtils::LoadImage(imageURI, doc, doc->GetDocumentURI(),
rv = nsContentUtils::LoadImage(aNewURI, aDocument,
aDocument->GetDocumentURI(),
this, nsIRequest::LOAD_NORMAL,
getter_AddRefs(req));
if (NS_FAILED(rv)) {
@ -662,12 +690,12 @@ nsImageLoadingContent::StringToURI(const nsAString& aSpec,
nsCOMPtr<nsIURI> baseURL = thisContent->GetBaseURI();
// (2) Get the charset
const nsACString &charset = aDocument->GetDocumentCharacterSet();
const nsAFlatCString &charset = aDocument->GetDocumentCharacterSet();
// (3) Construct the silly thing
return NS_NewURI(aURI,
aSpec,
charset.IsEmpty() ? nsnull : PromiseFlatCString(charset).get(),
charset.IsEmpty() ? nsnull : charset.get(),
baseURL,
nsContentUtils::GetIOService());
}

View File

@ -46,17 +46,16 @@
#include "nsCOMPtr.h"
#include "nsString.h"
/**
* This is an implementation of nsIImageLoadingContent. This class
* can be subclassed by various content nodes that want to provide
* image-loading functionality (eg <img>, <object>, etc).
*/
class nsIURI;
class nsIDocument;
class imgILoader;
class nsIIOService;
/**
* This is an implementation of nsIImageLoadingContent. This class
* can be subclassed by various content nodes that want to provide
* image-loading functionality (eg <img>, <object>, etc).
*/
class nsImageLoadingContent : public nsIImageLoadingContent
{
/* METHODS */
@ -76,10 +75,6 @@ protected:
* the charset, constructing URI objects, and any other incidentals
* into this superclass.
*
* Note that this is different from the ImageURIChanged(AString)
* declared in nsIImageLoadingContent.idl -- because it allows
* control over whether loading is to be forced.
*
* @param aNewURI the URI spec to be loaded (may be a relative URI)
* @param aForce If true, make sure to load the URI. If false, only
* load if the URI is different from the currently loaded URI.
@ -101,6 +96,31 @@ protected:
*/
PRInt32 ImageState() const;
/**
* ImageURIChanged is called by subclasses when the appropriate
* attributes (eg 'src' for <img> tags) change. If callers have an
* URI object already available, they should use this method.
*
* @param aNewURI the URI to be loaded
* @param aForce If true, make sure to load the URI. If false, only
* load if the URI is different from the currently loaded URI.
* @param aNotify If true, nsIDocumentObserver state change notifications
* will be sent as needed.
* @param aDocument Optional parameter giving the document this node is in.
* This is purely a performance optimization.
*/
nsresult ImageURIChanged(nsIURI* aNewURI, PRBool aForce, PRBool aNotify,
nsIDocument* aDocument = nsnull);
/**
* helper to get the document for this content (from the nodeinfo
* and such). Not named GetDocument to prevent ambiguous method
* names in subclasses
*
* @return the document we belong to
*/
nsIDocument* GetOurDocument();
/**
* CancelImageRequests is called by subclasses when they want to
* cancel all image requests (for example when the subclass is
@ -186,16 +206,6 @@ private:
void CancelImageRequests(nsresult aReason, PRBool aEvenIfSizeAvailable,
PRInt16 aNewImageStatus);
/**
* helper to get the document for this content (from the nodeinfo
* and such). Not named GetDocument to prevent ambiguous method
* names in subclasses (though why this private method leads to
* ambiguity is not clear to me....).
*
* @return the document we belong to
*/
nsIDocument* GetOurDocument();
/**
* Method to create an nsIURI object from the given string (will
* handle getting the right charset, base, etc). You MUST pass in a

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,299 @@
// vim:set et cin sw=2 sts=2:
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla <object> loading code.
*
* The Initial Developer of the Original Code is
* Christian Biesinger <cbiesinger@web.de>.
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef NSOBJECTLOADINGCONTENT_H_
#define NSOBJECTLOADINGCONTENT_H_
#include "nsImageLoadingContent.h"
#include "nsIStreamListener.h"
#include "nsIFrameLoader.h"
#include "nsIInterfaceRequestor.h"
#include "nsIChannelEventSink.h"
#include "nsIObjectLoadingContent.h"
#include "nsWeakReference.h"
struct nsAsyncInstantiateEvent;
class AutoNotifier;
class AutoFallback;
/**
* 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)
*/
class nsObjectLoadingContent : public nsImageLoadingContent
, public nsIStreamListener
, public nsIFrameLoaderOwner
, public nsIObjectLoadingContent
, public nsIInterfaceRequestor
, public nsIChannelEventSink
// Plugins code wants a weak reference to
// notification callbacks
, public nsSupportsWeakReference
{
friend class AutoNotifier;
friend class AutoFallback;
public:
// This enum's values must be the same as the constants on
// nsIObjectLoadingContent
enum ObjectType {
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
};
/**
* @param aInitialType The type this object starts as; should correspond
* to the frame that gets initially constructed for it.
*/
nsObjectLoadingContent(ObjectType aInitialType = eType_Loading);
virtual ~nsObjectLoadingContent();
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIFRAMELOADEROWNER
NS_DECL_NSIOBJECTLOADINGCONTENT
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICHANNELEVENTSINK
#ifdef HAVE_CPP_AMBIGUITY_RESOLVING_USING
// Fix a gcc compile warning
using nsImageLoadingContent::OnDataAvailable;
#endif
ObjectType Type() { return mType; }
/**
* 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.
*/
PRInt32 ObjectState() const;
protected:
/**
* 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.
* @param aForceType Whether to always use aTypeHint as the type, instead
* of letting the server override it.
* @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 ObjectURIChanged(const nsAString& aURI,
PRBool aNotify,
const nsCString& aTypeHint = EmptyCString(),
PRBool aForceType = PR_FALSE,
PRBool aForceLoad = PR_FALSE);
/**
* Loads the object from the given URI.
*
* 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 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..
*
* 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.
*
* @param aForceType Whether the passed-in type should override
* server-supplied MIME types. Will be ignored if
* aTypeHint is empty.
* @param aForceLoad If true, the object will be refetched even if the URI
* is the same as the currently-loaded object.
*/
nsresult ObjectURIChanged(nsIURI* aURI,
PRBool aNotify,
const nsCString& aTypeHint = EmptyCString(),
PRBool aForceType = PR_FALSE,
PRBool aForceLoad = PR_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
#ifdef MOZ_SVG
eSupportSVG = PR_BIT(3), // SVG is supported (image/svg+xml)
#endif
eSupportClassID = PR_BIT(4) // The classid attribute is supported
};
/**
* 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 no classids.
*/
virtual PRUint32 GetCapabilities() const;
/**
* Fall back to rendering the alternative content.
*/
void Fallback(PRBool aNotify);
/**
* Subclasses must call this function when they are removed from the
* document.
*
* XXX This is a temporary workaround for docshell suckyness
*/
void RemovedFromDocument();
private:
/**
* Check whether the given request represents a successful load.
*/
static PRBool IsSuccessfulRequest(nsIRequest* aRequest);
/**
* Check whether the URI can be handled internally.
*/
static PRBool CanHandleURI(nsIURI* aURI);
/**
* Checks whether the given type is a supported document type.
*/
PRBool IsSupportedDocument(const nsCString& aType);
/**
* 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 UnloadContent();
/**
* Notifies document observes about a new type/state of this object.
* Triggers frame construction as needed. mType must be set correctly when
* this method is called. This method is cheap if the type and state didn't
* actually change.
*/
void NotifyStateChanged(ObjectType aOldType, PRInt32 aOldState);
ObjectType GetTypeOfContent(const nsCString& aMIMEType);
/**
* Gets the frame that's associated with this content node in
* presentation 0.
*/
nsIObjectFrame* GetFrame();
/**
* Whether to treat this content as a plugin, even though we can't handle
* the type. This function impl should match the checks in the plugin host.
*/
static PRBool ShouldShowDefaultPlugin(nsIContent* aContent);
/**
* The final listener to ship the data to (imagelib, uriloader, etc)
*/
nsCOMPtr<nsIStreamListener> mFinalListener;
/**
* Frame loader, for content documents we load.
*/
nsCOMPtr<nsIFrameLoader> mFrameLoader;
/**
* The content type of the resource we were last asked to load.
*/
nsCString mContentType;
/**
* The channel that's currently being loaded. This is a weak reference.
* Non-null between asyncOpen and onStopRequest.
*/
nsIChannel* mChannel;
// The data we were last asked to load
nsCOMPtr<nsIURI> mURI;
/**
* Type of the currently-loaded content.
*/
ObjectType mType : 16;
/**
* Whether we are about to call instantiate on our frame. If we aren't,
* SetFrame needs to asynchronously call Instantiate.
*/
PRBool mInstantiating : 1;
// Blocking status from content policy
PRBool mUserDisabled : 1;
PRBool mSuppressed : 1;
friend struct nsAsyncInstantiateEvent;
};
#endif

View File

@ -48,7 +48,6 @@ XPIDL_MODULE = content_html
XPIDLSRCS = \
nsISelectElement.idl \
nsIPhonetic.idl \
nsIPluginElement.idl \
$(NULL)
EXPORTS = \

View File

@ -1,60 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Johnny Stenback <jst@mozilla.org> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
/**
* Interface which plugin elements (e.g. embed and object) implement
* (but don't automatically expose to JS) in addition to their dom
* specific interface.
*/
[scriptable, uuid(41be252d-c47b-40f3-94bc-bffe51762d68)]
interface nsIPluginElement : nsISupports
{
/**
* The actual mime type (the one we got back from the network
* request) for the plugin element.
*/
readonly attribute ACString actualType;
/**
* Non-scriptable setter for the actual mime type (the one we got
* back from the network request).
*/
[noscript] void setActualType(in ACString actualType);
};

View File

@ -42,9 +42,8 @@
#include "nsStyleConsts.h"
#include "nsPresContext.h"
#include "nsIDocument.h"
#include "nsLayoutAtoms.h"
#include "nsCSSPseudoClasses.h"
#include "nsIEventStateManager.h"
#include "nsObjectLoadingContent.h"
// XXX this is to get around conflicts with windows.h defines
// introduced through jni.h
@ -55,6 +54,7 @@
class nsHTMLAppletElement : public nsGenericHTMLElement,
public nsObjectLoadingContent,
public nsIDOMHTMLAppletElement
{
public:
@ -84,6 +84,15 @@ public:
NS_IMETHOD GetTabIndex(PRInt32* aTabIndex);
NS_IMETHOD SetTabIndex(PRInt32 aTabIndex);
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers);
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
PRBool aNullParent = PR_TRUE);
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify);
virtual PRBool ParseAttribute(nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult);
@ -91,7 +100,15 @@ public:
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual PRInt32 IntrinsicState() const;
// nsObjectLoadingContent
virtual PRUint32 GetCapabilities() const;
protected:
/**
* Calls ObjectURIChanged with the correct arguments to start the plugin
* load.
*/
NS_HIDDEN_(void) StartAppletLoad(PRBool aNotify);
PRPackedBool mReflectedApplet;
PRPackedBool mIsDoneAddingChildren;
};
@ -101,8 +118,8 @@ NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Applet)
nsHTMLAppletElement::nsHTMLAppletElement(nsINodeInfo *aNodeInfo, PRBool aFromParser)
: nsGenericHTMLElement(aNodeInfo), mReflectedApplet(PR_FALSE),
mIsDoneAddingChildren(!aFromParser)
: nsGenericHTMLElement(aNodeInfo), nsObjectLoadingContent(eType_Plugin),
mReflectedApplet(PR_FALSE), mIsDoneAddingChildren(!aFromParser)
{
}
@ -116,11 +133,22 @@ nsHTMLAppletElement::IsDoneAddingChildren()
return mIsDoneAddingChildren;
}
PRUint32
nsHTMLAppletElement::GetCapabilities() const
{
return eSupportPlugins;
}
void
nsHTMLAppletElement::DoneAddingChildren()
{
mIsDoneAddingChildren = PR_TRUE;
RecreateFrames();
// If we're already in the document, start the load, because BindToTree
// didn't.
if (IsInDoc()) {
StartAppletLoad(MayHaveFrame());
}
}
NS_IMPL_ADDREF_INHERITED(nsHTMLAppletElement, nsGenericElement)
@ -130,6 +158,15 @@ NS_IMPL_RELEASE_INHERITED(nsHTMLAppletElement, nsGenericElement)
// QueryInterface implementation for nsHTMLAppletElement
NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLAppletElement, nsGenericHTMLElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLAppletElement)
NS_INTERFACE_MAP_ENTRY(imgIDecoderObserver)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIFrameLoaderOwner)
NS_INTERFACE_MAP_ENTRY(nsIObjectLoadingContent)
NS_INTERFACE_MAP_ENTRY(nsIImageLoadingContent)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLAppletElement)
NS_HTML_CONTENT_INTERFACE_MAP_END
@ -196,15 +233,71 @@ nsHTMLAppletElement::GetAttributeMappingFunction() const
return &MapAttributesIntoRule;
}
nsresult
nsHTMLAppletElement::BindToTree(nsIDocument* aDocument,
nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
if (NS_FAILED(rv)) {
return rv;
}
// Must start loading stuff after being in the document, but only when we
// already have all our children.
if (mIsDoneAddingChildren) {
// Don't need to notify: We have no frames yet, since we weren't in a
// document
StartAppletLoad(PR_FALSE);
}
return rv;
}
void
nsHTMLAppletElement::UnbindFromTree(PRBool aDeep,
PRBool aNullParent)
{
RemovedFromDocument();
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
nsresult
nsHTMLAppletElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify)
{
// If we plan to call ObjectURIChanged, 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 ObjectURIChanged call in that case.
if (aNotify &&
aNameSpaceID == kNameSpaceID_None && aName == nsHTMLAtoms::code) {
ObjectURIChanged(aValue, aNotify,
NS_LITERAL_CSTRING("application/x-java-vm"),
PR_TRUE, PR_TRUE);
}
return nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
}
void
nsHTMLAppletElement::StartAppletLoad(PRBool aNotify)
{
nsAutoString uri;
GetAttr(kNameSpaceID_None, nsHTMLAtoms::code, uri);
ObjectURIChanged(uri, aNotify, NS_LITERAL_CSTRING("application/x-java-vm"), PR_TRUE);
}
PRInt32
nsHTMLAppletElement::IntrinsicState() const
{
PRInt32 state = nsGenericHTMLElement::IntrinsicState();
void* broken = GetProperty(nsCSSPseudoClasses::mozBroken);
if (NS_PTR_TO_INT32(broken)) {
state |= NS_EVENT_STATE_BROKEN;
}
return state;
return nsGenericHTMLElement::IntrinsicState() | ObjectState();
}

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
// vim:set et sw=2 sts=2 cin:
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -36,7 +37,7 @@
* ***** END LICENSE BLOCK ***** */
#include "nsIDOMHTMLObjectElement.h"
#include "nsGenericHTMLElement.h"
#include "nsImageLoadingContent.h"
#include "nsObjectLoadingContent.h"
#include "nsHTMLAtoms.h"
#include "nsStyleConsts.h"
#include "nsDOMError.h"
@ -49,14 +50,9 @@
#include "nsIObjectFrame.h"
#include "nsIPluginInstance.h"
#include "nsIPluginInstanceInternal.h"
#include "nsIPluginElement.h"
#include "nsIEventStateManager.h"
#include "nsCSSPseudoClasses.h"
#include "nsLayoutAtoms.h"
class nsHTMLObjectElement : public nsGenericHTMLFormElement,
public nsImageLoadingContent,
public nsIPluginElement,
public nsObjectLoadingContent,
public nsIDOMHTMLObjectElement
{
public:
@ -66,9 +62,6 @@ public:
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIPluginElement
NS_DECL_NSIPLUGINELEMENT
// nsIDOMNode
NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsGenericHTMLFormElement::)
@ -84,6 +77,16 @@ public:
// nsIContent
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers);
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
PRBool aNullParent = PR_TRUE);
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify);
// Overriden nsIFormControl methods
NS_IMETHOD_(PRInt32) GetType() const { return NS_FORM_OBJECT; }
NS_IMETHOD Reset();
@ -102,9 +105,17 @@ public:
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual PRInt32 IntrinsicState() const;
// nsObjectLoadingContent
virtual PRUint32 GetCapabilities() const;
protected:
/**
* Calls ObjectURIChanged with the correct arguments to start the plugin
* load.
*/
NS_HIDDEN_(void) StartObjectLoad(PRBool aNotify);
PRPackedBool mIsDoneAddingChildren;
nsCString mActualType;
};
@ -131,7 +142,12 @@ void
nsHTMLObjectElement::DoneAddingChildren()
{
mIsDoneAddingChildren = PR_TRUE;
RecreateFrames();
// If we're already in a document, we need to trigger the load
// Otherwise, BindToTree takes care of that.
if (IsInDoc()) {
StartObjectLoad(MayHaveFrame());
}
}
NS_IMPL_ADDREF_INHERITED(nsHTMLObjectElement, nsGenericElement)
@ -142,28 +158,18 @@ NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLObjectElement,
nsGenericHTMLFormElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLObjectElement)
NS_INTERFACE_MAP_ENTRY(imgIDecoderObserver)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIFrameLoaderOwner)
NS_INTERFACE_MAP_ENTRY(nsIObjectLoadingContent)
NS_INTERFACE_MAP_ENTRY(nsIImageLoadingContent)
NS_INTERFACE_MAP_ENTRY(nsIPluginElement)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLObjectElement)
NS_HTML_CONTENT_INTERFACE_MAP_END
NS_IMETHODIMP
nsHTMLObjectElement::SetActualType(const nsACString& aActualType)
{
mActualType = aActualType;
return NS_OK;
}
NS_IMETHODIMP
nsHTMLObjectElement::GetActualType(nsACString& aActualType)
{
aActualType = mActualType;
return NS_OK;
}
// nsIDOMHTMLObjectElement
@ -188,6 +194,63 @@ nsHTMLObjectElement::IsFocusable(PRInt32 *aTabIndex)
return PR_TRUE;
}
nsresult
nsHTMLObjectElement::BindToTree(nsIDocument* aDocument,
nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
if (NS_FAILED(rv)) {
return rv;
}
// If we already have all the children, start the load.
if (mIsDoneAddingChildren) {
// Don't need to notify: We have no frames yet, since we weren't in a
// document
StartObjectLoad(PR_FALSE);
}
return NS_OK;
}
void
nsHTMLObjectElement::UnbindFromTree(PRBool aDeep,
PRBool aNullParent)
{
RemovedFromDocument();
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
}
nsresult
nsHTMLObjectElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify)
{
// If we plan to call ObjectURIChanged, 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 ObjectURIChanged call in that case.
if (aNotify &&
aNameSpaceID == kNameSpaceID_None && aName == nsHTMLAtoms::data) {
nsAutoString type;
GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, type);
ObjectURIChanged(aValue, aNotify, NS_ConvertUTF16toUTF8(type), PR_FALSE, PR_TRUE);
}
return nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
}
// nsIFormControl
NS_IMETHODIMP
@ -340,20 +403,35 @@ nsHTMLObjectElement::GetAttributeMappingFunction() const
return &MapAttributesIntoRule;
}
void
nsHTMLObjectElement::StartObjectLoad(PRBool aNotify)
{
nsAutoString uri;
nsresult rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::data, uri);
nsAutoString type;
GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, type);
NS_ConvertUTF16toUTF8 ctype(type);
// 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.
if (rv == NS_CONTENT_ATTR_NOT_THERE) {
ObjectURIChanged(nsnull, aNotify, ctype);
} else {
ObjectURIChanged(uri, aNotify, ctype);
}
}
PRInt32
nsHTMLObjectElement::IntrinsicState() const
{
PRInt32 state = nsGenericHTMLFormElement::IntrinsicState();
void* image = GetProperty(nsLayoutAtoms::imageFrame);
if (NS_PTR_TO_INT32(image)) {
state |= nsImageLoadingContent::ImageState();
}
void* broken = GetProperty(nsCSSPseudoClasses::mozBroken);
if (NS_PTR_TO_INT32(broken)) {
state |= NS_EVENT_STATE_BROKEN;
}
return state;
return nsGenericHTMLFormElement::IntrinsicState() | ObjectState();
}
PRUint32
nsHTMLObjectElement::GetCapabilities() const
{
return nsObjectLoadingContent::GetCapabilities() | eSupportClassID;
}

View File

@ -44,17 +44,13 @@
#include "nsIDOMHTMLBaseFontElement.h"
#include "nsIDOMEventReceiver.h"
#include "nsGenericHTMLElement.h"
#include "nsImageLoadingContent.h"
#include "nsObjectLoadingContent.h"
#include "nsHTMLAtoms.h"
#include "nsStyleConsts.h"
#include "nsPresContext.h"
#include "nsRuleData.h"
#include "nsMappedAttributes.h"
#include "nsStyleContext.h"
#include "nsIPluginElement.h"
#include "nsCSSPseudoClasses.h"
#include "nsIEventStateManager.h"
#include "nsLayoutAtoms.h"
#ifdef MOZ_SVG
#include "nsIDOMGetSVGDocument.h"
@ -66,8 +62,7 @@
extern nsAttrValue::EnumTable kListTypeTable[];
class nsHTMLSharedElement : public nsGenericHTMLElement,
public nsImageLoadingContent,
public nsIPluginElement,
public nsObjectLoadingContent,
public nsIDOMHTMLEmbedElement,
#ifdef MOZ_SVG
public nsIDOMGetSVGDocument,
@ -87,9 +82,6 @@ public:
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIPluginElement
NS_DECL_NSIPLUGINELEMENT
// nsIDOMNode
NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsGenericHTMLElement::)
@ -146,8 +138,17 @@ public:
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual PRInt32 IntrinsicState() const;
protected:
nsCString mActualType;
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers);
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
PRBool aNullParent = PR_TRUE);
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify);
// nsObjectLoadingContent
virtual PRUint32 GetCapabilities() const;
};
@ -155,7 +156,9 @@ NS_IMPL_NS_NEW_HTML_ELEMENT(Shared)
nsHTMLSharedElement::nsHTMLSharedElement(nsINodeInfo *aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
: nsGenericHTMLElement(aNodeInfo),
nsObjectLoadingContent(aNodeInfo->Equals(nsHTMLAtoms::embed) ? eType_Plugin
: eType_Null)
{
}
@ -177,8 +180,14 @@ NS_HTML_CONTENT_INTERFACE_MAP_AMBIGOUS_BEGIN(nsHTMLSharedElement,
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMGetSVGDocument, embed)
#endif
NS_INTERFACE_MAP_ENTRY_IF_TAG(imgIDecoderObserver, embed)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIStreamListener, embed)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIRequestObserver, embed)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIFrameLoaderOwner, embed)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIObjectLoadingContent, embed)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIImageLoadingContent, embed)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIPluginElement, embed)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIInterfaceRequestor, embed)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIChannelEventSink, embed)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsISupportsWeakReference, embed)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLParamElement, param)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLIsIndexElement, isindex)
NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLBaseElement, base)
@ -214,22 +223,6 @@ NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Name, name)
NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Type, type)
NS_IMPL_STRING_ATTR(nsHTMLSharedElement, Src, src)
NS_IMETHODIMP
nsHTMLSharedElement::SetActualType(const nsACString& aActualType)
{
mActualType = aActualType;
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSharedElement::GetActualType(nsACString& aActualType)
{
aActualType = mActualType;
return NS_OK;
}
#ifdef MOZ_SVG
// nsIDOMGetSVGDocument
NS_IMETHODIMP
@ -239,12 +232,14 @@ nsHTMLSharedElement::GetSVGDocument(nsIDOMSVGDocument** aResult)
*aResult = nsnull;
if (!mNodeInfo->Equals(nsHTMLAtoms::embed) || !IsInDoc())
if (!mNodeInfo->Equals(nsHTMLAtoms::embed) || !IsInDoc()) {
return NS_OK;
}
nsIDocument *sub_doc = GetOwnerDoc()->GetSubDocumentFor(this);
if (sub_doc)
if (sub_doc) {
CallQueryInterface(sub_doc, aResult);
}
return NS_OK;
}
@ -434,10 +429,11 @@ DirectoryMenuMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
// type: enum
const nsAttrValue* value = aAttributes->GetAttr(nsHTMLAtoms::type);
if (value) {
if (value->Type() == nsAttrValue::eEnum)
if (value->Type() == nsAttrValue::eEnum) {
aData->mListData->mType.SetIntValue(value->GetEnumValue(), eCSSUnit_Enumerated);
else
} else {
aData->mListData->mType.SetIntValue(NS_STYLE_LIST_STYLE_DISC, eCSSUnit_Enumerated);
}
}
}
}
@ -513,19 +509,85 @@ nsHTMLSharedElement::GetAttributeMappingFunction() const
return nsGenericHTMLElement::GetAttributeMappingFunction();
}
nsresult
nsHTMLSharedElement::BindToTree(nsIDocument* aDocument,
nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
// Must start loading stuff after being in a document
if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
nsAutoString uri;
nsresult rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, uri);
if (rv != NS_CONTENT_ATTR_NOT_THERE) {
nsAutoString type;
GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, type);
// Don't notify: We aren't in a document yet, so we have no frames
ObjectURIChanged(uri, PR_FALSE, NS_ConvertUTF16toUTF8(type), PR_TRUE);
} else {
// The constructor set the type to eType_Plugin; but if we have no src
// attribute, then we aren't really a plugin
Fallback(PR_FALSE);
}
}
return rv;
}
void
nsHTMLSharedElement::UnbindFromTree(PRBool aDeep,
PRBool aNullParent)
{
if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
RemovedFromDocument();
}
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
nsresult
nsHTMLSharedElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify)
{
if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
// If we plan to call ObjectURIChanged, we want to do it first so that the
// image 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. Skip the ObjectURIChanged call in that case.
if (aNotify &&
aNameSpaceID == kNameSpaceID_None && aName == nsHTMLAtoms::src) {
nsAutoString type;
GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, type);
ObjectURIChanged(aValue, aNotify, NS_ConvertUTF16toUTF8(type), PR_TRUE, PR_TRUE);
}
}
return nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
aValue, aNotify);
}
PRUint32
nsHTMLSharedElement::GetCapabilities() const
{
return eSupportImages | eSupportPlugins
#ifdef MOZ_SVG
| eSupportSVG
#endif
;
}
PRInt32
nsHTMLSharedElement::IntrinsicState() const
{
PRInt32 state = nsGenericHTMLElement::IntrinsicState();
if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
void* image = GetProperty(nsLayoutAtoms::imageFrame);
if (NS_PTR_TO_INT32(image)) {
state |= nsImageLoadingContent::ImageState();
}
void* broken = GetProperty(nsCSSPseudoClasses::mozBroken);
if (NS_PTR_TO_INT32(broken)) {
state |= NS_EVENT_STATE_BROKEN;
}
state |= ObjectState();
}
return state;
}

View File

@ -65,6 +65,9 @@ public:
virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject);
virtual PRBool CanSavePresentation(nsIRequest *aNewRequest);
const nsCString& GetType() const { return mMimeType; }
nsIContent* GetPluginContent() { return mPluginContent; }
protected:
nsresult CreateSyntheticPluginDocument();
@ -73,6 +76,49 @@ protected:
nsCString mMimeType;
};
class nsPluginStreamListener : public nsMediaDocumentStreamListener
{
public:
nsPluginStreamListener(nsPluginDocument* doc) :
nsMediaDocumentStreamListener(doc), mPluginDoc(doc) {}
NS_IMETHOD OnStartRequest(nsIRequest* request, nsISupports *ctxt);
private:
nsRefPtr<nsPluginDocument> mPluginDoc;
};
NS_IMETHODIMP
nsPluginStreamListener::OnStartRequest(nsIRequest* request, nsISupports *ctxt)
{
nsresult rv = nsMediaDocumentStreamListener::OnStartRequest(request, ctxt);
if (NS_FAILED(rv)) {
return rv;
}
nsIContent* embed = mPluginDoc->GetPluginContent();
// Now we have a frame for our <embed>, start the load
nsIFrame* frame = mDocument->GetShellAt(0)->GetPrimaryFrameFor(embed);
if (!frame) {
return rv;
}
nsIObjectFrame* objFrame;
CallQueryInterface(frame, &objFrame);
if (!objFrame) {
return NS_ERROR_UNEXPECTED;
}
rv = objFrame->Instantiate(mPluginDoc->GetType().get(),
mDocument->nsIDocument::GetDocumentURI());
if (NS_FAILED(rv)) {
return rv;
}
NS_ASSERTION(mNextStream, "We should have a listener by now");
return mNextStream->OnStartRequest(request, ctxt);
}
// NOTE! nsDocument::operator new() zeroes out all members, so don't
// bother initializing members to 0.
@ -141,9 +187,10 @@ nsPluginDocument::StartDocumentLoad(const char* aCommand,
return rv;
}
mStreamListener = new nsMediaDocumentStreamListener(this);
if (!mStreamListener)
mStreamListener = new nsPluginStreamListener(this);
if (!mStreamListener) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ASSERTION(aDocListener, "null aDocListener");
NS_ADDREF(*aDocListener = mStreamListener);
@ -159,8 +206,9 @@ nsPluginDocument::CreateSyntheticPluginDocument()
if (dsti) {
PRBool isMsgPane = PR_FALSE;
dsti->NameEquals(NS_LITERAL_STRING("messagepane").get(), &isMsgPane);
if (isMsgPane)
if (isMsgPane) {
return NS_ERROR_FAILURE;
}
}
// make our generic document
@ -212,6 +260,8 @@ nsPluginDocument::CreateSyntheticPluginDocument()
mPluginContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::type,
NS_ConvertUTF8toUTF16(mMimeType), PR_FALSE);
// This will not start the load because nsObjectLoadingContent checks whether
// its document is an nsIPluginDocument
body->AppendChildTo(mPluginContent, PR_FALSE);
return NS_OK;
@ -222,8 +272,9 @@ nsPluginDocument::CreateSyntheticPluginDocument()
NS_IMETHODIMP
nsPluginDocument::SetStreamListener(nsIStreamListener *aListener)
{
if (mStreamListener)
if (mStreamListener) {
mStreamListener->SetStreamListener(aListener);
}
nsMediaDocument::UpdateTitleAndCharset(mMimeType);

View File

@ -156,6 +156,7 @@ LOCAL_INCLUDES += \
-I$(srcdir)/../tables \
-I$(srcdir)/../printing \
-I$(srcdir)/../xul/base/src \
-I$(srcdir)/../../content/base/src \
-I$(srcdir)/../../content/events/src \
-I$(srcdir)/../../content/xbl/src \
-I$(srcdir)/../../view/src \

View File

@ -114,6 +114,7 @@
#include "nsBoxFrame.h"
#include "nsIBoxLayout.h"
#include "nsImageFrame.h"
#include "nsIObjectLoadingContent.h"
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
@ -5441,7 +5442,29 @@ nsCSSFrameConstructor::ConstructHTMLFrame(nsFrameConstructorState& aState,
ProcessPseudoFrames(aState, aFrameItems);
}
isReplaced = PR_TRUE;
rv = NS_NewObjectFrame(mPresShell, &newFrame);
nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(aContent));
NS_ASSERTION(objContent,
"applet, embed and object must implement nsIObjectLoadingContent!");
if (!objContent) {
// XBL might trigger this...
return NS_ERROR_UNEXPECTED;
}
PRUint32 type;
objContent->GetDisplayedType(&type);
if (type == nsIObjectLoadingContent::TYPE_LOADING) {
// Ideally, this should show the standby attribute
rv = NS_NewEmptyFrame(mPresShell, &newFrame);
}
else if (type == nsIObjectLoadingContent::TYPE_PLUGIN)
rv = NS_NewObjectFrame(mPresShell, &newFrame);
else if (type == nsIObjectLoadingContent::TYPE_IMAGE)
rv = NS_NewImageFrame(mPresShell, &newFrame);
else if (type == nsIObjectLoadingContent::TYPE_DOCUMENT)
rv = NS_NewSubDocumentFrame(mPresShell, &newFrame);
// Otherwise, it's null - doing nothing here will fallback appropriately
// (i.e., render the children)
}
}
else if (nsHTMLAtoms::fieldset == aTag) {

View File

@ -50,6 +50,23 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IOBJECTFRAME_IID)
NS_IMETHOD GetPluginInstance(nsIPluginInstance*& aPluginInstance) = 0;
/**
* Instantiate a plugin for a channel, returning a stream listener for the
* data.
*/
virtual nsresult Instantiate(nsIChannel* aChannel, nsIStreamListener** aStreamListener) = 0;
/**
* Instantiate a plugin that loads the data itself.
* @param aMimeType Type of the plugin to instantiate. May be null.
* This argument is ignored if a classid is present on the
* plugin.
* @param aURI URI of the plugin data. May be null.
* @note XXX this method is here only temporarily, until plugins are loaded
* from content.
*/
virtual nsresult Instantiate(const char* aMimeType, nsIURI* aURI) = 0;
};

View File

@ -26,6 +26,7 @@
* Leon Sha <leon.sha@sun.com>
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Robert O'Callahan <roc+moz@cs.cmu.edu>
* Christian Biesinger <cbiesinger@web.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -61,7 +62,6 @@
#include "nsIDocument.h"
#include "nsIHTMLDocument.h"
#include "nsINodeInfo.h"
#include "nsIPluginElement.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
#include "nsIPluginInstanceOwner.h"
@ -115,6 +115,7 @@
#include "nsUnicharUtils.h"
#include "nsTransform2D.h"
#include "nsIImageLoadingContent.h"
#include "nsIObjectLoadingContent.h"
#include "nsPIDOMWindow.h"
#include "nsContentUtils.h"
#include "nsIStringBundle.h"
@ -632,80 +633,9 @@ nsObjectFrame::Init(nsPresContext* aPresContext,
nsresult rv = nsObjectFrameSuper::Init(aPresContext, aContent, aParent,
aContext, aPrevInFlow);
if (NS_FAILED(rv))
return rv;
// Find our content type
nsCAutoString type;
rv = GetMIMEType(type);
// If that fails, just return and render nothing.
if (NS_FAILED(rv))
return NS_OK;
// Ideally this should move to Reflow when the stream starts to come
if (IsSupportedImage(type)) {
// kick off the image load in the content node
// XXX once this moves to somewhere where we have the data stream,
// we should have a way to load images with a channel....
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(aContent);
if (!imageLoader) {
NS_ERROR("Not an image loading content?");
return NS_ERROR_UNEXPECTED;
}
nsAutoString data;
// If this is an OBJECT tag, we should look for a DATA attribute.
// If not, it's an EMBED tag, and so we should look for a SRC attribute.
if (aContent->Tag() == nsHTMLAtoms::object)
rv = aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::data, data);
else
rv = aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, data);
imageLoader->ImageURIChanged(data);
// Let the content know that it's actually loading an image.
// XXXbz this is a bit of a hack, pending moving object data
// loading to content.
aContent->SetProperty(nsLayoutAtoms::imageFrame, NS_INT32_TO_PTR(1));
nsIFrame * aNewFrame = nsnull;
rv = NS_NewImageFrame(aPresContext->PresShell(), &aNewFrame);
if (NS_FAILED(rv))
return rv;
// XXX we're using the same style context for ourselves and the
// image frame. If this ever changes, please fix HandleChild() to deal.
rv = aNewFrame->Init(aPresContext, aContent, this, aContext, aPrevInFlow);
if (NS_SUCCEEDED(rv)) {
nsHTMLContainerFrame::CreateViewForFrame(aNewFrame, nsnull, PR_FALSE);
mFrames.AppendFrame(this, aNewFrame);
}
else
aNewFrame->Destroy(aPresContext);
return rv; // bail at this point
}
// for now, we should try to do the same for "document" types and
// create an iframe-like sub-frame
if (IsSupportedDocument(aContent, type)) {
nsIFrame * aNewFrame = nsnull;
rv = NS_NewSubDocumentFrame(aPresContext->PresShell(), &aNewFrame);
if (NS_FAILED(rv))
return rv;
// XXX we're using the same style context for ourselves and the
// iframe. If this ever changes, please fix HandleChild() to deal.
rv = aNewFrame->Init(aPresContext, aContent, this, aContext, aPrevInFlow);
if (NS_SUCCEEDED(rv)) {
nsHTMLContainerFrame::CreateViewForFrame(aNewFrame, nsnull, PR_FALSE);
mFrames.AppendFrame(this, aNewFrame);
} else {
aNewFrame->Destroy(aPresContext);
}
}
nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(mContent));
NS_ASSERTION(objContent, "Why not an object loading content?");
objContent->HasNewFrame(this);
return rv;
}
@ -829,7 +759,7 @@ nsObjectFrame::CreateWidget(nscoord aWidth,
}
nsIViewManager* viewMan = view->GetViewManager();
// make the view as hidden since we don't know the (x,y) until Paint
// mark the view as hidden since we don't know the (x,y) until Paint
// XXX is the above comment correct?
viewMan->SetViewVisibility(view, nsViewVisibility_kHide);
@ -1001,12 +931,14 @@ SizeAnchor(nsIContent *aAnchor, PRInt32 aWidth, PRInt32 aHeight)
nsAutoString tmp;
tmp.AppendInt(aWidth);
AppendASCIItoUTF16("px", tmp);
tmp.AppendLiteral("px");
css2props->SetWidth(tmp);
tmp.Truncate();
tmp.AppendInt(aHeight);
AppendASCIItoUTF16("px", tmp);
tmp.AppendLiteral("px");
css2props->SetHeight(tmp);
}
@ -1084,195 +1016,8 @@ nsObjectFrame::Reflow(nsPresContext* aPresContext,
return rv;
}
// if mInstance is null, we need to determine what kind of object we are and instantiate ourselves
if (!mInstanceOwner) {
// XXX - do we need to create this for widgets as well?
mInstanceOwner = new nsPluginInstanceOwner();
if (!mInstanceOwner)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mInstanceOwner);
mInstanceOwner->Init(aPresContext, this);
// get the nsIPluginHost service
nsCOMPtr<nsIPluginHost> pluginHost(do_GetService(kCPluginManagerCID));
nsCOMPtr<nsISupports> container;
nsCOMPtr<nsIURI> fullURL;
nsAutoString classid;
nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
nsAutoString codeBase;
if ((NS_CONTENT_ATTR_HAS_VALUE ==
mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::codebase, codeBase)) &&
!codeBase.IsEmpty()) {
nsCOMPtr<nsIURI> codeBaseURL;
rv = MakeAbsoluteURL(getter_AddRefs(codeBaseURL), codeBase, baseURI);
if (NS_SUCCEEDED(rv)) {
baseURI = codeBaseURL;
}
}
// if we have a clsid, we're either an internal widget, an ActiveX control, or an applet
if (mContent->Tag() == nsHTMLAtoms::object &&
NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::classid, classid)) {
PRBool bJavaObject;
bJavaObject = StringBeginsWith(classid, NS_LITERAL_STRING("java:"));
// if we find "java:" in the class id, we have a java applet
if (bJavaObject) {
if (!baseURI) {
rv = NS_ERROR_FAILURE;
}
else {
fullURL = baseURI;
if (pluginHost) {
mInstanceOwner->SetPluginHost(pluginHost);
rv = InstantiatePlugin(aPresContext, aMetrics, aReflowState,
pluginHost, "application/x-java-vm",
fullURL);
}
}
}
else { // otherwise, we're either an ActiveX control or an internal widget
// These are some builtin types that we know about for now.
// (Eventually this will move somewhere else.)
if (classid.EqualsLiteral("browser")) {
rv = InstantiateWidget(aPresContext, aMetrics,
aReflowState, kCAppShellCID);
}
else {
// if we haven't matched to an internal type, check to see if
// we have an ActiveX handler
// if not, create the default plugin
if (!baseURI) {
rv = NS_ERROR_FAILURE;
}
else {
fullURL = baseURI;
if (pluginHost) {
mInstanceOwner->SetPluginHost(pluginHost);
if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForType("application/x-oleobject"))) {
rv = InstantiatePlugin(aPresContext, aMetrics, aReflowState,
pluginHost, "application/x-oleobject",
fullURL);
} else if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForType("application/oleobject"))) {
rv = InstantiatePlugin(aPresContext, aMetrics, aReflowState,
pluginHost, "application/oleobject",
fullURL);
} else {
rv = NS_ERROR_FAILURE;
}
}
}
}
}
// finish up
if (NS_SUCCEEDED(rv)) {
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
}
else { // no clsid - the object is either an applet or a plugin
nsAutoString src;
if (!baseURI) {
rv = NS_ERROR_FAILURE;
}
else {
if (pluginHost) {
mInstanceOwner->SetPluginHost(pluginHost);
nsIAtom *tag = mContent->Tag();
if (tag == nsHTMLAtoms::applet) {
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::code, src)) {
// Create an absolute URL
rv = MakeAbsoluteURL(getter_AddRefs(fullURL), src, baseURI);
}
else
fullURL = baseURI;
rv = InstantiatePlugin(aPresContext, aMetrics, aReflowState,
pluginHost, "application/x-java-vm", fullURL);
} else { // traditional plugin
nsXPIDLCString mimeTypeStr;
nsAutoString type;
mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, type);
if (type.Length()) {
mimeTypeStr.Adopt(ToNewCString(type));
}
// Stream in the object source if there is one...
// If this is an OBJECT tag, we should look for a DATA attribute.
// If not, it's an EMBED tag, and so we should look for a SRC attribute.
if (tag == nsHTMLAtoms::object)
rv = mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::data, src);
else
rv = mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, src);
if (NS_CONTENT_ATTR_HAS_VALUE == rv) {
// Create an absolute URL
rv = MakeAbsoluteURL(getter_AddRefs(fullURL), src, baseURI);
if (NS_FAILED(rv)) {
// Failed to create URI, maybe because we didn't
// reconize the protocol handler ==> treat like
// no 'src'/'data' was specified in the embed/object tag
fullURL = baseURI;
}
}
else {
// we didn't find a src or data param, so just set the url
// to the base
fullURL = baseURI;
}
// now try to instantiate a plugin instance based on a mime type
const char* mimeType = mimeTypeStr.get();
if (mimeType || !src.IsEmpty()) {
if (!mimeType) {
// we don't have a mime type, try to figure it out
// from extension
PRInt32 offset = src.RFindChar(PRUnichar('.'));
if (offset != kNotFound)
pluginHost->IsPluginEnabledForExtension(NS_ConvertUTF16toUTF8(Substring(src, offset + 1, src.Length())).get(), mimeType);
}
// if we fail to get a mime type from extension we can
// still try to instantiate plugin as it can be possible
// to determine it later
rv = InstantiatePlugin(aPresContext, aMetrics, aReflowState,
pluginHost, mimeType, fullURL);
}
else // if we have neither we should not bother
rv = NS_ERROR_FAILURE;
}
}
}
}
}
else { // if (!mInstanceOwner)
rv = ReinstantiatePlugin(aPresContext, aMetrics, aReflowState);
}
// finish up
if (NS_FAILED(rv)) {
// XXXbz A bit of a hack with the property name, but that's ok.
// biesi's moving this stuff into content anyway. ;)
mContent->SetProperty(nsCSSPseudoClasses::mozBroken,
NS_INT32_TO_PTR(1));
// check for alternative content with CantRenderReplacedElement()
rv = aPresContext->PresShell()->CantRenderReplacedElement(this);
} else {
// XXXbz can't quite unset the property here, since that would
// actually clobber it on nodes that are supposed to have it! Not
// sure why...
NotifyContentObjectWrapper();
}
FixupWindow(nsSize(aMetrics.width, aMetrics.height));
aStatus = NS_FRAME_COMPLETE;
@ -1281,81 +1026,13 @@ nsObjectFrame::Reflow(nsPresContext* aPresContext,
}
nsresult
nsObjectFrame::InstantiateWidget(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState,
nsCID aWidgetCID)
{
nsresult rv;
GetDesiredSize(aPresContext, aReflowState, aMetrics);
nsIView *parentWithView;
nsPoint origin;
GetOffsetFromView(origin, &parentWithView);
// Just make the frigging widget
float t2p;
t2p = aPresContext->TwipsToPixels();
PRInt32 x = NSTwipsToIntPixels(origin.x, t2p);
PRInt32 y = NSTwipsToIntPixels(origin.y, t2p);
PRInt32 width = NSTwipsToIntPixels(aMetrics.width, t2p);
PRInt32 height = NSTwipsToIntPixels(aMetrics.height, t2p);
nsRect r = nsRect(x, y, width, height);
mWidget = do_CreateInstance(aWidgetCID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
mWidget->Create(parentWithView->GetNearestWidget(nsnull), r, nsnull, nsnull);
mWidget->Show(PR_TRUE);
return rv;
}
nsresult
nsObjectFrame::InstantiatePlugin(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState,
nsIPluginHost* aPluginHost,
nsObjectFrame::InstantiatePlugin(nsIPluginHost* aPluginHost,
const char* aMimeType,
nsIURI* aURI)
{
nsIView *parentWithView;
nsPoint origin;
nsPluginWindow *window;
float t2p;
t2p = aPresContext->TwipsToPixels();
mFullURL = aURI;
// we need to recalculate this now that we have access to the nsPluginInstanceOwner
// and its size info (as set in the tag)
GetDesiredSize(aPresContext, aReflowState, aMetrics);
mInstanceOwner->GetWindow(window);
NS_ENSURE_TRUE(window, NS_ERROR_NULL_POINTER);
GetOffsetFromView(origin, &parentWithView);
window->x = NSTwipsToIntPixels(origin.x, t2p);
window->y = NSTwipsToIntPixels(origin.y, t2p);
window->width = NSTwipsToIntPixels(aMetrics.width, t2p);
window->height = NSTwipsToIntPixels(aMetrics.height, t2p);
// on the Mac we need to set the clipRect to { 0, 0, 0, 0 } for now. This will keep
// us from drawing on screen until the widget is properly positioned, which will not
// happen until we have finished the reflow process.
window->clipRect.top = 0;
window->clipRect.left = 0;
#if !(defined(XP_MAC) || defined(XP_MACOSX))
window->clipRect.bottom = NSTwipsToIntPixels(aMetrics.height, t2p);
window->clipRect.right = NSTwipsToIntPixels(aMetrics.width, t2p);
#else
window->clipRect.bottom = 0;
window->clipRect.right = 0;
#endif
#ifdef DEBUG
mInstantiating = PR_TRUE;
#endif
@ -1379,45 +1056,48 @@ nsObjectFrame::InstantiatePlugin(nsPresContext* aPresContext,
mInstantiating = PR_FALSE;
#endif
// XXX having to do this sucks. it'd be better to move the code from DidReflow
// to FixupWindow or something.
nsIPresShell *shell = GetPresContext()->GetPresShell();
shell->AppendReflowCommand(this, eReflowType_StyleChanged, nsnull);
return rv;
}
// This is called when the page containing plugin is resized, and plugin has its dimensions
// specified in percentage, so it needs to follow the page on the fly.
nsresult
nsObjectFrame::ReinstantiatePlugin(nsPresContext* aPresContext, nsHTMLReflowMetrics& aMetrics, const nsHTMLReflowState& aReflowState)
void
nsObjectFrame::FixupWindow(const nsSize& aSize)
{
nsIView *parentWithView;
nsPoint origin;
nsPresContext* presContext = GetPresContext();
float t2p = presContext->TwipsToPixels();
if (!mInstanceOwner)
return;
nsPluginWindow *window;
float t2p;
t2p = aPresContext->TwipsToPixels();
// we need to recalculate this now that we have access to the nsPluginInstanceOwner
// and its size info (as set in the tag)
GetDesiredSize(aPresContext, aReflowState, aMetrics);
mInstanceOwner->GetWindow(window);
NS_ENSURE_TRUE(window, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(window, /**/);
nsPoint origin;
nsIView *parentWithView;
GetOffsetFromView(origin, &parentWithView);
window->x = NSTwipsToIntPixels(origin.x, t2p);
window->y = NSTwipsToIntPixels(origin.y, t2p);
window->width = NSTwipsToIntPixels(aMetrics.width, t2p);
window->height = NSTwipsToIntPixels(aMetrics.height, t2p);
window->width = NSTwipsToIntPixels(aSize.width, t2p);
window->height = NSTwipsToIntPixels(aSize.height, t2p);
// ignore this for now on the Mac because the widget is not properly positioned
// yet and won't be until we have finished the reflow process.
#if defined(XP_MAC) || defined(XP_MACOSX)
// on the Mac we need to set the clipRect to { 0, 0, 0, 0 } for now. This will keep
// us from drawing on screen until the widget is properly positioned, which will not
// happen until we have finished the reflow process.
window->clipRect.top = 0;
window->clipRect.left = 0;
window->clipRect.bottom = NSTwipsToIntPixels(aMetrics.height, t2p);
window->clipRect.right = NSTwipsToIntPixels(aMetrics.width, t2p);
#if !(defined(XP_MAC) || defined(XP_MACOSX))
window->clipRect.bottom = NSTwipsToIntPixels(aSize.height, t2p);
window->clipRect.right = NSTwipsToIntPixels(aSize.width, t2p);
#else
window->clipRect.bottom = 0;
window->clipRect.right = 0;
#endif
return NS_OK;
}
nsresult
@ -1485,9 +1165,6 @@ nsObjectFrame::IsHidden(PRBool aCheckVisibilityStyle) const
// not to hide the <embed> once you'd put the 'hidden' attribute
// on the tag...
// these |NS_ConvertASCIItoUCS2|s can't be |NS_LITERAL_STRING|s
// until |EqualsIgnoreCase| get's fixed
// HIDDEN w/ no attributes gets translated as we are hidden for
// compatibility w/ 4.x and IE so we don't create a non-painting
// widget in layout. See bug 188959.
@ -1620,7 +1297,7 @@ nsObjectFrame::CreateDefaultFrames(nsPresContext *aPresContext,
// Kick off the image load.
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(img);
imageLoader->ImageURIChanged(src);
// XXX imageLoader->ImageURIChanged(src);
// get the localized text
nsXPIDLString missingPluginLabel;
@ -1640,7 +1317,7 @@ nsObjectFrame::CreateDefaultFrames(nsPresContext *aPresContext,
}
if (!stringBundleService || NS_FAILED(rv))
missingPluginLabel = NS_LITERAL_STRING("Click here to download plugin.");
missingPluginLabel.AssignLiteral("Click here to download plugin.");
text->SetText(missingPluginLabel, PR_FALSE);
@ -1882,30 +1559,7 @@ nsObjectFrame::Paint(nsPresContext* aPresContext,
window.clipRect.left = 0; window.clipRect.right = 0;
// XXX platform specific printing code
#if defined(XP_MAC) && !TARGET_CARBON
// Mac does things a little differently.
GrafPtr curPort;
::GetPort(&curPort); // get the current port
nsPluginPort port;
port.port = (CGrafPort*)curPort;
port.portx = window.x;
port.porty = window.y;
RgnHandle curClip = ::NewRgn();
NS_ENSURE_TRUE(curClip, NS_ERROR_NULL_POINTER);
::GetClip(curClip); // save old clip
::SetOrigin(-window.x,-window.y); // port must be set correctly prior to telling plugin to print
Rect r = {0,0,window.height,window.width};
::ClipRect(&r); // also set the clip
window.window = &port;
npprint.print.embedPrint.platformPrint = (void*)window.window;
npprint.print.embedPrint.window = window;
// send off print info to plugin
rv = pi->Print(&npprint);
#elif defined(XP_UNIX) && !defined(XP_MACOSX)
#if defined(XP_UNIX) && !defined(XP_MACOSX)
/* UNIX does things completely differently:
* We call the plugin and it sends generated PostScript data into a
* file handle we provide. If the plugin returns with success we embed
@ -1960,13 +1614,6 @@ nsObjectFrame::Paint(nsPresContext* aPresContext,
#endif
#if defined(XP_MAC) && !TARGET_CARBON
// Clean-up on Mac
::SetOrigin(0,0);
::SetClip(curClip); // restore previous clip
::DisposeRgn(curClip);
#endif
// XXX Nav 4.x always sent a SetWindow call after print. Should we do the same?
nsDidReflowStatus status = NS_FRAME_REFLOW_FINISHED; // should we use a special status?
frame->DidReflow(shell->GetPresContext(),
@ -2132,6 +1779,123 @@ nsresult nsObjectFrame::GetPluginInstance(nsIPluginInstance*& aPluginInstance)
return mInstanceOwner->GetInstance(aPluginInstance);
}
nsresult
nsObjectFrame::PrepareInstanceOwner()
{
if (!mInstanceOwner) {
mInstanceOwner = new nsPluginInstanceOwner();
if (!mInstanceOwner)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mInstanceOwner);
mInstanceOwner->Init(GetPresContext(), this);
} else {
mInstanceOwner->SetInstance(nsnull);
}
return NS_OK;
}
nsresult
nsObjectFrame::Instantiate(nsIChannel* aChannel, nsIStreamListener** aStreamListener)
{
nsresult rv = PrepareInstanceOwner();
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPluginHost> pluginHost(do_GetService(kCPluginManagerCID, &rv));
if (NS_FAILED(rv))
return rv;
mInstanceOwner->SetPluginHost(pluginHost);
// This must be done before instantiating the plugin
FixupWindow(mRect.Size());
aChannel->GetURI(getter_AddRefs(mFullURL));
rv = pluginHost->InstantiatePluginForChannel(aChannel, mInstanceOwner, aStreamListener);
// XXX having to do this sucks. it'd be better to move the code from DidReflow
// to FixupWindow.
nsIPresShell *shell = GetPresContext()->GetPresShell();
shell->AppendReflowCommand(this, eReflowType_StyleChanged, nsnull);
return rv;
}
nsresult
nsObjectFrame::Instantiate(const char* aMimeType, nsIURI* aURI)
{
nsresult rv = PrepareInstanceOwner();
NS_ENSURE_SUCCESS(rv, rv);
// This must be done before instantiating the plugin
FixupWindow(mRect.Size());
// get the nsIPluginHost service
nsCOMPtr<nsIPluginHost> pluginHost(do_GetService(kCPluginManagerCID, &rv));
if (NS_FAILED(rv))
return rv;
mInstanceOwner->SetPluginHost(pluginHost);
nsCOMPtr<nsISupports> container;
nsAutoString classid;
nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
nsAutoString codeBase;
if ((NS_CONTENT_ATTR_HAS_VALUE ==
mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::codebase, codeBase)) &&
!codeBase.IsEmpty()) {
nsCOMPtr<nsIURI> codeBaseURL;
rv = MakeAbsoluteURL(getter_AddRefs(codeBaseURL), codeBase, baseURI);
if (NS_SUCCEEDED(rv)) {
baseURI = codeBaseURL;
}
}
if (!baseURI)
return NS_ERROR_FAILURE;
// If we have no other URI, use the base URI of the node.
// XXX(biesi) I have no idea why that is the right thing, but it's what the
// code used to do...
if (!aURI)
aURI = baseURI; // Our baseURI nsCOMPtr will keep this alive
// if we have a clsid, we're either an internal widget, an ActiveX control, or an applet
if (mContent->Tag() == nsHTMLAtoms::object &&
NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::classid, classid)) {
// Find a MIME type for the class ID
nsCOMPtr<nsIObjectLoadingContent> objContent =
do_QueryInterface(GetContent(), &rv);
nsCAutoString type;
if (objContent)
rv = objContent->TypeForClassID(classid, type);
// XXX why baseURI??
if (NS_SUCCEEDED(rv))
rv = InstantiatePlugin(pluginHost, type.get(), baseURI);
}
else { // no clsid - the object is either an applet or a plugin
if (!aMimeType || !*aMimeType) {
// we don't have a mime type, try to figure it out
// from extension
nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
if (url) {
nsCAutoString ext;
rv = url->GetFileExtension(ext);
if (NS_SUCCEEDED(rv))
pluginHost->IsPluginEnabledForExtension(ext.get(), aMimeType);
}
}
rv = InstantiatePlugin(pluginHost, aMimeType, aURI);
}
// finish up
if (NS_SUCCEEDED(rv)) {
NotifyContentObjectWrapper();
}
return rv;
}
void
nsObjectFrame::NotifyContentObjectWrapper()
{
@ -2470,7 +2234,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetDOMElement(nsIDOMElement* *result)
if (nsnull != mOwner) {
nsIContent* cont = mOwner->GetContent();
if (cont) {
rv = cont->QueryInterface(NS_GET_IID(nsIDOMElement), (void **)result);
rv = CallQueryInterface(cont, result);
}
}
@ -3080,14 +2844,6 @@ nsObjectFrame::PluginNotAvailable(const char *aMimeType)
nsDependentCString type(aMimeType);
// Tell mContent about the mime type
nsCOMPtr<nsIPluginElement> pluginElement(do_QueryInterface(mContent));
if (pluginElement) {
pluginElement->SetActualType(type);
}
if (!sDefaultPluginDisabled) {
// The default plugin is enabled, don't fire events etc.
return;

View File

@ -98,6 +98,9 @@ public:
NS_IMETHOD Destroy(nsPresContext* aPresContext);
NS_IMETHOD GetPluginInstance(nsIPluginInstance*& aPluginInstance);
virtual nsresult Instantiate(nsIChannel* aChannel, nsIStreamListener** aStreamListener);
virtual nsresult Instantiate(const char* aMimeType, nsIURI* aURI);
/* fail on any requests to get a cursor from us because plugins set their own! see bug 118877 */
NS_IMETHOD GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor)
@ -129,8 +132,6 @@ public:
*/
NS_HIDDEN_(nsresult) GetMIMEType(nsACString& aType);
// for a given aRoot, this walks the frame tree looking for the next outFrame
static nsIObjectFrame* GetNextObjectFrame(nsPresContext* aPresContext,
nsIFrame* aRoot);
@ -168,21 +169,15 @@ protected:
const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aDesiredSize);
nsresult InstantiateWidget(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState,
nsCID aWidgetCID);
nsresult InstantiatePlugin(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState,
nsIPluginHost* aPluginHost,
nsresult InstantiatePlugin(nsIPluginHost* aPluginHost,
const char* aMimetype,
nsIURI* aURL);
nsresult ReinstantiatePlugin(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState);
/**
* Adjust the plugin's idea of its size, using aSize as its new size.
* (aSize must be in twips)
*/
void FixupWindow(const nsSize& aSize);
nsresult HandleChild(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics,
@ -203,6 +198,12 @@ protected:
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState);
/**
* Makes sure that mInstanceOwner is valid and without a current plugin
* instance. Essentially, this prepares the frame to receive a new plugin.
*/
NS_HIDDEN_(nsresult) PrepareInstanceOwner();
friend class nsPluginInstanceOwner;
private:
nsPluginInstanceOwner *mInstanceOwner;

View File

@ -51,11 +51,12 @@
interface nsIPlugin;
interface nsIURI;
interface nsIDOMPlugin;
interface nsIChannel;
[ptr] native PRLibraryPtr(PRLibrary);
[ref] native nsIStreamListenerRef(nsIStreamListener *);
[uuid(e740d8c4-fd94-456a-9506-9e044c5da27a)]
[uuid(ABB36800-EA77-4172-AD14-603A02DB2B53)]
interface nsIPluginHost : nsIFactory
{
void init();
@ -70,6 +71,13 @@ interface nsIPluginHost : nsIFactory
void instantiateFullPagePlugin(in string aMimeType, in nsIURI aURI, in nsIStreamListenerRef aStreamListener, in nsIPluginInstanceOwner aOwner);
/**
* Instantiate an embedded plugin for an existing channel. The caller is
* responsible for opening the channel. It may or may not be already opened
* when this function is called.
*/
nsIStreamListener instantiatePluginForChannel(in nsIChannel aChannel, in nsIPluginInstanceOwner aOwner);
void setUpPluginInstance(in string aMimeType, in nsIURI aURL, in nsIPluginInstanceOwner aOwner);
void isPluginEnabledForType(in string aMimeType);

View File

@ -2016,7 +2016,7 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request,
mPluginStreamInfo->SetRequest(request);
nsCAutoString aContentType;
nsCAutoString aContentType; // XXX but we already got the type above!
rv = channel->GetContentType(aContentType);
if (NS_FAILED(rv))
return rv;
@ -3294,6 +3294,35 @@ nsPluginHostImpl::GetPluginTempDir(nsIFile **aDir)
return sPluginTempDir->Clone(aDir);
}
NS_IMETHODIMP nsPluginHostImpl::InstantiatePluginForChannel(nsIChannel* aChannel,
nsIPluginInstanceOwner* aOwner,
nsIStreamListener** aListener)
{
NS_PRECONDITION(aChannel && aOwner,
"Invalid arguments to InstantiatePluginForChannel");
nsCOMPtr<nsIURI> uri;
nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
if (NS_FAILED(rv))
return rv;
#ifdef PLUGIN_LOGGING
if (PR_LOG_TEST(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL)) {
nsCAutoString urlSpec;
uri->GetAsciiSpec(urlSpec);
PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_NORMAL,
("nsPluginHostImpl::InstantiatePluginForChannel Begin owner=%p, url=%s\n",
aOwner, urlSpec.get()));
PR_LogFlush();
}
#endif
// XXX do we need to look for stopped plugins, like InstantiateEmbeddedPlugin
// does?
return NewEmbeddedPluginStreamListener(uri, aOwner, nsnull, aListener);
}
////////////////////////////////////////////////////////////////////////
/* Called by nsPluginInstanceOwner (nsObjectFrame.cpp - embedded case) */
@ -5897,16 +5926,16 @@ nsPluginHostImpl::StopPluginInstance(nsIPluginInstance* aInstance)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
/* Called by InstantiateEmbeddedPlugin() */
nsresult nsPluginHostImpl::NewEmbeddedPluginStream(nsIURI* aURL,
nsIPluginInstanceOwner *aOwner,
nsIPluginInstance* aInstance)
nsresult nsPluginHostImpl::NewEmbeddedPluginStreamListener(nsIURI* aURL,
nsIPluginInstanceOwner *aOwner,
nsIPluginInstance* aInstance,
nsIStreamListener** aListener)
{
if (!aURL)
return NS_OK;
nsPluginStreamListenerPeer *listener = new nsPluginStreamListenerPeer();
nsRefPtr<nsPluginStreamListenerPeer> listener =
new nsPluginStreamListenerPeer();
if (listener == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
@ -5922,7 +5951,22 @@ nsresult nsPluginHostImpl::NewEmbeddedPluginStream(nsIURI* aURL,
rv = listener->InitializeEmbedded(aURL, nsnull, aOwner, this);
else
rv = NS_ERROR_ILLEGAL_VALUE;
if (NS_SUCCEEDED(rv))
NS_ADDREF(*aListener = listener);
return rv;
}
////////////////////////////////////////////////////////////////////////
/* Called by InstantiateEmbeddedPlugin() */
nsresult nsPluginHostImpl::NewEmbeddedPluginStream(nsIURI* aURL,
nsIPluginInstanceOwner *aOwner,
nsIPluginInstance* aInstance)
{
nsCOMPtr<nsIStreamListener> listener;
nsresult rv = NewEmbeddedPluginStreamListener(aURL, aOwner, aInstance,
getter_AddRefs(listener));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIDocument> doc;
nsCOMPtr<nsILoadGroup> loadGroup;
@ -5950,7 +5994,6 @@ nsresult nsPluginHostImpl::NewEmbeddedPluginStream(nsIURI* aURL,
}
}
delete listener;
return rv;
}

View File

@ -266,6 +266,12 @@ public:
NS_IMETHOD
GetPluginFactory(const char *aMimeType, nsIPlugin** aPlugin);
NS_IMETHOD
InstantiatePluginForChannel(nsIChannel* aChannel,
nsIPluginInstanceOwner* aOwner,
nsIStreamListener** aListener);
NS_IMETHOD
InstantiateEmbeddedPlugin(const char *aMimeType, nsIURI* aURL, nsIPluginInstanceOwner *aOwner);
@ -417,6 +423,11 @@ private:
nsresult
LoadXPCOMPlugins(nsIComponentManager* aComponentManager);
nsresult
NewEmbeddedPluginStreamListener(nsIURI* aURL, nsIPluginInstanceOwner *aOwner,
nsIPluginInstance* aInstance,
nsIStreamListener** aListener);
nsresult
NewEmbeddedPluginStream(nsIURI* aURL, nsIPluginInstanceOwner *aOwner, nsIPluginInstance* aInstance);

View File

@ -464,7 +464,7 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info)
#ifdef NS_DEBUG
printf("GetMIMEDescription() returned \"%s\"\n", mimedescr);
#endif
if (NS_FAILED(rv = ParsePluginMimeDescription(mimedescr, info)))
if (NS_FAILED(rv = ParsePluginMimeDescription(mimedescr, info)))
return rv;
nsCAutoString filename;
if (NS_FAILED(rv = mPlugin->GetNativePath(filename)))