385 lines
11 KiB
C++
385 lines
11 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape 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/NPL/
|
|
*
|
|
* 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 Communicator client code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
#include "nsIDOMHTMLElement.h"
|
|
#include "nsIScriptObjectOwner.h"
|
|
#include "nsIDOMEventReceiver.h"
|
|
#include "nsIHTMLContent.h"
|
|
#include "nsGenericHTMLElement.h"
|
|
#include "nsHTMLAtoms.h"
|
|
#include "nsHTMLIIDs.h"
|
|
#include "nsIStyleContext.h"
|
|
#include "nsIMutableStyleContext.h"
|
|
#include "nsStyleConsts.h"
|
|
#include "nsIPresContext.h"
|
|
#include "nsIPresShell.h"
|
|
#include "nsIDocument.h"
|
|
#include "nsIFrame.h"
|
|
#include "nsObjectFrame.h"
|
|
#include "nsLayoutAtoms.h"
|
|
#include "nsObjectFrame.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsIAllocator.h"
|
|
#include "xptinfo.h"
|
|
#include "nsIInterfaceInfoManager.h"
|
|
#include "nsIPluginInstance.h"
|
|
#include "nsIXPConnect.h"
|
|
#include "nsIServiceManager.h"
|
|
|
|
// XXX define nsIDOMHTMLEmbedElement; add in nav attrs
|
|
|
|
//static NS_DEFINE_IID(kIDOMHTMLEmbedElementIID, NS_IDOMHTMLEmbedELEMENT_IID);
|
|
|
|
class nsHTMLEmbedElement : public nsIDOMHTMLElement,
|
|
public nsIJSScriptObject,
|
|
public nsIHTMLContent
|
|
{
|
|
public:
|
|
nsHTMLEmbedElement(nsINodeInfo *aNodeInfo);
|
|
virtual ~nsHTMLEmbedElement();
|
|
|
|
// nsISupports
|
|
NS_DECL_ISUPPORTS
|
|
|
|
// nsIDOMNode
|
|
NS_IMPL_IDOMNODE_USING_GENERIC(mInner)
|
|
|
|
// nsIDOMElement
|
|
NS_IMPL_IDOMELEMENT_USING_GENERIC(mInner)
|
|
|
|
// nsIDOMHTMLElement
|
|
NS_IMPL_IDOMHTMLELEMENT_USING_GENERIC(mInner)
|
|
|
|
// nsIDOMHTMLEmbedElement
|
|
|
|
// nsIJSScriptObject
|
|
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC(mInner)
|
|
virtual PRBool AddProperty(JSContext *aContext, JSObject *aObj,
|
|
jsval aID, jsval *aVp);
|
|
virtual PRBool DeleteProperty(JSContext *aContext, JSObject *aObj,
|
|
jsval aID, jsval *aVp);
|
|
virtual PRBool GetProperty(JSContext *aContext, JSObject *aObj,
|
|
jsval aID, jsval *aVp);
|
|
virtual PRBool SetProperty(JSContext *aContext, JSObject *aObj,
|
|
jsval aID, jsval *aVp);
|
|
virtual PRBool EnumerateProperty(JSContext *aContext, JSObject *aObj);
|
|
virtual PRBool Resolve(JSContext *aContext, JSObject *aObj, jsval aID);
|
|
virtual PRBool Convert(JSContext *aContext, JSObject *aObj, jsval aID);
|
|
virtual void Finalize(JSContext *aContext, JSObject *aObj);
|
|
|
|
// nsIContent
|
|
NS_IMPL_ICONTENT_USING_GENERIC(mInner)
|
|
|
|
// nsIHTMLContent
|
|
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
|
|
|
|
protected:
|
|
nsresult GetPluginInstance(nsIPluginInstance** aPluginInstance);
|
|
|
|
protected:
|
|
nsGenericHTMLLeafElement mInner;
|
|
};
|
|
|
|
nsresult
|
|
NS_NewHTMLEmbedElement(nsIHTMLContent** aInstancePtrResult,
|
|
nsINodeInfo *aNodeInfo)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aInstancePtrResult);
|
|
NS_ENSURE_ARG_POINTER(aNodeInfo);
|
|
|
|
nsIHTMLContent* it = new nsHTMLEmbedElement(aNodeInfo);
|
|
if (nsnull == it) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
|
|
}
|
|
|
|
|
|
nsHTMLEmbedElement::nsHTMLEmbedElement(nsINodeInfo *aNodeInfo)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
mInner.Init(this, aNodeInfo);
|
|
}
|
|
|
|
nsHTMLEmbedElement::~nsHTMLEmbedElement()
|
|
{
|
|
}
|
|
|
|
NS_IMPL_ADDREF(nsHTMLEmbedElement)
|
|
|
|
NS_IMPL_RELEASE(nsHTMLEmbedElement)
|
|
|
|
nsresult
|
|
nsHTMLEmbedElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
{
|
|
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
|
|
#if XXX
|
|
if (aIID.Equals(kIDOMHTMLEmbedElementIID)) {
|
|
nsIDOMHTMLEmbedElement* tmp = this;
|
|
*aInstancePtr = (void*) tmp;
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
#endif
|
|
return NS_NOINTERFACE;
|
|
}
|
|
|
|
nsresult
|
|
nsHTMLEmbedElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|
{
|
|
nsHTMLEmbedElement* it = new nsHTMLEmbedElement(mInner.mNodeInfo);
|
|
if (nsnull == it) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
mInner.CopyInnerTo(this, &it->mInner, aDeep);
|
|
return it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLEmbedElement::StringToAttribute(nsIAtom* aAttribute,
|
|
const nsString& aValue,
|
|
nsHTMLValue& aResult)
|
|
{
|
|
if (aAttribute == nsHTMLAtoms::align) {
|
|
if (nsGenericHTMLElement::ParseAlignValue(aValue, aResult)) {
|
|
return NS_CONTENT_ATTR_HAS_VALUE;
|
|
}
|
|
}
|
|
else if (nsGenericHTMLElement::ParseImageAttribute(aAttribute,
|
|
aValue, aResult)) {
|
|
return NS_CONTENT_ATTR_HAS_VALUE;
|
|
}
|
|
return NS_CONTENT_ATTR_NOT_THERE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLEmbedElement::AttributeToString(nsIAtom* aAttribute,
|
|
const nsHTMLValue& aValue,
|
|
nsString& aResult) const
|
|
{
|
|
if (aAttribute == nsHTMLAtoms::align) {
|
|
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
|
|
nsGenericHTMLElement::AlignValueToString(aValue, aResult);
|
|
return NS_CONTENT_ATTR_HAS_VALUE;
|
|
}
|
|
}
|
|
else if (nsGenericHTMLElement::ImageAttributeToString(aAttribute,
|
|
aValue, aResult)) {
|
|
return NS_CONTENT_ATTR_HAS_VALUE;
|
|
}
|
|
return mInner.AttributeToString(aAttribute, aValue, aResult);
|
|
}
|
|
|
|
static void
|
|
MapAttributesInto(const nsIHTMLMappedAttributes* aAttributes,
|
|
nsIMutableStyleContext* aContext,
|
|
nsIPresContext* aPresContext)
|
|
{
|
|
nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aContext, aPresContext);
|
|
nsGenericHTMLElement::MapImageAttributesInto(aAttributes, aContext, aPresContext);
|
|
nsGenericHTMLElement::MapImageBorderAttributeInto(aAttributes, aContext, aPresContext, nsnull);
|
|
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLEmbedElement::GetMappedAttributeImpact(const nsIAtom* aAttribute,
|
|
PRInt32& aHint) const
|
|
{
|
|
if (! nsGenericHTMLElement::GetCommonMappedAttributesImpact(aAttribute, aHint)) {
|
|
if (! nsGenericHTMLElement::GetImageMappedAttributesImpact(aAttribute, aHint)) {
|
|
if (! nsGenericHTMLElement::GetImageAlignAttributeImpact(aAttribute, aHint)) {
|
|
if (! nsGenericHTMLElement::GetImageBorderAttributeImpact(aAttribute, aHint)) {
|
|
aHint = NS_STYLE_HINT_CONTENT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLEmbedElement::GetAttributeMappingFunctions(nsMapAttributesFunc& aFontMapFunc,
|
|
nsMapAttributesFunc& aMapFunc) const
|
|
{
|
|
aFontMapFunc = nsnull;
|
|
aMapFunc = &MapAttributesInto;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLEmbedElement::HandleDOMEvent(nsIPresContext* aPresContext,
|
|
nsEvent* aEvent,
|
|
nsIDOMEvent** aDOMEvent,
|
|
PRUint32 aFlags,
|
|
nsEventStatus* aEventStatus)
|
|
{
|
|
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
|
aFlags, aEventStatus);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLEmbedElement::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const
|
|
{
|
|
return mInner.SizeOf(aSizer, aResult, sizeof(*this));
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
// This is cribbed from nsHTMLImageElement::GetImageFrame.
|
|
|
|
nsresult
|
|
nsHTMLEmbedElement::GetPluginInstance(nsIPluginInstance** aPluginInstance)
|
|
{
|
|
nsresult result;
|
|
nsCOMPtr<nsIPresContext> context;
|
|
nsCOMPtr<nsIPresShell> shell;
|
|
|
|
if (mInner.mDocument) {
|
|
// Make sure the presentation is up-to-date
|
|
result = mInner.mDocument->FlushPendingNotifications();
|
|
if (NS_FAILED(result)) {
|
|
return result;
|
|
}
|
|
}
|
|
|
|
result = nsGenericHTMLElement::GetPresContext(this,
|
|
getter_AddRefs(context));
|
|
if (NS_FAILED(result)) {
|
|
return result;
|
|
}
|
|
|
|
result = context->GetShell(getter_AddRefs(shell));
|
|
if (NS_FAILED(result)) {
|
|
return result;
|
|
}
|
|
|
|
nsIFrame* frame;
|
|
result = shell->GetPrimaryFrameFor(this, &frame);
|
|
if (NS_FAILED(result)) {
|
|
return result;
|
|
}
|
|
|
|
if (frame) {
|
|
nsCOMPtr<nsIAtom> type;
|
|
|
|
frame->GetFrameType(getter_AddRefs(type));
|
|
|
|
if (type.get() == nsLayoutAtoms::objectFrame) {
|
|
// XXX We could have created an interface for this, but Troy
|
|
// preferred the ugliness of a static cast to the weight of
|
|
// a new interface.
|
|
|
|
nsObjectFrame* objectFrame = NS_STATIC_CAST(nsObjectFrame*, frame);
|
|
|
|
return objectFrame->GetPluginInstance(*aPluginInstance);
|
|
}
|
|
}
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
/***************************************************************************/
|
|
|
|
// nsIJSScriptObject
|
|
|
|
PRBool
|
|
nsHTMLEmbedElement::AddProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
|
{
|
|
return mInner.AddProperty(aContext, aObj, aID, aVp);
|
|
}
|
|
|
|
PRBool
|
|
nsHTMLEmbedElement::DeleteProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
|
{
|
|
return mInner.DeleteProperty(aContext, aObj, aID, aVp);
|
|
}
|
|
|
|
PRBool
|
|
nsHTMLEmbedElement::GetProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
|
{
|
|
if (JSVAL_IS_STRING(aID)) {
|
|
PRBool retval = PR_FALSE;
|
|
char* cString = JS_GetStringBytes(JS_ValueToString(aContext, aID));
|
|
|
|
nsCOMPtr<nsIInterfaceInfoManager> iim =
|
|
dont_AddRef(XPTI_GetInterfaceInfoManager());
|
|
nsCOMPtr<nsIXPConnect> xpc =
|
|
do_GetService(nsIXPConnect::GetCID());
|
|
|
|
if (iim && xpc) {
|
|
nsIID* iid;
|
|
if (NS_SUCCEEDED(iim->GetIIDForName(cString, &iid)) && iid) {
|
|
nsCOMPtr<nsIPluginInstance> pi;
|
|
if (NS_SUCCEEDED(GetPluginInstance(getter_AddRefs(pi))) && pi) {
|
|
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
|
JSObject* ifaceObj;
|
|
|
|
if (NS_SUCCEEDED(xpc->WrapNative(aContext, aObj, pi, *iid,
|
|
getter_AddRefs(holder))) && holder &&
|
|
NS_SUCCEEDED(holder->GetJSObject(&ifaceObj)) && ifaceObj) {
|
|
*aVp = OBJECT_TO_JSVAL(ifaceObj);
|
|
retval = PR_TRUE;
|
|
}
|
|
}
|
|
nsAllocator::Free(iid);
|
|
return retval;
|
|
}
|
|
}
|
|
}
|
|
|
|
return mInner.GetProperty(aContext, aObj, aID, aVp);
|
|
}
|
|
|
|
PRBool
|
|
nsHTMLEmbedElement::SetProperty(JSContext *aContext, JSObject *aObj, jsval aID, jsval *aVp)
|
|
{
|
|
return mInner.SetProperty(aContext, aObj, aID, aVp);
|
|
}
|
|
|
|
PRBool
|
|
nsHTMLEmbedElement::EnumerateProperty(JSContext *aContext, JSObject *aObj)
|
|
{
|
|
return mInner.EnumerateProperty(aContext, aObj);
|
|
}
|
|
|
|
PRBool
|
|
nsHTMLEmbedElement::Resolve(JSContext *aContext, JSObject *aObj, jsval aID)
|
|
{
|
|
return mInner.Resolve(aContext, aObj, aID);
|
|
}
|
|
|
|
PRBool
|
|
nsHTMLEmbedElement::Convert(JSContext *aContext, JSObject *aObj, jsval aID)
|
|
{
|
|
return mInner.Convert(aContext, aObj, aID);
|
|
}
|
|
|
|
void
|
|
nsHTMLEmbedElement::Finalize(JSContext *aContext, JSObject *aObj)
|
|
{
|
|
mInner.Finalize(aContext, aObj);
|
|
}
|
|
|
|
|