WebCore:
authorrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Jan 2005 02:34:22 +0000 (02:34 +0000)
committerrjw <rjw@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Jan 2005 02:34:22 +0000 (02:34 +0000)
Fixed several issues all arising from analysis of plugin detection code at ifilm.com:

Fixed <rdar://problem/3958592> can't script plug-ins if plug-in is invoked with <object> element instead of <embed>
Fixed <rdar://problem/3958597> <object> elements with IDs do not show up as named properties of the document
Fixed <rdar://problem/3960973> DOM objects for plugin elements are not accessible
Fixed <rdar://problem/3958601> need an additional class ID in WebCore for the Real plug-in

We now support accessing scriptable plugin objects that are specified with <applet>, <embed>, or <object>
tags.  Also, if any of these elements are named they can be accessed from the document or window objects.
Finally, DOM methods are properties will be forwarded appropriately for the plugin's root scriptable object.

        Reviewed by Chris.

        * khtml/dom/html_document.cpp:
        (HTMLDocument::objects):
        * khtml/dom/html_document.h:
        * khtml/ecma/kjs_dom.cpp:
        (DOMDocumentProtoFunc::tryCall):
        (DOMElementProtoFunc::tryCall):
        (KJS::getRuntimeObject):
        * khtml/ecma/kjs_dom.h:
        * khtml/ecma/kjs_html.cpp:
        (KJS::HTMLDocument::tryGet):
        (KJS::HTMLElement::tryGet):
        (KJS::HTMLCollection::tryGet):
        (KJS::HTMLCollection::getNamedItems):
        * khtml/ecma/kjs_window.cpp:
        (Window::get):
        * khtml/html/html_miscimpl.cpp:
        (HTMLCollectionImpl::traverseNextItem):
        * khtml/html/html_miscimpl.h:
        (DOM::HTMLCollectionImpl::):
        * khtml/html/html_objectimpl.cpp:
        (HTMLAppletElementImpl::getAppletInstance):
        (HTMLObjectElementImpl::HTMLObjectElementImpl):
        (HTMLObjectElementImpl::getObjectInstance):
        * khtml/html/html_objectimpl.h:
        * khtml/rendering/render_frames.cpp:
        (RenderPartObject::updateWidget):
        * kwq/KWQKHTMLPart.h:
        * kwq/KWQKHTMLPart.mm:
        (KWQKHTMLPart::getObjectInstanceForView):

JavaScriptCore:
Fixed several issues all arising from analysis of plugin detection code at ifilm.com:

Fixed <rdar://problem/3958592> can't script plug-ins if plug-in is invoked with <object> element instead of <embed>
Fixed <rdar://problem/3958597> <object> elements with IDs do not show up as named properties of the document
Fixed <rdar://problem/3960973> DOM objects for plugin elements are not accessible
Fixed <rdar://problem/3958601> need an additional class ID in WebCore for the Real plug-in

We now support accessing scriptable plugin objects that are specified with <applet>, <embed>, or <object>
tags.  Also, if any of these elements are named they can be accessed from the document or window objects.
Finally, DOM methods are properties will be forwarded appropriately for the plugin's root scriptable object.

        Reviewed by Chris.

        * bindings/objc/objc_instance.h:
        * bindings/objc/objc_instance.mm:
        (ObjcInstance::supportsSetValueOfUndefinedField):
        * bindings/runtime.h:
        (KJS::Bindings::Instance::supportsSetValueOfUndefinedField):
        * bindings/runtime_object.cpp:
        (RuntimeObjectImp::RuntimeObjectImp):
        (RuntimeObjectImp::get):
        (RuntimeObjectImp::put):
        (RuntimeObjectImp::canPut):
        (RuntimeObjectImp::hasProperty):
        (RuntimeObjectImp::defaultValue):
        * bindings/runtime_object.h:
        (KJS::RuntimeObjectImp::fallbackObject):
        * kjs/object.cpp:
        (KJS::ObjectImp::ObjectImp):
        * kjs/object.h:
        (KJS::ObjectImp::forwardingScriptMessage):
        (KJS::ObjectImp::setForwardingScriptMessage):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@8400 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/bindings/objc/objc_instance.h
JavaScriptCore/bindings/objc/objc_instance.mm
JavaScriptCore/bindings/runtime.h
JavaScriptCore/bindings/runtime_object.cpp
JavaScriptCore/bindings/runtime_object.h
JavaScriptCore/kjs/object.cpp
JavaScriptCore/kjs/object.h
WebCore/ChangeLog-2005-08-23
WebCore/khtml/dom/html_document.cpp
WebCore/khtml/dom/html_document.h
WebCore/khtml/ecma/kjs_dom.cpp
WebCore/khtml/ecma/kjs_dom.h
WebCore/khtml/ecma/kjs_html.cpp
WebCore/khtml/ecma/kjs_window.cpp
WebCore/khtml/html/html_miscimpl.cpp
WebCore/khtml/html/html_miscimpl.h
WebCore/khtml/html/html_objectimpl.cpp
WebCore/khtml/html/html_objectimpl.h
WebCore/khtml/rendering/render_frames.cpp
WebCore/kwq/KWQKHTMLPart.h
WebCore/kwq/KWQKHTMLPart.mm

index 132fa0ba21c58c827a5c0ace39031b6a9d208b7b..c877f168355898ebcc93aab73c9cccdfc438c7bb 100644 (file)
@@ -1,3 +1,38 @@
+2005-01-18  Richard Williamson   <rjw@apple.com>
+
+       Fixed several issues all arising from analysis of plugin detection code at ifilm.com:
+
+       Fixed <rdar://problem/3958592> can't script plug-ins if plug-in is invoked with <object> element instead of <embed>
+       Fixed <rdar://problem/3958597> <object> elements with IDs do not show up as named properties of the document
+       Fixed <rdar://problem/3960973> DOM objects for plugin elements are not accessible
+       Fixed <rdar://problem/3958601> need an additional class ID in WebCore for the Real plug-in
+
+       We now support accessing scriptable plugin objects that are specified with <applet>, <embed>, or <object>
+       tags.  Also, if any of these elements are named they can be accessed from the document or window objects.
+       Finally, DOM methods are properties will be forwarded appropriately for the plugin's root scriptable object.
+
+        Reviewed by Chris.
+
+        * bindings/objc/objc_instance.h:
+        * bindings/objc/objc_instance.mm:
+        (ObjcInstance::supportsSetValueOfUndefinedField):
+        * bindings/runtime.h:
+        (KJS::Bindings::Instance::supportsSetValueOfUndefinedField):
+        * bindings/runtime_object.cpp:
+        (RuntimeObjectImp::RuntimeObjectImp):
+        (RuntimeObjectImp::get):
+        (RuntimeObjectImp::put):
+        (RuntimeObjectImp::canPut):
+        (RuntimeObjectImp::hasProperty):
+        (RuntimeObjectImp::defaultValue):
+        * bindings/runtime_object.h:
+        (KJS::RuntimeObjectImp::fallbackObject):
+        * kjs/object.cpp:
+        (KJS::ObjectImp::ObjectImp):
+        * kjs/object.h:
+        (KJS::ObjectImp::forwardingScriptMessage):
+        (KJS::ObjectImp::setForwardingScriptMessage):
+
 2005-01-18  Richard Williamson   <rjw@apple.com>
 
        Back out a change that was incorrectly committed yesterday.
index 5b3bb81720ab5c482bdf0a388132c3ece3dccc38..3172acdf93f5c68688bedb3476539fae2ebb23a2 100644 (file)
@@ -60,6 +60,7 @@ public:
     virtual Value invokeDefaultMethod (ExecState *exec, const List &args);
 
     virtual void setValueOfField (ExecState *exec, const Field *aField, const Value &aValue) const;
+    virtual bool supportsSetValueOfUndefinedField ();
     virtual void setValueOfUndefinedField (ExecState *exec, const Identifier &property, const Value &aValue);
     
     virtual Value ObjcInstance::getValueOfField (ExecState *exec, const Field *aField) const;
index 88e24e5f7067d1cb7559203e1a55d3ee4badb899..6ec2fcb0231b3cd10ffcccb0d46c301192cd7b03 100644 (file)
@@ -302,6 +302,16 @@ void ObjcInstance::setValueOfField (KJS::ExecState *exec, const Field *aField, c
     aField->setValueToInstance (exec, this, aValue);
 }
 
+bool ObjcInstance::supportsSetValueOfUndefinedField ()
+{
+    id targetObject = getObject();
+    
+    if ([targetObject respondsToSelector:@selector(setValue:forUndefinedKey:)])
+       return true;
+       
+    return false;
+}
+
 void ObjcInstance::setValueOfUndefinedField (KJS::ExecState *exec, const KJS::Identifier &property, const KJS::Value &aValue)
 {
     id targetObject = getObject();
index d5c2e2379f1b107a3ac0b64dae383dc73d775179..af12b02f15e7071916592b37f8539a9c0a16f41f 100644 (file)
@@ -157,6 +157,7 @@ public:
     virtual Value getValueOfField (ExecState *exec, const Field *aField) const;
     virtual Value getValueOfUndefinedField (ExecState *exec, const Identifier &property, Type hint) const { return Undefined(); };
     virtual void setValueOfField (ExecState *exec, const Field *aField, const Value &aValue) const;
+    virtual bool supportsSetValueOfUndefinedField () { return false; };
     virtual void setValueOfUndefinedField (ExecState *exec, const Identifier &property, const Value &aValue) {};
     
     virtual Value invokeMethod (ExecState *exec, const MethodList &method, const List &args) = 0;
index 543492f386ab3644aca18daad4f93fd950bbcf9c..c09d5a5a270044f70e847cd84f169e5891aaf139 100644 (file)
@@ -60,6 +60,13 @@ RuntimeObjectImp::RuntimeObjectImp(Bindings::Instance *i, bool oi) : ObjectImp (
     instance = i;
 }
 
+RuntimeObjectImp::RuntimeObjectImp(Bindings::Instance *i, const Value &fb, bool oi) : ObjectImp ((ObjectImp *)0)
+{
+    ownsInstance = oi;
+    instance = i;
+    fallback = fb;
+}
+
 Value RuntimeObjectImp::get(ExecState *exec, const Identifier &propertyName) const
 {
     Value result = Undefined();
@@ -82,17 +89,23 @@ Value RuntimeObjectImp::get(ExecState *exec, const Identifier &propertyName) con
             if (methodList.length() > 0) {
                 result = Object (new RuntimeMethodImp(exec, propertyName, methodList));
             }
+           else if (!fallback.isNull() && fallback.type() == ObjectType){
+               ObjectImp *imp = static_cast<ObjectImp*>(fallback.imp());
+               imp->setForwardingScriptMessage(true);
+               result = imp->get (exec, propertyName);
+               imp->setForwardingScriptMessage(false);
+           }
         }
-    
+       
         if (result.type() == UndefinedType) {
             // Try a fallback object.
             result = aClass->fallbackObject (exec, instance, propertyName);
         }
     }
         
-        
     instance->end();
 
+    
     return result;
 }
 
@@ -107,7 +120,25 @@ void RuntimeObjectImp::put(ExecState *exec, const Identifier &propertyName,
         getInternalInstance()->setValueOfField(exec, aField, value);
     }
     else {
-        getInternalInstance()->setValueOfUndefinedField(exec, propertyName, value);
+       bool domHasProperty = false;
+       if (!fallback.isNull() && fallback.type() == ObjectType){
+           ObjectImp *imp = static_cast<ObjectImp*>(fallback.imp());
+           imp->setForwardingScriptMessage(true);
+           domHasProperty = imp->hasProperty(exec, propertyName);
+           imp->setForwardingScriptMessage(false);
+       }
+       
+       // If the DOM has the property, give it a crack first (even if it read-only).
+       if (domHasProperty || !getInternalInstance()->supportsSetValueOfUndefinedField()) {
+           ObjectImp *imp = static_cast<ObjectImp*>(fallback.imp());
+           imp->setForwardingScriptMessage(true);
+           imp->put(exec, propertyName, value, attr);
+           imp->setForwardingScriptMessage(false);
+       }
+       // Now let the runtime object attempt to handle the undefined field.
+       else if (getInternalInstance()->supportsSetValueOfUndefinedField()){
+           getInternalInstance()->setValueOfUndefinedField(exec, propertyName, value);
+       }
     }
 
     instance->end();
@@ -115,18 +146,32 @@ void RuntimeObjectImp::put(ExecState *exec, const Identifier &propertyName,
 
 bool RuntimeObjectImp::canPut(ExecState *exec, const Identifier &propertyName) const
 {
+    bool result = false;
+
     instance->begin();
 
     Field *aField = instance->getClass()->fieldNamed(propertyName.ascii(), instance);
 
     instance->end();
 
-    return aField ? true : false;
+    if (aField)
+       return true;
+    
+    if (!fallback.isNull() && fallback.type() == ObjectType) {
+       ObjectImp *imp = static_cast<ObjectImp*>(fallback.imp());
+       imp->setForwardingScriptMessage(true);
+       result = imp->canPut (exec, propertyName);
+       imp->setForwardingScriptMessage(false);
+    }
+       
+    return result;
 }
 
 bool RuntimeObjectImp::hasProperty(ExecState *exec,
                             const Identifier &propertyName) const
 {
+    bool result = false;
+    
     instance->begin();
 
     Field *aField = instance->getClass()->fieldNamed(propertyName.ascii(), instance);
@@ -141,8 +186,15 @@ bool RuntimeObjectImp::hasProperty(ExecState *exec,
 
     if (methodList.length() > 0)
         return true;
+
+    if (!fallback.isNull() && fallback.type() == ObjectType) {
+       ObjectImp *imp = static_cast<ObjectImp*>(fallback.imp());
+       imp->setForwardingScriptMessage(true);
+       result = imp->hasProperty (exec, propertyName);
+       imp->setForwardingScriptMessage(false);
+    }
         
-    return false;
+    return result;
 }
 
 bool RuntimeObjectImp::deleteProperty(ExecState *exec,
@@ -154,13 +206,23 @@ bool RuntimeObjectImp::deleteProperty(ExecState *exec,
 
 Value RuntimeObjectImp::defaultValue(ExecState *exec, Type hint) const
 {
+    Value result;
+    
     instance->begin();
 
-    Value aValue = getInternalInstance()->defaultValue(hint);
+    if (!fallback.isNull() && fallback.type() == ObjectType) {
+       ObjectImp *imp = static_cast<ObjectImp*>(fallback.imp());
+       imp->setForwardingScriptMessage(true);
+       result = imp->defaultValue (exec, hint);
+       imp->setForwardingScriptMessage(false);
+    }
+    else {
+       result = getInternalInstance()->defaultValue(hint);
+    }
     
     instance->end();
     
-    return aValue;
+    return result;
 }
     
 bool RuntimeObjectImp::implementsCall() const
index cd06816812d1409f3774564a0b5627e88ed2d633..36f22404e6daa94569165fe0c59b59cee2d0c8dc 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <JavaScriptCore/runtime.h>
 #include <JavaScriptCore/object.h>
+#include <JavaScriptCore/protect.h>
 
 namespace KJS {
 
@@ -37,6 +38,7 @@ public:
     ~RuntimeObjectImp();
     
     RuntimeObjectImp(Bindings::Instance *i, bool ownsInstance = true);
+    RuntimeObjectImp(Bindings::Instance *i, const Value &fallback, bool ownsInstance = true);
 
     const ClassInfo *classInfo() const { return &info; }
 
@@ -62,9 +64,12 @@ public:
     virtual bool implementsCall() const;
     virtual Value call(ExecState *exec, Object &thisObj, const List &args);
 
-private:
+    Value fallbackObject() { return fallback; }
     
     static const ClassInfo info;
+
+private:
+    ProtectedValue fallback;
     Bindings::Instance *instance;
     bool ownsInstance;
 };
index 94f75af4f6527b3a857c9fe039694a8bece9cb2a..03bfd93bcd7651e7c5b50ba86181cbe2f3f362b5 100644 (file)
@@ -124,13 +124,13 @@ Value Object::call(ExecState *exec, Object &thisObj, const List &args)
 // ------------------------------ ObjectImp ------------------------------------
 
 ObjectImp::ObjectImp(const Object &proto)
-  : _proto(static_cast<ObjectImp*>(proto.imp())), _internalValue(0L)
+  : _proto(static_cast<ObjectImp*>(proto.imp())), _internalValue(0L), _forwardingScriptMessage(false)
 {
   //fprintf(stderr,"ObjectImp::ObjectImp %p\n",(void*)this);
 }
 
 ObjectImp::ObjectImp(ObjectImp *proto)
-  : _proto(proto), _internalValue(0L)
+  : _proto(proto), _internalValue(0L), _forwardingScriptMessage(false)
 {
   //fprintf(stderr,"ObjectImp::ObjectImp %p\n",(void*)this);
 }
@@ -140,6 +140,7 @@ ObjectImp::ObjectImp()
   //fprintf(stderr,"ObjectImp::ObjectImp %p\n",(void*)this);
   _proto = NullImp::staticNull;
   _internalValue = 0L;
+  _forwardingScriptMessage = false;
 }
 
 ObjectImp::~ObjectImp()
index 64a076a0afbb7dba9585fff2aae47549af687778..8e15825fd80d39d40ba20c9dfe7d68e60cd0ff98 100644 (file)
@@ -600,6 +600,11 @@ namespace KJS {
     void saveProperties(SavedProperties &p) const { _prop.save(p); }
     void restoreProperties(const SavedProperties &p) { _prop.restore(p); }
 
+#if APPLE_CHANGES
+    bool forwardingScriptMessage() const { return _forwardingScriptMessage; }
+    void setForwardingScriptMessage(bool f) { _forwardingScriptMessage = f; }
+#endif
+
   protected:
     PropertyMap _prop;
   private:
@@ -607,6 +612,10 @@ namespace KJS {
     ValueImp *_proto;
     ValueImp *_internalValue;
     ScopeChain _scope;
+
+#if APPLE_CHANGES
+    bool _forwardingScriptMessage;
+#endif    
   };
 
   /**
index 0ad9cc42837357197d5d40b8a880a1888d27abe0..3b10efbedb8d89a0f577bfadf6255462f2ce762f 100644 (file)
@@ -1,3 +1,48 @@
+2005-01-18  Richard Williamson   <rjw@apple.com>
+       
+       Fixed several issues all arising from analysis of plugin detection code at ifilm.com:
+
+       Fixed <rdar://problem/3958592> can't script plug-ins if plug-in is invoked with <object> element instead of <embed>
+       Fixed <rdar://problem/3958597> <object> elements with IDs do not show up as named properties of the document
+       Fixed <rdar://problem/3960973> DOM objects for plugin elements are not accessible
+       Fixed <rdar://problem/3958601> need an additional class ID in WebCore for the Real plug-in
+
+       We now support accessing scriptable plugin objects that are specified with <applet>, <embed>, or <object>
+       tags.  Also, if any of these elements are named they can be accessed from the document or window objects.
+       Finally, DOM methods are properties will be forwarded appropriately for the plugin's root scriptable object.
+
+        Reviewed by Chris.
+
+        * khtml/dom/html_document.cpp:
+        (HTMLDocument::objects):
+        * khtml/dom/html_document.h:
+        * khtml/ecma/kjs_dom.cpp:
+        (DOMDocumentProtoFunc::tryCall):
+        (DOMElementProtoFunc::tryCall):
+        (KJS::getRuntimeObject):
+        * khtml/ecma/kjs_dom.h:
+        * khtml/ecma/kjs_html.cpp:
+        (KJS::HTMLDocument::tryGet):
+        (KJS::HTMLElement::tryGet):
+        (KJS::HTMLCollection::tryGet):
+        (KJS::HTMLCollection::getNamedItems):
+        * khtml/ecma/kjs_window.cpp:
+        (Window::get):
+        * khtml/html/html_miscimpl.cpp:
+        (HTMLCollectionImpl::traverseNextItem):
+        * khtml/html/html_miscimpl.h:
+        (DOM::HTMLCollectionImpl::):
+        * khtml/html/html_objectimpl.cpp:
+        (HTMLAppletElementImpl::getAppletInstance):
+        (HTMLObjectElementImpl::HTMLObjectElementImpl):
+        (HTMLObjectElementImpl::getObjectInstance):
+        * khtml/html/html_objectimpl.h:
+        * khtml/rendering/render_frames.cpp:
+        (RenderPartObject::updateWidget):
+        * kwq/KWQKHTMLPart.h:
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::getObjectInstanceForView):
+
 2005-01-18  David Hyatt  <hyatt@apple.com>
 
        Fix for 3948123, rolling over link erases nearby text.  The repaint rect check for lines was wrong whenever
index eab1256025b0dab65acffe0295b2042e93f84042..603bce3c566b13fb8f527ef779a338c7100e3771 100644 (file)
@@ -166,6 +166,12 @@ HTMLCollection HTMLDocument::embeds() const
     return HTMLCollection(impl, HTMLCollectionImpl::DOC_EMBEDS);
 }
 
+HTMLCollection HTMLDocument::objects() const
+{
+    if(!impl) return HTMLCollection();
+    return HTMLCollection(impl, HTMLCollectionImpl::DOC_OBJECTS);
+}
+
 HTMLCollection HTMLDocument::links() const
 {
     if(!impl) return HTMLCollection();
index 6bbd8be54d9f5430a92072c4a800b73488436dc5..9b2d3b16a816a98b7afc7f5e6fc018621791c23f 100644 (file)
@@ -163,6 +163,13 @@ public:
      */
     HTMLCollection embeds() const;
 
+    /**
+     * A collection of all the <object> OBJECT </object> elements that
+     * include embedded elements in a document.
+     *
+     */
+    HTMLCollection objects() const;
+
     /**
      * A collection of all <code> AREA </code> elements and anchor (
      * <code> A </code> ) elements in a document with a value for the
index 3081c6ee1f40667f673eb6c4c818f469decf9f1d..9a3030234dd59bb17440747c9869282f18b70563 100644 (file)
@@ -947,7 +947,23 @@ Value DOMDocumentProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List
     return getDOMNodeList(exec,doc.getElementsByTagNameNS(args[0].toString(exec).string(),
                                                           args[1].toString(exec).string()));
   case DOMDocument::GetElementById:
+#if APPLE_CHANGES
+    {
+       DOM::Element node = doc.getElementById(args[0].toString(exec).string());
+       if (!node.isNull()) {
+           Value domValue = getDOMNode(exec, node);
+           ObjectImp *imp = static_cast<ObjectImp *>(domValue.imp());
+           if (!imp->forwardingScriptMessage() && (node.handle()->id() == ID_APPLET || node.handle()->id() == ID_EMBED || node.handle()->id() == ID_OBJECT)) {
+               Value v = getRuntimeObject(exec,node,domValue);
+               if (!v.isNull())
+                   return v;
+           }
+           return domValue;
+       }
+    }
+#else  
     return getDOMNode(exec,doc.getElementById(args[0].toString(exec).string()));
+#endif
   case DOMDocument::CreateRange:
     return getDOMRange(exec,doc.createRange());
   case DOMDocument::CreateNodeIterator: {
@@ -1085,8 +1101,18 @@ Value DOMElement::tryGet(ExecState *exec, const Identifier &propertyName) const
   return Undefined();
 }
 
-Value DOMElementProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
+Value DOMElementProtoFunc::tryCall(ExecState *exec, Object &to, const List &args)
 {
+  Object thisObj;
+
+  if (to.classInfo() == &KJS::RuntimeObjectImp::info) {
+    KJS::RuntimeObjectImp *imp = static_cast<KJS::RuntimeObjectImp *>(to.imp());
+    thisObj = imp->fallbackObject().toObject(exec);
+  }
+  else {
+    thisObj = to;
+  }
+  
   if (!thisObj.inherits(&KJS::DOMNode::info)) { // node should be enough here, given the cast
     Object err = Error::create(exec,TypeError);
     exec->setException(err);
@@ -1544,7 +1570,7 @@ Value KJS::getDOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap &m)
   return Value(cacheDOMObject<DOM::NamedNodeMap, KJS::DOMNamedNodeMap>(exec, m));
 }
 
-Value KJS::getRuntimeObject(ExecState *exec, const DOM::Node &node)
+Value KJS::getRuntimeObject(ExecState *exec, const DOM::Node &node, const Value &fallback)
 {
     DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
 
@@ -1554,7 +1580,7 @@ Value KJS::getRuntimeObject(ExecState *exec, const DOM::Node &node)
             
             if (appletElement->getAppletInstance()) {
                 // The instance is owned by the applet element.
-                RuntimeObjectImp *appletImp = new RuntimeObjectImp(appletElement->getAppletInstance(), false);
+                RuntimeObjectImp *appletImp = new RuntimeObjectImp(appletElement->getAppletInstance(), fallback, false);
                 return Value(appletImp);
             }
         }
@@ -1562,7 +1588,15 @@ Value KJS::getRuntimeObject(ExecState *exec, const DOM::Node &node)
             DOM::HTMLEmbedElementImpl *embedElement = static_cast<DOM::HTMLEmbedElementImpl *>(element.handle());
             
             if (embedElement->getEmbedInstance()) {
-                RuntimeObjectImp *runtimeImp = new RuntimeObjectImp(embedElement->getEmbedInstance(), false);
+                RuntimeObjectImp *runtimeImp = new RuntimeObjectImp(embedElement->getEmbedInstance(), fallback, false);
+                return Value(runtimeImp);
+            }
+        }
+        else if (node.handle()->id() == ID_OBJECT) {
+            DOM::HTMLObjectElementImpl *objectElement = static_cast<DOM::HTMLObjectElementImpl *>(element.handle());
+            
+            if (objectElement->getObjectInstance()) {
+                RuntimeObjectImp *runtimeImp = new RuntimeObjectImp(objectElement->getObjectInstance(), fallback, false);
                 return Value(runtimeImp);
             }
         }
index 343c67e382669c7e778690bc120bfc1f27cedb6a..b6308435cb5d423a5ef960f22b8f31444caa1c68 100644 (file)
@@ -263,7 +263,7 @@ namespace KJS {
   Value getDOMDocumentNode(ExecState *exec, const DOM::Document &n);
   bool checkNodeSecurity(ExecState *exec, const DOM::Node& n);
 #if APPLE_CHANGES
-  Value getRuntimeObject(ExecState *exec, const DOM::Node &n);
+  Value getRuntimeObject(ExecState *exec, const DOM::Node &n, const Value &fallback);
 #endif
   Value getDOMNode(ExecState *exec, const DOM::Node &n);
   Value getDOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap &m);
index c1654db5037735b23ad0f4f91eb65e7d03c6c20c..9996bb81a08baec907cac68cd91432731efc9e69 100644 (file)
@@ -317,17 +317,37 @@ Value KJS::HTMLDocument::tryGet(ExecState *exec, const Identifier &propertyName)
     DOM::HTMLCollection applets = doc.applets();
     DOM::HTMLElement anApplet = applets.namedItem (propertyName.string());
     if (!anApplet.isNull()) {
-        Value v = getRuntimeObject(exec,anApplet);
-       if (!v.isNull())
-           return v;
+       Value domValue = getDOMNode(exec,anApplet);
+       ObjectImp *imp = static_cast<ObjectImp *>(domValue.imp());
+       if (!imp->forwardingScriptMessage()) {
+           Value v = getRuntimeObject(exec,anApplet,getDOMNode(exec,anApplet));
+           if (!v.isNull())
+               return v;
+       }
     }
 
     DOM::HTMLCollection embeds = doc.embeds();
     DOM::HTMLElement anEmbed = embeds.namedItem (propertyName.string());
     if (!anEmbed.isNull()) {
-        Value v = getRuntimeObject(exec,anEmbed);
-       if (!v.isNull())
-           return v;
+       Value domValue = getDOMNode(exec,anEmbed);
+       ObjectImp *imp = static_cast<ObjectImp *>(domValue.imp());
+       if (!imp->forwardingScriptMessage()) {
+           Value v = getRuntimeObject(exec,anEmbed,getDOMNode(exec,anEmbed));
+           if (!v.isNull())
+               return v;
+       }
+    }
+
+    DOM::HTMLCollection objects = doc.objects();
+    DOM::HTMLElement anObject = objects.namedItem (propertyName.string());
+    if (!anObject.isNull()) {
+       Value domValue = getDOMNode(exec,anObject);
+       ObjectImp *imp = static_cast<ObjectImp *>(domValue.imp());
+       if (!imp->forwardingScriptMessage()) {
+           Value v = getRuntimeObject(exec,anObject,getDOMNode(exec,anObject));
+           if (!v.isNull())
+               return v;
+       }
     }
 #endif
 
@@ -1165,10 +1185,15 @@ Value KJS::HTMLElement::tryGet(ExecState *exec, const Identifier &propertyName)
       break;
 #if APPLE_CHANGES
     case ID_EMBED:
+    case ID_OBJECT:
     case ID_APPLET: {
-        Value v = getRuntimeObject(exec,element);
-       if (!v.isNull())
-           return v;
+       Value domValue = getDOMNode(exec,element);
+       ObjectImp *imp = static_cast<ObjectImp *>(domValue.imp());
+       if (!imp->forwardingScriptMessage()) { 
+           Value v = getRuntimeObject(exec,element,getDOMNode(exec,element));
+           if (!v.isNull())
+               return v;
+       }
     }
       break;
 #endif
@@ -3008,17 +3033,25 @@ Value KJS::HTMLCollection::tryGet(ExecState *exec, const Identifier &propertyNam
       DOM::Node node = collection.item(u);
 
 #if APPLE_CHANGES
-        if (!node.isNull() && (node.handle()->id() == ID_APPLET || node.handle()->id() == ID_EMBED)) {
-            Value v = getRuntimeObject(exec,node);
-           if (!v.isNull())
+       if (!node.isNull()) {
+           Value domValue = getDOMNode(exec,node);
+           ObjectImp *imp = static_cast<ObjectImp *>(domValue.imp());
+           if (!imp->forwardingScriptMessage() && 
+                    (node.handle()->id() == ID_APPLET || node.handle()->id() == ID_EMBED || node.handle()->id() == ID_OBJECT)) {
+             Value v = getRuntimeObject(exec, node, domValue);
+             if (!v.isNull())
                return v;
-        }
-#endif
+           }
+           return domValue;
+       }
+#else
       return getDOMNode(exec,node);
+#endif
     }
     else
       return getNamedItems(exec,propertyName);
   }
+  return Undefined();
 }
 
 // HTMLCollections are strange objects, they support both get and call,
@@ -3100,14 +3133,20 @@ Value KJS::HTMLCollection::getNamedItems(ExecState *exec, const Identifier &prop
   if (namedItems.count() == 1) {
     DOM::Node node = namedItems[0];
 #if APPLE_CHANGES
-    if (!node.isNull() && (node.handle()->id() == ID_APPLET || node.handle()->id() == ID_EMBED)) {
-      Value v = getRuntimeObject(exec, node);
-      if (!v.isNull())
-       return v;
+    if (!node.isNull()) {
+       Value domValue = getDOMNode(exec,node);
+       ObjectImp *imp = static_cast<ObjectImp *>(domValue.imp());
+       if (!imp->forwardingScriptMessage() && 
+                (node.handle()->id() == ID_APPLET || node.handle()->id() == ID_EMBED || node.handle()->id() == ID_OBJECT)) {
+         Value v = getRuntimeObject(exec, node, domValue);
+         if (!v.isNull())
+           return v;
+       }
+       return domValue;
     }
-#endif
-
+#else
     return getDOMNode(exec,node);
+#endif
   }
   
   return Value(new DOMNamedNodesCollection(exec,namedItems));
index 056181dc4adc0e6be44ff6c9c438bc77d9eb203e..406c9ebfcaf7a8110f2c86b6f6621b6579e746e5 100644 (file)
@@ -62,6 +62,8 @@
 #include "xml/dom_position.h"
 #include "html/html_documentimpl.h"
 
+#include "misc/htmltags.h"
+
 using DOM::DocumentImpl;
 using DOM::DOMString;
 using DOM::Node;
@@ -848,9 +850,21 @@ Value Window::get(ExecState *exec, const Identifier &p) const
   if (isSafeScript(exec) &&
       m_part->document().isHTMLDocument()) { // might be XML
     DOM::HTMLCollection coll = m_part->htmlDocument().all();
-    DOM::HTMLElement element = coll.namedItem(p.string());
+    DOM::HTMLElement element = coll.namedItem(p.string());    
     if (!element.isNull()) {
+#if APPLE_CHANGES
+       Value domValue = getDOMNode(exec,element);
+       ObjectImp *imp = static_cast<ObjectImp *>(domValue.imp());
+       if (!imp->forwardingScriptMessage() && 
+               (element.handle()->id() == ID_APPLET || element.handle()->id() == ID_EMBED || element.handle()->id() == ID_OBJECT)) {
+           Value v = getRuntimeObject(exec,element,domValue);
+           if (!v.isNull())
+               return v;
+       }
+       return domValue;
+#else
       return getDOMNode(exec,element);
+#endif
     }
   }
 
index 8eaf4f125d05d6dad5d932d24d7bd5b80b1ad440..5d1334bb4774f7190a65bf270eba6cc446f8730b 100644 (file)
@@ -168,6 +168,10 @@ NodeImpl *HTMLCollectionImpl::traverseNextItem(NodeImpl *current) const
                 if(e->id() == ID_EMBED)
                     found = true;
                 break;
+            case DOC_OBJECTS:   // all OBJECT elements
+                if(e->id() == ID_OBJECT)
+                    found = true;
+                break;
             case DOC_LINKS:     // all A _and_ AREA elements with a value for href
                 if(e->id() == ID_A || e->id() == ID_AREA)
                     if(!e->getAttribute(ATTR_HREF).isNull())
index 19c4d902a0f66c7f25773f683bb0f67f14d840d4..8ea8527b110b4bd15c040bde1ece5c2e2a4e722a 100644 (file)
@@ -54,7 +54,8 @@ public:
         // from HTMLDocument
         DOC_IMAGES = 0, // all IMG elements in the document
         DOC_APPLETS,   // all OBJECT and APPLET elements
-        DOC_EMBEDS,   // all EMBED elements
+        DOC_EMBEDS,    // all EMBED elements
+        DOC_OBJECTS,   // all OBJECT elements
         DOC_FORMS,     // all FORMS
         DOC_LINKS,     // all A _and_ AREA elements with a value for href
         DOC_ANCHORS,      // all A elements with a value for name
index d8bf5d9621948d3548f8a7ac84fec063e09ba59f..ccef41b8ef3f33d1a30ce44a127eac231e4dd6ab 100644 (file)
@@ -203,7 +203,7 @@ KJS::Bindings::Instance *HTMLAppletElementImpl::getAppletInstance() const
         r->createWidgetIfNecessary();
         if (r->widget()){
             // Call into the part (and over the bridge) to pull the Bindings::Instance
-            // from the guts of the Java VM.
+            // from the guts of the plugin.
             void *_view = r->widget()->getView();
             appletInstance = KWQ(part)->getAppletInstanceForView((NSView *)_view);
         }
@@ -362,7 +362,11 @@ bool HTMLEmbedElementImpl::isURLAttribute(AttributeImpl *attr) const
 // -------------------------------------------------------------------------
 
 HTMLObjectElementImpl::HTMLObjectElementImpl(DocumentPtr *doc) 
+#if APPLE_CHANGES
+: HTMLElementImpl(doc), m_imageLoader(0), objectInstance(0)
+#else
 : HTMLElementImpl(doc), m_imageLoader(0)
+#endif
 {
     needWidgetUpdate = false;
 }
@@ -377,6 +381,29 @@ NodeImpl::Id HTMLObjectElementImpl::id() const
     return ID_OBJECT;
 }
 
+#if APPLE_CHANGES
+KJS::Bindings::Instance *HTMLObjectElementImpl::getObjectInstance() const
+{
+    KHTMLPart* part = getDocument()->part();
+    if (!part)
+        return 0;
+
+    if (objectInstance)
+        return objectInstance;
+    
+    RenderPartObject *r = static_cast<RenderPartObject*>(m_render);
+    if (r) {
+        if (r->widget()){
+            // Call into the part (and over the bridge) to pull the Bindings::Instance
+            // from the guts of the plugin.
+            void *_view = r->widget()->getView();
+            objectInstance = KWQ(part)->getObjectInstanceForView((NSView *)_view);
+        }
+    }
+    return objectInstance;
+}
+#endif
+
 HTMLFormElementImpl *HTMLObjectElementImpl::form() const
 {
   return 0;
index 42b3ad5826cf93d7318ce06740620de33ab0f689..5d68536439bf6abc6b493a6f4d69893943ce8958 100644 (file)
@@ -136,11 +136,20 @@ public:
     
     virtual bool isURLAttribute(AttributeImpl *attr) const;
 
+#if APPLE_CHANGES
+    KJS::Bindings::Instance *getObjectInstance() const;
+#endif
+
     QString serviceType;
     QString url;
     QString classId;
     bool needWidgetUpdate;
     HTMLImageLoader* m_imageLoader;
+
+#if APPLE_CHANGES
+private:
+    mutable KJS::Bindings::Instance *objectInstance;
+#endif
 };
 
 // -------------------------------------------------------------------------
index 1c9589bbf324124f9d6a179174f9a7a24d4409f7..4ead66f4fbd3841f69b95d729a4c5de11e097de1 100644 (file)
@@ -783,6 +783,8 @@ void RenderPartObject::updateWidget()
               serviceType = "application/x-shockwave-flash";
           } else if (o->classId.contains("CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA")) {
               serviceType = "audio/x-pn-realaudio-plugin";
+          } else if (o->classId.contains("FDC7A535-4070-4B92-A0EA-D9994BCC0DC5")) {
+              serviceType = "audio/x-pn-realaudio-plugin";
           } else if (o->classId.contains("02BF25D5-8C17-4B23-BC80-D3488ABDDC6B")) {
               serviceType = "video/quicktime";
           } else if (o->classId.contains("166B1BCA-3F9C-11CF-8075-444553540000")) {
index 0c36688a866edb3352a942ef210bf47801902a2f..bbd32222fe2e276ae3f8cb1bcb05741cae83da8b 100644 (file)
@@ -319,6 +319,7 @@ public:
     bool haveToldBridgeAboutLoad(const QString &urlString);
 
     KJS::Bindings::Instance *getEmbedInstanceForView(NSView *aView);
+    KJS::Bindings::Instance *getObjectInstanceForView(NSView *aView);
     KJS::Bindings::Instance *getAppletInstanceForView(NSView *aView);
     void addPluginRootObject(const KJS::Bindings::RootObject *root);
     void cleanupPluginRootObjects();
index e2d6a38f9c9f3a22c071fe3ec3067e4222d4ffd0..bcb406239b7f6ada76f569b2ff4d797047c175bd 100644 (file)
@@ -3812,6 +3812,21 @@ KJS::Bindings::Instance *KWQKHTMLPart::getEmbedInstanceForView (NSView *aView)
     return 0;
 }
 
+KJS::Bindings::Instance *KWQKHTMLPart::getObjectInstanceForView (NSView *aView)
+{
+    if ([aView respondsToSelector:@selector(objectForWebScript)]){
+        id object = [aView objectForWebScript];
+        if (object)
+            return KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::ObjectiveCLanguage, object);
+    }
+    else if ([aView respondsToSelector:@selector(pluginScriptableObject)]){
+        void *object = [aView pluginScriptableObject];
+        if (object)
+            return KJS::Bindings::Instance::createBindingForLanguageInstance (KJS::Bindings::Instance::CLanguage, object);
+    }
+    return 0;
+}
+
 void KWQKHTMLPart::addPluginRootObject(const KJS::Bindings::RootObject *root)
 {
     rootObjects.append (root);