Index: khtml/khtml_ext.cpp =================================================================== RCS file: /home/kde/kdelibs/khtml/khtml_ext.cpp,v retrieving revision 1.45 diff -u -p -r1.45 khtml_ext.cpp --- khtml/khtml_ext.cpp 15 Mar 2002 22:53:08 -0000 1.45 +++ khtml/khtml_ext.cpp 4 Aug 2004 21:33:19 -0000 @@ -505,6 +505,19 @@ bool KHTMLPartBrowserHostExtension::open return m_part->openURLInFrame( url, urlArgs ); } +void KHTMLPartBrowserHostExtension::virtual_hook( int id, void *data ) +{ + if (id == VIRTUAL_FIND_FRAME_PARENT) + { + FindFrameParentParams *param = static_cast(data); + KHTMLPart *parentPart = m_part->findFrameParent(param->callingPart, param->frame); + if (parentPart) + param->parent = parentPart->browserHostExtension(); + return; + } + BrowserHostExtension::virtual_hook( id, data ); +} + KHTMLZoomFactorAction::KHTMLZoomFactorAction( KHTMLPart *part, bool direction, const QString &text, const QString &icon, const QObject *receiver, const char *slot, QObject *parent, const char *name ) : KAction( text, icon, 0, receiver, slot, parent, name ) { Index: khtml/khtml_ext.h =================================================================== RCS file: /home/kde/kdelibs/khtml/khtml_ext.h,v retrieving revision 1.18 diff -u -p -r1.18 khtml_ext.h --- khtml/khtml_ext.h 15 Mar 2002 22:53:08 -0000 1.18 +++ khtml/khtml_ext.h 4 Aug 2004 21:33:19 -0000 @@ -67,6 +67,9 @@ public: virtual const QPtrList frames() const; virtual bool openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs ); + +protected: + virtual void virtual_hook( int id, void* data ); private: KHTMLPart *m_part; }; Index: khtml/khtml_part.cpp =================================================================== RCS file: /home/kde/kdelibs/khtml/khtml_part.cpp,v retrieving revision 1.684.2.18 diff -u -p -r1.684.2.18 khtml_part.cpp --- khtml/khtml_part.cpp 3 Dec 2002 05:46:11 -0000 1.684.2.18 +++ khtml/khtml_part.cpp 4 Aug 2004 21:33:21 -0000 @@ -532,12 +532,16 @@ DOM::Document KHTMLPart::document() cons return d->m_doc; } - KParts::BrowserExtension *KHTMLPart::browserExtension() const { return d->m_extension; } +KParts::BrowserHostExtension *KHTMLPart::browserHostExtension() const +{ + return d->m_hostExtension; +} + KHTMLView *KHTMLPart::view() const { return d->m_view; @@ -754,7 +758,7 @@ void KHTMLPart::slotShowDocument( const } else if ( frameName != QString::fromLatin1( "_self" ) ) { - khtml::ChildFrame *_frame = recursiveFrameRequest( url, args ); + khtml::ChildFrame *_frame = recursiveFrameRequest( this, url, args ); if ( !_frame ) { @@ -2285,7 +2289,7 @@ void KHTMLPart::urlSelected( const QStri if ( hasTarget ) { // unknown frame names should open in a new window. - khtml::ChildFrame *frame = recursiveFrameRequest( cURL, args, false ); + khtml::ChildFrame *frame = recursiveFrameRequest( this, cURL, args, false ); if ( frame ) { args.metaData()["referrer"] = d->m_referrer; @@ -3104,6 +3108,7 @@ void KHTMLPart::slotChildCompleted( bool void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args ) { khtml::ChildFrame *child = frame( sender()->parent() ); + KHTMLPart *callingHtmlPart = const_cast(dynamic_cast(sender()->parent())); QString frameName = args.frameName.lower(); if ( !frameName.isEmpty() ) @@ -3128,7 +3133,7 @@ void KHTMLPart::slotChildURLRequest( con } else if ( frameName != QString::fromLatin1( "_self" ) ) { - khtml::ChildFrame *_frame = recursiveFrameRequest( url, args ); + khtml::ChildFrame *_frame = recursiveFrameRequest( callingHtmlPart, url, args ); if ( !_frame ) { @@ -3173,42 +3178,95 @@ khtml::ChildFrame *KHTMLPart::frame( con return 0L; } -KHTMLPart *KHTMLPart::findFrame( const QString &f ) +#undef DEBUG_FINDFRAME + +bool KHTMLPart::checkFrameAccess(KHTMLPart *callingHtmlPart) { -#if 0 - kdDebug() << "KHTMLPart::findFrame '" << f << "'" << endl; - FrameIt it2 = d->m_frames.begin(); - FrameIt end = d->m_frames.end(); - for (; it2 != end; ++it2 ) - kdDebug() << " - having frame '" << (*it2).m_name << "'" << endl; + if (callingHtmlPart == this) + return true; // trivial + + if (htmlDocument().isNull()) { +#ifdef DEBUG_FINDFRAME + kdDebug(6050) << "KHTMLPart::checkFrameAccess: Empty part " << this << " URL = " << m_url.prettyURL() << endl; #endif - // ### http://www.w3.org/TR/html4/appendix/notes.html#notes-frames - ConstFrameIt it = d->m_frames.find( f ); - if ( it == d->m_frames.end() ) + return false; // we are empty? + } + + // now compare the domains + if (callingHtmlPart && !callingHtmlPart->htmlDocument().isNull() && + !htmlDocument().isNull()) { + DOM::DOMString actDomain = callingHtmlPart->htmlDocument().domain(); + DOM::DOMString destDomain = htmlDocument().domain(); + +#ifdef DEBUG_FINDFRAME + kdDebug(6050) << "KHTMLPart::checkFrameAccess: actDomain = '" << actDomain.string() << "' destDomain = '" << destDomain.string() << "'" << endl; +#endif + + if (actDomain == destDomain) + return true; + } +#ifdef DEBUG_FINDFRAME + else { - //kdDebug() << "KHTMLPart::findFrame frame " << f << " not found" << endl; - return 0L; + kdDebug(6050) << "KHTMLPart::checkFrameAccess: Unknown part/domain " << callingHtmlPart << " tries to access part " << this << endl; } - else { +#endif + return false; +} + +KHTMLPart * +KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame ) +{ +#ifdef DEBUG_FINDFRAME + kdDebug(6050) << "KHTMLPart::findFrameParent: this = " << this << " URL = " << m_url.prettyURL() << " findFrameParent( " << f << " )" << endl; +#endif + // Check access + KHTMLPart *callingHtmlPart = dynamic_cast(callingPart); + + if (!checkFrameAccess(callingHtmlPart)) + return 0; + + FrameIt it = d->m_frames.find( f ); + FrameIt end = d->m_frames.end(); + if ( it != end ) + { +#ifdef DEBUG_FINDFRAME + kdDebug(6050) << "KHTMLPart::findFrameParent: FOUND!" << endl; +#endif + if (childFrame) + *childFrame = &(*it); + return this; + } + + it = d->m_frames.begin(); + for (; it != end; ++it ) + { KParts::ReadOnlyPart *p = (*it).m_part; if ( p && p->inherits( "KHTMLPart" )) { - //kdDebug() << "KHTMLPart::findFrame frame " << f << " is a KHTMLPart, ok" << endl; - return (KHTMLPart*)p; - } - else - { -#if 0 - if (p) - kdWarning() << "KHTMLPart::findFrame frame " << f << " found but isn't a KHTMLPart ! " << p->className() << endl; - else - kdWarning() << "KHTMLPart::findFrame frame " << f << " found but m_part=0L" << endl; -#endif - return 0L; + KHTMLPart *frameParent = static_cast(p)->findFrameParent(callingPart, f, childFrame); + if (frameParent) + return frameParent; } } + return 0; +} + + +KHTMLPart *KHTMLPart::findFrame( const QString &f ) +{ + khtml::ChildFrame *childFrame; + KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame); + if (parentFrame) + { + KParts::ReadOnlyPart *p = childFrame->m_part; + if ( p && p->inherits( "KHTMLPart" )) + return static_cast(p); + } + return 0; } + KParts::ReadOnlyPart *KHTMLPart::currentFrame() const { KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this); @@ -3244,37 +3302,29 @@ KHTMLPart *KHTMLPart::parentPart() return (KHTMLPart *)parent(); } -khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( const KURL &url, const KParts::URLArgs &args, - bool callParent ) +khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url, + const KParts::URLArgs &args, bool callParent ) { - FrameIt it = d->m_frames.find( args.frameName ); - - if ( it != d->m_frames.end() ) - return &(*it); - - it = d->m_frames.begin(); - FrameIt end = d->m_frames.end(); - for (; it != end; ++it ) - if ( (*it).m_part && (*it).m_part->inherits( "KHTMLPart" ) ) - { - KHTMLPart *childPart = (KHTMLPart *)(KParts::ReadOnlyPart *)(*it).m_part; - - khtml::ChildFrame *res = childPart->recursiveFrameRequest( url, args, false ); - if ( !res ) - continue; - - childPart->requestObject( res, url, args ); - return 0L; - } +#ifdef DEBUG_FINDFRAME + kdDebug( 6050 ) << "KHTMLPart::recursiveFrameRequest this = " << this << ", frame = " << args.frameName << ", url = " << url.prettyURL() << endl; +#endif + khtml::ChildFrame *childFrame; + KHTMLPart *childPart = findFrameParent(callingHtmlPart, args.frameName, &childFrame); + if (childPart) + { + if (childPart == this) + return childFrame; + + childPart->requestObject( childFrame, url, args ); + return 0; + } if ( parentPart() && callParent ) { - khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( url, args ); - - if ( res ) - parentPart()->requestObject( res, url, args ); + khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, callParent ); - return 0L; + if ( res ) + parentPart()->requestObject( res, url, args ); } return 0L; @@ -3282,7 +3332,7 @@ khtml::ChildFrame *KHTMLPart::recursiveF void KHTMLPart::saveState( QDataStream &stream ) { - kdDebug( 6050 ) << "KHTMLPart::saveState saving URL " << m_url.url() << endl; + kdDebug( 6050 ) << "KHTMLPart::saveState this = " << this << " saving URL " << m_url.url() << endl; stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY() << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight(); Index: khtml/khtml_part.h =================================================================== RCS file: /home/kde/kdelibs/khtml/khtml_part.h,v retrieving revision 1.186.2.2 diff -u -p -r1.186.2.2 khtml_part.h --- khtml/khtml_part.h 26 Sep 2002 09:09:29 -0000 1.186.2.2 +++ khtml/khtml_part.h 4 Aug 2004 21:33:22 -0000 @@ -233,6 +233,12 @@ public: KParts::BrowserExtension *browserExtension() const; /** + * @internal + * Returns a pointer to the @ref KParts::BrowserHostExtension + */ + KParts::BrowserHostExtension *browserHostExtension() const; + + /** * Returns a pointer to the HTML document's view. */ KHTMLView *view() const; @@ -640,6 +646,16 @@ public: KHTMLPart *findFrame( const QString &f ); /** + * @internal + * Recursively finds the part containing the frame with name @p f + * and checks if it is accessible by @p callingPart + * Returns 0L if no suitable frame can't be found. + * Returns parent part if a suitable frame was found and + * frame info in @p *childFrame + */ + KHTMLPart *findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame=0 ); + + /** * Return the current frame (the one that has focus) * Not necessarily a direct child of ours, framesets can be nested. * Returns "this" if this part isn't a frameset. @@ -1003,6 +1019,12 @@ private: * @internal */ bool openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs ); + + /** + * @internal + * Returns whether callingHtmlPart may access this part + */ + bool checkFrameAccess(KHTMLPart *callingHtmlPart); void startAutoScroll(); void stopAutoScroll(); @@ -1057,7 +1079,7 @@ private: DOM::DocumentImpl *xmlDocImpl() const; khtml::ChildFrame *frame( const QObject *obj ); - khtml::ChildFrame *recursiveFrameRequest( const KURL &url, const KParts::URLArgs &args, bool callParent = true ); + khtml::ChildFrame *recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url, const KParts::URLArgs &args, bool callParent = true ); bool checkLinkSecurity(const KURL &linkURL,const QString &message = QString::null, const QString &button = QString::null); QVariant executeScript(QString filename, int baseLine, const DOM::Node &n, const QString &script); Index: kparts/browserextension.cpp =================================================================== RCS file: /home/kde/kdelibs/kparts/browserextension.cpp,v retrieving revision 1.38.2.1 diff -u -p -r1.38.2.1 browserextension.cpp --- kparts/browserextension.cpp 29 Nov 2002 11:40:27 -0000 1.38.2.1 +++ kparts/browserextension.cpp 4 Aug 2004 21:33:22 -0000 @@ -571,6 +571,17 @@ BrowserHostExtension *BrowserHostExtensi void BrowserExtension::virtual_hook( int, void* ) { /*BASE::virtual_hook( id, data );*/ } +BrowserHostExtension * +BrowserHostExtension::findFrameParent(KParts::ReadOnlyPart *callingPart, const QString &frame) +{ + FindFrameParentParams param; + param.parent = 0; + param.callingPart = callingPart; + param.frame = frame; + virtual_hook(VIRTUAL_FIND_FRAME_PARENT, ¶m); + return param.parent; +} + void BrowserHostExtension::virtual_hook( int, void* ) { /*BASE::virtual_hook( id, data );*/ } Index: kparts/browserextension.h =================================================================== RCS file: /home/kde/kdelibs/kparts/browserextension.h,v retrieving revision 1.88 diff -u -p -r1.88 browserextension.h --- kparts/browserextension.h 15 Mar 2002 15:35:44 -0000 1.88 +++ kparts/browserextension.h 4 Aug 2004 21:33:22 -0000 @@ -577,10 +577,16 @@ public: * * Note that this method does not query the child objects recursively. */ - virtual const QPtrList frames() const; /** + * @internal + * Returns the part that contains @p frame and that may be accessed + * by @p callingPart + */ + BrowserHostExtension *findFrameParent(KParts::ReadOnlyPart *callingPart, const QString &frame); + + /** * Opens the given url in a hosted child frame. The frame name is specified in the * frameName variable in the urlArgs argument structure (see @ref KParts::URLArgs ) . */ @@ -593,6 +599,19 @@ public: static BrowserHostExtension *childObject( QObject *obj ); protected: + /** This 'enum' along with the structure below is NOT part of the public API. + * It's going to disappear in KDE 4.0 and is likely to change inbetween. + * + * @internal + */ + enum { VIRTUAL_FIND_FRAME_PARENT = 0x10 }; + struct FindFrameParentParams + { + BrowserHostExtension *parent; + KParts::ReadOnlyPart *callingPart; + QString frame; + }; + virtual void virtual_hook( int id, void* data ); private: class BrowserHostExtensionPrivate;