Patch: Delayed url check for EMBED/APPLET/OBJECT elements

Koos Vriezen koos.vriezen at xs4all.nl
Fri Sep 5 14:49:13 BST 2003


Hi,

Attached a patch that delays the url check from HTML*Impl::attach() to
RenderPartObject::updateWidget(). The reason is that attach() is called
before any PARAM tags are attached, so urls declared like

 <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" WIDTH="80"
 HEIGHT="80" ALIGN="left">
 <PARAM NAME="type" VALUE="application/x-java-applet;version=1.3">
 <PARAM NAME="archive" VALUE="myappletarchive.jar">
 <PARAM NAME="code" VALUE="MyClass.class">
 </OBJECT>

(MyClass.class) cannot be checked this way.
This patch also cleans up the almost similar HTML*Impl::attach()
implementations.

Please review.

Koos
-------------- next part --------------
Index: html/html_objectimpl.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_objectimpl.h,v
retrieving revision 1.54
diff -u -3 -p -r1.54 html_objectimpl.h
--- html/html_objectimpl.h	30 Apr 2003 10:51:19 -0000	1.54
+++ html/html_objectimpl.h	5 Sep 2003 13:34:18 -0000
@@ -44,10 +44,13 @@ public:
     HTMLObjectBaseElementImpl(DocumentPtr *doc);
 
     virtual void parseAttribute(AttributeImpl *attr);
+    virtual void attach();
     virtual void detach();
 
     virtual void recalcStyle( StyleChange ch );
 
+    void renderAlternative();
+
     bool get(const unsigned long, const QString &, KParts::LiveConnectExtension::Type &, unsigned long &, QString &);
     bool put(const unsigned long, const QString &, const QString &);
     bool call(const unsigned long, const QString &, const QStringList &, KParts::LiveConnectExtension::Type &, unsigned long &, QString &);
@@ -60,6 +63,7 @@ public:
     QString classId;
     QString serviceType;
     bool needWidgetUpdate;
+    bool m_renderAlternative;
 
 protected slots:
     void liveConnectEvent(const unsigned long, const QString&, const KParts::LiveConnectExtension::ArgList&);
@@ -119,13 +123,8 @@ public:
     virtual void parseAttribute(AttributeImpl *token);
 
     virtual void attach();
-    virtual void detach();
 
     DocumentImpl* contentDocument() const;
-
-    void renderAlternative();
-
-    bool m_renderAlternative;
 };
 
 // -------------------------------------------------------------------------
Index: html/html_objectimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_objectimpl.cpp,v
retrieving revision 1.113
diff -u -3 -p -r1.113 html_objectimpl.cpp
--- html/html_objectimpl.cpp	8 Aug 2003 09:24:43 -0000	1.113
+++ html/html_objectimpl.cpp	5 Sep 2003 13:34:18 -0000
@@ -50,6 +50,7 @@ HTMLObjectBaseElementImpl::HTMLObjectBas
     : HTMLElementImpl(doc), liveconnect(0L)
 {
     needWidgetUpdate = false;
+    m_renderAlternative = false;
 }
 
 void HTMLObjectBaseElementImpl::setServiceType(const QString & val) {
@@ -96,6 +97,20 @@ void HTMLObjectBaseElementImpl::recalcSt
     HTMLElementImpl::recalcStyle( ch );
 }
 
+void HTMLObjectBaseElementImpl::renderAlternative()
+{
+    // an unbelievable hack. FIXME!!
+
+    if ( m_renderAlternative ) return;
+
+    if ( attached() )
+        detach();
+
+    m_renderAlternative = true;
+
+    attach();
+}
+
 bool HTMLObjectBaseElementImpl::get(const unsigned long objid, const QString & field, KParts::LiveConnectExtension::Type & type, unsigned long & retobjid, QString & value) {
     if (!liveconnect)
         return false;
@@ -153,9 +168,56 @@ void HTMLObjectBaseElementImpl::liveConn
 	w->part()->executeScript(this, script);
 }
 
+void HTMLObjectBaseElementImpl::attach() {
+    assert(!attached());
+    assert(!m_render);
+
+    if (m_renderAlternative) {
+        // render alternative content
+        ElementImpl::attach();
+        return;
+    }
+
+    if (!parentNode()->renderer()) {
+        NodeBaseImpl::attach();
+        return;
+    }
+
+    RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
+    _style->ref();
+
+    if (parentNode()->renderer() && _style->display() != NONE) 
+    {
+        needWidgetUpdate = false;
+        bool imagelike = serviceType.startsWith("image/");
+        if (imagelike) {
+            m_render = new (getDocument()->renderArena()) RenderImage(this);
+            // make sure we don't attach the inner contents
+            addCSSProperty(CSS_PROP_DISPLAY, CSS_VAL_NONE);
+        }
+        else
+            m_render = new (getDocument()->renderArena())RenderPartObject(this);
+
+        m_render->setStyle(_style);
+        parentNode()->renderer()->addChild(m_render, nextRenderer());
+        if (imagelike)
+            m_render->updateFromElement();
+    }
+
+    _style->deref();
+    NodeBaseImpl::attach();
+
+    // ### do this when we are actually finished loading instead
+    if (m_render) dispatchHTMLEvent(EventImpl::LOAD_EVENT, false, false);
+}
+
 void HTMLObjectBaseElementImpl::detach() {
     setLiveConnect(0L);
 
+    if (attached())
+        // ### do this when we are actualy removed from document instead
+        dispatchHTMLEvent(EventImpl::UNLOAD_EVENT,false,false);
+
     HTMLElementImpl::detach();
 }
 
@@ -199,43 +261,22 @@ void HTMLAppletElementImpl::parseAttribu
 
 void HTMLAppletElementImpl::attach()
 {
-    assert(!attached());
-    assert(!m_render);
-
     KHTMLView* w = getDocument()->view();
 
-    if (!parentNode()->renderer() || getAttribute(ATTR_CODE).isNull()) {
-        NodeBaseImpl::attach();
-        return;
-    }
-
-    RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
-    _style->ref();
-
 #ifndef Q_WS_QWS // FIXME?
-    KURL url = getDocument()->baseURL();
     DOMString codeBase = getAttribute( ATTR_CODEBASE );
     DOMString code = getAttribute( ATTR_CODE );
     if ( !codeBase.isEmpty() )
-        url = KURL( url, codeBase.string() );
+        url = codeBase.string();
     if ( !code.isEmpty() )
-        url = KURL( url, code.string() );
+        url = code.string();
 
-    if (w && w->part()->javaEnabled() &&
-        getDocument()->isURLAllowed( url.url() ) &&
-        parentNode()->renderer() && 
-        _style->display() != NONE) 
-    {
-        needWidgetUpdate=false;
-        m_render = new (getDocument()->renderArena()) RenderPartObject(this);
+    if (!w || !w->part()->javaEnabled())
+#endif
+        m_renderAlternative = true;
 
-        m_render->setStyle(_style);
-        parentNode()->renderer()->addChild(m_render, nextRenderer());
-    }
+    HTMLObjectBaseElementImpl::attach();
 
-#endif
-    _style->deref();
-    NodeBaseImpl::attach();
 }
 
 // -------------------------------------------------------------------------
@@ -305,25 +346,12 @@ void HTMLEmbedElementImpl::parseAttribut
 
 void HTMLEmbedElementImpl::attach()
 {
-    assert(!attached());
-    assert(!m_render);
+    KHTMLView* w = getDocument()->view();
 
-    if (parentNode()->renderer()) {
-        KHTMLView* w = getDocument()->view();
-        RenderStyle* _style = getDocument()->styleSelector()->styleForElement( this );
-        _style->ref();
-
-        if (w && w->part()->pluginsEnabled() && getDocument()->isURLAllowed( url ) &&
-            parentNode()->id() != ID_OBJECT && _style->display() != NONE ) {
-            needWidgetUpdate=false;
-            m_render = new (getDocument()->renderArena()) RenderPartObject(this);
-            m_render->setStyle(_style );
-            parentNode()->renderer()->addChild(m_render, nextRenderer());
-        }
-        _style->deref();
-    }
+    if (!w || !w->part()->pluginsEnabled())
+        m_renderAlternative = true;
 
-    NodeBaseImpl::attach();
+    HTMLObjectBaseElementImpl::attach();
 }
 
 // -------------------------------------------------------------------------
@@ -331,7 +359,6 @@ void HTMLEmbedElementImpl::attach()
 HTMLObjectElementImpl::HTMLObjectElementImpl(DocumentPtr *doc)
     : HTMLObjectBaseElementImpl(doc)
 {
-    m_renderAlternative = false;
 }
 
 HTMLObjectElementImpl::~HTMLObjectElementImpl()
@@ -387,67 +414,12 @@ DocumentImpl* HTMLObjectElementImpl::con
 
 void HTMLObjectElementImpl::attach()
 {
-    assert(!attached());
-    assert(!m_render);
-
     KHTMLView* w = getDocument()->view();
-    if ( !w || !w->part()->pluginsEnabled() ||
-         ( url.isEmpty() && classId.isEmpty() && id() != ID_APPLET) ||
-         m_renderAlternative || !getDocument()->isURLAllowed( url ) ) {
-        // render alternative content
-        ElementImpl::attach();
-        return;
-    }
-
-    RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
-    _style->ref();
-
-    if (parentNode()->renderer() && _style->display() != NONE) {
-        needWidgetUpdate=false;
-        bool imagelike = serviceType.startsWith("image/");
-        if (imagelike) {
-            m_render = new (getDocument()->renderArena()) RenderImage(this);
-            // make sure we don't attach the inner contents
-            addCSSProperty(CSS_PROP_DISPLAY, CSS_VAL_NONE);
-        }
-        else
-            m_render = new (getDocument()->renderArena()) RenderPartObject(this);
-
-        m_render->setStyle(_style);
-        parentNode()->renderer()->addChild(m_render, nextRenderer());
-        if (imagelike)
-            m_render->updateFromElement();
-    }
-
-    _style->deref();
-
-    NodeBaseImpl::attach();
-
-    // ### do this when we are actually finished loading instead
-    if (m_render)  dispatchHTMLEvent(EventImpl::LOAD_EVENT,false,false);
-}
-
-void HTMLObjectElementImpl::detach()
-{
-    if (attached())
-        // ### do this when we are actualy removed from document instead
-        dispatchHTMLEvent(EventImpl::UNLOAD_EVENT,false,false);
-
-    HTMLObjectBaseElementImpl::detach();
-}
-
-void HTMLObjectElementImpl::renderAlternative()
-{
-    // an unbelievable hack. FIXME!!
-
-    if ( m_renderAlternative ) return;
-
-    if ( attached() )
-        detach();
 
-    m_renderAlternative = true;
+    if (!w || !w->part()->pluginsEnabled())
+        m_renderAlternative = true;
 
-    attach();
+    HTMLObjectBaseElementImpl::attach();
 }
 
 // -------------------------------------------------------------------------
Index: rendering/render_frames.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_frames.cpp,v
retrieving revision 1.161
diff -u -3 -p -r1.161 render_frames.cpp
--- rendering/render_frames.cpp	28 Aug 2003 13:06:26 -0000	1.161
+++ rendering/render_frames.cpp	5 Sep 2003 13:34:19 -0000
@@ -604,6 +604,7 @@ void RenderPartObject::updateWidget()
   if (element()->id() == ID_OBJECT || element()->id() == ID_EMBED || element()->id() == ID_APPLET) {
 
       objbase = static_cast<HTMLObjectBaseElementImpl *>(element());
+      url = objbase->url;
 
       for (NodeImpl* child = element()->firstChild(); child; child=child->nextSibling()) {
           if ( child->id() == ID_PARAM ) {
@@ -613,8 +614,15 @@ void RenderPartObject::updateWidget()
               aStr += QString::fromLatin1("=\"");
               aStr += p->value();
               aStr += QString::fromLatin1("\"");
-              if (p->name().lower() == QString::fromLatin1("type"))
+              QString name_lower = p->name().lower();
+              if (name_lower == QString::fromLatin1("type")) {
                   objbase->setServiceType(p->value());
+              } else if (url.isEmpty() &&
+                         (name_lower == QString::fromLatin1("src") ||
+                          name_lower == QString::fromLatin1("movie") ||
+                          name_lower == QString::fromLatin1("code"))) {
+                  url = p->value();
+              }
               params.append(aStr);
           }
       }
@@ -631,6 +639,11 @@ void RenderPartObject::updateWidget()
               }
           }
       }
+      if (url.isEmpty() || !objbase->getDocument()->isURLAllowed(url)) {
+          // not a valid url
+          objbase->renderAlternative();
+          return;
+      }
   }
 
   if(element()->id() == ID_OBJECT || element()->id() == ID_APPLET) {
@@ -652,13 +665,11 @@ void RenderPartObject::updateWidget()
 
       if ( !embed )
       {
-          url = objbase->url;
           serviceType = objbase->serviceType;
           if(serviceType.isEmpty() && !objbase->classId.isEmpty()) {
 
               // We have a clsid, means this is activex (Niko)
               serviceType = "application/x-activex-handler";
-              url = "dummy"; // Not needed, but KHTMLPart aborts the request if empty
 
               if(objbase->classId.contains(QString::fromLatin1("D27CDB6E-AE6D-11cf-96B8-444553540000"))) {
                   // It is ActiveX, but the nsplugin system handling
@@ -678,32 +689,6 @@ void RenderPartObject::updateWidget()
               // TODO: add more plugins here
           }
 
-          if((url.isEmpty() || url.isNull())) {
-              // look for a SRC attribute in the params
-              NodeImpl *child = objbase->firstChild();
-              while ( child ) {
-                  if ( child->id() == ID_PARAM ) {
-                      HTMLParamElementImpl *p = static_cast<HTMLParamElementImpl *>( child );
-
-                      if ( p->name().lower()==QString::fromLatin1("src") ||
-                           p->name().lower()==QString::fromLatin1("movie") ||
-                           p->name().lower()==QString::fromLatin1("code") )
-                      {
-                          url = p->value();
-                          break;
-                      }
-                  }
-                  child = child->nextSibling();
-              }
-          }
-
-
-          if ( url.isEmpty() && serviceType.isEmpty() ) {
-#ifdef DEBUG_LAYOUT
-              kdDebug(6031) << "RenderPartObject::close - empty url and serviceType" << endl;
-#endif
-              return;
-          }
           part->requestObject( this, url, serviceType, params );
       }
       else {
@@ -723,7 +708,6 @@ void RenderPartObject::updateWidget()
   }
   else if ( element()->id() == ID_EMBED ) {
 
-      url = objbase->url;
       serviceType = objbase->serviceType;
 
       if ( url.isEmpty() && serviceType.isEmpty() ) {
@@ -847,8 +831,9 @@ void RenderPartObject::slotPartLoadingEr
     }
 
     // didn't work, render alternative content.
-    if ( element() && element()->id() == ID_OBJECT )
-        static_cast<HTMLObjectElementImpl*>( element() )->renderAlternative();
+    if ( element() && (
+         element()->id() == ID_OBJECT || element()->id() == ID_EMBED || element()->id() == ID_APPLET))
+        static_cast<HTMLObjectBaseElementImpl*>( element() )->renderAlternative();
 }
 
 void RenderPartObject::layout( )


More information about the kfm-devel mailing list