00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "khtml_part.h"
00032
00033 #include "khtml_pagecache.h"
00034
00035 #include "dom/dom_string.h"
00036 #include "dom/dom_element.h"
00037 #include "dom/dom_exception.h"
00038 #include "html/html_documentimpl.h"
00039 #include "html/html_baseimpl.h"
00040 #include "html/html_objectimpl.h"
00041 #include "html/html_miscimpl.h"
00042 #include "html/html_imageimpl.h"
00043 #include "html/html_objectimpl.h"
00044 #include "rendering/render_text.h"
00045 #include "rendering/render_frames.h"
00046 #include "rendering/render_layer.h"
00047 #include "misc/htmlhashes.h"
00048 #include "misc/loader.h"
00049 #include "xml/dom2_eventsimpl.h"
00050 #include "xml/dom2_rangeimpl.h"
00051 #include "xml/xml_tokenizer.h"
00052 #include "css/cssstyleselector.h"
00053 #include "css/csshelper.h"
00054 using namespace DOM;
00055
00056 #include "khtmlview.h"
00057 #include <kparts/partmanager.h>
00058 #include "ecma/kjs_proxy.h"
00059 #include "khtml_settings.h"
00060 #include "kjserrordlg.h"
00061
00062 #include <kjs/function.h>
00063 #include <kjs/interpreter.h>
00064
00065 #include "htmlpageinfo.h"
00066
00067 #include <sys/types.h>
00068 #include <assert.h>
00069 #include <unistd.h>
00070
00071 #include <config.h>
00072
00073 #include <dcopclient.h>
00074 #include <dcopref.h>
00075 #include <kstandarddirs.h>
00076 #include <kstringhandler.h>
00077 #include <kio/job.h>
00078 #include <kio/global.h>
00079 #include <kio/netaccess.h>
00080 #include <kprotocolmanager.h>
00081 #include <kdebug.h>
00082 #include <kiconloader.h>
00083 #include <klocale.h>
00084 #include <kcharsets.h>
00085 #include <kmessagebox.h>
00086 #include <kstdaction.h>
00087 #include <kfiledialog.h>
00088 #include <ktrader.h>
00089 #include <kdatastream.h>
00090 #include <ktempfile.h>
00091 #include <kglobalsettings.h>
00092 #include <kurldrag.h>
00093 #include <kapplication.h>
00094 #include <kparts/browserinterface.h>
00095 #if !defined(QT_NO_DRAGANDDROP)
00096 #include <kmultipledrag.h>
00097 #endif
00098 #include "../kutils/kfinddialog.h"
00099 #include "../kutils/kfind.h"
00100
00101 #include <ksslcertchain.h>
00102 #include <ksslinfodlg.h>
00103
00104 #include <kfileitem.h>
00105 #include <kurifilter.h>
00106 #include <kstatusbar.h>
00107 #include <kurllabel.h>
00108
00109 #include <qclipboard.h>
00110 #include <qfile.h>
00111 #include <qtooltip.h>
00112 #include <qmetaobject.h>
00113 #include <private/qucomextra_p.h>
00114
00115 #include "khtmlpart_p.h"
00116 #include "kpopupmenu.h"
00117 #include "rendering/render_form.h"
00118 #include <kwin.h>
00119
00120 #define HINT_UTF8 106
00121
00122 namespace khtml {
00123 class PartStyleSheetLoader : public CachedObjectClient
00124 {
00125 public:
00126 PartStyleSheetLoader(KHTMLPart *part, DOM::DOMString url, DocLoader* dl)
00127 {
00128 m_part = part;
00129 m_cachedSheet = dl->requestStyleSheet(url, QString::null, "text/css",
00130 true );
00131 if (m_cachedSheet)
00132 m_cachedSheet->ref( this );
00133 }
00134 virtual ~PartStyleSheetLoader()
00135 {
00136 if ( m_cachedSheet ) m_cachedSheet->deref(this);
00137 }
00138 virtual void setStyleSheet(const DOM::DOMString&, const DOM::DOMString &sheet)
00139 {
00140 if ( m_part )
00141 m_part->setUserStyleSheet( sheet.string() );
00142
00143 delete this;
00144 }
00145 virtual void error( int, const QString& ) {
00146 delete this;
00147 }
00148 QGuardedPtr<KHTMLPart> m_part;
00149 khtml::CachedCSSStyleSheet *m_cachedSheet;
00150 };
00151 }
00152
00153 void khtml::ChildFrame::liveConnectEvent(const unsigned long, const QString & event, const KParts::LiveConnectExtension::ArgList & args)
00154 {
00155 if (!m_part || !m_frame || !m_liveconnect)
00156
00157 return;
00158
00159 QString script;
00160 script.sprintf("%s(", event.latin1());
00161
00162 KParts::LiveConnectExtension::ArgList::const_iterator i = args.begin();
00163 const KParts::LiveConnectExtension::ArgList::const_iterator argsBegin = i;
00164 const KParts::LiveConnectExtension::ArgList::const_iterator argsEnd = args.end();
00165
00166 for ( ; i != argsEnd; ++i) {
00167 if (i != argsBegin)
00168 script += ",";
00169 if ((*i).first == KParts::LiveConnectExtension::TypeString) {
00170 script += "\"";
00171 script += QString((*i).second).replace('\\', "\\\\").replace('"', "\\\"");
00172 script += "\"";
00173 } else
00174 script += (*i).second;
00175 }
00176 script += ")";
00177 kdDebug(6050) << "khtml::ChildFrame::liveConnectEvent " << script << endl;
00178
00179 KHTMLPart * part = ::qt_cast<KHTMLPart *>(m_part->parent());
00180 if (!part)
00181 return;
00182 if (!m_jscript)
00183 part->framejScript(m_part);
00184 if (m_jscript) {
00185
00186 KJS::Completion cmp;
00187 m_jscript->evaluate(QString::null, 1, script, 0L, &cmp);
00188 } else
00189 part->executeScript(m_frame->element(), script);
00190 }
00191
00192 KHTMLFrameList::Iterator KHTMLFrameList::find( const QString &name )
00193 {
00194 Iterator it = begin();
00195 const Iterator e = end();
00196
00197 for (; it!=e; ++it )
00198 if ( (*it)->m_name==name )
00199 break;
00200
00201 return it;
00202 }
00203
00204 KHTMLPart::KHTMLPart( QWidget *parentWidget, const char *widgetname, QObject *parent, const char *name, GUIProfile prof )
00205 : KParts::ReadOnlyPart( parent, name )
00206 {
00207 d = 0;
00208 KHTMLFactory::registerPart( this );
00209 setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
00210
00211
00212 init( new KHTMLView( this, parentWidget, widgetname ), prof );
00213 }
00214
00215 KHTMLPart::KHTMLPart( KHTMLView *view, QObject *parent, const char *name, GUIProfile prof )
00216 : KParts::ReadOnlyPart( parent, name )
00217 {
00218 d = 0;
00219 KHTMLFactory::registerPart( this );
00220 setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
00221
00222
00223 assert( view );
00224 init( view, prof );
00225 }
00226
00227 void KHTMLPart::init( KHTMLView *view, GUIProfile prof )
00228 {
00229 if ( prof == DefaultGUI )
00230 setXMLFile( "khtml.rc" );
00231 else if ( prof == BrowserViewGUI )
00232 setXMLFile( "khtml_browser.rc" );
00233
00234 d = new KHTMLPartPrivate(parent());
00235
00236 d->m_view = view;
00237 setWidget( d->m_view );
00238
00239 d->m_guiProfile = prof;
00240 d->m_extension = new KHTMLPartBrowserExtension( this, "KHTMLBrowserExtension" );
00241 d->m_hostExtension = new KHTMLPartBrowserHostExtension( this );
00242 d->m_statusBarExtension = new KParts::StatusBarExtension( this );
00243 d->m_statusBarIconLabel = 0L;
00244 d->m_statusBarPopupLabel = 0L;
00245
00246 d->m_bSecurityInQuestion = false;
00247 d->m_paLoadImages = 0;
00248 d->m_paDebugScript = 0;
00249 d->m_bMousePressed = false;
00250 d->m_bRightMousePressed = false;
00251 d->m_paViewDocument = new KAction( i18n( "View Do&cument Source" ), CTRL + Key_U, this, SLOT( slotViewDocumentSource() ), actionCollection(), "viewDocumentSource" );
00252 d->m_paViewFrame = new KAction( i18n( "View Frame Source" ), 0, this, SLOT( slotViewFrameSource() ), actionCollection(), "viewFrameSource" );
00253 d->m_paViewInfo = new KAction( i18n( "View Document Information" ), CTRL+Key_I, this, SLOT( slotViewPageInfo() ), actionCollection(), "viewPageInfo" );
00254 d->m_paSaveBackground = new KAction( i18n( "Save &Background Image As..." ), 0, this, SLOT( slotSaveBackground() ), actionCollection(), "saveBackground" );
00255 d->m_paSaveDocument = KStdAction::saveAs( this, SLOT( slotSaveDocument() ), actionCollection(), "saveDocument" );
00256 if ( parentPart() )
00257 d->m_paSaveDocument->setShortcut( KShortcut() );
00258 d->m_paSaveFrame = new KAction( i18n( "Save &Frame As..." ), 0, this, SLOT( slotSaveFrame() ), actionCollection(), "saveFrame" );
00259 d->m_paSecurity = new KAction( i18n( "Security..." ), "decrypted", 0, this, SLOT( slotSecurity() ), actionCollection(), "security" );
00260 d->m_paSecurity->setWhatsThis( i18n( "Security Settings<p>"
00261 "Shows the certificate of the displayed page. Only "
00262 "pages that have been transmitted using a secure, encrypted connection have a "
00263 "certificate.<p> "
00264 "Hint: If the image shows a closed lock, the page has been transmitted over a "
00265 "secure connection.") );
00266 d->m_paDebugRenderTree = new KAction( i18n( "Print Rendering Tree to STDOUT" ), 0, this, SLOT( slotDebugRenderTree() ), actionCollection(), "debugRenderTree" );
00267 d->m_paDebugDOMTree = new KAction( i18n( "Print DOM Tree to STDOUT" ), 0, this, SLOT( slotDebugDOMTree() ), actionCollection(), "debugDOMTree" );
00268 d->m_paStopAnimations = new KAction( i18n( "Stop Animated Images" ), 0, this, SLOT( slotStopAnimations() ), actionCollection(), "stopAnimations" );
00269
00270 d->m_paSetEncoding = new KActionMenu( i18n( "Set &Encoding" ), "charset", actionCollection(), "setEncoding" );
00271 d->m_paSetEncoding->setDelayed( false );
00272
00273 d->m_automaticDetection = new KPopupMenu( 0L );
00274
00275 d->m_automaticDetection->insertItem( i18n( "Semi-Automatic" ), 0 );
00276 d->m_automaticDetection->insertItem( i18n( "Arabic" ), 1 );
00277 d->m_automaticDetection->insertItem( i18n( "Baltic" ), 2 );
00278 d->m_automaticDetection->insertItem( i18n( "Central European" ), 3 );
00279
00280 d->m_automaticDetection->insertItem( i18n( "Greek" ), 5 );
00281 d->m_automaticDetection->insertItem( i18n( "Hebrew" ), 6 );
00282 d->m_automaticDetection->insertItem( i18n( "Japanese" ), 7 );
00283
00284 d->m_automaticDetection->insertItem( i18n( "Russian" ), 9 );
00285
00286 d->m_automaticDetection->insertItem( i18n( "Turkish" ), 11 );
00287 d->m_automaticDetection->insertItem( i18n( "Ukrainian" ), 12 );
00288
00289 d->m_automaticDetection->insertItem( i18n( "Western European" ), 14 );
00290
00291 connect( d->m_automaticDetection, SIGNAL( activated( int ) ), this, SLOT( slotAutomaticDetectionLanguage( int ) ) );
00292
00293 d->m_paSetEncoding->popupMenu()->insertItem( i18n( "Automatic Detection" ), d->m_automaticDetection, 0 );
00294
00295 d->m_paSetEncoding->insert( new KActionSeparator( actionCollection() ) );
00296
00297
00298 d->m_manualDetection = new KSelectAction( i18n( "short for Manual Detection", "Manual" ), 0, this, SLOT( slotSetEncoding() ), actionCollection(), "manualDetection" );
00299 QStringList encodings = KGlobal::charsets()->descriptiveEncodingNames();
00300 d->m_manualDetection->setItems( encodings );
00301 d->m_manualDetection->setCurrentItem( -1 );
00302 d->m_paSetEncoding->insert( d->m_manualDetection );
00303
00304
00305 KConfig *config = KGlobal::config();
00306 if ( config->hasGroup( "HTML Settings" ) ) {
00307 config->setGroup( "HTML Settings" );
00308 khtml::Decoder::AutoDetectLanguage language;
00309 QCString name = QTextCodec::codecForLocale()->name();
00310 name = name.lower();
00311
00312 if ( name == "cp1256" || name == "iso-8859-6" ) {
00313 language = khtml::Decoder::Arabic;
00314 }
00315 else if ( name == "cp1257" || name == "iso-8859-13" || name == "iso-8859-4" ) {
00316 language = khtml::Decoder::Baltic;
00317 }
00318 else if ( name == "cp1250" || name == "ibm852" || name == "iso-8859-2" || name == "iso-8859-3" ) {
00319 language = khtml::Decoder::CentralEuropean;
00320 }
00321 else if ( name == "cp1251" || name == "koi8-r" || name == "iso-8859-5" ) {
00322 language = khtml::Decoder::Russian;
00323 }
00324 else if ( name == "koi8-u" ) {
00325 language = khtml::Decoder::Ukrainian;
00326 }
00327 else if ( name == "cp1253" || name == "iso-8859-7" ) {
00328 language = khtml::Decoder::Greek;
00329 }
00330 else if ( name == "cp1255" || name == "iso-8859-8" || name == "iso-8859-8-i" ) {
00331 language = khtml::Decoder::Hebrew;
00332 }
00333 else if ( name == "jis7" || name == "eucjp" || name == "sjis" ) {
00334 language = khtml::Decoder::Japanese;
00335 }
00336 else if ( name == "cp1254" || name == "iso-8859-9" ) {
00337 language = khtml::Decoder::Turkish;
00338 }
00339 else if ( name == "cp1252" || name == "iso-8859-1" || name == "iso-8859-15" ) {
00340 language = khtml::Decoder::WesternEuropean;
00341 }
00342 else
00343 language = khtml::Decoder::SemiautomaticDetection;
00344
00345 int _id = config->readNumEntry( "AutomaticDetectionLanguage", language );
00346 d->m_automaticDetection->setItemChecked( _id, true );
00347 d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );
00348
00349 d->m_autoDetectLanguage = static_cast< khtml::Decoder::AutoDetectLanguage >( _id );
00350 }
00351
00352
00353 d->m_paUseStylesheet = new KSelectAction( i18n( "Use S&tylesheet"), 0, this, SLOT( slotUseStylesheet() ), actionCollection(), "useStylesheet" );
00354
00355 if ( prof == BrowserViewGUI ) {
00356 d->m_paIncZoomFactor = new KHTMLZoomFactorAction( this, true, i18n(
00357 "Enlarge Font" ), "viewmag+", "CTRL++;CTRL+=", this,
00358 SLOT( slotIncZoomFast() ), actionCollection(), "incFontSizes" );
00359 d->m_paIncZoomFactor->setWhatsThis( i18n( "Enlarge Font<p>"
00360 "Make the font in this window bigger. "
00361 "Click and hold down the mouse button for a menu with all available font sizes." ) );
00362 d->m_paDecZoomFactor = new KHTMLZoomFactorAction( this, false, i18n(
00363 "Shrink Font" ), "viewmag-", CTRL + Key_Minus, this,
00364 SLOT( slotDecZoomFast() ), actionCollection(), "decFontSizes" );
00365 d->m_paDecZoomFactor->setWhatsThis( i18n( "Shrink Font<p>"
00366 "Make the font in this window smaller. "
00367 "Click and hold down the mouse button for a menu with all available font sizes." ) );
00368 }
00369
00370 d->m_paFind = KStdAction::find( this, SLOT( slotFind() ), actionCollection(), "find" );
00371 d->m_paFind->setWhatsThis( i18n( "Find text<p>"
00372 "Shows a dialog that allows you to find text on the displayed page." ) );
00373
00374 d->m_paFindNext = KStdAction::findNext( this, SLOT( slotFindNext() ), actionCollection(), "findNext" );
00375 d->m_paFindNext->setWhatsThis( i18n( "Find next<p>"
00376 "Find the next occurrence of the text that you "
00377 "have found using the <b>Find Text</b> function" ) );
00378 if ( parentPart() )
00379 {
00380 d->m_paFind->setShortcut( KShortcut() );
00381 d->m_paFindNext->setShortcut( KShortcut() );
00382 }
00383
00384 d->m_paPrintFrame = new KAction( i18n( "Print Frame..." ), "frameprint", 0, this, SLOT( slotPrintFrame() ), actionCollection(), "printFrame" );
00385 d->m_paPrintFrame->setWhatsThis( i18n( "Print Frame<p>"
00386 "Some pages have several frames. To print only a single frame, click "
00387 "on it and then use this function." ) );
00388
00389 d->m_paSelectAll = KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection(), "selectAll" );
00390 if ( parentPart() )
00391 d->m_paSelectAll->setShortcut( KShortcut() );
00392
00393 d->m_paToggleCaretMode = new KToggleAction(i18n("Toggle Caret Mode"),
00394 Key_F7, this, SLOT(slotToggleCaretMode()),
00395 actionCollection(), "caretMode");
00396 d->m_paToggleCaretMode->setChecked(isCaretMode());
00397 if (parentPart())
00398 d->m_paToggleCaretMode->setShortcut(KShortcut());
00399
00400
00401 d->m_bOpenMiddleClick = d->m_settings->isOpenMiddleClickEnabled();
00402 d->m_bBackRightClick = d->m_settings->isBackRightClickEnabled();
00403 d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
00404 setDebugScript( d->m_settings->isJavaScriptDebugEnabled() );
00405 d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
00406 d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();
00407
00408
00409 d->m_metaRefreshEnabled = d->m_settings->isAutoDelayedActionsEnabled ();
00410
00411 connect( view, SIGNAL( zoomView( int ) ), SLOT( slotZoomView( int ) ) );
00412
00413 connect( this, SIGNAL( completed() ),
00414 this, SLOT( updateActions() ) );
00415 connect( this, SIGNAL( completed( bool ) ),
00416 this, SLOT( updateActions() ) );
00417 connect( this, SIGNAL( started( KIO::Job * ) ),
00418 this, SLOT( updateActions() ) );
00419
00420 d->m_popupMenuXML = KXMLGUIFactory::readConfigFile( locate( "data", "khtml/khtml_popupmenu.rc", KHTMLFactory::instance() ) );
00421
00422 connect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
00423 this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
00424 connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
00425 this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00426 connect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
00427 this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00428
00429 connect ( &d->m_progressUpdateTimer, SIGNAL( timeout() ), this, SLOT( slotProgressUpdate() ) );
00430
00431 findTextBegin();
00432
00433 connect( &d->m_redirectionTimer, SIGNAL( timeout() ),
00434 this, SLOT( slotRedirect() ) );
00435
00436 d->m_dcopobject = new KHTMLPartIface(this);
00437
00438
00439
00440
00441
00442
00443
00444
00445 KGlobal::locale()->removeCatalogue("khtml");
00446 }
00447
00448 KHTMLPart::~KHTMLPart()
00449 {
00450
00451
00452 KConfig *config = KGlobal::config();
00453 config->setGroup( "HTML Settings" );
00454 config->writeEntry( "AutomaticDetectionLanguage", d->m_autoDetectLanguage );
00455
00456 delete d->m_automaticDetection;
00457 delete d->m_manualDetection;
00458
00459 slotWalletClosed();
00460 if (!parentPart()) {
00461 removeJSErrorExtension();
00462 delete d->m_statusBarPopupLabel;
00463 }
00464
00465 d->m_find = 0;
00466
00467 if ( d->m_manager )
00468 {
00469 d->m_manager->setActivePart( 0 );
00470
00471 }
00472
00473 stopAutoScroll();
00474 d->m_redirectionTimer.stop();
00475
00476 if (!d->m_bComplete)
00477 closeURL();
00478
00479 disconnect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
00480 this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
00481 disconnect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
00482 this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00483 disconnect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
00484 this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
00485
00486 clear();
00487
00488 if ( d->m_view )
00489 {
00490 d->m_view->hide();
00491 d->m_view->viewport()->hide();
00492 d->m_view->m_part = 0;
00493 }
00494
00495
00496
00497 delete d->m_jsedlg;
00498 d->m_jsedlg = 0;
00499
00500 if (!parentPart())
00501 delete d->m_frame;
00502 delete d; d = 0;
00503 KHTMLFactory::deregisterPart( this );
00504 }
00505
00506 bool KHTMLPart::restoreURL( const KURL &url )
00507 {
00508 kdDebug( 6050 ) << "KHTMLPart::restoreURL " << url.url() << endl;
00509
00510 d->m_redirectionTimer.stop();
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 d->m_bComplete = false;
00523 d->m_bLoadEventEmitted = false;
00524 d->m_workingURL = url;
00525
00526
00527 d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
00528 setDebugScript( KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
00529 d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
00530 d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
00531
00532 m_url = url;
00533
00534 d->m_restoreScrollPosition = true;
00535 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
00536 connect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
00537
00538 KHTMLPageCache::self()->fetchData( d->m_cacheId, this, SLOT(slotRestoreData(const QByteArray &)));
00539
00540 emit started( 0L );
00541
00542 return true;
00543 }
00544
00545
00546 bool KHTMLPart::openURL( const KURL &url )
00547 {
00548 kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL " << url.url() << endl;
00549
00550 d->m_redirectionTimer.stop();
00551
00552
00553
00554
00555 if ( url.protocol() == "error" && url.hasSubURL() ) {
00556 closeURL();
00557
00558 if( d->m_bJScriptEnabled )
00559 d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = QString::null;
00560
00566 KURL::List urls = KURL::split( url );
00567
00568
00569 if ( urls.count() > 1 ) {
00570 KURL mainURL = urls.first();
00571 int error = mainURL.queryItem( "error" ).toInt();
00572
00573 if ( error == 0 ) error = KIO::ERR_UNKNOWN;
00574 QString errorText = mainURL.queryItem( "errText", HINT_UTF8 );
00575 urls.pop_front();
00576 d->m_workingURL = KURL::join( urls );
00577
00578 emit d->m_extension->setLocationBarURL( d->m_workingURL.prettyURL() );
00579 htmlError( error, errorText, d->m_workingURL );
00580 return true;
00581 }
00582 }
00583
00584 if (!parentPart()) {
00585 QString host = url.isLocalFile() ? "localhost" : url.host();
00586 QString userAgent = KProtocolManager::userAgentForHost(host);
00587 if (userAgent != KProtocolManager::userAgentForHost(QString::null)) {
00588 if (!d->m_statusBarUALabel) {
00589 d->m_statusBarUALabel = new KURLLabel(d->m_statusBarExtension->statusBar());
00590 d->m_statusBarUALabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
00591 d->m_statusBarUALabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
00592 d->m_statusBarUALabel->setUseCursor(false);
00593 d->m_statusBarExtension->addStatusBarItem(d->m_statusBarUALabel, 0, false);
00594 d->m_statusBarUALabel->setPixmap(SmallIcon("agent", instance()));
00595 } else {
00596 QToolTip::remove(d->m_statusBarUALabel);
00597 }
00598 QToolTip::add(d->m_statusBarUALabel, i18n("The fake user-agent '%1' is in use.").arg(userAgent));
00599 } else if (d->m_statusBarUALabel) {
00600 d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarUALabel);
00601 delete d->m_statusBarUALabel;
00602 d->m_statusBarUALabel = 0L;
00603 }
00604 }
00605
00606 KParts::URLArgs args( d->m_extension->urlArgs() );
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 bool isFrameSet = false;
00617 if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
00618 HTMLDocumentImpl* htmlDoc = static_cast<HTMLDocumentImpl*>(d->m_doc);
00619 isFrameSet = htmlDoc->body() && (htmlDoc->body()->id() == ID_FRAMESET);
00620 }
00621
00622 if ( url.hasRef() && !isFrameSet )
00623 {
00624 bool noReloadForced = !args.reload && !args.redirectedRequest() && !args.doPost();
00625 if (noReloadForced && urlcmp( url.url(), m_url.url(), true, true ))
00626 {
00627 kdDebug( 6050 ) << "KHTMLPart::openURL, jumping to anchor. m_url = " << url.url() << endl;
00628 m_url = url;
00629 emit started( 0L );
00630
00631 if ( !gotoAnchor( url.encodedHtmlRef()) )
00632 gotoAnchor( url.htmlRef() );
00633
00634 d->m_bComplete = true;
00635 if (d->m_doc)
00636 d->m_doc->setParsing(false);
00637
00638 kdDebug( 6050 ) << "completed..." << endl;
00639 emit completed();
00640 return true;
00641 }
00642 }
00643
00644
00645
00646 if (args.reload) {
00647 args.xOffset = d->m_view->contentsX();
00648 args.yOffset = d->m_view->contentsY();
00649 d->m_extension->setURLArgs(args);
00650 }
00651
00652 if (!d->m_restored)
00653 closeURL();
00654
00655 d->m_restoreScrollPosition = d->m_restored;
00656 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
00657 connect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
00658
00659
00660
00661 m_url = url;
00662 if(m_url.protocol().startsWith( "http" ) && !m_url.host().isEmpty() &&
00663 m_url.path().isEmpty()) {
00664 m_url.setPath("/");
00665 emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
00666 }
00667
00668 d->m_workingURL = m_url;
00669
00670 args.metaData().insert("main_frame_request", parentPart() == 0 ? "TRUE" : "FALSE" );
00671 args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
00672 args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
00673 args.metaData().insert("PropagateHttpHeader", "true");
00674 args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE" : "FALSE" );
00675 args.metaData().insert("ssl_activate_warnings", "TRUE" );
00676 args.metaData().insert("cross-domain", toplevelURL().url());
00677
00678 if (d->m_restored)
00679 {
00680 args.metaData().insert("referrer", d->m_pageReferrer);
00681 d->m_cachePolicy = KIO::CC_Cache;
00682 }
00683 else if (args.reload)
00684 d->m_cachePolicy = KIO::CC_Reload;
00685 else
00686 d->m_cachePolicy = KProtocolManager::cacheControl();
00687
00688 if ( args.doPost() && (m_url.protocol().startsWith("http")) )
00689 {
00690 d->m_job = KIO::http_post( m_url, args.postData, false );
00691 d->m_job->addMetaData("content-type", args.contentType() );
00692 }
00693 else
00694 {
00695 d->m_job = KIO::get( m_url, false, false );
00696 d->m_job->addMetaData("cache", KIO::getCacheControlString(d->m_cachePolicy));
00697 }
00698
00699 if (widget())
00700 d->m_job->setWindow(widget()->topLevelWidget());
00701 d->m_job->addMetaData(args.metaData());
00702
00703 connect( d->m_job, SIGNAL( result( KIO::Job* ) ),
00704 SLOT( slotFinished( KIO::Job* ) ) );
00705 connect( d->m_job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00706 SLOT( slotData( KIO::Job*, const QByteArray& ) ) );
00707 connect ( d->m_job, SIGNAL( infoMessage( KIO::Job*, const QString& ) ),
00708 SLOT( slotInfoMessage(KIO::Job*, const QString& ) ) );
00709 connect( d->m_job, SIGNAL(redirection(KIO::Job*, const KURL& ) ),
00710 SLOT( slotRedirection(KIO::Job*, const KURL&) ) );
00711
00712 d->m_bComplete = false;
00713 d->m_bLoadEventEmitted = false;
00714
00715
00716 if( d->m_bJScriptEnabled )
00717 d->m_statusBarText[BarOverrideText] = d->m_statusBarText[BarDefaultText] = QString::null;
00718
00719
00720 d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
00721 setDebugScript( KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
00722 d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
00723 d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
00724
00725
00726 connect( d->m_job, SIGNAL( speed( KIO::Job*, unsigned long ) ),
00727 this, SLOT( slotJobSpeed( KIO::Job*, unsigned long ) ) );
00728
00729 connect( d->m_job, SIGNAL( percent( KIO::Job*, unsigned long ) ),
00730 this, SLOT( slotJobPercent( KIO::Job*, unsigned long ) ) );
00731
00732 connect( d->m_job, SIGNAL( result( KIO::Job* ) ),
00733 this, SLOT( slotJobDone( KIO::Job* ) ) );
00734
00735 d->m_jobspeed = 0;
00736
00737
00738
00739 if ( args.reload && !settings()->userStyleSheet().isEmpty() ) {
00740 KURL url( settings()->userStyleSheet() );
00741 KIO::StatJob *job = KIO::stat( url, false );
00742 connect( job, SIGNAL( result( KIO::Job * ) ),
00743 this, SLOT( slotUserSheetStatDone( KIO::Job * ) ) );
00744 }
00745 emit started( 0L );
00746
00747 return true;
00748 }
00749
00750 bool KHTMLPart::closeURL()
00751 {
00752 if ( d->m_job )
00753 {
00754 KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
00755 d->m_job->kill();
00756 d->m_job = 0;
00757 }
00758
00759 if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
00760 HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc );
00761
00762 if ( hdoc->body() && d->m_bLoadEventEmitted ) {
00763 hdoc->body()->dispatchWindowEvent( EventImpl::UNLOAD_EVENT, false, false );
00764 if ( d->m_doc )
00765 d->m_doc->updateRendering();
00766 d->m_bLoadEventEmitted = false;
00767 }
00768 }
00769
00770 d->m_bComplete = true;
00771 d->m_bLoadEventEmitted = true;
00772 d->m_cachePolicy = KProtocolManager::cacheControl();
00773
00774 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
00775
00776 KHTMLPageCache::self()->cancelFetch(this);
00777 if ( d->m_doc && d->m_doc->parsing() )
00778 {
00779 kdDebug( 6050 ) << " was still parsing... calling end " << endl;
00780 slotFinishedParsing();
00781 d->m_doc->setParsing(false);
00782 }
00783
00784 if ( !d->m_workingURL.isEmpty() )
00785 {
00786
00787 kdDebug( 6050 ) << "Aborted before starting to render, reverting location bar to " << m_url.prettyURL() << endl;
00788 emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
00789 }
00790
00791 d->m_workingURL = KURL();
00792
00793 if ( d->m_doc && d->m_doc->docLoader() )
00794 khtml::Cache::loader()->cancelRequests( d->m_doc->docLoader() );
00795
00796
00797 {
00798 ConstFrameIt it = d->m_frames.begin();
00799 const ConstFrameIt end = d->m_frames.end();
00800 for (; it != end; ++it )
00801 {
00802 if ( (*it)->m_run )
00803 (*it)->m_run->abort();
00804 if ( !( *it )->m_part.isNull() )
00805 ( *it )->m_part->closeURL();
00806 }
00807 }
00808
00809 {
00810 ConstFrameIt it = d->m_objects.begin();
00811 const ConstFrameIt end = d->m_objects.end();
00812 for (; it != end; ++it)
00813 {
00814 if ( !( *it )->m_part.isNull() )
00815 ( *it )->m_part->closeURL();
00816 }
00817 }
00818
00819 if ( d && d->m_redirectionTimer.isActive() )
00820 d->m_redirectionTimer.stop();
00821
00822
00823 emit nodeActivated(Node());
00824
00825
00826 if ( d->m_view )
00827 d->m_view->closeChildDialogs();
00828
00829 return true;
00830 }
00831
00832 DOM::HTMLDocument KHTMLPart::htmlDocument() const
00833 {
00834 if (d->m_doc && d->m_doc->isHTMLDocument())
00835 return static_cast<HTMLDocumentImpl*>(d->m_doc);
00836 else
00837 return static_cast<HTMLDocumentImpl*>(0);
00838 }
00839
00840 DOM::Document KHTMLPart::document() const
00841 {
00842 return d->m_doc;
00843 }
00844
00845 QString KHTMLPart::documentSource() const
00846 {
00847 QString sourceStr;
00848 if ( !( m_url.isLocalFile() ) && KHTMLPageCache::self()->isComplete( d->m_cacheId ) )
00849 {
00850 QByteArray sourceArray;
00851 QDataStream dataStream( sourceArray, IO_WriteOnly );
00852 KHTMLPageCache::self()->saveData( d->m_cacheId, &dataStream );
00853 QTextStream stream( sourceArray, IO_ReadOnly );
00854 stream.setCodec( QTextCodec::codecForName( encoding().latin1() ) );
00855 sourceStr = stream.read();
00856 } else
00857 {
00858 QString tmpFile;
00859 if( KIO::NetAccess::download( m_url, tmpFile, NULL ) )
00860 {
00861 QFile f( tmpFile );
00862 if ( f.open( IO_ReadOnly ) )
00863 {
00864 QTextStream stream( &f );
00865 stream.setCodec( QTextCodec::codecForName( encoding().latin1() ) );
00866 sourceStr = stream.read();
00867 f.close();
00868 }
00869 KIO::NetAccess::removeTempFile( tmpFile );
00870 }
00871 }
00872
00873 return sourceStr;
00874 }
00875
00876
00877 KParts::BrowserExtension *KHTMLPart::browserExtension() const
00878 {
00879 return d->m_extension;
00880 }
00881
00882 KParts::BrowserHostExtension *KHTMLPart::browserHostExtension() const
00883 {
00884 return d->m_hostExtension;
00885 }
00886
00887 KHTMLView *KHTMLPart::view() const
00888 {
00889 return d->m_view;
00890 }
00891
00892 void KHTMLPart::setStatusMessagesEnabled( bool enable )
00893 {
00894 d->m_statusMessagesEnabled = enable;
00895 }
00896
00897 KJS::Interpreter *KHTMLPart::jScriptInterpreter()
00898 {
00899 KJSProxy *proxy = jScript();
00900 if (!proxy || proxy->paused())
00901 return 0;
00902
00903 return proxy->interpreter();
00904 }
00905
00906 bool KHTMLPart::statusMessagesEnabled() const
00907 {
00908 return d->m_statusMessagesEnabled;
00909 }
00910
00911 void KHTMLPart::setJScriptEnabled( bool enable )
00912 {
00913 if ( !enable && jScriptEnabled() && d->m_frame && d->m_frame->m_jscript ) {
00914 d->m_frame->m_jscript->clear();
00915 }
00916 d->m_bJScriptForce = enable;
00917 d->m_bJScriptOverride = true;
00918 }
00919
00920 bool KHTMLPart::jScriptEnabled() const
00921 {
00922 if(onlyLocalReferences()) return false;
00923
00924 if ( d->m_bJScriptOverride )
00925 return d->m_bJScriptForce;
00926 return d->m_bJScriptEnabled;
00927 }
00928
00929 void KHTMLPart::setMetaRefreshEnabled( bool enable )
00930 {
00931 d->m_metaRefreshEnabled = enable;
00932 }
00933
00934 bool KHTMLPart::metaRefreshEnabled() const
00935 {
00936 return d->m_metaRefreshEnabled;
00937 }
00938
00939
00940
00941
00942
00943
00944
00945
00946 #define DIRECT_LINKAGE_TO_ECMA
00947
00948 #ifdef DIRECT_LINKAGE_TO_ECMA
00949 extern "C" { KJSProxy *kjs_html_init(khtml::ChildFrame * childframe); }
00950 #endif
00951
00952 static bool createJScript(khtml::ChildFrame *frame)
00953 {
00954 #ifndef DIRECT_LINKAGE_TO_ECMA
00955 KLibrary *lib = KLibLoader::self()->library("kjs_html");
00956 if ( !lib ) {
00957 setJScriptEnabled( false );
00958 return false;
00959 }
00960
00961 void *sym = lib->symbol("kjs_html_init");
00962 if ( !sym ) {
00963 lib->unload();
00964 setJScriptEnabled( false );
00965 return false;
00966 }
00967 typedef KJSProxy* (*initFunction)(khtml::ChildFrame *);
00968 initFunction initSym = (initFunction) sym;
00969 frame->m_jscript = (*initSym)(d->m_frame);
00970 frame->m_kjs_lib = lib;
00971 #else
00972 frame->m_jscript = kjs_html_init(frame);
00973
00974 #endif
00975 return true;
00976 }
00977
00978 KJSProxy *KHTMLPart::jScript()
00979 {
00980 if (!jScriptEnabled()) return 0;
00981
00982 if ( !d->m_frame ) {
00983 KHTMLPart * p = parentPart();
00984 if (!p) {
00985 d->m_frame = new khtml::ChildFrame;
00986 d->m_frame->m_part = this;
00987 } else {
00988 ConstFrameIt it = p->d->m_frames.begin();
00989 const ConstFrameIt end = p->d->m_frames.end();
00990 for (; it != end; ++it)
00991 if ((*it)->m_part.operator->() == this) {
00992 d->m_frame = *it;
00993 break;
00994 }
00995 }
00996 if ( !d->m_frame )
00997 return 0;
00998 }
00999 if ( !d->m_frame->m_jscript )
01000 if (!createJScript(d->m_frame))
01001 return 0;
01002 if (d->m_bJScriptDebugEnabled)
01003 d->m_frame->m_jscript->setDebugEnabled(true);
01004
01005 return d->m_frame->m_jscript;
01006 }
01007
01008 QVariant KHTMLPart::crossFrameExecuteScript(const QString& target, const QString& script)
01009 {
01010 KHTMLPart* destpart = this;
01011
01012 QString trg = target.lower();
01013
01014 if (target == "_top") {
01015 while (destpart->parentPart())
01016 destpart = destpart->parentPart();
01017 }
01018 else if (target == "_parent") {
01019 if (parentPart())
01020 destpart = parentPart();
01021 }
01022 else if (target == "_self" || target == "_blank") {
01023
01024 }
01025 else {
01026 destpart = findFrame(target);
01027 if (!destpart)
01028 destpart = this;
01029 }
01030
01031
01032 if (destpart == this)
01033 return executeScript(DOM::Node(), script);
01034
01035
01036 if (destpart->checkFrameAccess(this))
01037 return destpart->executeScript(DOM::Node(), script);
01038
01039
01040 return executeScript(DOM::Node(), script);
01041 }
01042
01043
01044
01045
01046 KJSErrorDlg *KHTMLPart::jsErrorExtension() {
01047 if (!d->m_settings->jsErrorsEnabled()) {
01048 return 0L;
01049 }
01050
01051 if (parentPart()) {
01052 return parentPart()->jsErrorExtension();
01053 }
01054
01055 if (!d->m_statusBarJSErrorLabel) {
01056 d->m_statusBarJSErrorLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
01057 d->m_statusBarJSErrorLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
01058 d->m_statusBarJSErrorLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
01059 d->m_statusBarJSErrorLabel->setUseCursor(false);
01060 d->m_statusBarExtension->addStatusBarItem(d->m_statusBarJSErrorLabel, 0, false);
01061 QToolTip::add(d->m_statusBarJSErrorLabel, i18n("This web page contains coding errors."));
01062 d->m_statusBarJSErrorLabel->setPixmap(SmallIcon("bug", instance()));
01063 connect(d->m_statusBarJSErrorLabel, SIGNAL(leftClickedURL()), SLOT(launchJSErrorDialog()));
01064 connect(d->m_statusBarJSErrorLabel, SIGNAL(rightClickedURL()), SLOT(jsErrorDialogContextMenu()));
01065 }
01066 if (!d->m_jsedlg) {
01067 d->m_jsedlg = new KJSErrorDlg;
01068 d->m_jsedlg->setURL(m_url.prettyURL());
01069 if (KGlobalSettings::showIconsOnPushButtons()) {
01070 d->m_jsedlg->_clear->setIconSet(SmallIconSet("locationbar_erase"));
01071 d->m_jsedlg->_close->setIconSet(SmallIconSet("fileclose"));
01072 }
01073 }
01074 return d->m_jsedlg;
01075 }
01076
01077 void KHTMLPart::removeJSErrorExtension() {
01078 if (parentPart()) {
01079 parentPart()->removeJSErrorExtension();
01080 return;
01081 }
01082 if (d->m_statusBarJSErrorLabel != 0) {
01083 d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarJSErrorLabel );
01084 delete d->m_statusBarJSErrorLabel;
01085 d->m_statusBarJSErrorLabel = 0;
01086 }
01087 delete d->m_jsedlg;
01088 d->m_jsedlg = 0;
01089 }
01090
01091 void KHTMLPart::disableJSErrorExtension() {
01092 removeJSErrorExtension();
01093
01094
01095
01096
01097 d->m_settings->setJSErrorsEnabled(false);
01098 DCOPClient::mainClient()->send("konqueror*", "KonquerorIface", "reparseConfiguration()", QByteArray());
01099 }
01100
01101 void KHTMLPart::jsErrorDialogContextMenu() {
01102 KPopupMenu *m = new KPopupMenu(0L);
01103 m->insertItem(i18n("&Hide Errors"), this, SLOT(removeJSErrorExtension()));
01104 m->insertItem(i18n("&Disable Error Reporting"), this, SLOT(disableJSErrorExtension()));
01105 m->popup(QCursor::pos());
01106 }
01107
01108 void KHTMLPart::launchJSErrorDialog() {
01109 KJSErrorDlg *dlg = jsErrorExtension();
01110 if (dlg) {
01111 dlg->show();
01112 dlg->raise();
01113 }
01114 }
01115
01116 QVariant KHTMLPart::executeScript(const QString& filename, int baseLine, const DOM::Node& n, const QString& script)
01117 {
01118 #ifdef KJS_VERBOSE
01119
01120 kdDebug(6070) << "executeScript: caller='" << name() << "' filename=" << filename << " baseLine=" << baseLine << endl;
01121 #endif
01122 KJSProxy *proxy = jScript();
01123
01124 if (!proxy || proxy->paused())
01125 return QVariant();
01126
01127 KJS::Completion comp;
01128
01129 QVariant ret = proxy->evaluate(filename, baseLine, script, n, &comp);
01130
01131
01132
01133
01134 if (comp.complType() == KJS::Throw && !comp.value().isNull()) {
01135 KJSErrorDlg *dlg = jsErrorExtension();
01136 if (dlg) {
01137 KJS::UString msg = comp.value().toString(proxy->interpreter()->globalExec());
01138 dlg->addError(i18n("<b>Error</b>: %1: %2").arg(filename, msg.qstring()));
01139 }
01140 }
01141
01142
01143 if ( !d->m_redirectURL.isEmpty() && d->m_delayRedirect == -1 )
01144 {
01145 kdDebug(6070) << "executeScript done, handling immediate redirection NOW" << endl;
01146
01147 khtml::Tokenizer* t = d->m_doc->tokenizer();
01148 if(t)
01149 t->abort();
01150 d->m_redirectionTimer.start( 0, true );
01151 }
01152
01153 return ret;
01154 }
01155
01156 QVariant KHTMLPart::executeScript( const QString &script )
01157 {
01158 return executeScript( DOM::Node(), script );
01159 }
01160
01161 QVariant KHTMLPart::executeScript( const DOM::Node &n, const QString &script )
01162 {
01163 #ifdef KJS_VERBOSE
01164 kdDebug(6070) << "KHTMLPart::executeScript caller='" << name() << "' node=" << n.nodeName().string().latin1() << "(" << (n.isNull() ? 0 : n.nodeType()) << ") " << endl;
01165 #endif
01166 KJSProxy *proxy = jScript();
01167
01168 if (!proxy || proxy->paused())
01169 return QVariant();
01170 ++(d->m_runningScripts);
01171 KJS::Completion comp;
01172 const QVariant ret = proxy->evaluate( QString::null, 1, script, n, &comp );
01173 --(d->m_runningScripts);
01174
01175
01176
01177
01178 if (comp.complType() == KJS::Throw && !comp.value().isNull()) {
01179 KJSErrorDlg *dlg = jsErrorExtension();
01180 if (dlg) {
01181 KJS::UString msg = comp.value().toString(proxy->interpreter()->globalExec());
01182 dlg->addError(i18n("<b>Error</b>: node %1: %2").arg(n.nodeName().string()).arg(msg.qstring()));
01183 }
01184 }
01185
01186 if (!d->m_runningScripts && d->m_doc && !d->m_doc->parsing() && d->m_submitForm )
01187 submitFormAgain();
01188
01189 #ifdef KJS_VERBOSE
01190 kdDebug(6070) << "KHTMLPart::executeScript - done" << endl;
01191 #endif
01192 return ret;
01193 }
01194
01195 bool KHTMLPart::scheduleScript(const DOM::Node &n, const QString& script)
01196 {
01197
01198
01199 d->scheduledScript = script;
01200 d->scheduledScriptNode = n;
01201
01202 return true;
01203 }
01204
01205 QVariant KHTMLPart::executeScheduledScript()
01206 {
01207 if( d->scheduledScript.isEmpty() )
01208 return QVariant();
01209
01210
01211
01212 QVariant ret = executeScript( d->scheduledScriptNode, d->scheduledScript );
01213 d->scheduledScript = QString();
01214 d->scheduledScriptNode = DOM::Node();
01215
01216 return ret;
01217 }
01218
01219 void KHTMLPart::setJavaEnabled( bool enable )
01220 {
01221 d->m_bJavaForce = enable;
01222 d->m_bJavaOverride = true;
01223 }
01224
01225 bool KHTMLPart::javaEnabled() const
01226 {
01227 if (onlyLocalReferences()) return false;
01228
01229 #ifndef Q_WS_QWS
01230 if( d->m_bJavaOverride )
01231 return d->m_bJavaForce;
01232 return d->m_bJavaEnabled;
01233 #else
01234 return false;
01235 #endif
01236 }
01237
01238 KJavaAppletContext *KHTMLPart::javaContext()
01239 {
01240 return 0;
01241 }
01242
01243 KJavaAppletContext *KHTMLPart::createJavaContext()
01244 {
01245 return 0;
01246 }
01247
01248 void KHTMLPart::setPluginsEnabled( bool enable )
01249 {
01250 d->m_bPluginsForce = enable;
01251 d->m_bPluginsOverride = true;
01252 }
01253
01254 bool KHTMLPart::pluginsEnabled() const
01255 {
01256 if (onlyLocalReferences()) return false;
01257
01258 if ( d->m_bPluginsOverride )
01259 return d->m_bPluginsForce;
01260 return d->m_bPluginsEnabled;
01261 }
01262
01263 static int s_DOMTreeIndentLevel = 0;
01264
01265 void KHTMLPart::slotDebugDOMTree()
01266 {
01267 if ( d->m_doc && d->m_doc->firstChild() )
01268 qDebug("%s", d->m_doc->firstChild()->toString().string().latin1());
01269
01270
01271
01272 const int indentLevel = s_DOMTreeIndentLevel++;
01273
01274 ConstFrameIt it = d->m_frames.begin();
01275 const ConstFrameIt end = d->m_frames.end();
01276 for (; it != end; ++it )
01277 if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
01278 KParts::ReadOnlyPart* const p = ( *it )->m_part;
01279 kdDebug(6050) << QString().leftJustify(s_DOMTreeIndentLevel*4,' ') << "FRAME " << p->name() << " " << endl;
01280 static_cast<KHTMLPart*>( p )->slotDebugDOMTree();
01281 }
01282 s_DOMTreeIndentLevel = indentLevel;
01283 }
01284
01285 void KHTMLPart::slotDebugScript()
01286 {
01287 if (jScript())
01288 jScript()->showDebugWindow();
01289 }
01290
01291 void KHTMLPart::slotDebugRenderTree()
01292 {
01293 #ifndef NDEBUG
01294 if ( d->m_doc ) {
01295 d->m_doc->renderer()->printTree();
01296
01297
01298
01299
01300
01301 }
01302 #endif
01303 }
01304
01305 void KHTMLPart::slotStopAnimations()
01306 {
01307 stopAnimations();
01308 }
01309
01310 void KHTMLPart::setAutoloadImages( bool enable )
01311 {
01312 if ( d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable )
01313 return;
01314
01315 if ( d->m_doc )
01316 d->m_doc->docLoader()->setAutoloadImages( enable );
01317
01318 unplugActionList( "loadImages" );
01319
01320 if ( enable ) {
01321 delete d->m_paLoadImages;
01322 d->m_paLoadImages = 0;
01323 }
01324 else if ( !d->m_paLoadImages )
01325 d->m_paLoadImages = new KAction( i18n( "Display Images on Page" ), "images_display", 0, this, SLOT( slotLoadImages() ), actionCollection(), "loadImages" );
01326
01327 if ( d->m_paLoadImages ) {
01328 QPtrList<KAction> lst;
01329 lst.append( d->m_paLoadImages );
01330 plugActionList( "loadImages", lst );
01331 }
01332 }
01333
01334 bool KHTMLPart::autoloadImages() const
01335 {
01336 if ( d->m_doc )
01337 return d->m_doc->docLoader()->autoloadImages();
01338
01339 return true;
01340 }
01341
01342 void KHTMLPart::clear()
01343 {
01344 if ( d->m_bCleared )
01345 return;
01346
01347 d->m_bCleared = true;
01348
01349 d->m_bClearing = true;
01350
01351 {
01352 ConstFrameIt it = d->m_frames.begin();
01353 const ConstFrameIt end = d->m_frames.end();
01354 for(; it != end; ++it )
01355 {
01356
01357 if ( (*it)->m_run )
01358 (*it)->m_run->abort();
01359 }
01360 }
01361
01362 {
01363 ConstFrameIt it = d->m_objects.begin();
01364 const ConstFrameIt end = d->m_objects.end();
01365 for(; it != end; ++it )
01366 {
01367
01368 if ( (*it)->m_run )
01369 (*it)->m_run->abort();
01370 }
01371 }
01372
01373
01374 findTextBegin();
01375 d->m_mousePressNode = DOM::Node();
01376
01377
01378 if ( d->m_doc )
01379 d->m_doc->detach();
01380
01381
01382 if ( d->m_frame && d->m_frame->m_jscript )
01383 d->m_frame->m_jscript->clear();
01384
01385
01386 if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->layer())
01387 d->m_doc->renderer()->layer()->suspendMarquees();
01388
01389 if ( d->m_view )
01390 d->m_view->clear();
01391
01392
01393
01394 if ( d->m_doc ) {
01395 d->m_doc->deref();
01396 }
01397 d->m_doc = 0;
01398
01399 delete d->m_decoder;
01400 d->m_decoder = 0;
01401
01402
01403 disconnect( partManager(), SIGNAL( activePartChanged( KParts::Part * ) ),
01404 this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
01405
01406 if (d->m_frames.count())
01407 {
01408 KHTMLFrameList frames = d->m_frames;
01409 d->m_frames.clear();
01410 ConstFrameIt it = frames.begin();
01411 const ConstFrameIt end = frames.end();
01412 for(; it != end; ++it )
01413 {
01414 if ( (*it)->m_part )
01415 {
01416 partManager()->removePart( (*it)->m_part );
01417 delete (KParts::ReadOnlyPart *)(*it)->m_part;
01418 }
01419 delete *it;
01420 }
01421 }
01422
01423 if (d->m_objects.count())
01424 {
01425 KHTMLFrameList objects = d->m_objects;
01426 d->m_objects.clear();
01427 ConstFrameIt oi = objects.begin();
01428 const ConstFrameIt oiEnd = objects.end();
01429
01430 for (; oi != oiEnd; ++oi )
01431 delete *oi;
01432 }
01433
01434
01435 connect( partManager(), SIGNAL( activePartChanged( KParts::Part * ) ),
01436 this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
01437
01438 d->m_delayRedirect = 0;
01439 d->m_redirectURL = QString::null;
01440 d->m_redirectionTimer.stop();
01441 d->m_redirectLockHistory = true;
01442 d->m_bClearing = false;
01443 d->m_frameNameId = 1;
01444 d->m_bFirstData = true;
01445
01446 d->m_bMousePressed = false;
01447
01448 d->m_selectionStart = DOM::Node();
01449 d->m_selectionEnd = DOM::Node();
01450 d->m_startOffset = 0;
01451 d->m_endOffset = 0;
01452 #ifndef QT_NO_CLIPBOARD
01453 connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
01454 #endif
01455
01456 d->m_jobPercent = 0;
01457
01458 if ( !d->m_haveEncoding )
01459 d->m_encoding = QString::null;
01460 #ifdef SPEED_DEBUG
01461 d->m_parsetime.restart();
01462 #endif
01463 }
01464
01465 bool KHTMLPart::openFile()
01466 {
01467 return true;
01468 }
01469
01470 DOM::HTMLDocumentImpl *KHTMLPart::docImpl() const
01471 {
01472 if ( d && d->m_doc && d->m_doc->isHTMLDocument() )
01473 return static_cast<HTMLDocumentImpl*>(d->m_doc);
01474 return 0;
01475 }
01476
01477 DOM::DocumentImpl *KHTMLPart::xmlDocImpl() const
01478 {
01479 if ( d )
01480 return d->m_doc;
01481 return 0;
01482 }
01483
01484 void KHTMLPart::slotInfoMessage(KIO::Job* kio_job, const QString& msg)
01485 {
01486 assert(d->m_job == kio_job);
01487
01488 if (!parentPart())
01489 setStatusBarText(msg, BarDefaultText);
01490 }
01491
01492 void KHTMLPart::setPageSecurity( PageSecurity sec )
01493 {
01494 emit d->m_extension->setPageSecurity( sec );
01495 if ( sec != NotCrypted && !d->m_statusBarIconLabel && !parentPart() ) {
01496 d->m_statusBarIconLabel = new KURLLabel( d->m_statusBarExtension->statusBar() );
01497 d->m_statusBarIconLabel->setFixedHeight( instance()->iconLoader()->currentSize(KIcon::Small) );
01498 d->m_statusBarIconLabel->setSizePolicy(QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ));
01499 d->m_statusBarIconLabel->setUseCursor( false );
01500 d->m_statusBarExtension->addStatusBarItem( d->m_statusBarIconLabel, 0, false );
01501 connect( d->m_statusBarIconLabel, SIGNAL( leftClickedURL() ), SLOT( slotSecurity() ) );
01502 } else if (d->m_statusBarIconLabel) {
01503 QToolTip::remove(d->m_statusBarIconLabel);
01504 }
01505
01506 if (d->m_statusBarIconLabel) {
01507 if (d->m_ssl_in_use)
01508 QToolTip::add(d->m_statusBarIconLabel,
01509 i18n("Session is secured with %1 bit %2.").arg(d->m_ssl_cipher_used_bits).arg(d->m_ssl_cipher));
01510 else QToolTip::add(d->m_statusBarIconLabel, i18n("Session is not secured."));
01511 }
01512
01513 QString iconName;
01514 switch (sec) {
01515 case NotCrypted:
01516 iconName = "decrypted";
01517 if ( d->m_statusBarIconLabel ) {
01518 d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarIconLabel );
01519 delete d->m_statusBarIconLabel;
01520 d->m_statusBarIconLabel = 0L;
01521 }
01522 break;
01523 case Encrypted:
01524 iconName = "encrypted";
01525 break;
01526 case Mixed:
01527 iconName = "halfencrypted";
01528 break;
01529 }
01530 d->m_paSecurity->setIcon( iconName );
01531 if ( d->m_statusBarIconLabel )
01532 d->m_statusBarIconLabel->setPixmap( SmallIcon( iconName, instance() ) );
01533 }
01534
01535 void KHTMLPart::slotData( KIO::Job* kio_job, const QByteArray &data )
01536 {
01537 assert ( d->m_job == kio_job );
01538
01539
01540
01541 if ( !d->m_workingURL.isEmpty() )
01542 {
01543
01544
01545
01546
01547
01548 d->m_job->suspend();
01549 begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
01550 d->m_job->resume();
01551
01552 if (d->m_cachePolicy == KIO::CC_Refresh)
01553 d->m_doc->docLoader()->setCachePolicy(KIO::CC_Verify);
01554 else
01555 d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
01556
01557 d->m_workingURL = KURL();
01558
01559 d->m_cacheId = KHTMLPageCache::self()->createCacheEntry();
01560
01561
01562 d->m_httpHeaders = d->m_job->queryMetaData("HTTP-Headers");
01563 time_t cacheCreationDate = d->m_job->queryMetaData("cache-creation-date").toLong();
01564 d->m_doc->docLoader()->setCacheCreationDate(cacheCreationDate);
01565
01566 d->m_pageServices = d->m_job->queryMetaData("PageServices");
01567 d->m_pageReferrer = d->m_job->queryMetaData("referrer");
01568
01569 d->m_bSecurityInQuestion = false;
01570 d->m_ssl_in_use = (d->m_job->queryMetaData("ssl_in_use") == "TRUE");
01571
01572 {
01573 KHTMLPart *p = parentPart();
01574 if (p && p->d->m_ssl_in_use != d->m_ssl_in_use) {
01575 while (p->parentPart()) p = p->parentPart();
01576
01577 p->setPageSecurity( Mixed );
01578 p->d->m_bSecurityInQuestion = true;
01579 }
01580 }
01581
01582 setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );
01583
01584
01585 d->m_ssl_parent_ip = d->m_job->queryMetaData("ssl_parent_ip");
01586 d->m_ssl_parent_cert = d->m_job->queryMetaData("ssl_parent_cert");
01587 d->m_ssl_peer_certificate = d->m_job->queryMetaData("ssl_peer_certificate");
01588 d->m_ssl_peer_chain = d->m_job->queryMetaData("ssl_peer_chain");
01589 d->m_ssl_peer_ip = d->m_job->queryMetaData("ssl_peer_ip");
01590 d->m_ssl_cipher = d->m_job->queryMetaData("ssl_cipher");
01591 d->m_ssl_cipher_desc = d->m_job->queryMetaData("ssl_cipher_desc");
01592 d->m_ssl_cipher_version = d->m_job->queryMetaData("ssl_cipher_version");
01593 d->m_ssl_cipher_used_bits = d->m_job->queryMetaData("ssl_cipher_used_bits");
01594 d->m_ssl_cipher_bits = d->m_job->queryMetaData("ssl_cipher_bits");
01595 d->m_ssl_cert_state = d->m_job->queryMetaData("ssl_cert_state");
01596
01597 if (d->m_statusBarIconLabel) {
01598 QToolTip::remove(d->m_statusBarIconLabel);
01599 if (d->m_ssl_in_use) {
01600 QToolTip::add(d->m_statusBarIconLabel, i18n("Session is secured with %1 bit %2.").arg(d->m_ssl_cipher_used_bits).arg(d->m_ssl_cipher));
01601 } else {
01602 QToolTip::add(d->m_statusBarIconLabel, i18n("Session is not secured."));
01603 }
01604 }
01605
01606
01607 QString qData = d->m_job->queryMetaData("charset");
01608 if ( !qData.isEmpty() && !d->m_haveEncoding )
01609 d->m_encoding = qData;
01610
01611
01612 qData = d->m_job->queryMetaData("http-refresh");
01613 if( !qData.isEmpty())
01614 d->m_doc->processHttpEquiv("refresh", qData);
01615
01616
01617 QString baseURL = d->m_job->queryMetaData ("content-location");
01618 if (!baseURL.isEmpty())
01619 d->m_doc->setBaseURL(KURL( d->m_doc->completeURL(baseURL) ));
01620
01621 if ( !m_url.isLocalFile() ) {
01622
01623 d->m_lastModified = d->m_job->queryMetaData("modified");
01624 } else
01625 d->m_lastModified = QString::null;
01626 }
01627
01628 KHTMLPageCache::self()->addData(d->m_cacheId, data);
01629 write( data.data(), data.size() );
01630 if (d->m_frame && d->m_frame->m_jscript)
01631 d->m_frame->m_jscript->dataReceived();
01632 }
01633
01634 void KHTMLPart::slotRestoreData(const QByteArray &data )
01635 {
01636
01637 if ( !d->m_workingURL.isEmpty() )
01638 {
01639 long saveCacheId = d->m_cacheId;
01640 QString savePageReferrer = d->m_pageReferrer;
01641 begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
01642 d->m_pageReferrer = savePageReferrer;
01643 d->m_cacheId = saveCacheId;
01644 d->m_workingURL = KURL();
01645 }
01646
01647
01648 write( data.data(), data.size() );
01649
01650 if (data.size() == 0)
01651 {
01652
01653
01654 if (d->m_doc && d->m_doc->parsing())
01655 end();
01656 }
01657 }
01658
01659 void KHTMLPart::showError( KIO::Job* job )
01660 {
01661 kdDebug(6050) << "KHTMLPart::showError d->m_bParsing=" << (d->m_doc && d->m_doc->parsing()) << " d->m_bComplete=" << d->m_bComplete
01662 << " d->m_bCleared=" << d->m_bCleared << endl;
01663
01664 if (job->error() == KIO::ERR_NO_CONTENT)
01665 return;
01666
01667 if ( (d->m_doc && d->m_doc->parsing()) || d->m_workingURL.isEmpty() )
01668 job->showErrorDialog( );
01669 else
01670 {
01671 htmlError( job->error(), job->errorText(), d->m_workingURL );
01672 }
01673 }
01674
01675
01676 void KHTMLPart::htmlError( int errorCode, const QString& text, const KURL& reqUrl )
01677 {
01678 kdDebug(6050) << "KHTMLPart::htmlError errorCode=" << errorCode << " text=" << text << endl;
01679
01680 bool bJSFO = d->m_bJScriptForce;
01681 bool bJSOO = d->m_bJScriptOverride;
01682 d->m_bJScriptForce = false;
01683 d->m_bJScriptOverride = true;
01684 begin();
01685 QString errText = QString::fromLatin1( "<HTML dir=%1><HEAD><TITLE>" )
01686 .arg(QApplication::reverseLayout() ? "rtl" : "ltr");
01687 errText += i18n( "Error while loading %1" ).arg( reqUrl.htmlURL() );
01688 errText += QString::fromLatin1( "</TITLE></HEAD><BODY><P>" );
01689 errText += i18n( "An error occurred while loading <B>%1</B>:" ).arg( reqUrl.htmlURL() );
01690 errText += QString::fromLatin1( "</P>" );
01691 errText += QStyleSheet::convertFromPlainText( KIO::buildErrorString( errorCode, text ) );
01692 errText += QString::fromLatin1( "</BODY></HTML>" );
01693 write(errText);
01694 end();
01695
01696 d->m_bJScriptForce = bJSFO;
01697 d->m_bJScriptOverride = bJSOO;
01698
01699
01700
01701
01702 m_url = reqUrl;
01703 d->m_workingURL = KURL();
01704 emit started( 0 );
01705 emit completed();
01706 return;
01707
01708
01709 QString errorName, techName, description;
01710 QStringList causes, solutions;
01711
01712 QByteArray raw = KIO::rawErrorDetail( errorCode, text, &reqUrl );
01713 QDataStream stream(raw, IO_ReadOnly);
01714
01715 stream >> errorName >> techName >> description >> causes >> solutions;
01716
01717 QString url, protocol, datetime;
01718 url = reqUrl.prettyURL();
01719 protocol = reqUrl.protocol();
01720 datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
01721 false );
01722
01723 QString doc = QString::fromLatin1( "<html><head><title>" );
01724 doc += i18n( "Error: " );
01725 doc += errorName;
01726 doc += QString::fromLatin1( " - %1</title></head><body><h1>" ).arg( url );
01727 doc += i18n( "The requested operation could not be completed" );
01728 doc += QString::fromLatin1( "</h1><h2>" );
01729 doc += errorName;
01730 doc += QString::fromLatin1( "</h2>" );
01731 if ( !techName.isNull() ) {
01732 doc += QString::fromLatin1( "<h2>" );
01733 doc += i18n( "Technical Reason: " );
01734 doc += techName;
01735 doc += QString::fromLatin1( "</h2>" );
01736 }
01737 doc += QString::fromLatin1( "<h3>" );
01738 doc += i18n( "Details of the Request:" );
01739 doc += QString::fromLatin1( "</h3><ul><li>" );
01740 doc += i18n( "URL: %1" ).arg( url );
01741 doc += QString::fromLatin1( "</li><li>" );
01742 if ( !protocol.isNull() ) {
01743
01744
01745 doc += QString::fromLatin1( "</li><li>" );
01746 }
01747 doc += i18n( "Date and Time: %1" ).arg( datetime );
01748 doc += QString::fromLatin1( "</li><li>" );
01749 doc += i18n( "Additional Information: %1" ).arg( text );
01750 doc += QString::fromLatin1( "</li></ul><h3>" );
01751 doc += i18n( "Description:" );
01752 doc += QString::fromLatin1( "</h3><p>" );
01753 doc += description;
01754 doc += QString::fromLatin1( "</p>" );
01755 if ( causes.count() ) {
01756 doc += QString::fromLatin1( "<h3>" );
01757 doc += i18n( "Possible Causes:" );
01758 doc += QString::fromLatin1( "</h3><ul><li>" );
01759 doc += causes.join( "</li><li>" );
01760 doc += QString::fromLatin1( "</li></ul>" );
01761 }
01762 if ( solutions.count() ) {
01763 doc += QString::fromLatin1( "<h3>" );
01764 doc += i18n( "Possible Solutions:" );
01765 doc += QString::fromLatin1( "</h3><ul><li>" );
01766 doc += solutions.join( "</li><li>" );
01767 doc += QString::fromLatin1( "</li></ul>" );
01768 }
01769 doc += QString::fromLatin1( "</body></html>" );
01770
01771 write( doc );
01772 end();
01773 }
01774
01775 void KHTMLPart::slotFinished( KIO::Job * job )
01776 {
01777 d->m_job = 0L;
01778 d->m_jobspeed = 0L;
01779
01780 if (job->error())
01781 {
01782 KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
01783
01784
01785
01786
01787
01788
01789 if (job->error() == KIO::ERR_IS_DIRECTORY)
01790 {
01791 KParts::URLArgs args;
01792 emit d->m_extension->openURLRequest( d->m_workingURL, args );
01793 }
01794 else
01795 {
01796 emit canceled( job->errorString() );
01797
01798 checkCompleted();
01799 showError( job );
01800 }
01801
01802 return;
01803 }
01804
01805
01806 KHTMLPageCache::self()->endData(d->m_cacheId);
01807 if (d->m_frame && d->m_frame->m_jscript)
01808 d->m_frame->m_jscript->dataReceived();
01809
01810 if ( d->m_doc && d->m_doc->docLoader()->expireDate() && m_url.protocol().lower().startsWith("http"))
01811 KIO::http_update_cache(m_url, false, d->m_doc->docLoader()->expireDate());
01812
01813 d->m_workingURL = KURL();
01814
01815 if ( d->m_doc && d->m_doc->parsing())
01816 end();
01817 }
01818
01819 void KHTMLPart::begin( const KURL &url, int xOffset, int yOffset )
01820 {
01821 clear();
01822 d->m_bCleared = false;
01823 d->m_cacheId = 0;
01824 d->m_bComplete = false;
01825 d->m_bLoadEventEmitted = false;
01826
01827 if(url.isValid()) {
01828 QString urlString = url.url();
01829 KHTMLFactory::vLinks()->insert( urlString );
01830 QString urlString2 = url.prettyURL();
01831 if ( urlString != urlString2 ) {
01832 KHTMLFactory::vLinks()->insert( urlString2 );
01833 }
01834 }
01835
01836
01837 if (!parentPart()) {
01838 removeJSErrorExtension();
01839 setSuppressedPopupIndicator( false );
01840 }
01841
01842
01843
01844
01845 KParts::URLArgs args( d->m_extension->urlArgs() );
01846 args.xOffset = xOffset;
01847 args.yOffset = yOffset;
01848 d->m_extension->setURLArgs( args );
01849
01850 d->m_pageReferrer = QString::null;
01851
01852 KURL ref(url);
01853 d->m_referrer = ref.protocol().startsWith("http") ? ref.url() : "";
01854
01855 m_url = url;
01856 KURL baseurl;
01857
01858 if ( !m_url.isEmpty() )
01859 {
01860 KURL title( baseurl );
01861 title.setRef( QString::null );
01862 title.setQuery( QString::null );
01863 emit setWindowCaption( title.prettyURL() );
01864 }
01865 else
01866 emit setWindowCaption( i18n( "[Untitled]" ) );
01867
01868 bool servedAsXHTML = args.serviceType == "application/xhtml+xml";
01869 bool servedAsXML = KMimeType::mimeType(args.serviceType)->is( "text/xml" );
01870
01871 if ( servedAsXML && !servedAsXHTML ) {
01872 d->m_doc = DOMImplementationImpl::instance()->createDocument( d->m_view );
01873 } else {
01874 d->m_doc = DOMImplementationImpl::instance()->createHTMLDocument( d->m_view );
01875
01876 static_cast<HTMLDocumentImpl *>(d->m_doc)->setHTMLRequested( !servedAsXHTML );
01877 }
01878 #ifndef KHTML_NO_CARET
01879
01880 #endif
01881
01882 d->m_doc->ref();
01883 d->m_doc->setURL( m_url.url() );
01884 if (!d->m_doc->attached())
01885 d->m_doc->attach( );
01886
01887
01888 d->m_doc->setBaseURL( baseurl );
01889 d->m_doc->docLoader()->setShowAnimations( KHTMLFactory::defaultHTMLSettings()->showAnimations() );
01890 emit docCreated();
01891
01892 d->m_paUseStylesheet->setItems(QStringList());
01893 d->m_paUseStylesheet->setEnabled( false );
01894
01895 setAutoloadImages( KHTMLFactory::defaultHTMLSettings()->autoLoadImages() );
01896 QString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet();
01897 if ( !userStyleSheet.isEmpty() )
01898 setUserStyleSheet( KURL( userStyleSheet ) );
01899
01900 d->m_doc->setRestoreState(args.docState);
01901 d->m_doc->open();
01902 connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
01903
01904 emit d->m_extension->enableAction( "print", true );
01905
01906 d->m_doc->setParsing(true);
01907 }
01908
01909 void KHTMLPart::write( const char *str, int len )
01910 {
01911 if ( !d->m_decoder )
01912 d->m_decoder = createDecoder();
01913
01914 if ( len == -1 )
01915 len = strlen( str );
01916
01917 if ( len == 0 )
01918 return;
01919
01920 QString decoded = d->m_decoder->decode( str, len );
01921
01922 if(decoded.isEmpty()) return;
01923
01924 if(d->m_bFirstData) {
01925
01926 d->m_doc->determineParseMode( decoded );
01927 d->m_bFirstData = false;
01928
01929
01930
01931 if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
01932 d->m_doc->setDecoderCodec(d->m_decoder->codec());
01933 d->m_doc->recalcStyle( NodeImpl::Force );
01934 }
01935
01936 khtml::Tokenizer* t = d->m_doc->tokenizer();
01937 if(t)
01938 t->write( decoded, true );
01939 }
01940
01941 void KHTMLPart::write( const QString &str )
01942 {
01943 if ( str.isNull() )
01944 return;
01945
01946 if(d->m_bFirstData) {
01947
01948 d->m_doc->setParseMode( DocumentImpl::Strict );
01949 d->m_bFirstData = false;
01950 }
01951 khtml::Tokenizer* t = d->m_doc->tokenizer();
01952 if(t)
01953 t->write( str, true );
01954 }
01955
01956 void KHTMLPart::end()
01957 {
01958
01959 if(d->m_decoder)
01960 write(d->m_decoder->flush());
01961 if (d->m_doc)
01962 d->m_doc->finishParsing();
01963 }
01964
01965 bool KHTMLPart::doOpenStream( const QString& mimeType )
01966 {
01967 KMimeType::Ptr mime = KMimeType::mimeType(mimeType);
01968 if ( mime->is( "text/html" ) || mime->is( "text/xml" ) )
01969 {
01970 begin( url() );
01971 return true;
01972 }
01973 return false;
01974 }
01975
01976 bool KHTMLPart::doWriteStream( const QByteArray& data )
01977 {
01978 write( data.data(), data.size() );
01979 return true;
01980 }
01981
01982 bool KHTMLPart::doCloseStream()
01983 {
01984 end();
01985 return true;
01986 }
01987
01988
01989 void KHTMLPart::paint(QPainter *p, const QRect &rc, int yOff, bool *more)
01990 {
01991 if (!d->m_view) return;
01992 d->m_view->paint(p, rc, yOff, more);
01993 }
01994
01995 void KHTMLPart::stopAnimations()
01996 {
01997 if ( d->m_doc )
01998 d->m_doc->docLoader()->setShowAnimations( KHTMLSettings::KAnimationDisabled );
01999
02000 ConstFrameIt it = d->m_frames.begin();
02001 const ConstFrameIt end = d->m_frames.end();
02002 for (; it != end; ++it )
02003 if ( !(*it)->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
02004 KParts::ReadOnlyPart* const p = ( *it )->m_part;
02005 static_cast<KHTMLPart*>( p )->stopAnimations();
02006 }
02007 }
02008
02009 void KHTMLPart::resetFromScript()
02010 {
02011 closeURL();
02012 d->m_bComplete = false;
02013 d->m_bLoadEventEmitted = false;
02014 disconnect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
02015 connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
02016 d->m_doc->setParsing(true);
02017
02018 emit started( 0L );
02019 }
02020
02021 void KHTMLPart::slotFinishedParsing()
02022 {
02023 d->m_doc->setParsing(false);
02024 checkEmitLoadEvent();
02025 disconnect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
02026
02027 if (!d->m_view)
02028 return;
02029
02030 checkCompleted();
02031 }
02032
02033 void KHTMLPart::slotLoaderRequestStarted( khtml::DocLoader* dl, khtml::CachedObject *obj )
02034 {
02035 if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
02036 KHTMLPart* p = this;
02037 while ( p ) {
02038 KHTMLPart* const op = p;
02039 ++(p->d->m_totalObjectCount);
02040 p = p->parentPart();
02041 if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount
02042 && !op->d->m_progressUpdateTimer.isActive())
02043 op->d->m_progressUpdateTimer.start( 200, true );
02044 }
02045 }
02046 }
02047
02048 void KHTMLPart::slotLoaderRequestDone( khtml::DocLoader* dl, khtml::CachedObject *obj )
02049 {
02050 if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
02051 KHTMLPart* p = this;
02052 while ( p ) {
02053 KHTMLPart* const op = p;
02054 ++(p->d->m_loadedObjects);
02055 p = p->parentPart();
02056 if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount && op->d->m_jobPercent <= 100
02057 && !op->d->m_progressUpdateTimer.isActive())
02058 op->d->m_progressUpdateTimer.start( 200, true );
02059 }
02060 }
02061
02062 checkCompleted();
02063 }
02064
02065 void KHTMLPart::slotProgressUpdate()
02066 {
02067 int percent;
02068 if ( d->m_loadedObjects < d->m_totalObjectCount )
02069 percent = d->m_jobPercent / 4 + ( d->m_loadedObjects*300 ) / ( 4*d->m_totalObjectCount );
02070 else
02071 percent = d->m_jobPercent;
02072
02073 if( d->m_bComplete )
02074 percent = 100;
02075
02076 if (d->m_statusMessagesEnabled) {
02077 if( d->m_bComplete )
02078 emit d->m_extension->infoMessage( i18n( "Page loaded." ));
02079 else if ( d->m_loadedObjects < d->m_totalObjectCount && percent >= 75 )
02080 emit d->m_extension->infoMessage( i18n( "%n Image of %1 loaded.", "%n Images of %1 loaded.", d->m_loadedObjects).arg(d->m_totalObjectCount) );
02081 }
02082
02083 emit d->m_extension->loadingProgress( percent );
02084 }
02085
02086 void KHTMLPart::slotJobSpeed( KIO::Job* , unsigned long speed )
02087 {
02088 d->m_jobspeed = speed;
02089 if (!parentPart())
02090 setStatusBarText(jsStatusBarText(), BarOverrideText);
02091 }
02092
02093 void KHTMLPart::slotJobPercent( KIO::Job* , unsigned long percent )
02094 {
02095 d->m_jobPercent = percent;
02096
02097 if ( !parentPart() )
02098 d->m_progressUpdateTimer.start( 0, true );
02099 }
02100
02101 void KHTMLPart::slotJobDone( KIO::Job* )
02102 {
02103 d->m_jobPercent = 100;
02104
02105 if ( !parentPart() )
02106 d->m_progressUpdateTimer.start( 0, true );
02107 }
02108
02109 void KHTMLPart::slotUserSheetStatDone( KIO::Job *_job )
02110 {
02111 using namespace KIO;
02112
02113 if ( _job->error() ) {
02114 showError( _job );
02115 return;
02116 }
02117
02118 const UDSEntry entry = dynamic_cast<KIO::StatJob *>( _job )->statResult();
02119 UDSEntry::ConstIterator it = entry.begin();
02120 const UDSEntry::ConstIterator end = entry.end();
02121 for ( ; it != end; ++it ) {
02122 if ( ( *it ).m_uds == UDS_MODIFICATION_TIME ) {
02123 break;
02124 }
02125 }
02126
02127
02128
02129 if ( it != end ) {
02130 const time_t lastModified = static_cast<time_t>( ( *it ).m_long );
02131 if ( d->m_userStyleSheetLastModified >= lastModified ) {
02132 return;
02133 }
02134 d->m_userStyleSheetLastModified = lastModified;
02135 }
02136
02137 setUserStyleSheet( KURL( settings()->userStyleSheet() ) );
02138 }
02139
02140 void KHTMLPart::checkCompleted()
02141 {
02142
02143
02144
02145
02146
02147 if (d->m_doc && !d->m_doc->parsing() && !d->m_focusNodeRestored)
02148 {
02149 if (d->m_focusNodeNumber >= 0)
02150 d->m_doc->setFocusNode(d->m_doc->nodeWithAbsIndex(d->m_focusNodeNumber));
02151
02152 d->m_focusNodeRestored = true;
02153 }
02154
02155 bool bPendingChildRedirection = false;
02156
02157 ConstFrameIt it = d->m_frames.begin();
02158 const ConstFrameIt end = d->m_frames.end();
02159 for (; it != end; ++it ) {
02160 if ( !(*it)->m_bCompleted )
02161 {
02162
02163 return;
02164 }
02165
02166 if ( (*it)->m_bPendingRedirection )
02167 bPendingChildRedirection = true;
02168 }
02169
02170
02171 {
02172 ConstFrameIt oi = d->m_objects.begin();
02173 const ConstFrameIt oiEnd = d->m_objects.end();
02174
02175 for (; oi != oiEnd; ++oi )
02176 if ( !(*oi)->m_bCompleted )
02177 return;
02178 }
02179
02180 if ( d->m_bComplete || (d->m_doc && d->m_doc->parsing()) )
02181 return;
02182
02183
02184 int requests = 0;
02185 if ( d->m_doc && d->m_doc->docLoader() )
02186 requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
02187
02188 if ( requests > 0 )
02189 {
02190
02191 return;
02192 }
02193
02194
02195
02196 d->m_bComplete = true;
02197 d->m_cachePolicy = KProtocolManager::cacheControl();
02198 d->m_totalObjectCount = 0;
02199 d->m_loadedObjects = 0;
02200
02201 KHTMLPart* p = this;
02202 while ( p ) {
02203 KHTMLPart* op = p;
02204 p = p->parentPart();
02205 if ( !p && !op->d->m_progressUpdateTimer.isActive())
02206 op->d->m_progressUpdateTimer.start( 0, true );
02207 }
02208
02209 checkEmitLoadEvent();
02210
02211 bool pendingAction = false;
02212
02213 if ( !d->m_redirectURL.isEmpty() )
02214 {
02215
02216
02217 if ( parentPart() == 0 ) {
02218
02219 d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
02220 } else {
02221
02222 }
02223
02224 pendingAction = true;
02225 }
02226 else if ( bPendingChildRedirection )
02227 {
02228 pendingAction = true;
02229 }
02230
02231
02232
02233
02234
02235 d->m_view->complete( pendingAction );
02236
02237
02238 QStringList sheets;
02239 if (d->m_doc)
02240 sheets = d->m_doc->availableStyleSheets();
02241 sheets.prepend( i18n( "Automatic Detection" ) );
02242 d->m_paUseStylesheet->setItems( sheets );
02243
02244 d->m_paUseStylesheet->setEnabled( sheets.count() > 2);
02245 if (sheets.count() > 2)
02246 {
02247 d->m_paUseStylesheet->setCurrentItem(kMax(sheets.findIndex(d->m_sheetUsed), 0));
02248 slotUseStylesheet();
02249 }
02250
02251 setJSDefaultStatusBarText(QString::null);
02252
02253 #ifdef SPEED_DEBUG
02254 kdDebug(6050) << "DONE: " <<d->m_parsetime.elapsed() << endl;
02255 #endif
02256 }
02257
02258 void KHTMLPart::checkEmitLoadEvent()
02259 {
02260 if ( d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing() ) return;
02261
02262 ConstFrameIt it = d->m_frames.begin();
02263 const ConstFrameIt end = d->m_frames.end();
02264 for (; it != end; ++it )
02265 if ( !(*it)->m_bCompleted )
02266 return;
02267
02268 ConstFrameIt oi = d->m_objects.begin();
02269 const ConstFrameIt oiEnd = d->m_objects.end();
02270
02271 for (; oi != oiEnd; ++oi )
02272 if ( !(*oi)->m_bCompleted )
02273 return;
02274
02275
02276
02277
02278 int requests = 0;
02279 if ( d->m_doc && d->m_doc->docLoader() )
02280 requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
02281
02282 if ( requests > 0 )
02283 return;
02284
02285 d->m_bLoadEventEmitted = true;
02286 if (d->m_doc)
02287 d->m_doc->close();
02288 }
02289
02290 const KHTMLSettings *KHTMLPart::settings() const
02291 {
02292 return d->m_settings;
02293 }
02294
02295 #ifndef KDE_NO_COMPAT
02296 KURL KHTMLPart::baseURL() const
02297 {
02298 if ( !d->m_doc ) return KURL();
02299
02300 return d->m_doc->baseURL();
02301 }
02302
02303 QString KHTMLPart::baseTarget() const
02304 {
02305 if ( !d->m_doc ) return QString::null;
02306
02307 return d->m_doc->baseTarget();
02308 }
02309 #endif
02310
02311 KURL KHTMLPart::completeURL( const QString &url )
02312 {
02313 if ( !d->m_doc ) return KURL( url );
02314
02315 if (d->m_decoder)
02316 return KURL(d->m_doc->completeURL(url), d->m_decoder->codec()->mibEnum());
02317
02318 return KURL( d->m_doc->completeURL( url ) );
02319 }
02320
02321
02322
02323 void KHTMLPart::scheduleRedirection( int delay, const QString &url, bool doLockHistory )
02324 {
02325 kdDebug(6050) << "KHTMLPart::scheduleRedirection delay=" << delay << " url=" << url << endl;
02326 kdDebug(6050) << "current redirectURL=" << d->m_redirectURL << " with delay " << d->m_delayRedirect << endl;
02327 if( delay < 24*60*60 &&
02328 ( d->m_redirectURL.isEmpty() || delay <= d->m_delayRedirect) ) {
02329 d->m_delayRedirect = delay;
02330 d->m_redirectURL = url;
02331 d->m_redirectLockHistory = doLockHistory;
02332 kdDebug(6050) << " d->m_bComplete=" << d->m_bComplete << endl;
02333 if ( d->m_bComplete ) {
02334 d->m_redirectionTimer.stop();
02335 d->m_redirectionTimer.start( kMax(0, 1000 * d->m_delayRedirect), true );
02336 }
02337 }
02338 }
02339
02340 void KHTMLPart::slotRedirect()
02341 {
02342 kdDebug(6050) << this << " slotRedirect()" << endl;
02343 QString u = d->m_redirectURL;
02344 d->m_delayRedirect = 0;
02345 d->m_redirectURL = QString::null;
02346
02347
02348 if ( u.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
02349 {
02350 QString script = KURL::decode_string( u.right( u.length() - 11 ) );
02351 kdDebug( 6050 ) << "KHTMLPart::slotRedirect script=" << script << endl;
02352 QVariant res = executeScript( DOM::Node(), script );
02353 if ( res.type() == QVariant::String ) {
02354 begin( url() );
02355 write( res.asString() );
02356 end();
02357 }
02358 return;
02359 }
02360 KParts::URLArgs args;
02361 KURL cUrl( m_url );
02362 KURL url( u );
02363
02364
02365 if ( openedByJS() && d->m_opener )
02366 cUrl = d->m_opener->url();
02367
02368 if (!kapp || !kapp->authorizeURLAction("redirect", cUrl, url))
02369 {
02370 kdWarning(6050) << "KHTMLPart::scheduleRedirection: Redirection from " << cUrl << " to " << url << " REJECTED!" << endl;
02371 return;
02372 }
02373
02374 if ( urlcmp( u, m_url.url(), true, true ) )
02375 {
02376 args.metaData().insert("referrer", d->m_pageReferrer);
02377 }
02378
02379
02380
02381
02382
02383
02384 if (parentPart())
02385 args.metaData().insert("cross-domain", toplevelURL().url());
02386
02387 args.setLockHistory( d->m_redirectLockHistory );
02388
02389 urlSelected( u, 0, 0, "_self", args );
02390 }
02391
02392 void KHTMLPart::slotRedirection(KIO::Job*, const KURL& url)
02393 {
02394
02395
02396 emit d->m_extension->setLocationBarURL( url.prettyURL() );
02397 d->m_workingURL = url;
02398 }
02399
02400 bool KHTMLPart::setEncoding( const QString &name, bool override )
02401 {
02402 d->m_encoding = name;
02403 d->m_haveEncoding = override;
02404
02405 if( !m_url.isEmpty() ) {
02406
02407 closeURL();
02408 KURL url = m_url;
02409 m_url = 0;
02410 d->m_restored = true;
02411 openURL(url);
02412 d->m_restored = false;
02413 }
02414
02415 return true;
02416 }
02417
02418 QString KHTMLPart::encoding() const
02419 {
02420 if(d->m_haveEncoding && !d->m_encoding.isEmpty())
02421 return d->m_encoding;
02422
02423 if(d->m_decoder && d->m_decoder->encoding())
02424 return QString(d->m_decoder->encoding());
02425
02426 return defaultEncoding();
02427 }
02428
02429 QString KHTMLPart::defaultEncoding() const
02430 {
02431 QString encoding = settings()->encoding();
02432 if ( !encoding.isEmpty() )
02433 return encoding;
02434
02435
02436 if ( url().protocol().startsWith( "http" ) )
02437 return "iso-8859-1";
02438 else
02439 return KGlobal::locale()->encoding();
02440 }
02441
02442 void KHTMLPart::setUserStyleSheet(const KURL &url)
02443 {
02444 if ( d->m_doc && d->m_doc->docLoader() )
02445 (void) new khtml::PartStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
02446 }
02447
02448 void KHTMLPart::setUserStyleSheet(const QString &styleSheet)
02449 {
02450 if ( d->m_doc )
02451 d->m_doc->setUserStyleSheet( styleSheet );
02452 }
02453
02454 bool KHTMLPart::gotoAnchor( const QString &name )
02455 {
02456 if (!d->m_doc)
02457 return false;
02458
02459 HTMLCollectionImpl *anchors =
02460 new HTMLCollectionImpl( d->m_doc, HTMLCollectionImpl::DOC_ANCHORS);
02461 anchors->ref();
02462 NodeImpl *n = anchors->namedItem(name);
02463 anchors->deref();
02464
02465 if(!n) {
02466 n = d->m_doc->getElementById( name );
02467 }
02468
02469 d->m_doc->setCSSTarget(n);
02470
02471
02472 bool quirkyName = !n && !d->m_doc->inStrictMode() && (name.isEmpty() || name.lower() == "top");
02473
02474 if (quirkyName) {
02475 d->m_view->setContentsPos(0, 0);
02476 return true;
02477 } else if (!n) {
02478 kdDebug(6050) << "KHTMLPart::gotoAnchor node '" << name << "' not found" << endl;
02479 return false;
02480 }
02481
02482 int x = 0, y = 0;
02483 int gox, dummy;
02484 HTMLElementImpl *a = static_cast<HTMLElementImpl *>(n);
02485
02486 a->getUpperLeftCorner(x, y);
02487 if (x <= d->m_view->contentsX())
02488 gox = x - 10;
02489 else {
02490 gox = d->m_view->contentsX();
02491 if ( x + 10 > d->m_view->contentsX()+d->m_view->visibleWidth()) {
02492 a->getLowerRightCorner(x, dummy);
02493 gox = x - d->m_view->visibleWidth() + 10;
02494 }
02495 }
02496
02497 d->m_view->setContentsPos(gox, y-20);
02498
02499 return true;
02500 }
02501
02502 bool KHTMLPart::nextAnchor()
02503 {
02504 if (!d->m_doc)
02505 return false;
02506 d->m_view->focusNextPrevNode ( true );
02507
02508 return true;
02509 }
02510
02511 bool KHTMLPart::prevAnchor()
02512 {
02513 if (!d->m_doc)
02514 return false;
02515 d->m_view->focusNextPrevNode ( false );
02516
02517 return true;
02518 }
02519
02520 void KHTMLPart::setStandardFont( const QString &name )
02521 {
02522 d->m_settings->setStdFontName(name);
02523 }
02524
02525 void KHTMLPart::setFixedFont( const QString &name )
02526 {
02527 d->m_settings->setFixedFontName(name);
02528 }
02529
02530 void KHTMLPart::setURLCursor( const QCursor &c )
02531 {
02532 d->m_linkCursor = c;
02533 }
02534
02535 QCursor KHTMLPart::urlCursor() const
02536 {
02537 return d->m_linkCursor;
02538 }
02539
02540 bool KHTMLPart::onlyLocalReferences() const
02541 {
02542 return d->m_onlyLocalReferences;
02543 }
02544
02545 void KHTMLPart::setOnlyLocalReferences(bool enable)
02546 {
02547 d->m_onlyLocalReferences = enable;
02548 }
02549
02550 void KHTMLPartPrivate::setFlagRecursively(
02551 bool KHTMLPartPrivate::*flag, bool value)
02552 {
02553
02554 this->*flag = value;
02555
02556
02557 {
02558 QValueList<khtml::ChildFrame*>::Iterator it = m_frames.begin();
02559 const QValueList<khtml::ChildFrame*>::Iterator itEnd = m_frames.end();
02560 for (; it != itEnd; ++it) {
02561 KHTMLPart* const part = static_cast<KHTMLPart *>((KParts::ReadOnlyPart *)(*it)->m_part);
02562 if (part->inherits("KHTMLPart"))
02563 part->d->setFlagRecursively(flag, value);
02564 }
02565 }
02566
02567 {
02568 QValueList<khtml::ChildFrame*>::Iterator it = m_objects.begin();
02569 const QValueList<khtml::ChildFrame*>::Iterator itEnd = m_objects.end();
02570 for (; it != itEnd; ++it) {
02571 KHTMLPart* const part = static_cast<KHTMLPart *>((KParts::ReadOnlyPart *)(*it)->m_part);
02572 if (part->inherits("KHTMLPart"))
02573 part->d->setFlagRecursively(flag, value);
02574 }
02575 }
02576 }
02577
02578 void KHTMLPart::setCaretMode(bool enable)
02579 {
02580 #ifndef KHTML_NO_CARET
02581 kdDebug(6200) << "setCaretMode(" << enable << ")" << endl;
02582 if (isCaretMode() == enable) return;
02583 d->setFlagRecursively(&KHTMLPartPrivate::m_caretMode, enable);
02584
02585 if (!isEditable()) {
02586 if (enable) {
02587 view()->initCaret(true);
02588 view()->ensureCaretVisible();
02589 } else
02590 view()->caretOff();
02591 }
02592 #endif // KHTML_NO_CARET
02593 }
02594
02595 bool KHTMLPart::isCaretMode() const
02596 {
02597 return d->m_caretMode;
02598 }
02599
02600 void KHTMLPart::setEditable(bool enable)
02601 {
02602 #ifndef KHTML_NO_CARET
02603 if (isEditable() == enable) return;
02604 d->setFlagRecursively(&KHTMLPartPrivate::m_designMode, enable);
02605
02606 if (!isCaretMode()) {
02607 if (enable) {
02608 view()->initCaret(true);
02609 view()->ensureCaretVisible();
02610 } else
02611 view()->caretOff();
02612 }
02613 #endif // KHTML_NO_CARET
02614 }
02615
02616 bool KHTMLPart::isEditable() const
02617 {
02618 return d->m_designMode;
02619 }
02620
02621 void KHTMLPart::setCaretPosition(DOM::Node node, long offset, bool extendSelection)
02622 {
02623 #ifndef KHTML_NO_CARET
02624 #if 0
02625 kdDebug(6200) << k_funcinfo << "node: " << node.handle() << " nodeName: "
02626 << node.nodeName().string() << " offset: " << offset
02627 << " extendSelection " << extendSelection << endl;
02628 #endif
02629 if (view()->moveCaretTo(node.handle(), offset, !extendSelection))
02630 emitSelectionChanged();
02631 view()->ensureCaretVisible();
02632 #endif // KHTML_NO_CARET
02633 }
02634
02635 KHTMLPart::CaretDisplayPolicy KHTMLPart::caretDisplayPolicyNonFocused() const
02636 {
02637 #ifndef KHTML_NO_CARET
02638 return (CaretDisplayPolicy)view()->caretDisplayPolicyNonFocused();
02639 #else // KHTML_NO_CARET
02640 return CaretInvisible;
02641 #endif // KHTML_NO_CARET
02642 }
02643
02644 void KHTMLPart::setCaretDisplayPolicyNonFocused(CaretDisplayPolicy policy)
02645 {
02646 #ifndef KHTML_NO_CARET
02647 view()->setCaretDisplayPolicyNonFocused(policy);
02648 #endif // KHTML_NO_CARET
02649 }
02650
02651 void KHTMLPart::setCaretVisible(bool show)
02652 {
02653 #ifndef KHTML_NO_CARET
02654 if (show) {
02655
02656 NodeImpl *caretNode = xmlDocImpl()->focusNode();
02657 if (isCaretMode() || isEditable()
02658 || (caretNode && caretNode->contentEditable())) {
02659 view()->caretOn();
02660 }
02661
02662 } else {
02663
02664 view()->caretOff();
02665
02666 }
02667 #endif // KHTML_NO_CARET
02668 }
02669
02670 void KHTMLPart::findTextBegin()
02671 {
02672 d->m_findPos = -1;
02673 d->m_findNode = 0;
02674 d->m_findPosEnd = -1;
02675 d->m_findNodeEnd= 0;
02676 delete d->m_find;
02677 d->m_find = 0L;
02678 }
02679
02680 bool KHTMLPart::initFindNode( bool selection, bool reverse, bool fromCursor )
02681 {
02682 if ( !d->m_doc )
02683 return false;
02684
02685 DOM::NodeImpl* firstNode = 0L;
02686 if (d->m_doc->isHTMLDocument())
02687 firstNode = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
02688 else
02689 firstNode = d->m_doc;
02690
02691 if ( !firstNode )
02692 {
02693
02694 return false;
02695 }
02696 if ( firstNode->id() == ID_FRAMESET )
02697 {
02698
02699 return false;
02700 }
02701
02702 if ( selection && hasSelection() )
02703 {
02704
02705 if ( !fromCursor )
02706 {
02707 d->m_findNode = reverse ? d->m_selectionEnd.handle() : d->m_selectionStart.handle();
02708 d->m_findPos = reverse ? d->m_endOffset : d->m_startOffset;
02709 }
02710 d->m_findNodeEnd = reverse ? d->m_selectionStart.handle() : d->m_selectionEnd.handle();
02711 d->m_findPosEnd = reverse ? d->m_startOffset : d->m_endOffset;
02712 }
02713 else
02714 {
02715
02716 if ( !fromCursor )
02717 {
02718 d->m_findNode = firstNode;
02719 d->m_findPos = reverse ? -1 : 0;
02720 }
02721 d->m_findNodeEnd = reverse ? firstNode : 0;
02722 d->m_findPosEnd = reverse ? 0 : -1;
02723 if ( reverse )
02724 {
02725
02726 khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
02727 if ( obj )
02728 {
02729
02730 while ( obj->lastChild() )
02731 {
02732 obj = obj->lastChild();
02733 }
02734
02735 while ( !obj->element() && obj->objectAbove() )
02736 {
02737 obj = obj->objectAbove();
02738 }
02739 d->m_findNode = obj->element();
02740 }
02741 }
02742 }
02743 return true;
02744 }
02745
02746
02747 bool KHTMLPart::findTextNext( const QString &str, bool forward, bool caseSensitive, bool isRegExp )
02748 {
02749 if ( !initFindNode( false, !forward, false ) )
02750 return false;
02751 while(1)
02752 {
02753 if( (d->m_findNode->nodeType() == Node::TEXT_NODE || d->m_findNode->nodeType() == Node::CDATA_SECTION_NODE) && d->m_findNode->renderer() )
02754 {
02755 DOMString nodeText = d->m_findNode->nodeValue();
02756 DOMStringImpl *t = nodeText.implementation();
02757 QConstString s(t->s, t->l);
02758
02759 int matchLen = 0;
02760 if ( isRegExp ) {
02761 QRegExp matcher( str );
02762 matcher.setCaseSensitive( caseSensitive );
02763 d->m_findPos = matcher.search(s.string(), d->m_findPos+1);
02764 if ( d->m_findPos != -1 )
02765 matchLen = matcher.matchedLength();
02766 }
02767 else {
02768 d->m_findPos = s.string().find(str, d->m_findPos+1, caseSensitive);
02769 matchLen = str.length();
02770 }
02771
02772 if(d->m_findPos != -1)
02773 {
02774 int x = 0, y = 0;
02775 if(static_cast<khtml::RenderText *>(d->m_findNode->renderer())
02776 ->posOfChar(d->m_findPos, x, y))
02777 d->m_view->setContentsPos(x-50, y-50);
02778
02779 d->m_selectionStart = d->m_findNode;
02780 d->m_startOffset = d->m_findPos;
02781 d->m_selectionEnd = d->m_findNode;
02782 d->m_endOffset = d->m_findPos + matchLen;
02783 d->m_startBeforeEnd = true;
02784
02785 d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
02786 d->m_selectionEnd.handle(), d->m_endOffset );
02787 emitSelectionChanged();
02788 return true;
02789 }
02790 }
02791 d->m_findPos = -1;
02792
02793 NodeImpl *next;
02794
02795 if ( forward )
02796 {
02797 next = d->m_findNode->firstChild();
02798
02799 if(!next) next = d->m_findNode->nextSibling();
02800 while(d->m_findNode && !next) {
02801 d->m_findNode = d->m_findNode->parentNode();
02802 if( d->m_findNode ) {
02803 next = d->m_findNode->nextSibling();
02804 }
02805 }
02806 }
02807 else
02808 {
02809 next = d->m_findNode->lastChild();
02810
02811 if (!next ) next = d->m_findNode->previousSibling();
02812 while ( d->m_findNode && !next )
02813 {
02814 d->m_findNode = d->m_findNode->parentNode();
02815 if( d->m_findNode )
02816 {
02817 next = d->m_findNode->previousSibling();
02818 }
02819 }
02820 }
02821
02822 d->m_findNode = next;
02823 if(!d->m_findNode) return false;
02824 }
02825 }
02826
02827
02828 void KHTMLPart::slotFind()
02829 {
02830 KParts::ReadOnlyPart *part = currentFrame();
02831 if (!part)
02832 return;
02833 if (!part->inherits("KHTMLPart") )
02834 {
02835 kdError(6000) << "slotFind: part is a " << part->className() << ", can't do a search into it" << endl;
02836 return;
02837 }
02838 static_cast<KHTMLPart *>( part )->findText();
02839 }
02840
02841 void KHTMLPart::slotFindNext()
02842 {
02843 KParts::ReadOnlyPart *part = currentFrame();
02844 if (!part)
02845 return;
02846 if (!part->inherits("KHTMLPart") )
02847 {
02848 kdError(6000) << "slotFindNext: part is a " << part->className() << ", can't do a search into it" << endl;
02849 return;
02850 }
02851 static_cast<KHTMLPart *>( part )->findTextNext();
02852 }
02853
02854 void KHTMLPart::slotFindDone()
02855 {
02856
02857 }
02858
02859 void KHTMLPart::slotFindDialogDestroyed()
02860 {
02861 d->m_lastFindState.options = d->m_findDialog->options();
02862 d->m_lastFindState.history = d->m_findDialog->findHistory();
02863 d->m_findDialog->deleteLater();
02864 d->m_findDialog = 0L;
02865 }
02866
02867 void KHTMLPart::findText()
02868 {
02869
02870 if ( !d->m_doc )
02871 return;
02872
02873
02874 if ( d->m_findDialog )
02875 {
02876 KWin::activateWindow( d->m_findDialog->winId() );
02877 return;
02878 }
02879
02880
02881 #ifndef QT_NO_CLIPBOARD
02882 disconnect( kapp->clipboard(), SIGNAL(selectionChanged()), this, SLOT(slotClearSelection()) );
02883 #endif
02884
02885
02886 d->m_findDialog = new KFindDialog( false , widget(), "khtmlfind" );
02887 d->m_findDialog->setHasSelection( hasSelection() );
02888 d->m_findDialog->setHasCursor( d->m_findNode != 0 );
02889 if ( d->m_findNode )
02890 d->m_lastFindState.options |= KFindDialog::FromCursor;
02891
02892
02893 d->m_findDialog->setFindHistory( d->m_lastFindState.history );
02894 d->m_findDialog->setOptions( d->m_lastFindState.options );
02895
02896 d->m_lastFindState.options = -1;
02897
02898 d->m_findDialog->show();
02899 connect( d->m_findDialog, SIGNAL(okClicked()), this, SLOT(slotFindNext()) );
02900 connect( d->m_findDialog, SIGNAL(finished()), this, SLOT(slotFindDialogDestroyed()) );
02901
02902 findText( d->m_findDialog->pattern(), 0 , widget(), d->m_findDialog );
02903 }
02904
02905 void KHTMLPart::findText( const QString &str, long options, QWidget *parent, KFindDialog *findDialog )
02906 {
02907
02908 if ( !d->m_doc )
02909 return;
02910
02911 #ifndef QT_NO_CLIPBOARD
02912 connect( kapp->clipboard(), SIGNAL(selectionChanged()), SLOT(slotClearSelection()) );
02913 #endif
02914
02915
02916 delete d->m_find;
02917 d->m_find = new KFind( str, options, parent, findDialog );
02918 d->m_find->closeFindNextDialog();
02919 connect( d->m_find, SIGNAL( highlight( const QString &, int, int ) ),
02920 this, SLOT( slotHighlight( const QString &, int, int ) ) );
02921
02922
02923
02924 if ( !findDialog )
02925 {
02926 d->m_lastFindState.options = options;
02927 initFindNode( options & KFindDialog::SelectedText,
02928 options & KFindDialog::FindBackwards,
02929 options & KFindDialog::FromCursor );
02930 }
02931 }
02932
02933
02934 bool KHTMLPart::findTextNext()
02935 {
02936 if (!d->m_find)
02937 {
02938
02939 findText();
02940 return false;
02941 }
02942
02943 long options = 0;
02944 if ( d->m_findDialog )
02945 {
02946 if ( d->m_find->pattern() != d->m_findDialog->pattern() ) {
02947 d->m_find->setPattern( d->m_findDialog->pattern() );
02948 d->m_find->resetCounts();
02949 }
02950 options = d->m_findDialog->options();
02951 if ( d->m_lastFindState.options != options )
02952 {
02953 d->m_find->setOptions( options );
02954
02955 if ( options & KFindDialog::SelectedText )
02956 Q_ASSERT( hasSelection() );
02957
02958 long difference = d->m_lastFindState.options ^ options;
02959 if ( difference & (KFindDialog::SelectedText | KFindDialog::FromCursor ) )
02960 {
02961
02962 (void) initFindNode( options & KFindDialog::SelectedText,
02963 options & KFindDialog::FindBackwards,
02964 options & KFindDialog::FromCursor );
02965 }
02966 d->m_lastFindState.options = options;
02967 }
02968 } else
02969 options = d->m_lastFindState.options;
02970
02971 KFind::Result res = KFind::NoMatch;
02972 khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
02973 khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
02974 khtml::RenderTextArea *tmpTextArea=0L;
02975
02976 while( res == KFind::NoMatch )
02977 {
02978 if ( d->m_find->needData() )
02979 {
02980 if ( !obj ) {
02981
02982 break;
02983 }
02984
02985
02986
02987
02988
02989 d->m_stringPortions.clear();
02990 int newLinePos = -1;
02991 QString str;
02992 DOM::NodeImpl* lastNode = d->m_findNode;
02993 while ( obj && newLinePos == -1 )
02994 {
02995
02996 QString s;
02997 bool renderAreaText = obj->parent() && (QCString(obj->parent()->renderName())== "RenderTextArea");
02998 bool renderLineText = (QCString(obj->renderName())== "RenderLineEdit");
02999 if ( renderAreaText )
03000 {
03001 khtml::RenderTextArea *parent= static_cast<khtml::RenderTextArea *>(obj->parent());
03002 s = parent->text();
03003 s = s.replace(0xa0, ' ');
03004 tmpTextArea = parent;
03005 }
03006 else if ( renderLineText )
03007 {
03008 khtml::RenderLineEdit *parentLine= static_cast<khtml::RenderLineEdit *>(obj);
03009 s = parentLine->widget()->text();
03010 s = s.replace(0xa0, ' ');
03011 }
03012 else if ( obj->isText() )
03013 {
03014 bool isLink = false;
03015
03016
03017 if ( options & FindLinksOnly )
03018 {
03019 DOM::NodeImpl *parent = obj->element();
03020 while ( parent )
03021 {
03022 if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
03023 {
03024 isLink = true;
03025 break;
03026 }
03027 parent = parent->parentNode();
03028 }
03029 }
03030 else
03031 {
03032 isLink = true;
03033 }
03034
03035 if ( isLink && obj->parent()!=tmpTextArea )
03036 {
03037 s = static_cast<khtml::RenderText *>(obj)->data().string();
03038 s = s.replace(0xa0, ' ');
03039 }
03040 }
03041 else if ( obj->isBR() )
03042 s = '\n';
03043 else if ( !obj->isInline() && !str.isEmpty() )
03044 s = '\n';
03045
03046 if ( lastNode == d->m_findNodeEnd )
03047 s.truncate( d->m_findPosEnd );
03048 if ( !s.isEmpty() )
03049 {
03050 newLinePos = s.find( '\n' );
03051 int index = str.length();
03052 if ( newLinePos != -1 )
03053 newLinePos += index;
03054 str += s;
03055
03056 d->m_stringPortions.append( KHTMLPartPrivate::StringPortion( index, lastNode ) );
03057 }
03058
03059 if ( obj == end )
03060 obj = 0L;
03061 else
03062 {
03063
03064
03065 do {
03066
03067
03068
03069 obj = (options & KFindDialog::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
03070 } while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
03071 }
03072 if ( obj )
03073 lastNode = obj->element();
03074 else
03075 lastNode = 0;
03076 }
03077
03078 if ( !str.isEmpty() )
03079 {
03080 d->m_find->setData( str, d->m_findPos );
03081 }
03082
03083 d->m_findPos = -1;
03084 d->m_findNode = lastNode;
03085 }
03086 if ( !d->m_find->needData() )
03087 {
03088
03089 res = d->m_find->find();
03090 }
03091 }
03092
03093 if ( res == KFind::NoMatch )
03094 {
03095 kdDebug() << "No more matches." << endl;
03096 if ( !(options & FindNoPopups) && d->m_find->shouldRestart() )
03097 {
03098
03099 initFindNode( false, options & KFindDialog::FindBackwards, false );
03100 findTextNext();
03101 }
03102 else
03103 {
03104
03105
03106
03107 initFindNode( false, options & KFindDialog::FindBackwards, false );
03108 d->m_find->resetCounts();
03109 slotClearSelection();
03110 }
03111 kdDebug() << "Dialog closed." << endl;
03112 }
03113
03114 return res == KFind::Match;
03115 }
03116
03117 void KHTMLPart::slotHighlight( const QString& , int index, int length )
03118 {
03119
03120 QValueList<KHTMLPartPrivate::StringPortion>::Iterator it = d->m_stringPortions.begin();
03121 const QValueList<KHTMLPartPrivate::StringPortion>::Iterator itEnd = d->m_stringPortions.end();
03122 QValueList<KHTMLPartPrivate::StringPortion>::Iterator prev = it;
03123
03124 while ( it != itEnd && (*it).index <= index )
03125 {
03126 prev = it;
03127 ++it;
03128 }
03129 Q_ASSERT ( prev != itEnd );
03130 DOM::NodeImpl* node = (*prev).node;
03131 Q_ASSERT( node );
03132
03133 d->m_selectionStart = node;
03134 d->m_startOffset = index - (*prev).index;
03135
03136 khtml::RenderObject* obj = node->renderer();
03137 khtml::RenderTextArea *parent = 0L;
03138 khtml::RenderLineEdit *parentLine = 0L;
03139 bool renderLineText =false;
03140
03141 QRect highlightedRect;
03142 bool renderAreaText =false;
03143 Q_ASSERT( obj );
03144 if ( obj )
03145 {
03146 int x = 0, y = 0;
03147 renderAreaText = (QCString(obj->parent()->renderName())== "RenderTextArea");
03148 renderLineText = (QCString(obj->renderName())== "RenderLineEdit");
03149
03150
03151 if( renderAreaText )
03152 parent= static_cast<khtml::RenderTextArea *>(obj->parent());
03153 if ( renderLineText )
03154 parentLine= static_cast<khtml::RenderLineEdit *>(obj);
03155 if ( !renderLineText )
03156
03157
03158 {
03159 int dummy;
03160 static_cast<khtml::RenderText *>(node->renderer())
03161 ->caretPos( d->m_startOffset, false, x, y, dummy, dummy );
03162
03163 if ( x != -1 || y != -1 )
03164 {
03165 d->m_view->setContentsPos(x-50, y-50);
03166 highlightedRect.setTopLeft( d->m_view->mapToGlobal(QPoint(x, y)) );
03167 }
03168 }
03169 }
03170
03171 it = prev;
03172 while ( it != itEnd && (*it).index < index + length )
03173 {
03174 prev = it;
03175 ++it;
03176 }
03177 Q_ASSERT ( prev != itEnd );
03178
03179 d->m_selectionEnd = (*prev).node;
03180 d->m_endOffset = index + length - (*prev).index;
03181 d->m_startBeforeEnd = true;
03182
03183
03184 if(d->m_selectionStart == d->m_selectionEnd)
03185 {
03186 bool isLink = false;
03187
03188
03189 DOM::NodeImpl *parent = d->m_selectionStart.handle();
03190 while ( parent )
03191 {
03192 if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
03193 {
03194 isLink = true;
03195 break;
03196 }
03197 parent = parent->parentNode();
03198 }
03199
03200 if(isLink == true)
03201 {
03202 d->m_doc->setFocusNode( parent );
03203 }
03204 }
03205
03206 #if 0
03207 kdDebug(6050) << "slotHighlight: " << d->m_selectionStart.handle() << "," << d->m_startOffset << " - " <<
03208 d->m_selectionEnd.handle() << "," << d->m_endOffset << endl;
03209 it = d->m_stringPortions.begin();
03210 for ( ; it != d->m_stringPortions.end() ; ++it )
03211 kdDebug(6050) << " StringPortion: from index=" << (*it).index << " -> node=" << (*it).node << endl;
03212 #endif
03213 if( renderAreaText )
03214 {
03215 if( parent )
03216 parent->highLightWord( length, d->m_endOffset-length );
03217 }
03218 else if ( renderLineText )
03219 {
03220 if( parentLine )
03221 parentLine->highLightWord( length, d->m_endOffset-length );
03222 }
03223 else
03224 {
03225 d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
03226 d->m_selectionEnd.handle(), d->m_endOffset );
03227 if (d->m_selectionEnd.handle()->renderer() )
03228 {
03229 int x, y, height, dummy;
03230 static_cast<khtml::RenderText *>(d->m_selectionEnd.handle()->renderer())
03231 ->caretPos( d->m_endOffset, false, x, y, dummy, height );
03232
03233 if ( x != -1 || y != -1 )
03234 {
03235
03236
03237 highlightedRect.setBottomRight( d->m_view->mapToGlobal( QPoint(x, y+height) ) );
03238 }
03239 }
03240 }
03241 emitSelectionChanged();
03242
03243
03244 if ( d->m_findDialog && !highlightedRect.isNull() )
03245 {
03246 highlightedRect.moveBy( -d->m_view->contentsX(), -d->m_view->contentsY() );
03247
03248 KDialog::avoidArea( d->m_findDialog, highlightedRect );
03249 }
03250 }
03251
03252 QString KHTMLPart::selectedTextAsHTML() const
03253 {
03254 if(!hasSelection()) {
03255 kdDebug() << "selectedTextAsHTML(): selection is not valid. Returning empty selection" << endl;
03256 return QString::null;
03257 }
03258 if(d->m_startOffset < 0 || d->m_endOffset <0) {
03259 kdDebug() << "invalid values for end/startOffset " << d->m_startOffset << " " << d->m_endOffset << endl;
03260 return QString::null;
03261 }
03262 DOM::Range r = selection();
03263 if(r.isNull() || r.isDetached())
03264 return QString::null;
03265 int exceptioncode = 0;
03266 return r.handle()->toHTML(exceptioncode).string();
03267 }
03268
03269 QString KHTMLPart::selectedText() const
03270 {
03271 bool hasNewLine = true;
03272 bool seenTDTag = false;
03273 QString text;
03274 DOM::Node n = d->m_selectionStart;
03275 while(!n.isNull()) {
03276 if(n.nodeType() == DOM::Node::TEXT_NODE && n.handle()->renderer()) {
03277 DOM::DOMStringImpl *dstr = static_cast<DOM::TextImpl*>(n.handle())->renderString();
03278 QString str(dstr->s, dstr->l);
03279 if(!str.isEmpty()) {
03280 if(seenTDTag) {
03281 text += " ";
03282 seenTDTag = false;
03283 }
03284 hasNewLine = false;
03285 if(n == d->m_selectionStart && n == d->m_selectionEnd)
03286 text = str.mid(d->m_startOffset, d->m_endOffset - d->m_startOffset);
03287 else if(n == d->m_selectionStart)
03288 text = str.mid(d->m_startOffset);
03289 else if(n == d->m_selectionEnd)
03290 text += str.left(d->m_endOffset);
03291 else
03292 text += str;
03293 }
03294 }
03295 else {
03296
03297 unsigned short id = n.elementId();
03298 switch(id) {
03299 case ID_TEXTAREA:
03300 text += static_cast<HTMLTextAreaElementImpl*>(n.handle())->value().string();
03301 break;
03302 case ID_INPUT:
03303 text += static_cast<HTMLInputElementImpl*>(n.handle())->value().string();
03304 break;
03305 case ID_SELECT:
03306 text += static_cast<HTMLSelectElementImpl*>(n.handle())->value().string();
03307 break;
03308 case ID_BR:
03309 text += "\n";
03310 hasNewLine = true;
03311 break;
03312 case ID_IMG:
03313 text += static_cast<HTMLImageElementImpl*>(n.handle())->altText().string();
03314 break;
03315 case ID_TD:
03316 break;
03317 case ID_TH:
03318 case ID_HR:
03319 case ID_OL:
03320 case ID_UL:
03321 case ID_LI:
03322 case ID_DD:
03323 case ID_DL:
03324 case ID_DT:
03325 case ID_PRE:
03326 case ID_BLOCKQUOTE:
03327 case ID_DIV:
03328 if (!hasNewLine)
03329 text += "\n";
03330 hasNewLine = true;
03331 break;
03332 case ID_P:
03333 case ID_TR:
03334 case ID_H1:
03335 case ID_H2:
03336 case ID_H3:
03337 case ID_H4:
03338 case ID_H5:
03339 case ID_H6:
03340 if (!hasNewLine)
03341 text += "\n";
03342
03343 hasNewLine = true;
03344 break;
03345 }
03346 }
03347 if(n == d->m_selectionEnd) break;
03348 DOM::Node next = n.firstChild();
03349 if(next.isNull()) next = n.nextSibling();
03350 while( next.isNull() && !n.parentNode().isNull() ) {
03351 n = n.parentNode();
03352 next = n.nextSibling();
03353 unsigned short id = n.elementId();
03354 switch(id) {
03355 case ID_TD:
03356 seenTDTag = true;
03357 break;
03358 case ID_TH:
03359 case ID_HR:
03360 case ID_OL:
03361 case ID_UL:
03362 case ID_LI:
03363 case ID_DD:
03364 case ID_DL:
03365 case ID_DT:
03366 case ID_PRE:
03367 case ID_BLOCKQUOTE:
03368 case ID_DIV:
03369 seenTDTag = false;
03370 if (!hasNewLine)
03371 text += "\n";
03372 hasNewLine = true;
03373 break;
03374 case ID_P:
03375 case ID_TR:
03376 case ID_H1:
03377 case ID_H2:
03378 case ID_H3:
03379 case ID_H4:
03380 case ID_H5:
03381 case ID_H6:
03382 if (!hasNewLine)
03383 text += "\n";
03384
03385 hasNewLine = true;
03386 break;
03387 }
03388 }
03389
03390 n = next;
03391 }
03392
03393 if(text.isEmpty())
03394 return QString::null;
03395
03396 int start = 0;
03397 int end = text.length();
03398
03399
03400 while ((start < end) && (text[start] == '\n'))
03401 ++start;
03402
03403
03404 while ((start < (end-1)) && (text[end-1] == '\n') && (text[end-2] == '\n'))
03405 --end;
03406
03407 return text.mid(start, end-start);
03408 }
03409
03410 bool KHTMLPart::hasSelection() const
03411 {
03412 if ( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
03413 return false;
03414 if ( d->m_selectionStart == d->m_selectionEnd &&
03415 d->m_startOffset == d->m_endOffset )
03416 return false;
03417 return true;
03418 }
03419
03420 DOM::Range KHTMLPart::selection() const
03421 {
03422 if( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
03423 return DOM::Range();
03424 DOM::Range r = document().createRange();
03425 RangeImpl *rng = r.handle();
03426 int exception = 0;
03427 NodeImpl *n = d->m_selectionStart.handle();
03428 if(!n->parentNode() ||
03429 !n->renderer() ||
03430 (!n->renderer()->isReplaced() && !n->renderer()->isBR())) {
03431 rng->setStart( n, d->m_startOffset, exception );
03432 if(exception) {
03433 kdDebug(6000) << "1 -selection() threw the exception " << exception << ". Returning empty range." << endl;
03434 return DOM::Range();
03435 }
03436 } else {
03437 int o_start = 0;
03438 while ((n = n->previousSibling()))
03439 o_start++;
03440 rng->setStart( d->m_selectionStart.parentNode().handle(), o_start + d->m_startOffset, exception );
03441 if(exception) {
03442 kdDebug(6000) << "2 - selection() threw the exception " << exception << ". Returning empty range." << endl;
03443 return DOM::Range();
03444 }
03445
03446 }
03447
03448 n = d->m_selectionEnd.handle();
03449 if(!n->parentNode() ||
03450 !n->renderer() ||
03451 (!n->renderer()->isReplaced() && !n->renderer()->isBR())) {
03452
03453 rng->setEnd( n, d->m_endOffset, exception );
03454 if(exception) {
03455 kdDebug(6000) << "3 - selection() threw the exception " << exception << ". Returning empty range." << endl;
03456 return DOM::Range();
03457 }
03458
03459 } else {
03460 int o_end = 0;
03461 while ((n = n->previousSibling()))
03462 o_end++;
03463 rng->setEnd( d->m_selectionEnd.parentNode().handle(), o_end + d->m_endOffset, exception);
03464 if(exception) {
03465 kdDebug(6000) << "4 - selection() threw the exception " << exception << ". Returning empty range." << endl;
03466 return DOM::Range();
03467 }
03468
03469 }
03470
03471 return r;
03472 }
03473
03474 void KHTMLPart::selection(DOM::Node &s, long &so, DOM::Node &e, long &eo) const
03475 {
03476 s = d->m_selectionStart;
03477 so = d->m_startOffset;
03478 e = d->m_selectionEnd;
03479 eo = d->m_endOffset;
03480 }
03481
03482 void KHTMLPart::setSelection( const DOM::Range &r )
03483 {
03484
03485
03486 if ( r.collapsed() )
03487 slotClearSelection();
03488 else {
03489 d->m_selectionStart = r.startContainer();
03490 d->m_startOffset = r.startOffset();
03491 d->m_selectionEnd = r.endContainer();
03492 d->m_endOffset = r.endOffset();
03493 d->m_doc->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
03494 d->m_selectionEnd.handle(),d->m_endOffset);
03495 #ifndef KHTML_NO_CARET
03496 bool v = d->m_view->placeCaret();
03497 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
03498 #endif
03499 }
03500 }
03501
03502 void KHTMLPart::slotClearSelection()
03503 {
03504 bool hadSelection = hasSelection();
03505 #ifndef KHTML_NO_CARET
03506
03507
03508
03509 #else
03510 d->m_selectionStart = 0;
03511 d->m_startOffset = 0;
03512 d->m_selectionEnd = 0;
03513 d->m_endOffset = 0;
03514 #endif
03515 if ( d->m_doc ) d->m_doc->clearSelection();
03516 if ( hadSelection )
03517 emitSelectionChanged();
03518 #ifndef KHTML_NO_CARET
03519 bool v = d->m_view->placeCaret();
03520 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
03521 #endif
03522 }
03523
03524 void KHTMLPart::resetHoverText()
03525 {
03526 if( !d->m_overURL.isEmpty() )
03527 {
03528 d->m_overURL = d->m_overURLTarget = QString::null;
03529 emit onURL( QString::null );
03530
03531 setStatusBarText(QString::null, BarHoverText);
03532 emit d->m_extension->mouseOverInfo(0);
03533 }
03534 }
03535
03536 void KHTMLPart::overURL( const QString &url, const QString &target, bool )
03537 {
03538 KURL u = completeURL(url);
03539
03540
03541 if ( url.isEmpty() )
03542 u.setFileName( url );
03543
03544 emit onURL( url );
03545
03546 if ( url.isEmpty() ) {
03547 setStatusBarText(u.htmlURL(), BarHoverText);
03548 return;
03549 }
03550
03551 if (url.find( QString::fromLatin1( "javascript:" ),0, false ) == 0 ) {
03552 QString jscode = KURL::decode_string( url.mid( url.find( "javascript:", 0, false ) ) );
03553 jscode = KStringHandler::rsqueeze( jscode, 80 );
03554 if (url.startsWith("javascript:window.open"))
03555 jscode += i18n(" (In new window)");
03556 setStatusBarText( QStyleSheet::escape( jscode ), BarHoverText );
03557 return;
03558 }
03559
03560 KFileItem item(u, QString::null, KFileItem::Unknown);
03561 emit d->m_extension->mouseOverInfo(&item);
03562
03563 QString com;
03564
03565 KMimeType::Ptr typ = KMimeType::findByURL( u );
03566
03567 if ( typ )
03568 com = typ->comment( u, false );
03569
03570 if ( !u.isValid() ) {
03571 setStatusBarText(u.htmlURL(), BarHoverText);
03572 return;
03573 }
03574
03575 if ( u.isLocalFile() )
03576 {
03577
03578
03579 QCString path = QFile::encodeName( u.path() );
03580
03581 struct stat buff;
03582 bool ok = !stat( path.data(), &buff );
03583
03584 struct stat lbuff;
03585 if (ok) ok = !lstat( path.data(), &lbuff );
03586
03587 QString text = u.htmlURL();
03588 QString text2 = text;
03589
03590 if (ok && S_ISLNK( lbuff.st_mode ) )
03591 {
03592 QString tmp;
03593 if ( com.isNull() )
03594 tmp = i18n( "Symbolic Link");
03595 else
03596 tmp = i18n("%1 (Link)").arg(com);
03597 char buff_two[1024];
03598 text += " -> ";
03599 int n = readlink ( path.data(), buff_two, 1022);
03600 if (n == -1)
03601 {
03602 text2 += " ";
03603 text2 += tmp;
03604 setStatusBarText(text2, BarHoverText);
03605 return;
03606 }
03607 buff_two[n] = 0;
03608
03609 text += buff_two;
03610 text += " ";
03611 text += tmp;
03612 }
03613 else if ( ok && S_ISREG( buff.st_mode ) )
03614 {
03615 if (buff.st_size < 1024)
03616 text = i18n("%2 (%1 bytes)").arg((long) buff.st_size).arg(text2);
03617 else
03618 {
03619 float d = (float) buff.st_size/1024.0;
03620 text = i18n("%2 (%1 K)").arg(KGlobal::locale()->formatNumber(d, 2)).arg(text2);
03621 }
03622 text += " ";
03623 text += com;
03624 }
03625 else if ( ok && S_ISDIR( buff.st_mode ) )
03626 {
03627 text += " ";
03628 text += com;
03629 }
03630 else
03631 {
03632 text += " ";
03633 text += com;
03634 }
03635 setStatusBarText(text, BarHoverText);
03636 }
03637 else
03638 {
03639 QString extra;
03640 if (target.lower() == "_blank")
03641 {
03642 extra = i18n(" (In new window)");
03643 }
03644 else if (!target.isEmpty() &&
03645 (target.lower() != "_top") &&
03646 (target.lower() != "_self") &&
03647 (target.lower() != "_parent"))
03648 {
03649 KHTMLPart *p = this;
03650 while (p->parentPart())
03651 p = p->parentPart();
03652 if (!p->frameExists(target))
03653 extra = i18n(" (In new window)");
03654 else
03655 extra = i18n(" (In other frame)");
03656 }
03657
03658 if (u.protocol() == QString::fromLatin1("mailto")) {
03659 QString mailtoMsg ;
03660 mailtoMsg += i18n("Email to: ") + KURL::decode_string(u.path());
03661 QStringList queries = QStringList::split('&', u.query().mid(1));
03662 QStringList::Iterator it = queries.begin();
03663 const QStringList::Iterator itEnd = queries.end();
03664 for (; it != itEnd; ++it)
03665 if ((*it).startsWith(QString::fromLatin1("subject=")))
03666 mailtoMsg += i18n(" - Subject: ") + KURL::decode_string((*it).mid(8));
03667 else if ((*it).startsWith(QString::fromLatin1("cc=")))
03668 mailtoMsg += i18n(" - CC: ") + KURL::decode_string((*it).mid(3));
03669 else if ((*it).startsWith(QString::fromLatin1("bcc=")))
03670 mailtoMsg += i18n(" - BCC: ") + KURL::decode_string((*it).mid(4));
03671 mailtoMsg = QStyleSheet::escape(mailtoMsg);
03672 mailtoMsg.replace(QRegExp("([\n\r\t]|[ ]{10})"), QString::null);
03673 setStatusBarText("<qt>"+mailtoMsg, BarHoverText);
03674 return;
03675 }
03676
03677 #if 0
03678 else if (u.protocol() == QString::fromLatin1("http")) {
03679 DOM::Node hrefNode = nodeUnderMouse().parentNode();
03680 while (hrefNode.nodeName().string() != QString::fromLatin1("A") && !hrefNode.isNull())
03681 hrefNode = hrefNode.parentNode();
03682
03683 if (!hrefNode.isNull()) {
03684 DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
03685 if (!hreflangNode.isNull()) {
03686 QString countryCode = hreflangNode.nodeValue().string().lower();
03687
03688 if (countryCode == QString::fromLatin1("en"))
03689 countryCode = QString::fromLatin1("gb");
03690 QString flagImg = QString::fromLatin1("<img src=%1>").arg(
03691 locate("locale", QString::fromLatin1("l10n/")
03692 + countryCode
03693 + QString::fromLatin1("/flag.png")));
03694 emit setStatusBarText(flagImg + u.prettyURL() + extra);
03695 }
03696 }
03697 }
03698 #endif
03699 setStatusBarText(u.htmlURL() + extra, BarHoverText);
03700 }
03701 }
03702
03703
03704
03705
03706
03707 void KHTMLPart::urlSelected( const QString &url, int button, int state, const QString &_target, KParts::URLArgs args )
03708 {
03709 bool hasTarget = false;
03710
03711 QString target = _target;
03712 if ( target.isEmpty() && d->m_doc )
03713 target = d->m_doc->baseTarget();
03714 if ( !target.isEmpty() )
03715 hasTarget = true;
03716
03717 if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
03718 {
03719 crossFrameExecuteScript( target, KURL::decode_string( url.mid( 11 ) ) );
03720 return;
03721 }
03722
03723 KURL cURL = completeURL(url);
03724
03725 if ( url.isEmpty() )
03726 cURL.setFileName( url );
03727
03728 if ( !cURL.isValid() )
03729
03730 return;
03731
03732 kdDebug(6050) << this << " urlSelected: complete URL:" << cURL.url() << " target=" << target << endl;
03733
03734 if ( state & ControlButton )
03735 {
03736 args.setNewTab(true);
03737 emit d->m_extension->createNewWindow( cURL, args );
03738 return;
03739 }
03740
03741 if ( button == LeftButton && ( state & ShiftButton ) )
03742 {
03743 KIO::MetaData metaData;
03744 metaData["referrer"] = d->m_referrer;
03745 KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), cURL, metaData );
03746 return;
03747 }
03748
03749 if (!checkLinkSecurity(cURL,
03750 i18n( "<qt>This untrusted page links to<BR><B>%1</B>.<BR>Do you want to follow the link?" ),
03751 i18n( "Follow" )))
03752 return;
03753
03754 args.frameName = target;
03755
03756 args.metaData().insert("main_frame_request",
03757 parentPart() == 0 ? "TRUE":"FALSE");
03758 args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
03759 args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
03760 args.metaData().insert("PropagateHttpHeader", "true");
03761 args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
03762 args.metaData().insert("ssl_activate_warnings", "TRUE");
03763
03764 if ( hasTarget && target != "_self" && target != "_top" && target != "_blank" && target != "_parent" )
03765 {
03766
03767 khtml::ChildFrame *frame = recursiveFrameRequest( this, cURL, args, false );
03768 if ( frame )
03769 {
03770 args.metaData()["referrer"] = d->m_referrer;
03771 requestObject( frame, cURL, args );
03772 return;
03773 }
03774 }
03775
03776 if ( !d->m_bComplete && !hasTarget )
03777 closeURL();
03778
03779 if (!d->m_referrer.isEmpty() && !args.metaData().contains("referrer"))
03780 args.metaData()["referrer"] = d->m_referrer;
03781
03782 if ( button == NoButton && (state & ShiftButton) && (state & ControlButton) )
03783 {
03784 emit d->m_extension->createNewWindow( cURL, args );
03785 return;
03786 }
03787
03788 if ( state & ShiftButton)
03789 {
03790 KParts::WindowArgs winArgs;
03791 winArgs.lowerWindow = true;
03792 KParts::ReadOnlyPart *newPart = 0;
03793 emit d->m_extension->createNewWindow( cURL, args, winArgs, newPart );
03794 return;
03795 }
03796
03797 view()->viewport()->unsetCursor();
03798 emit d->m_extension->openURLRequest( cURL, args );
03799 }
03800
03801 void KHTMLPart::slotViewDocumentSource()
03802 {
03803 KURL url(m_url);
03804 bool isTempFile = false;
03805 if (!(url.isLocalFile()) && KHTMLPageCache::self()->isComplete(d->m_cacheId))
03806 {
03807 KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
03808 if (sourceFile.status() == 0)
03809 {
03810 KHTMLPageCache::self()->saveData(d->m_cacheId, sourceFile.dataStream());
03811 url = KURL();
03812 url.setPath(sourceFile.name());
03813 isTempFile = true;
03814 }
03815 }
03816
03817 (void) KRun::runURL( url, QString::fromLatin1("text/plain"), isTempFile );
03818 }
03819
03820 void KHTMLPart::slotViewPageInfo()
03821 {
03822 KHTMLInfoDlg *dlg = new KHTMLInfoDlg(NULL, "KHTML Page Info Dialog", false, WDestructiveClose);
03823 dlg->_close->setGuiItem(KStdGuiItem::close());
03824
03825 if (d->m_doc)
03826 dlg->_title->setText(d->m_doc->title().string());
03827
03828
03829 if ( parentPart() && d->m_doc && d->m_doc->isHTMLDocument() ) {
03830 dlg->setCaption(i18n("Frame Information"));
03831 }
03832
03833 QString editStr = QString::null;
03834
03835 if (!d->m_pageServices.isEmpty())
03836 editStr = i18n(" <a href=\"%1\">[Properties]</a>").arg(d->m_pageServices);
03837
03838 QString squeezedURL = KStringHandler::csqueeze( url().prettyURL(), 80 );
03839 dlg->_url->setText("<a href=\"" + url().url() + "\">" + squeezedURL + "</a>" + editStr);
03840 if (lastModified().isEmpty())
03841 {
03842 dlg->_lastModified->hide();
03843 dlg->_lmLabel->hide();
03844 }
03845 else
03846 dlg->_lastModified->setText(lastModified());
03847
03848 const QString& enc = encoding();
03849 if (enc.isEmpty()) {
03850 dlg->_eLabel->hide();
03851 dlg->_encoding->hide();
03852 } else {
03853 dlg->_encoding->setText(enc);
03854 }
03855
03856 const QStringList headers = QStringList::split("\n", d->m_httpHeaders);
03857
03858 QStringList::ConstIterator it = headers.begin();
03859 const QStringList::ConstIterator itEnd = headers.end();
03860
03861 for (; it != itEnd; ++it) {
03862 const QStringList header = QStringList::split(QRegExp(":[ ]+"), *it);
03863 if (header.count() != 2)
03864 continue;
03865 new QListViewItem(dlg->_headers, header[0], header[1]);
03866 }
03867
03868 dlg->show();
03869
03870 }
03871
03872
03873 void KHTMLPart::slotViewFrameSource()
03874 {
03875 KParts::ReadOnlyPart *frame = currentFrame();
03876 if ( !frame )
03877 return;
03878
03879 KURL url = frame->url();
03880 bool isTempFile = false;
03881 if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
03882 {
03883 long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;
03884
03885 if (KHTMLPageCache::self()->isComplete(cacheId))
03886 {
03887 KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
03888 if (sourceFile.status() == 0)
03889 {
03890 KHTMLPageCache::self()->saveData(cacheId, sourceFile.dataStream());
03891 url = KURL();
03892 url.setPath(sourceFile.name());
03893 isTempFile = true;
03894 }
03895 }
03896 }
03897
03898 (void) KRun::runURL( url, QString::fromLatin1("text/plain"), isTempFile );
03899 }
03900
03901 KURL KHTMLPart::backgroundURL() const
03902 {
03903
03904 if (!d->m_doc || !d->m_doc->isHTMLDocument())
03905 return KURL();
03906
03907 QString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
03908
03909 return KURL( m_url, relURL );
03910 }
03911
03912 void KHTMLPart::slotSaveBackground()
03913 {
03914 KIO::MetaData metaData;
03915 metaData["referrer"] = d->m_referrer;
03916 KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save Background Image As"), backgroundURL(), metaData );
03917 }
03918
03919 void KHTMLPart::slotSaveDocument()
03920 {
03921 KURL srcURL( m_url );
03922
03923 if ( srcURL.fileName(false).isEmpty() )
03924 srcURL.setFileName( "index.html" );
03925
03926 KIO::MetaData metaData;
03927
03928 KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, "text/html", d->m_cacheId );
03929 }
03930
03931 void KHTMLPart::slotSecurity()
03932 {
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951 KSSLInfoDlg *kid = new KSSLInfoDlg(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );
03952
03953 if (d->m_bSecurityInQuestion)
03954 kid->setSecurityInQuestion(true);
03955
03956 if (d->m_ssl_in_use) {
03957 KSSLCertificate *x = KSSLCertificate::fromString(d->m_ssl_peer_certificate.local8Bit());
03958 if (x) {
03959
03960 const QStringList cl = QStringList::split(QString("\n"), d->m_ssl_peer_chain);
03961 QPtrList<KSSLCertificate> ncl;
03962
03963 ncl.setAutoDelete(true);
03964 QStringList::ConstIterator it = cl.begin();
03965 const QStringList::ConstIterator itEnd = cl.end();
03966 for (; it != itEnd; ++it) {
03967 KSSLCertificate* const y = KSSLCertificate::fromString((*it).local8Bit());
03968 if (y) ncl.append(y);
03969 }
03970
03971 if (ncl.count() > 0)
03972 x->chain().setChain(ncl);
03973
03974 kid->setup(x,
03975 d->m_ssl_peer_ip,
03976 m_url.url(),
03977 d->m_ssl_cipher,
03978 d->m_ssl_cipher_desc,
03979 d->m_ssl_cipher_version,
03980 d->m_ssl_cipher_used_bits.toInt(),
03981 d->m_ssl_cipher_bits.toInt(),
03982 (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt()
03983 );
03984 kid->exec();
03985 delete x;
03986 } else kid->exec();
03987 } else kid->exec();
03988 }
03989
03990 void KHTMLPart::slotSaveFrame()
03991 {
03992 KParts::ReadOnlyPart *frame = currentFrame();
03993 if ( !frame )
03994 return;
03995
03996 KURL srcURL( frame->url() );
03997
03998 if ( srcURL.fileName(false).isEmpty() )
03999 srcURL.setFileName( "index.html" );
04000
04001 KIO::MetaData metaData;
04002
04003 KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save Frame As" ), srcURL, metaData, "text/html" );
04004 }
04005
04006 void KHTMLPart::slotSetEncoding()
04007 {
04008 d->m_automaticDetection->setItemChecked( int( d->m_autoDetectLanguage ), false );
04009 d->m_paSetEncoding->popupMenu()->setItemChecked( 0, false );
04010 d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), true );
04011
04012 QString enc = KGlobal::charsets()->encodingForName( d->m_manualDetection->currentText() );
04013 setEncoding( enc, true );
04014 }
04015
04016 void KHTMLPart::slotUseStylesheet()
04017 {
04018 if (d->m_doc)
04019 {
04020 bool autoselect = (d->m_paUseStylesheet->currentItem() == 0);
04021 d->m_sheetUsed = autoselect ? QString() : d->m_paUseStylesheet->currentText();
04022 d->m_doc->updateStyleSelector();
04023 }
04024 }
04025
04026 void KHTMLPart::updateActions()
04027 {
04028 bool frames = false;
04029
04030 QValueList<khtml::ChildFrame*>::ConstIterator it = d->m_frames.begin();
04031 const QValueList<khtml::ChildFrame*>::ConstIterator end = d->m_frames.end();
04032 for (; it != end; ++it )
04033 if ( (*it)->m_type == khtml::ChildFrame::Frame )
04034 {
04035 frames = true;
04036 break;
04037 }
04038
04039 d->m_paViewFrame->setEnabled( frames );
04040 d->m_paSaveFrame->setEnabled( frames );
04041
04042 if ( frames )
04043 d->m_paFind->setText( i18n( "&Find in Frame..." ) );
04044 else
04045 d->m_paFind->setText( i18n( "&Find..." ) );
04046
04047 KParts::Part *frame = 0;
04048
04049 if ( frames )
04050 frame = currentFrame();
04051
04052 bool enableFindAndSelectAll = true;
04053
04054 if ( frame )
04055 enableFindAndSelectAll = frame->inherits( "KHTMLPart" );
04056
04057 d->m_paFind->setEnabled( enableFindAndSelectAll );
04058 d->m_paSelectAll->setEnabled( enableFindAndSelectAll );
04059
04060 bool enablePrintFrame = false;
04061
04062 if ( frame )
04063 {
04064 QObject *ext = KParts::BrowserExtension::childObject( frame );
04065 if ( ext )
04066 enablePrintFrame = ext->metaObject()->slotNames().contains( "print()" );
04067 }
04068
04069 d->m_paPrintFrame->setEnabled( enablePrintFrame );
04070
04071 QString bgURL;
04072
04073
04074 if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
04075 bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
04076
04077 d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );
04078
04079 if ( d->m_paDebugScript )
04080 d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
04081 }
04082
04083 KParts::LiveConnectExtension *KHTMLPart::liveConnectExtension( const khtml::RenderPart *frame) const {
04084 const ConstFrameIt end = d->m_objects.end();
04085 for(ConstFrameIt it = d->m_objects.begin(); it != end; ++it )
04086 if ((*it)->m_frame == frame)
04087 return (*it)->m_liveconnect;
04088 return 0L;
04089 }
04090
04091 bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName,
04092 const QStringList ¶ms, bool isIFrame )
04093 {
04094
04095 FrameIt it = d->m_frames.find( frameName );
04096 if ( it == d->m_frames.end() )
04097 {
04098 khtml::ChildFrame * child = new khtml::ChildFrame;
04099
04100 child->m_name = frameName;
04101 it = d->m_frames.append( child );
04102 }
04103
04104 (*it)->m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
04105 (*it)->m_frame = frame;
04106 (*it)->m_params = params;
04107
04108
04109 if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
04110 {
04111 QVariant res = executeScript( DOM::Node(frame->element()), KURL::decode_string( url.right( url.length() - 11) ) );
04112 KURL myurl;
04113 myurl.setProtocol("javascript");
04114 if ( res.type() == QVariant::String )
04115 myurl.setPath(res.asString());
04116 return processObjectRequest(*it, myurl, QString("text/html") );
04117 }
04118 KURL u = url.isEmpty() ? KURL() : completeURL( url );
04119 return requestObject( *it, u );
04120 }
04121
04122 QString KHTMLPart::requestFrameName()
04123 {
04124 return QString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
04125 }
04126
04127 bool KHTMLPart::requestObject( khtml::RenderPart *frame, const QString &url, const QString &serviceType,
04128 const QStringList ¶ms )
04129 {
04130
04131 khtml::ChildFrame *child = new khtml::ChildFrame;
04132 FrameIt it = d->m_objects.append( child );
04133 (*it)->m_frame = frame;
04134 (*it)->m_type = khtml::ChildFrame::Object;
04135 (*it)->m_params = params;
04136
04137 KParts::URLArgs args;
04138 args.serviceType = serviceType;
04139 if (!requestObject( *it, completeURL( url ), args ) && !(*it)->m_run) {
04140 (*it)->m_bCompleted = true;
04141 return false;
04142 }
04143 return true;
04144 }
04145
04146 bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &_args )
04147 {
04148 if (!checkLinkSecurity(url))
04149 {
04150 kdDebug(6005) << this << " KHTMLPart::requestObject checkLinkSecurity refused" << endl;
04151 return false;
04152 }
04153 if ( child->m_bPreloaded )
04154 {
04155 kdDebug(6005) << "KHTMLPart::requestObject preload" << endl;
04156 if ( child->m_frame && child->m_part )
04157 child->m_frame->setWidget( child->m_part->widget() );
04158
04159 child->m_bPreloaded = false;
04160 return true;
04161 }
04162
04163
04164
04165 KParts::URLArgs args( _args );
04166
04167 if ( child->m_run )
04168 child->m_run->abort();
04169
04170 if ( child->m_part && !args.reload && urlcmp( child->m_part->url().url(), url.url(), true, true ) )
04171 args.serviceType = child->m_serviceType;
04172
04173 child->m_args = args;
04174 child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload);
04175 child->m_serviceName = QString::null;
04176 if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
04177 child->m_args.metaData()["referrer"] = d->m_referrer;
04178
04179 child->m_args.metaData().insert("PropagateHttpHeader", "true");
04180 child->m_args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
04181 child->m_args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
04182 child->m_args.metaData().insert("main_frame_request",
04183 parentPart() == 0 ? "TRUE":"FALSE");
04184 child->m_args.metaData().insert("ssl_was_in_use",
04185 d->m_ssl_in_use ? "TRUE":"FALSE");
04186 child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
04187 child->m_args.metaData().insert("cross-domain", toplevelURL().url());
04188
04189
04190 if ((url.isEmpty() || url.url() == "about:blank") && args.serviceType.isEmpty())
04191 args.serviceType = QString::fromLatin1( "text/html" );
04192
04193 if ( args.serviceType.isEmpty() ) {
04194 kdDebug(6050) << "Running new KHTMLRun for " << this << " and child=" << child << endl;
04195 child->m_run = new KHTMLRun( this, child, url, child->m_args, true );
04196 d->m_bComplete = false;
04197 return false;
04198 } else {
04199 return processObjectRequest( child, url, args.serviceType );
04200 }
04201 }
04202
04203 bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url, const QString &mimetype )
04204 {
04205
04206
04207
04208
04209
04210 KURL url( _url );
04211
04212
04213 if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) )
04214 {
04215 child->m_bCompleted = true;
04216 checkCompleted();
04217 return true;
04218 }
04219
04220 if (child->m_bNotify)
04221 {
04222 child->m_bNotify = false;
04223 if ( !child->m_args.lockHistory() )
04224 emit d->m_extension->openURLNotify();
04225 }
04226
04227 if ( child->m_serviceType != mimetype || !child->m_part )
04228 {
04229
04230
04231
04232 if ( child->m_type != khtml::ChildFrame::Object )
04233 {
04234 QString suggestedFilename;
04235 if ( child->m_run )
04236 suggestedFilename = child->m_run->suggestedFilename();
04237
04238 KParts::BrowserRun::AskSaveResult res = KParts::BrowserRun::askEmbedOrSave(
04239 url, mimetype, suggestedFilename );
04240 switch( res ) {
04241 case KParts::BrowserRun::Save:
04242 KHTMLPopupGUIClient::saveURL( widget(), i18n( "Save As" ), url, child->m_args.metaData(), QString::null, 0, suggestedFilename);
04243
04244 case KParts::BrowserRun::Cancel:
04245 child->m_bCompleted = true;
04246 checkCompleted();
04247 return true;
04248 default:
04249 break;
04250 }
04251 }
04252
04253 QStringList dummy;
04254 KParts::ReadOnlyPart *part = createPart( d->m_view->viewport(), child->m_name.ascii(), this, child->m_name.ascii(), mimetype, child->m_serviceName, dummy, child->m_params );
04255
04256 if ( !part )
04257 {
04258 if ( child->m_frame )
04259 if (child->m_frame->partLoadingErrorNotify( child, url, mimetype ))
04260 return true;
04261
04262 checkEmitLoadEvent();
04263 return false;
04264 }
04265
04266
04267 if ( child->m_part )
04268 {
04269 if (!::qt_cast<KHTMLPart*>(child->m_part) && child->m_jscript)
04270 child->m_jscript->clear();
04271 partManager()->removePart( (KParts::ReadOnlyPart *)child->m_part );
04272 delete (KParts::ReadOnlyPart *)child->m_part;
04273 if (child->m_liveconnect) {
04274 disconnect(child->m_liveconnect, SIGNAL(partEvent(const unsigned long, const QString &, const KParts::LiveConnectExtension::ArgList &)), child, SLOT(liveConnectEvent(const unsigned long, const QString&, const KParts::LiveConnectExtension::ArgList &)));
04275 child->m_liveconnect = 0L;
04276 }
04277 }
04278
04279 child->m_serviceType = mimetype;
04280 if ( child->m_frame )
04281 child->m_frame->setWidget( part->widget() );
04282
04283 if ( child->m_type != khtml::ChildFrame::Object )
04284 partManager()->addPart( part, false );
04285
04286
04287
04288 child->m_part = part;
04289
04290 if (::qt_cast<KHTMLPart*>(part)) {
04291 static_cast<KHTMLPart*>(part)->d->m_frame = child;
04292 } else if (child->m_frame) {
04293 child->m_liveconnect = KParts::LiveConnectExtension::childObject(part);
04294 if (child->m_liveconnect)
04295 connect(child->m_liveconnect, SIGNAL(partEvent(const unsigned long, const QString &, const KParts::LiveConnectExtension::ArgList &)), child, SLOT(liveConnectEvent(const unsigned long, const QString&, const KParts::LiveConnectExtension::ArgList &)));
04296 }
04297
04298 connect( part, SIGNAL( started( KIO::Job *) ),
04299 this, SLOT( slotChildStarted( KIO::Job *) ) );
04300 connect( part, SIGNAL( completed() ),
04301 this, SLOT( slotChildCompleted() ) );
04302 connect( part, SIGNAL( completed(bool) ),
04303 this, SLOT( slotChildCompleted(bool) ) );
04304 connect( part, SIGNAL( setStatusBarText( const QString & ) ),
04305 this, SIGNAL( setStatusBarText( const QString & ) ) );
04306 if ( part->inherits( "KHTMLPart" ) )
04307 {
04308 connect( this, SIGNAL( completed() ),
04309 part, SLOT( slotParentCompleted() ) );
04310 connect( this, SIGNAL( completed(bool) ),
04311 part, SLOT( slotParentCompleted() ) );
04312
04313
04314 connect( part, SIGNAL( docCreated() ),
04315 this, SLOT( slotChildDocCreated() ) );
04316 }
04317
04318 child->m_extension = KParts::BrowserExtension::childObject( part );
04319
04320 if ( child->m_extension )
04321 {
04322 connect( child->m_extension, SIGNAL( openURLNotify() ),
04323 d->m_extension, SIGNAL( openURLNotify() ) );
04324
04325 connect( child->m_extension, SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
04326 this, SLOT( slotChildURLRequest( const KURL &, const KParts::URLArgs & ) ) );
04327
04328 connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
04329 d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
04330 connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
04331 d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );
04332
04333 connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ),
04334 d->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ) );
04335 connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ),
04336 d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) );
04337 connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ),
04338 d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ) );
04339 connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ),
04340 d->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) );
04341 connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ),
04342 d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) );
04343 connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ),
04344 d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ) );
04345
04346 connect( child->m_extension, SIGNAL( infoMessage( const QString & ) ),
04347 d->m_extension, SIGNAL( infoMessage( const QString & ) ) );
04348
04349 connect( child->m_extension, SIGNAL( requestFocus( KParts::ReadOnlyPart * ) ),
04350 this, SLOT( slotRequestFocus( KParts::ReadOnlyPart * ) ) );
04351
04352 child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
04353 }
04354 }
04355 else if ( child->m_frame && child->m_part &&
04356 child->m_frame->widget() != child->m_part->widget() )
04357 child->m_frame->setWidget( child->m_part->widget() );
04358
04359 checkEmitLoadEvent();
04360
04361
04362 if ( !child->m_part )
04363 return false;
04364
04365 if ( child->m_bPreloaded )
04366 {
04367 if ( child->m_frame && child->m_part )
04368 child->m_frame->setWidget( child->m_part->widget() );
04369
04370 child->m_bPreloaded = false;
04371 return true;
04372 }
04373
04374 child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload);
04375
04376
04377
04378
04379
04380 child->m_args.serviceType = mimetype;
04381
04382
04383 child->m_bCompleted = child->m_type == khtml::ChildFrame::Object;
04384
04385 if ( child->m_extension )
04386 child->m_extension->setURLArgs( child->m_args );
04387
04388 if(url.protocol() == "javascript" || url.url() == "about:blank") {
04389 if (!child->m_part->inherits("KHTMLPart"))
04390 return false;
04391
04392 KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));
04393
04394 p->begin();
04395 if (d->m_doc && p->d->m_doc)
04396 p->d->m_doc->setBaseURL(d->m_doc->baseURL());
04397 if (!url.url().startsWith("about:")) {
04398 p->write(url.path());
04399 } else {
04400 p->m_url = url;
04401
04402 p->write("<HTML><TITLE></TITLE><BODY></BODY></HTML>");
04403 }
04404 p->end();
04405 return true;
04406 }
04407 else if ( !url.isEmpty() )
04408 {
04409
04410 bool b = child->m_part->openURL( url );
04411 if (child->m_bCompleted)
04412 checkCompleted();
04413 return b;
04414 }
04415 else
04416 {
04417 child->m_bCompleted = true;
04418 checkCompleted();
04419 return true;
04420 }
04421 }
04422
04423 KParts::ReadOnlyPart *KHTMLPart::createPart( QWidget *parentWidget, const char *widgetName,
04424 QObject *parent, const char *name, const QString &mimetype,
04425 QString &serviceName, QStringList &serviceTypes,
04426 const QStringList ¶ms )
04427 {
04428 QString constr;
04429 if ( !serviceName.isEmpty() )
04430 constr.append( QString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );
04431
04432 KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, QString::null );
04433
04434 if ( offers.isEmpty() ) {
04435 int pos = mimetype.find( "-plugin" );
04436 if (pos < 0)
04437 return 0L;
04438 QString stripped_mime = mimetype.left( pos );
04439 offers = KTrader::self()->query( stripped_mime, "KParts/ReadOnlyPart", constr, QString::null );
04440 if ( offers.isEmpty() )
04441 return 0L;
04442 }
04443
04444 KTrader::OfferList::ConstIterator it = offers.begin();
04445 const KTrader::OfferList::ConstIterator itEnd = offers.end();
04446 for ( ; it != itEnd; ++it )
04447 {
04448 KService::Ptr service = (*it);
04449
04450 KLibFactory* const factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) );
04451 if ( factory ) {
04452 KParts::ReadOnlyPart *res = 0L;
04453
04454 const char *className = "KParts::ReadOnlyPart";
04455 if ( service->serviceTypes().contains( "Browser/View" ) )
04456 className = "Browser/View";
04457
04458 if ( factory->inherits( "KParts::Factory" ) )
04459 res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
04460 else
04461 res = static_cast<KParts::ReadOnlyPart *>(factory->create( parentWidget, widgetName, className ));
04462
04463 if ( res ) {
04464 serviceTypes = service->serviceTypes();
04465 serviceName = service->name();
04466 return res;
04467 }
04468 } else {
04469
04470 kdWarning() << QString("There was an error loading the module %1.\nThe diagnostics is:\n%2")
04471 .arg(service->name()).arg(KLibLoader::self()->lastErrorMessage()) << endl;
04472 }
04473 }
04474 return 0;
04475 }
04476
04477 KParts::PartManager *KHTMLPart::partManager()
04478 {
04479 if ( !d->m_manager && d->m_view )
04480 {
04481 d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
04482 d->m_manager->setAllowNestedParts( true );
04483 connect( d->m_manager, SIGNAL( activePartChanged( KParts::Part * ) ),
04484 this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
04485 connect( d->m_manager, SIGNAL( partRemoved( KParts::Part * ) ),
04486 this, SLOT( slotPartRemoved( KParts::Part * ) ) );
04487 }
04488
04489 return d->m_manager;
04490 }
04491
04492 void KHTMLPart::submitFormAgain()
04493 {
04494 if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
04495 KHTMLPart::submitForm( d->m_submitForm->submitAction, d->m_submitForm->submitUrl, d->m_submitForm->submitFormData, d->m_submitForm->target, d->m_submitForm->submitContentType, d->m_submitForm->submitBoundary );
04496
04497 delete d->m_submitForm;
04498 d->m_submitForm = 0;
04499 disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
04500 }
04501
04502 void KHTMLPart::submitFormProxy( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
04503 {
04504 submitForm(action, url, formData, _target, contentType, boundary);
04505 }
04506
04507 void KHTMLPart::submitForm( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
04508 {
04509 kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
04510 if (d->m_formNotification == KHTMLPart::Only) {
04511 emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
04512 return;
04513 } else if (d->m_formNotification == KHTMLPart::Before) {
04514 emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
04515 }
04516
04517 KURL u = completeURL( url );
04518
04519 if ( !u.isValid() )
04520 {
04521
04522 return;
04523 }
04524
04525
04526
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537 if (!d->m_submitForm) {
04538 if (u.protocol() != "https" && u.protocol() != "mailto") {
04539 if (d->m_ssl_in_use) {
04540 int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning: This is a secure form but it is attempting to send your data back unencrypted."
04541 "\nA third party may be able to intercept and view this information."
04542 "\nAre you sure you wish to continue?"),
04543 i18n("Network Transmission"),KGuiItem(i18n("&Send Unencrypted")));
04544 if (rc == KMessageBox::Cancel)
04545 return;
04546 } else {
04547 KSSLSettings kss(true);
04548 if (kss.warnOnUnencrypted()) {
04549 int rc = KMessageBox::warningContinueCancel(NULL,
04550 i18n("Warning: Your data is about to be transmitted across the network unencrypted."
04551 "\nAre you sure you wish to continue?"),
04552 i18n("Network Transmission"),
04553 KGuiItem(i18n("&Send Unencrypted")),
04554 "WarnOnUnencryptedForm");
04555
04556 KConfig *config = kapp->config();
04557 QString grpNotifMsgs = QString::fromLatin1("Notification Messages");
04558 KConfigGroupSaver saver( config, grpNotifMsgs );
04559
04560 if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
04561 config->deleteEntry("WarnOnUnencryptedForm");
04562 config->sync();
04563 kss.setWarnOnUnencrypted(false);
04564 kss.save();
04565 }
04566 if (rc == KMessageBox::Cancel)
04567 return;
04568 }
04569 }
04570 }
04571
04572 if (u.protocol() == "mailto") {
04573 int rc = KMessageBox::warningContinueCancel(NULL,
04574 i18n("This site is attempting to submit form data via email.\n"
04575 "Do you want to continue?"),
04576 i18n("Network Transmission"),
04577 KGuiItem(i18n("&Send Email")),
04578 "WarnTriedEmailSubmit");
04579
04580 if (rc == KMessageBox::Cancel) {
04581 return;
04582 }
04583 }
04584 }
04585
04586
04587
04588
04589 QString urlstring = u.url();
04590
04591 if ( urlstring.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
04592 urlstring = KURL::decode_string(urlstring);
04593 crossFrameExecuteScript( _target, urlstring.right( urlstring.length() - 11) );
04594 return;
04595 }
04596
04597 if (!checkLinkSecurity(u,
04598 i18n( "<qt>The form will be submitted to <BR><B>%1</B><BR>on your local filesystem.<BR>Do you want to submit the form?" ),
04599 i18n( "Submit" )))
04600 return;
04601
04602 KParts::URLArgs args;
04603
04604 if (!d->m_referrer.isEmpty())
04605 args.metaData()["referrer"] = d->m_referrer;
04606
04607 args.metaData().insert("PropagateHttpHeader", "true");
04608 args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
04609 args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
04610 args.metaData().insert("main_frame_request",
04611 parentPart() == 0 ? "TRUE":"FALSE");
04612 args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
04613 args.metaData().insert("ssl_activate_warnings", "TRUE");
04614
04615
04616
04617 args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
04618
04619
04620 if (u.protocol() == "mailto") {
04621
04622 QString q = u.query().mid(1);
04623 QStringList nvps = QStringList::split("&", q);
04624 bool triedToAttach = false;
04625
04626 QStringList::Iterator nvp = nvps.begin();
04627 const QStringList::Iterator nvpEnd = nvps.end();
04628
04629
04630
04631
04632 while (nvp != nvpEnd) {
04633 const QStringList pair = QStringList::split("=", *nvp);
04634 if (pair.count() >= 2) {
04635 if (pair.first().lower() == "attach") {
04636 nvp = nvps.remove(nvp);
04637 triedToAttach = true;
04638 } else {
04639 ++nvp;
04640 }
04641 } else {
04642 ++nvp;
04643 }
04644 }
04645
04646 if (triedToAttach)
04647 KMessageBox::information(NULL, i18n("This site attempted to attach a file from your computer in the form submission. The attachment was removed for your protection."), i18n("KDE"), "WarnTriedAttach");
04648
04649
04650 QString bodyEnc;
04651 if (contentType.lower() == "multipart/form-data") {
04652
04653 bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
04654 formData.size()));
04655 } else if (contentType.lower() == "text/plain") {
04656
04657 QString tmpbody = QString::fromLatin1(formData.data(),
04658 formData.size());
04659 tmpbody.replace(QRegExp("[&]"), "\n");
04660 tmpbody.replace(QRegExp("[+]"), " ");
04661 tmpbody = KURL::decode_string(tmpbody);
04662 bodyEnc = KURL::encode_string(tmpbody);
04663 } else {
04664 bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
04665 formData.size()));
04666 }
04667
04668 nvps.append(QString("body=%1").arg(bodyEnc));
04669 q = nvps.join("&");
04670 u.setQuery(q);
04671 }
04672
04673 if ( strcmp( action, "get" ) == 0 ) {
04674 if (u.protocol() != "mailto")
04675 u.setQuery( QString::fromLatin1( formData.data(), formData.size() ) );
04676 args.setDoPost( false );
04677 }
04678 else {
04679 args.postData = formData;
04680 args.setDoPost( true );
04681
04682
04683 if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
04684 args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
04685 else
04686 args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
04687 }
04688
04689 if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
04690 if( d->m_submitForm ) {
04691 kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
04692 return;
04693 }
04694 d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
04695 d->m_submitForm->submitAction = action;
04696 d->m_submitForm->submitUrl = url;
04697 d->m_submitForm->submitFormData = formData;
04698 d->m_submitForm->target = _target;
04699 d->m_submitForm->submitContentType = contentType;
04700 d->m_submitForm->submitBoundary = boundary;
04701 connect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
04702 }
04703 else
04704 {
04705 emit d->m_extension->openURLRequest( u, args );
04706 }
04707 }
04708
04709 void KHTMLPart::popupMenu( const QString &linkUrl )
04710 {
04711 KURL popupURL;
04712 KURL linkKURL;
04713 KParts::URLArgs args;
04714 QString referrer;
04715 KParts::BrowserExtension::PopupFlags itemflags=KParts::BrowserExtension::ShowBookmark | KParts::BrowserExtension::ShowReload;
04716
04717 if ( linkUrl.isEmpty() ) {
04718 KHTMLPart* khtmlPart = this;
04719 while ( khtmlPart->parentPart() )
04720 {
04721 khtmlPart=khtmlPart->parentPart();
04722 }
04723 popupURL = khtmlPart->url();
04724 referrer = khtmlPart->pageReferrer();
04725 if (hasSelection())
04726 itemflags = KParts::BrowserExtension::ShowTextSelectionItems;
04727 else
04728 itemflags |= KParts::BrowserExtension::ShowNavigationItems;
04729 } else {
04730 popupURL = completeURL( linkUrl );
04731 linkKURL = popupURL;
04732 referrer = this->referrer();
04733
04734 if (!(d->m_strSelectedURLTarget).isEmpty() &&
04735 (d->m_strSelectedURLTarget.lower() != "_top") &&
04736 (d->m_strSelectedURLTarget.lower() != "_self") &&
04737 (d->m_strSelectedURLTarget.lower() != "_parent")) {
04738 if (d->m_strSelectedURLTarget.lower() == "_blank")
04739 args.setForcesNewWindow(true);
04740 else {
04741 KHTMLPart *p = this;
04742 while (p->parentPart())
04743 p = p->parentPart();
04744 if (!p->frameExists(d->m_strSelectedURLTarget))
04745 args.setForcesNewWindow(true);
04746 }
04747 }
04748 }
04749
04750
04751
04752 KHTMLPopupGUIClient* client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
04753 QGuardedPtr<QObject> guard( client );
04754
04755 QString mimetype = QString::fromLatin1( "text/html" );
04756 args.metaData()["referrer"] = referrer;
04757
04758 if (!linkUrl.isEmpty())
04759 {
04760 if (popupURL.isLocalFile())
04761 {
04762 mimetype = KMimeType::findByURL(popupURL,0,true,false)->name();
04763 }
04764 else
04765 {
04766 const QString fname(popupURL.fileName(false));
04767 if (!fname.isEmpty() && !popupURL.hasRef() && popupURL.query().isEmpty())
04768 {
04769 KMimeType::Ptr pmt = KMimeType::findByPath(fname,0,true);
04770
04771
04772
04773
04774
04775 if (pmt->name() != KMimeType::defaultMimeType() &&
04776 !pmt->is("application/x-perl") &&
04777 !pmt->is("application/x-perl-module") &&
04778 !pmt->is("application/x-php") &&
04779 !pmt->is("application/x-python-bytecode") &&
04780 !pmt->is("application/x-python") &&
04781 !pmt->is("application/x-shellscript"))
04782 mimetype = pmt->name();
04783 }
04784 }
04785 }
04786
04787 args.serviceType = mimetype;
04788
04789 emit d->m_extension->popupMenu( client, QCursor::pos(), popupURL, args, itemflags, S_IFREG );
04790
04791 if ( !guard.isNull() ) {
04792 delete client;
04793 emit popupMenu(linkUrl, QCursor::pos());
04794 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
04795 }
04796 }
04797
04798 void KHTMLPart::slotParentCompleted()
04799 {
04800
04801 if ( !d->m_redirectURL.isEmpty() && !d->m_redirectionTimer.isActive() )
04802 {
04803
04804 d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
04805 }
04806 }
04807
04808 void KHTMLPart::slotChildStarted( KIO::Job *job )
04809 {
04810 khtml::ChildFrame *child = frame( sender() );
04811
04812 assert( child );
04813
04814 child->m_bCompleted = false;
04815
04816 if ( d->m_bComplete )
04817 {
04818 #if 0
04819
04820 if ( !parentPart() )
04821 {
04822 emit d->m_extension->openURLNotify();
04823 }
04824 #endif
04825 d->m_bComplete = false;
04826 emit started( job );
04827 }
04828 }
04829
04830 void KHTMLPart::slotChildCompleted()
04831 {
04832 slotChildCompleted( false );
04833 }
04834
04835 void KHTMLPart::slotChildCompleted( bool pendingAction )
04836 {
04837 khtml::ChildFrame *child = frame( sender() );
04838
04839 if ( child ) {
04840 kdDebug(6050) << this << " slotChildCompleted child=" << child << " m_frame=" << child->m_frame << endl;
04841 child->m_bCompleted = true;
04842 child->m_bPendingRedirection = pendingAction;
04843 child->m_args = KParts::URLArgs();
04844 }
04845 checkCompleted();
04846 }
04847
04848 void KHTMLPart::slotChildDocCreated()
04849 {
04850 const KHTMLPart* htmlFrame = static_cast<const KHTMLPart *>(sender());
04851
04852
04853
04854 if ( d->m_doc && d->m_doc->isHTMLDocument() )
04855 {
04856 if ( sender()->inherits("KHTMLPart") )
04857 {
04858 DOMString domain = static_cast<HTMLDocumentImpl*>(d->m_doc)->domain();
04859 if (htmlFrame->d->m_doc && htmlFrame->d->m_doc->isHTMLDocument() )
04860
04861 static_cast<HTMLDocumentImpl*>(htmlFrame->d->m_doc)->setDomain( domain );
04862 }
04863 }
04864
04865 disconnect( htmlFrame, SIGNAL( docCreated() ), this, SLOT( slotChildDocCreated() ) );
04866 }
04867
04868 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
04869 {
04870 khtml::ChildFrame *child = frame( sender()->parent() );
04871 KHTMLPart *callingHtmlPart = const_cast<KHTMLPart *>(dynamic_cast<const KHTMLPart *>(sender()->parent()));
04872
04873
04874 QString urlStr = url.url();
04875 if ( urlStr.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
04876 QString script = KURL::decode_string( urlStr.right( urlStr.length() - 11 ) );
04877 executeScript( DOM::Node(), script );
04878 return;
04879 }
04880
04881 QString frameName = args.frameName.lower();
04882 if ( !frameName.isEmpty() ) {
04883 if ( frameName == QString::fromLatin1( "_top" ) )
04884 {
04885 emit d->m_extension->openURLRequest( url, args );
04886 return;
04887 }
04888 else if ( frameName == QString::fromLatin1( "_blank" ) )
04889 {
04890 emit d->m_extension->createNewWindow( url, args );
04891 return;
04892 }
04893 else if ( frameName == QString::fromLatin1( "_parent" ) )
04894 {
04895 KParts::URLArgs newArgs( args );
04896 newArgs.frameName = QString::null;
04897
04898 emit d->m_extension->openURLRequest( url, newArgs );
04899 return;
04900 }
04901 else if ( frameName != QString::fromLatin1( "_self" ) )
04902 {
04903 khtml::ChildFrame *_frame = recursiveFrameRequest( callingHtmlPart, url, args );
04904
04905 if ( !_frame )
04906 {
04907 emit d->m_extension->openURLRequest( url, args );
04908 return;
04909 }
04910
04911 child = _frame;
04912 }
04913 }
04914
04915 if ( child && child->m_type != khtml::ChildFrame::Object ) {
04916
04917 child->m_bNotify = true;
04918 requestObject( child, url, args );
04919 } else if ( frameName== "_self" )
04920 {
04921 KParts::URLArgs newArgs( args );
04922 newArgs.frameName = QString::null;
04923 emit d->m_extension->openURLRequest( url, newArgs );
04924 }
04925 }
04926
04927 void KHTMLPart::slotRequestFocus( KParts::ReadOnlyPart * )
04928 {
04929 emit d->m_extension->requestFocus(this);
04930 }
04931
04932 khtml::ChildFrame *KHTMLPart::frame( const QObject *obj )
04933 {
04934 assert( obj->inherits( "KParts::ReadOnlyPart" ) );
04935 const KParts::ReadOnlyPart* const part = static_cast<const KParts::ReadOnlyPart *>( obj );
04936
04937 FrameIt it = d->m_frames.begin();
04938 const FrameIt end = d->m_frames.end();
04939 for (; it != end; ++it )
04940 if ( (KParts::ReadOnlyPart *)(*it)->m_part == part )
04941 return *it;
04942
04943 FrameIt oi = d->m_objects.begin();
04944 const FrameIt oiEnd = d->m_objects.end();
04945 for (; oi != oiEnd; ++oi )
04946 if ( (KParts::ReadOnlyPart *)(*oi)->m_part == part )
04947 return *oi;
04948
04949 return 0L;
04950 }
04951
04952
04953
04954 bool KHTMLPart::checkFrameAccess(KHTMLPart *callingHtmlPart)
04955 {
04956 if (callingHtmlPart == this)
04957 return true;
04958
04959 if (htmlDocument().isNull()) {
04960 #ifdef DEBUG_FINDFRAME
04961 kdDebug(6050) << "KHTMLPart::checkFrameAccess: Empty part " << this << " URL = " << m_url << endl;
04962 #endif
04963 return false;
04964 }
04965
04966
04967 if (callingHtmlPart && !callingHtmlPart->htmlDocument().isNull() &&
04968 !htmlDocument().isNull()) {
04969 DOM::DOMString actDomain = callingHtmlPart->htmlDocument().domain();
04970 DOM::DOMString destDomain = htmlDocument().domain();
04971
04972 #ifdef DEBUG_FINDFRAME
04973 kdDebug(6050) << "KHTMLPart::checkFrameAccess: actDomain = '" << actDomain.string() << "' destDomain = '" << destDomain.string() << "'" << endl;
04974 #endif
04975
04976 if (actDomain == destDomain)
04977 return true;
04978 }
04979 #ifdef DEBUG_FINDFRAME
04980 else
04981 {
04982 kdDebug(6050) << "KHTMLPart::checkFrameAccess: Unknown part/domain " << callingHtmlPart << " tries to access part " << this << endl;
04983 }
04984 #endif
04985 return false;
04986 }
04987
04988 KHTMLPart *
04989 KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame )
04990 {
04991 #ifdef DEBUG_FINDFRAME
04992 kdDebug(6050) << "KHTMLPart::findFrameParent: this = " << this << " URL = " << m_url << " name = " << name() << " findFrameParent( " << f << " )" << endl;
04993 #endif
04994
04995 KHTMLPart* const callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);
04996
04997 if (!checkFrameAccess(callingHtmlPart))
04998 return 0;
04999
05000 if (!childFrame && !parentPart() && (name() == f))
05001 return this;
05002
05003 FrameIt it = d->m_frames.find( f );
05004 const FrameIt end = d->m_frames.end();
05005 if ( it != end )
05006 {
05007 #ifdef DEBUG_FINDFRAME
05008 kdDebug(6050) << "KHTMLPart::findFrameParent: FOUND!" << endl;
05009 #endif
05010 if (childFrame)
05011 *childFrame = *it;
05012 return this;
05013 }
05014
05015 it = d->m_frames.begin();
05016 for (; it != end; ++it )
05017 {
05018 KParts::ReadOnlyPart* const p = (*it)->m_part;
05019 if ( p && p->inherits( "KHTMLPart" ))
05020 {
05021 KHTMLPart* const frameParent = static_cast<KHTMLPart*>(p)->findFrameParent(callingPart, f, childFrame);
05022 if (frameParent)
05023 return frameParent;
05024 }
05025 }
05026 return 0;
05027 }
05028
05029
05030 KHTMLPart *KHTMLPart::findFrame( const QString &f )
05031 {
05032 khtml::ChildFrame *childFrame;
05033 KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame);
05034 if (parentFrame)
05035 {
05036 KParts::ReadOnlyPart *p = childFrame->m_part;
05037 if ( p && p->inherits( "KHTMLPart" ))
05038 return static_cast<KHTMLPart *>(p);
05039 }
05040 return 0;
05041 }
05042
05043 KParts::ReadOnlyPart *KHTMLPart::findFramePart(const QString &f)
05044 {
05045 khtml::ChildFrame *childFrame;
05046 return findFrameParent(this, f, &childFrame) ? static_cast<KParts::ReadOnlyPart *>(childFrame->m_part) : 0L;
05047 }
05048
05049 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
05050 {
05051 KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
05052
05053
05054
05055 while ( part && part->inherits("KHTMLPart") &&
05056 static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
05057 KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
05058 part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
05059 if ( !part ) return frameset;
05060 }
05061 return part;
05062 }
05063
05064 bool KHTMLPart::frameExists( const QString &frameName )
05065 {
05066 ConstFrameIt it = d->m_frames.find( frameName );
05067 if ( it == d->m_frames.end() )
05068 return false;
05069
05070
05071
05072
05073 return (!(*it)->m_frame.isNull());
05074 }
05075
05076 KJSProxy *KHTMLPart::framejScript(KParts::ReadOnlyPart *framePart)
05077 {
05078 KHTMLPart* const kp = ::qt_cast<KHTMLPart*>(framePart);
05079 if (kp)
05080 return kp->jScript();
05081
05082 FrameIt it = d->m_frames.begin();
05083 const FrameIt itEnd = d->m_frames.end();
05084
05085 for (; it != itEnd; ++it)
05086 if (framePart == (*it)->m_part) {
05087 if (!(*it)->m_jscript)
05088 createJScript(*it);
05089 return (*it)->m_jscript;
05090 }
05091 return 0L;
05092 }
05093
05094 KHTMLPart *KHTMLPart::parentPart()
05095 {
05096 return ::qt_cast<KHTMLPart *>( parent() );
05097 }
05098
05099 khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url,
05100 const KParts::URLArgs &args, bool callParent )
05101 {
05102 #ifdef DEBUG_FINDFRAME
05103 kdDebug( 6050 ) << "KHTMLPart::recursiveFrameRequest this = " << this << ", frame = " << args.frameName << ", url = " << url << endl;
05104 #endif
05105 khtml::ChildFrame *childFrame;
05106 KHTMLPart *childPart = findFrameParent(callingHtmlPart, args.frameName, &childFrame);
05107 if (childPart)
05108 {
05109 if (childPart == this)
05110 return childFrame;
05111
05112 childPart->requestObject( childFrame, url, args );
05113 return 0;
05114 }
05115
05116 if ( parentPart() && callParent )
05117 {
05118 khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, callParent );
05119
05120 if ( res )
05121 parentPart()->requestObject( res, url, args );
05122 }
05123
05124 return 0L;
05125 }
05126
05127 #ifndef NDEBUG
05128 static int s_saveStateIndentLevel = 0;
05129 #endif
05130
05131 void KHTMLPart::saveState( QDataStream &stream )
05132 {
05133 #ifndef NDEBUG
05134 QString indent = QString().leftJustify( s_saveStateIndentLevel * 4, ' ' );
05135 const int indentLevel = s_saveStateIndentLevel++;
05136 kdDebug( 6050 ) << indent << "saveState this=" << this << " '" << name() << "' saving URL " << m_url.url() << endl;
05137 #endif
05138
05139 stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
05140 << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();
05141
05142
05143 int focusNodeNumber;
05144 if (!d->m_focusNodeRestored)
05145 focusNodeNumber = d->m_focusNodeNumber;
05146 else if (d->m_doc && d->m_doc->focusNode())
05147 focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
05148 else
05149 focusNodeNumber = -1;
05150 stream << focusNodeNumber;
05151
05152
05153 stream << d->m_cacheId;
05154
05155
05156 QStringList docState;
05157 if (d->m_doc)
05158 {
05159 docState = d->m_doc->docState();
05160 }
05161 stream << d->m_encoding << d->m_sheetUsed << docState;
05162
05163 stream << d->m_zoomFactor;
05164
05165 stream << d->m_httpHeaders;
05166 stream << d->m_pageServices;
05167 stream << d->m_pageReferrer;
05168
05169
05170 stream << d->m_ssl_in_use
05171 << d->m_ssl_peer_certificate
05172 << d->m_ssl_peer_chain
05173 << d->m_ssl_peer_ip
05174 << d->m_ssl_cipher
05175 << d->m_ssl_cipher_desc
05176 << d->m_ssl_cipher_version
05177 << d->m_ssl_cipher_used_bits
05178 << d->m_ssl_cipher_bits
05179 << d->m_ssl_cert_state
05180 << d->m_ssl_parent_ip
05181 << d->m_ssl_parent_cert;
05182
05183
05184 QStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
05185 KURL::List frameURLLst;
05186 QValueList<QByteArray> frameStateBufferLst;
05187
05188 ConstFrameIt it = d->m_frames.begin();
05189 const ConstFrameIt end = d->m_frames.end();
05190 for (; it != end; ++it )
05191 {
05192 if ( !(*it)->m_part )
05193 continue;
05194
05195 frameNameLst << (*it)->m_name;
05196 frameServiceTypeLst << (*it)->m_serviceType;
05197 frameServiceNameLst << (*it)->m_serviceName;
05198 frameURLLst << (*it)->m_part->url();
05199
05200 QByteArray state;
05201 QDataStream frameStream( state, IO_WriteOnly );
05202
05203 if ( (*it)->m_extension )
05204 (*it)->m_extension->saveState( frameStream );
05205
05206 frameStateBufferLst << state;
05207 }
05208
05209
05210 stream << (Q_UINT32) frameNameLst.count();
05211 stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
05212 #ifndef NDEBUG
05213 s_saveStateIndentLevel = indentLevel;
05214 #endif
05215 }
05216
05217 void KHTMLPart::restoreState( QDataStream &stream )
05218 {
05219 KURL u;
05220 Q_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
05221 Q_UINT32 frameCount;
05222 QStringList frameNames, frameServiceTypes, docState, frameServiceNames;
05223 KURL::List frameURLs;
05224 QValueList<QByteArray> frameStateBuffers;
05225 QValueList<int> fSizes;
05226 QString encoding, sheetUsed;
05227 long old_cacheId = d->m_cacheId;
05228
05229 stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
05230
05231 d->m_view->setMarginWidth( mWidth );
05232 d->m_view->setMarginHeight( mHeight );
05233
05234
05235
05236 stream >> d->m_focusNodeNumber;
05237 d->m_focusNodeRestored = false;
05238
05239 stream >> d->m_cacheId;
05240
05241 stream >> encoding >> sheetUsed >> docState;
05242
05243 d->m_encoding = encoding;
05244 d->m_sheetUsed = sheetUsed;
05245
05246 int zoomFactor;
05247 stream >> zoomFactor;
05248 setZoomFactor(zoomFactor);
05249
05250 stream >> d->m_httpHeaders;
05251 stream >> d->m_pageServices;
05252 stream >> d->m_pageReferrer;
05253
05254
05255 stream >> d->m_ssl_in_use
05256 >> d->m_ssl_peer_certificate
05257 >> d->m_ssl_peer_chain
05258 >> d->m_ssl_peer_ip
05259 >> d->m_ssl_cipher
05260 >> d->m_ssl_cipher_desc
05261 >> d->m_ssl_cipher_version
05262 >> d->m_ssl_cipher_used_bits
05263 >> d->m_ssl_cipher_bits
05264 >> d->m_ssl_cert_state
05265 >> d->m_ssl_parent_ip
05266 >> d->m_ssl_parent_cert;
05267
05268 setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );
05269
05270 stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
05271 >> frameURLs >> frameStateBuffers;
05272
05273 d->m_bComplete = false;
05274 d->m_bLoadEventEmitted = false;
05275
05276
05277
05278
05279
05280 if (d->m_cacheId == old_cacheId)
05281 {
05282
05283 d->m_redirectionTimer.stop();
05284
05285 FrameIt fIt = d->m_frames.begin();
05286 const FrameIt fEnd = d->m_frames.end();
05287
05288 for (; fIt != fEnd; ++fIt )
05289 (*fIt)->m_bCompleted = false;
05290
05291 fIt = d->m_frames.begin();
05292
05293 QStringList::ConstIterator fNameIt = frameNames.begin();
05294 QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
05295 QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
05296 KURL::List::ConstIterator fURLIt = frameURLs.begin();
05297 QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
05298
05299 for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
05300 {
05301 khtml::ChildFrame* const child = *fIt;
05302
05303
05304
05305 if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
05306 {
05307 child->m_bPreloaded = true;
05308 child->m_name = *fNameIt;
05309 child->m_serviceName = *fServiceNameIt;
05310 processObjectRequest( child, *fURLIt, *fServiceTypeIt );
05311 }
05312 if ( child->m_part )
05313 {
05314 child->m_bCompleted = false;
05315 if ( child->m_extension && !(*fBufferIt).isEmpty() )
05316 {
05317 QDataStream frameStream( *fBufferIt, IO_ReadOnly );
05318 child->m_extension->restoreState( frameStream );
05319 }
05320 else
05321 child->m_part->openURL( *fURLIt );
05322 }
05323 }
05324
05325 KParts::URLArgs args( d->m_extension->urlArgs() );
05326 args.xOffset = xOffset;
05327 args.yOffset = yOffset;
05328 args.docState = docState;
05329 d->m_extension->setURLArgs( args );
05330
05331 d->m_view->resizeContents( wContents, hContents);
05332 d->m_view->setContentsPos( xOffset, yOffset );
05333
05334 m_url = u;
05335 }
05336 else
05337 {
05338
05339 closeURL();
05340
05341
05342 d->m_bCleared = false;
05343 clear();
05344 d->m_encoding = encoding;
05345 d->m_sheetUsed = sheetUsed;
05346
05347 QStringList::ConstIterator fNameIt = frameNames.begin();
05348 const QStringList::ConstIterator fNameEnd = frameNames.end();
05349
05350 QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
05351 QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
05352 KURL::List::ConstIterator fURLIt = frameURLs.begin();
05353 QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
05354
05355 for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
05356 {
05357 khtml::ChildFrame* const newChild = new khtml::ChildFrame;
05358 newChild->m_bPreloaded = true;
05359 newChild->m_name = *fNameIt;
05360 newChild->m_serviceName = *fServiceNameIt;
05361
05362
05363
05364 const FrameIt childFrame = d->m_frames.append( newChild );
05365
05366 processObjectRequest( *childFrame, *fURLIt, *fServiceTypeIt );
05367
05368 (*childFrame)->m_bPreloaded = true;
05369
05370 if ( (*childFrame)->m_part )
05371 {
05372 if ( (*childFrame)->m_extension )
05373 if ( (*childFrame)->m_extension && !(*fBufferIt).isEmpty() )
05374 {
05375 QDataStream frameStream( *fBufferIt, IO_ReadOnly );
05376 (*childFrame)->m_extension->restoreState( frameStream );
05377 }
05378 else
05379 (*childFrame)->m_part->openURL( *fURLIt );
05380 }
05381 }
05382
05383 KParts::URLArgs args( d->m_extension->urlArgs() );
05384 args.xOffset = xOffset;
05385 args.yOffset = yOffset;
05386 args.docState = docState;
05387
05388 d->m_extension->setURLArgs( args );
05389 if (!KHTMLPageCache::self()->isComplete(d->m_cacheId))
05390 {
05391 d->m_restored = true;
05392 openURL( u );
05393 d->m_restored = false;
05394 }
05395 else
05396 {
05397 restoreURL( u );
05398 }
05399 }
05400
05401 }
05402
05403 void KHTMLPart::show()
05404 {
05405 if ( d->m_view )
05406 d->m_view->show();
05407 }
05408
05409 void KHTMLPart::hide()
05410 {
05411 if ( d->m_view )
05412 d->m_view->hide();
05413 }
05414
05415 DOM::Node KHTMLPart::nodeUnderMouse() const
05416 {
05417 return d->m_view->nodeUnderMouse();
05418 }
05419
05420 DOM::Node KHTMLPart::nonSharedNodeUnderMouse() const
05421 {
05422 return d->m_view->nonSharedNodeUnderMouse();
05423 }
05424
05425 void KHTMLPart::emitSelectionChanged()
05426 {
05427 emit d->m_extension->enableAction( "copy", hasSelection() );
05428 if ( d->m_findDialog )
05429 d->m_findDialog->setHasSelection( hasSelection() );
05430
05431 emit d->m_extension->selectionInfo( selectedText() );
05432 emit selectionChanged();
05433 }
05434
05435 int KHTMLPart::zoomFactor() const
05436 {
05437 return d->m_zoomFactor;
05438 }
05439
05440
05441 static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
05442 static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
05443 static const int minZoom = 20;
05444 static const int maxZoom = 300;
05445
05446
05447 extern const int KDE_NO_EXPORT fastZoomSizes[] = { 20, 50, 75, 90, 100, 120, 150, 200, 300 };
05448 extern const int KDE_NO_EXPORT fastZoomSizeCount = sizeof fastZoomSizes / sizeof fastZoomSizes[0];
05449
05450 void KHTMLPart::slotIncZoom()
05451 {
05452 zoomIn(zoomSizes, zoomSizeCount);
05453 }
05454
05455 void KHTMLPart::slotDecZoom()
05456 {
05457 zoomOut(zoomSizes, zoomSizeCount);
05458 }
05459
05460 void KHTMLPart::slotIncZoomFast()
05461 {
05462 zoomIn(fastZoomSizes, fastZoomSizeCount);
05463 }
05464
05465 void KHTMLPart::slotDecZoomFast()
05466 {
05467 zoomOut(fastZoomSizes, fastZoomSizeCount);
05468 }
05469
05470 void KHTMLPart::zoomIn(const int stepping[], int count)
05471 {
05472 int zoomFactor = d->m_zoomFactor;
05473
05474 if (zoomFactor < maxZoom) {
05475
05476 for (int i = 0; i < count; ++i)
05477 if (stepping[i] > zoomFactor) {
05478 zoomFactor = stepping[i];
05479 break;
05480 }
05481 setZoomFactor(zoomFactor);
05482 }
05483 }
05484
05485 void KHTMLPart::zoomOut(const int stepping[], int count)
05486 {
05487 int zoomFactor = d->m_zoomFactor;
05488 if (zoomFactor > minZoom) {
05489
05490 for (int i = count-1; i >= 0; --i)
05491 if (stepping[i] < zoomFactor) {
05492 zoomFactor = stepping[i];
05493 break;
05494 }
05495 setZoomFactor(zoomFactor);
05496 }
05497 }
05498
05499 void KHTMLPart::setZoomFactor (int percent)
05500 {
05501 if (percent < minZoom) percent = minZoom;
05502 if (percent > maxZoom) percent = maxZoom;
05503 if (d->m_zoomFactor == percent) return;
05504 d->m_zoomFactor = percent;
05505
05506 if(d->m_doc) {
05507 QApplication::setOverrideCursor( waitCursor );
05508 if (d->m_doc->styleSelector())
05509 d->m_doc->styleSelector()->computeFontSizes(d->m_doc->paintDeviceMetrics(), d->m_zoomFactor);
05510 d->m_doc->recalcStyle( NodeImpl::Force );
05511 QApplication::restoreOverrideCursor();
05512 }
05513
05514 ConstFrameIt it = d->m_frames.begin();
05515 const ConstFrameIt end = d->m_frames.end();
05516 for (; it != end; ++it )
05517 if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
05518 KParts::ReadOnlyPart* const p = ( *it )->m_part;
05519 static_cast<KHTMLPart*>( p )->setZoomFactor(d->m_zoomFactor);
05520 }
05521
05522 if ( d->m_guiProfile == BrowserViewGUI ) {
05523 d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
05524 d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
05525 }
05526 }
05527
05528 void KHTMLPart::slotZoomView( int delta )
05529 {
05530 if ( delta < 0 )
05531 slotIncZoom();
05532 else
05533 slotDecZoom();
05534 }
05535
05536 void KHTMLPart::setStatusBarText( const QString& text, StatusBarPriority p)
05537 {
05538 if (!d->m_statusMessagesEnabled)
05539 return;
05540
05541 d->m_statusBarText[p] = text;
05542
05543
05544 QString tobe = d->m_statusBarText[BarHoverText];
05545 if (tobe.isEmpty())
05546 tobe = d->m_statusBarText[BarOverrideText];
05547 if (tobe.isEmpty()) {
05548 tobe = d->m_statusBarText[BarDefaultText];
05549 if (!tobe.isEmpty() && d->m_jobspeed)
05550 tobe += " ";
05551 if (d->m_jobspeed)
05552 tobe += i18n( "(%1/s)" ).arg( KIO::convertSize( d->m_jobspeed ) );
05553 }
05554 tobe = "<qt>"+tobe;
05555
05556 emit ReadOnlyPart::setStatusBarText(tobe);
05557 }
05558
05559
05560 void KHTMLPart::setJSStatusBarText( const QString &text )
05561 {
05562 setStatusBarText(text, BarOverrideText);
05563 }
05564
05565 void KHTMLPart::setJSDefaultStatusBarText( const QString &text )
05566 {
05567 setStatusBarText(text, BarDefaultText);
05568 }
05569
05570 QString KHTMLPart::jsStatusBarText() const
05571 {
05572 return d->m_statusBarText[BarOverrideText];
05573 }
05574
05575 QString KHTMLPart::jsDefaultStatusBarText() const
05576 {
05577 return d->m_statusBarText[BarDefaultText];
05578 }
05579
05580 QString KHTMLPart::referrer() const
05581 {
05582 return d->m_referrer;
05583 }
05584
05585 QString KHTMLPart::pageReferrer() const
05586 {
05587 KURL referrerURL = KURL( d->m_pageReferrer );
05588 if (referrerURL.isValid())
05589 {
05590 QString protocol = referrerURL.protocol();
05591
05592 if ((protocol == "http") ||
05593 ((protocol == "https") && (m_url.protocol() == "https")))
05594 {
05595 referrerURL.setRef(QString::null);
05596 referrerURL.setUser(QString::null);
05597 referrerURL.setPass(QString::null);
05598 return referrerURL.url();
05599 }
05600 }
05601
05602 return QString::null;
05603 }
05604
05605
05606 QString KHTMLPart::lastModified() const
05607 {
05608 if ( d->m_lastModified.isEmpty() && m_url.isLocalFile() ) {
05609
05610
05611
05612 QDateTime lastModif = QFileInfo( m_url.path() ).lastModified();
05613 d->m_lastModified = lastModif.toString( Qt::LocalDate );
05614 }
05615
05616 return d->m_lastModified;
05617 }
05618
05619 void KHTMLPart::slotLoadImages()
05620 {
05621 if (d->m_doc )
05622 d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );
05623
05624 ConstFrameIt it = d->m_frames.begin();
05625 const ConstFrameIt end = d->m_frames.end();
05626 for (; it != end; ++it )
05627 if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
05628 KParts::ReadOnlyPart* const p = ( *it )->m_part;
05629 static_cast<KHTMLPart*>( p )->slotLoadImages();
05630 }
05631 }
05632
05633 void KHTMLPart::reparseConfiguration()
05634 {
05635 KHTMLSettings *settings = KHTMLFactory::defaultHTMLSettings();
05636 settings->init();
05637
05638 setAutoloadImages( settings->autoLoadImages() );
05639 if (d->m_doc)
05640 d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );
05641
05642 d->m_bOpenMiddleClick = settings->isOpenMiddleClickEnabled();
05643 d->m_bBackRightClick = settings->isBackRightClickEnabled();
05644 d->m_bJScriptEnabled = settings->isJavaScriptEnabled(m_url.host());
05645 setDebugScript( settings->isJavaScriptDebugEnabled() );
05646 d->m_bJavaEnabled = settings->isJavaEnabled(m_url.host());
05647 d->m_bPluginsEnabled = settings->isPluginsEnabled(m_url.host());
05648 d->m_metaRefreshEnabled = settings->isAutoDelayedActionsEnabled ();
05649
05650 delete d->m_settings;
05651 d->m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings());
05652
05653 QApplication::setOverrideCursor( waitCursor );
05654 khtml::CSSStyleSelector::reparseConfiguration();
05655 if(d->m_doc) d->m_doc->updateStyleSelector();
05656 QApplication::restoreOverrideCursor();
05657 }
05658
05659 QStringList KHTMLPart::frameNames() const
05660 {
05661 QStringList res;
05662
05663 ConstFrameIt it = d->m_frames.begin();
05664 const ConstFrameIt end = d->m_frames.end();
05665 for (; it != end; ++it )
05666 if (!(*it)->m_bPreloaded)
05667 res += (*it)->m_name;
05668
05669 return res;
05670 }
05671
05672 QPtrList<KParts::ReadOnlyPart> KHTMLPart::frames() const
05673 {
05674 QPtrList<KParts::ReadOnlyPart> res;
05675
05676 ConstFrameIt it = d->m_frames.begin();
05677 const ConstFrameIt end = d->m_frames.end();
05678 for (; it != end; ++it )
05679 if (!(*it)->m_bPreloaded)
05680 res.append( (*it)->m_part );
05681
05682 return res;
05683 }
05684
05685 bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
05686 {
05687 kdDebug( 6050 ) << this << "KHTMLPart::openURLInFrame " << url << endl;
05688 FrameIt it = d->m_frames.find( urlArgs.frameName );
05689
05690 if ( it == d->m_frames.end() )
05691 return false;
05692
05693
05694 if ( !urlArgs.lockHistory() )
05695 emit d->m_extension->openURLNotify();
05696
05697 requestObject( *it, url, urlArgs );
05698
05699 return true;
05700 }
05701
05702 void KHTMLPart::setDNDEnabled( bool b )
05703 {
05704 d->m_bDnd = b;
05705 }
05706
05707 bool KHTMLPart::dndEnabled() const
05708 {
05709 return d->m_bDnd;
05710 }
05711
05712 void KHTMLPart::customEvent( QCustomEvent *event )
05713 {
05714 if ( khtml::MousePressEvent::test( event ) )
05715 {
05716 khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
05717 return;
05718 }
05719
05720 if ( khtml::MouseDoubleClickEvent::test( event ) )
05721 {
05722 khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
05723 return;
05724 }
05725
05726 if ( khtml::MouseMoveEvent::test( event ) )
05727 {
05728 khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
05729 return;
05730 }
05731
05732 if ( khtml::MouseReleaseEvent::test( event ) )
05733 {
05734 khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
05735 return;
05736 }
05737
05738 if ( khtml::DrawContentsEvent::test( event ) )
05739 {
05740 khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
05741 return;
05742 }
05743
05744 KParts::ReadOnlyPart::customEvent( event );
05745 }
05746
05752 static bool firstRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
05753 {
05754 for (khtml::RenderObject *n = renderNode; n; n = n->nextSibling()) {
05755 if (n->isText()) {
05756 khtml::RenderText* const textRenderer = static_cast<khtml::RenderText *>(n);
05757 const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
05758 const unsigned lim = runs.count();
05759 for (unsigned i = 0; i != lim; ++i) {
05760 if (runs[i]->m_y == y) {
05761 startNode = textRenderer->element();
05762 startOffset = runs[i]->m_start;
05763 return true;
05764 }
05765 }
05766 }
05767
05768 if (firstRunAt(n->firstChild(), y, startNode, startOffset)) {
05769 return true;
05770 }
05771 }
05772
05773 return false;
05774 }
05775
05781 static bool lastRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset)
05782 {
05783 khtml::RenderObject *n = renderNode;
05784 if (!n) {
05785 return false;
05786 }
05787 khtml::RenderObject *next;
05788 while ((next = n->nextSibling())) {
05789 n = next;
05790 }
05791
05792 while (1) {
05793 if (lastRunAt(n->firstChild(), y, endNode, endOffset)) {
05794 return true;
05795 }
05796
05797 if (n->isText()) {
05798 khtml::RenderText* const textRenderer = static_cast<khtml::RenderText *>(n);
05799 const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
05800 for (int i = (int)runs.count()-1; i >= 0; --i) {
05801 if (runs[i]->m_y == y) {
05802 endNode = textRenderer->element();
05803 endOffset = runs[i]->m_start + runs[i]->m_len;
05804 return true;
05805 }
05806 }
05807 }
05808
05809 if (n == renderNode) {
05810 return false;
05811 }
05812
05813 n = n->previousSibling();
05814 }
05815 }
05816
05817 void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
05818 {
05819 DOM::DOMString url = event->url();
05820 QMouseEvent *_mouse = event->qmouseEvent();
05821 DOM::Node innerNode = event->innerNode();
05822 d->m_mousePressNode = innerNode;
05823
05824 d->m_dragStartPos = _mouse->pos();
05825
05826 if ( !event->url().isNull() ) {
05827 d->m_strSelectedURL = event->url().string();
05828 d->m_strSelectedURLTarget = event->target().string();
05829 }
05830 else
05831 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
05832
05833 if ( _mouse->button() == LeftButton ||
05834 _mouse->button() == MidButton )
05835 {
05836 d->m_bMousePressed = true;
05837
05838 #ifndef KHTML_NO_SELECTION
05839 if ( _mouse->button() == LeftButton )
05840 {
05841 if ( (!d->m_strSelectedURL.isNull() && !isEditable())
05842 || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) )
05843 return;
05844 if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
05845 int offset = 0;
05846 DOM::NodeImpl* node = 0;
05847 khtml::RenderObject::SelPointState state;
05848 innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
05849 event->absX()-innerNode.handle()->renderer()->xPos(),
05850 event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state );
05851 d->m_extendMode = d->ExtendByChar;
05852 #ifdef KHTML_NO_CARET
05853 d->m_selectionStart = node;
05854 d->m_startOffset = offset;
05855
05856
05857
05858
05859
05860 d->m_selectionEnd = d->m_selectionStart;
05861 d->m_endOffset = d->m_startOffset;
05862 d->m_doc->clearSelection();
05863 #else // KHTML_NO_CARET
05864 d->m_view->moveCaretTo(node, offset, (_mouse->state() & ShiftButton) == 0);
05865 #endif // KHTML_NO_CARET
05866 d->m_initialNode = d->m_selectionStart;
05867 d->m_initialOffset = d->m_startOffset;
05868
05869 }
05870 else
05871 {
05872 #ifndef KHTML_NO_CARET
05873
05874 #else
05875 d->m_selectionStart = DOM::Node();
05876 d->m_selectionEnd = DOM::Node();
05877 #endif
05878 }
05879 emitSelectionChanged();
05880 startAutoScroll();
05881 }
05882 #else
05883 d->m_dragLastPos = _mouse->globalPos();
05884 #endif
05885 }
05886
05887 if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
05888 {
05889 d->m_bRightMousePressed = true;
05890 } else if ( _mouse->button() == RightButton )
05891 {
05892 popupMenu( d->m_strSelectedURL );
05893
05894 }
05895 }
05896
05897 void KHTMLPart::khtmlMouseDoubleClickEvent( khtml::MouseDoubleClickEvent *event )
05898 {
05899 QMouseEvent *_mouse = event->qmouseEvent();
05900 if ( _mouse->button() == LeftButton )
05901 {
05902 d->m_bMousePressed = true;
05903 DOM::Node innerNode = event->innerNode();
05904
05905 if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
05906 int offset = 0;
05907 DOM::NodeImpl* node = 0;
05908 khtml::RenderObject::SelPointState state;
05909 innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
05910 event->absX()-innerNode.handle()->renderer()->xPos(),
05911 event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state);
05912
05913
05914
05915 if ( node && node->renderer() )
05916 {
05917
05918 bool selectLine = (event->clickCount() == 3);
05919 d->m_extendMode = selectLine ? d->ExtendByLine : d->ExtendByWord;
05920
05921
05922 if (_mouse->state() & ShiftButton) {
05923 d->caretNode() = node;
05924 d->caretOffset() = offset;
05925 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
05926 d->m_selectionStart.handle(), d->m_startOffset,
05927 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
05928 d->m_initialNode = d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd;
05929 d->m_initialOffset = d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset;
05930 } else {
05931 d->m_selectionStart = d->m_selectionEnd = node;
05932 d->m_startOffset = d->m_endOffset = offset;
05933 d->m_startBeforeEnd = true;
05934 d->m_initialNode = node;
05935 d->m_initialOffset = offset;
05936 }
05937
05938
05939
05940 extendSelection( d->m_selectionStart.handle(), d->m_startOffset, d->m_selectionStart, d->m_startOffset, !d->m_startBeforeEnd, selectLine );
05941
05942 extendSelection( d->m_selectionEnd.handle(), d->m_endOffset, d->m_selectionEnd, d->m_endOffset, d->m_startBeforeEnd, selectLine );
05943
05944
05945
05946
05947 emitSelectionChanged();
05948 d->m_doc
05949 ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
05950 d->m_selectionEnd.handle(),d->m_endOffset);
05951 #ifndef KHTML_NO_CARET
05952 bool v = d->m_view->placeCaret();
05953 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
05954 #endif
05955 startAutoScroll();
05956 }
05957 }
05958 }
05959 }
05960
05961 void KHTMLPart::extendSelection( DOM::NodeImpl* node, long offset, DOM::Node& selectionNode, long& selectionOffset, bool right, bool selectLines )
05962 {
05963 khtml::RenderObject* obj = node->renderer();
05964
05965 if (obj->isText() && selectLines) {
05966 int pos;
05967 khtml::RenderText *renderer = static_cast<khtml::RenderText *>(obj);
05968 khtml::InlineTextBox *run = renderer->findInlineTextBox( offset, pos );
05969 DOMString t = node->nodeValue();
05970 DOM::NodeImpl* selNode = 0;
05971 long selOfs = 0;
05972
05973 if (!run)
05974 return;
05975
05976 int selectionPointY = run->m_y;
05977
05978
05979 khtml::RenderObject *renderNode = renderer;
05980 while (renderNode && renderNode->isInline())
05981 renderNode = renderNode->parent();
05982
05983 renderNode = renderNode->firstChild();
05984
05985 if (right) {
05986
05987
05988 if (!lastRunAt (renderNode, selectionPointY, selNode, selOfs))
05989 return;
05990 } else {
05991
05992
05993 if (!firstRunAt (renderNode, selectionPointY, selNode, selOfs))
05994 return;
05995 }
05996
05997 selectionNode = selNode;
05998 selectionOffset = selOfs;
05999 return;
06000 }
06001
06002 QString str;
06003 int len = 0;
06004 if ( obj->isText() ) {
06005 str = static_cast<khtml::RenderText *>(obj)->data().string();
06006 len = str.length();
06007 }
06008
06009 QChar ch;
06010 do {
06011
06012 if ( node ) {
06013 selectionNode = node;
06014 selectionOffset = offset;
06015 }
06016
06017
06018 while ( obj && ( (right && offset >= len-1) || (!right && offset <= 0) ) )
06019 {
06020 obj = right ? obj->objectBelow() : obj->objectAbove();
06021
06022 if ( obj ) {
06023
06024 str = QString::null;
06025 if ( obj->isText() )
06026 str = static_cast<khtml::RenderText *>(obj)->data().string();
06027 else if ( obj->isBR() )
06028 str = '\n';
06029 else if ( !obj->isInline() ) {
06030 obj = 0L;
06031 break;
06032 }
06033 len = str.length();
06034
06035
06036 if ( right )
06037 offset = -1;
06038 else
06039 offset = len;
06040 }
06041 }
06042 if ( !obj )
06043 break;
06044 node = obj->element();
06045 if ( right )
06046 {
06047 Q_ASSERT( offset < len-1 );
06048 ++offset;
06049 }
06050 else
06051 {
06052 Q_ASSERT( offset > 0 );
06053 --offset;
06054 }
06055
06056
06057 ch = str[ offset ];
06058
06059 } while ( !ch.isSpace() && !ch.isPunct() );
06060
06061
06062 if (right) ++selectionOffset;
06063 }
06064
06065 #ifndef KHTML_NO_SELECTION
06066 void KHTMLPart::extendSelectionTo(int x, int y, int absX, int absY, const DOM::Node &innerNode)
06067 {
06068 int offset;
06069
06070 DOM::NodeImpl* node=0;
06071 khtml::RenderObject::SelPointState state;
06072 innerNode.handle()->renderer()->checkSelectionPoint( x, y,
06073 absX-innerNode.handle()->renderer()->xPos(),
06074 absY-innerNode.handle()->renderer()->yPos(), node, offset, state);
06075 if (!node || !node->renderer()) return;
06076
06077
06078
06079
06080 bool withinNode = innerNode == node;
06081
06082
06083
06084 if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
06085 d->m_initialNode.isNull() ||
06086 !d->m_selectionStart.handle()->renderer() ||
06087 !d->m_selectionEnd.handle()->renderer()) return;
06088
06089 if (d->m_extendMode != d->ExtendByChar) {
06090
06091 bool caretBeforeInit = RangeImpl::compareBoundaryPoints(
06092 d->caretNode().handle(), d->caretOffset(),
06093 d->m_initialNode.handle(), d->m_initialOffset) <= 0;
06094 bool nodeBeforeInit = RangeImpl::compareBoundaryPoints(node, offset,
06095 d->m_initialNode.handle(), d->m_initialOffset) <= 0;
06096
06097 if (caretBeforeInit != nodeBeforeInit) {
06098
06099 extendSelection(d->m_initialNode.handle(), d->m_initialOffset,
06100 d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd,
06101 d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset,
06102 nodeBeforeInit, d->m_extendMode == d->ExtendByLine);
06103 }
06104 }
06105
06106 d->caretNode() = node;
06107 d->caretOffset() = offset;
06108
06109
06110 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
06111 d->m_selectionStart.handle(), d->m_startOffset,
06112 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
06113
06114 if ( !d->m_selectionStart.isNull() && !d->m_selectionEnd.isNull() )
06115 {
06116
06117 if (d->m_extendMode != d->ExtendByChar && withinNode)
06118 extendSelection( node, offset, d->caretNode(), d->caretOffset(), d->m_startBeforeEnd ^ !d->m_extendAtEnd, d->m_extendMode == d->ExtendByLine );
06119
06120 if (d->m_selectionEnd == d->m_selectionStart && d->m_endOffset < d->m_startOffset)
06121 d->m_doc
06122 ->setSelection(d->m_selectionStart.handle(),d->m_endOffset,
06123 d->m_selectionEnd.handle(),d->m_startOffset);
06124 else if (d->m_startBeforeEnd)
06125 d->m_doc
06126 ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
06127 d->m_selectionEnd.handle(),d->m_endOffset);
06128 else
06129 d->m_doc
06130 ->setSelection(d->m_selectionEnd.handle(),d->m_endOffset,
06131 d->m_selectionStart.handle(),d->m_startOffset);
06132 }
06133 #ifndef KHTML_NO_CARET
06134 d->m_view->placeCaret();
06135 #endif
06136 }
06137
06138 bool KHTMLPart::isExtendingSelection() const
06139 {
06140
06141
06142
06143 return d->m_bMousePressed;
06144 }
06145 #endif // KHTML_NO_SELECTION
06146
06147 void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
06148 {
06149 QMouseEvent *_mouse = event->qmouseEvent();
06150
06151 if( d->m_bRightMousePressed && parentPart() != 0 && d->m_bBackRightClick )
06152 {
06153 popupMenu( d->m_strSelectedURL );
06154 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
06155 d->m_bRightMousePressed = false;
06156 }
06157
06158 DOM::DOMString url = event->url();
06159 DOM::DOMString target = event->target();
06160 DOM::Node innerNode = event->innerNode();
06161
06162 #ifndef QT_NO_DRAGANDDROP
06163 if( d->m_bDnd && d->m_bMousePressed &&
06164 ( (!d->m_strSelectedURL.isEmpty() && !isEditable())
06165 || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) ) ) {
06166 if ( ( d->m_dragStartPos - _mouse->pos() ).manhattanLength() <= KGlobalSettings::dndEventDelay() )
06167 return;
06168
06169 QPixmap pix;
06170 HTMLImageElementImpl *img = 0L;
06171 QDragObject *drag = 0;
06172 KURL u;
06173
06174
06175
06176
06177
06178 if ( url.length() == 0 && innerNode.handle() && innerNode.handle()->id() == ID_IMG )
06179 {
06180 img = static_cast<HTMLImageElementImpl *>(innerNode.handle());
06181 u = KURL( completeURL( khtml::parseURL(img->getAttribute(ATTR_SRC)).string() ) );
06182 pix = KMimeType::mimeType("image/png")->pixmap(KIcon::Desktop);
06183 }
06184 else
06185 {
06186
06187 u = completeURL( d->m_strSelectedURL );
06188 pix = KMimeType::pixmapForURL(u, 0, KIcon::Desktop, KIcon::SizeMedium);
06189 }
06190
06191 u.setPass(QString::null);
06192
06193 KURLDrag* urlDrag = new KURLDrag( u, img ? 0 : d->m_view->viewport() );
06194 if ( !d->m_referrer.isEmpty() )
06195 urlDrag->metaData()["referrer"] = d->m_referrer;
06196
06197 if( img && img->complete()) {
06198 KMultipleDrag *mdrag = new KMultipleDrag( d->m_view->viewport() );
06199 mdrag->addDragObject( new QImageDrag( img->currentImage(), 0L ) );
06200 mdrag->addDragObject( urlDrag );
06201 drag = mdrag;
06202 }
06203 else
06204 drag = urlDrag;
06205
06206 if ( !pix.isNull() )
06207 drag->setPixmap( pix );
06208
06209 stopAutoScroll();
06210 if(drag)
06211 drag->drag();
06212
06213
06214 d->m_bMousePressed = false;
06215 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
06216 return;
06217 }
06218 #endif
06219
06220
06221 if ( !d->m_bMousePressed )
06222 {
06223
06224 if ( url.length() )
06225 {
06226 bool shiftPressed = ( _mouse->state() & ShiftButton );
06227
06228
06229 if ( !innerNode.isNull() && innerNode.elementId() == ID_IMG )
06230 {
06231 HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(innerNode.handle());
06232 if ( i && i->isServerMap() )
06233 {
06234 khtml::RenderObject *r = i->renderer();
06235 if(r)
06236 {
06237 int absx, absy, vx, vy;
06238 r->absolutePosition(absx, absy);
06239 view()->contentsToViewport( absx, absy, vx, vy );
06240
06241 int x(_mouse->x() - vx), y(_mouse->y() - vy);
06242
06243 d->m_overURL = url.string() + QString("?%1,%2").arg(x).arg(y);
06244 d->m_overURLTarget = target.string();
06245 overURL( d->m_overURL, target.string(), shiftPressed );
06246 return;
06247 }
06248 }
06249 }
06250
06251
06252 if ( d->m_overURL.isEmpty() || d->m_overURL != url || d->m_overURLTarget != target )
06253 {
06254 d->m_overURL = url.string();
06255 d->m_overURLTarget = target.string();
06256 overURL( d->m_overURL, target.string(), shiftPressed );
06257 }
06258 }
06259 else
06260 {
06261
06262 resetHoverText();
06263 }
06264 }
06265 else {
06266 #ifndef KHTML_NO_SELECTION
06267
06268 if( d->m_bMousePressed && innerNode.handle() && innerNode.handle()->renderer() &&
06269 ( (_mouse->state() & LeftButton) != 0 )) {
06270 extendSelectionTo(event->x(), event->y(),
06271 event->absX(), event->absY(), innerNode);
06272 #else
06273 if ( d->m_doc && d->m_view ) {
06274 QPoint diff( _mouse->globalPos() - d->m_dragLastPos );
06275
06276 if ( abs( diff.x() ) > 64 || abs( diff.y() ) > 64 ) {
06277 d->m_view->scrollBy( -diff.x(), -diff.y() );
06278 d->m_dragLastPos = _mouse->globalPos();
06279 }
06280 #endif
06281 }
06282 }
06283
06284 }
06285
06286 void KHTMLPart::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent *event )
06287 {
06288 DOM::Node innerNode = event->innerNode();
06289 d->m_mousePressNode = DOM::Node();
06290
06291 if ( d->m_bMousePressed ) {
06292 setStatusBarText(QString::null, BarHoverText);
06293 stopAutoScroll();
06294 }
06295
06296
06297
06298 d->m_bMousePressed = false;
06299
06300 QMouseEvent *_mouse = event->qmouseEvent();
06301 if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
06302 {
06303 d->m_bRightMousePressed = false;
06304 KParts::BrowserInterface *tmp_iface = d->m_extension->browserInterface();
06305 if( tmp_iface ) {
06306 tmp_iface->callMethod( "goHistory(int)", -1 );
06307 }
06308 }
06309 #ifndef QT_NO_CLIPBOARD
06310 if ((d->m_guiProfile == BrowserViewGUI) && (_mouse->button() == MidButton) && (event->url().isNull())) {
06311 kdDebug( 6050 ) << "KHTMLPart::khtmlMouseReleaseEvent() MMB shouldOpen="
06312 << d->m_bOpenMiddleClick << endl;
06313
06314 if (d->m_bOpenMiddleClick) {
06315 KHTMLPart *p = this;
06316 while (p->parentPart()) p = p->parentPart();
06317 p->d->m_extension->pasteRequest();
06318 }
06319 }
06320 #endif
06321
06322 #ifndef KHTML_NO_SELECTION
06323
06324 if(d->m_selectionStart == d->m_selectionEnd && d->m_startOffset == d->m_endOffset) {
06325 #ifndef KHTML_NO_CARET
06326 d->m_extendAtEnd = true;
06327 #else
06328 d->m_selectionStart = 0;
06329 d->m_selectionEnd = 0;
06330 d->m_startOffset = 0;
06331 d->m_endOffset = 0;
06332 #endif
06333 emitSelectionChanged();
06334 } else {
06335
06336
06337 DOM::Node n = d->m_selectionStart;
06338 d->m_startBeforeEnd = false;
06339 if( d->m_selectionStart == d->m_selectionEnd ) {
06340 if( d->m_startOffset < d->m_endOffset )
06341 d->m_startBeforeEnd = true;
06342 } else {
06343 #if 0
06344 while(!n.isNull()) {
06345 if(n == d->m_selectionEnd) {
06346 d->m_startBeforeEnd = true;
06347 break;
06348 }
06349 DOM::Node next = n.firstChild();
06350 if(next.isNull()) next = n.nextSibling();
06351 while( next.isNull() && !n.parentNode().isNull() ) {
06352 n = n.parentNode();
06353 next = n.nextSibling();
06354 }
06355 n = next;
06356 }
06357 #else
06358
06359 if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
06360 !d->m_selectionStart.handle()->renderer() ||
06361 !d->m_selectionEnd.handle()->renderer()) return;
06362 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
06363 d->m_selectionStart.handle(), d->m_startOffset,
06364 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
06365 #endif
06366 }
06367 if(!d->m_startBeforeEnd)
06368 {
06369 DOM::Node tmpNode = d->m_selectionStart;
06370 int tmpOffset = d->m_startOffset;
06371 d->m_selectionStart = d->m_selectionEnd;
06372 d->m_startOffset = d->m_endOffset;
06373 d->m_selectionEnd = tmpNode;
06374 d->m_endOffset = tmpOffset;
06375 d->m_startBeforeEnd = true;
06376 d->m_extendAtEnd = !d->m_extendAtEnd;
06377 }
06378 #ifndef KHTML_NO_CARET
06379 bool v = d->m_view->placeCaret();
06380 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
06381 #endif
06382
06383 #ifndef QT_NO_CLIPBOARD
06384 QString text = selectedText();
06385 text.replace(QChar(0xa0), ' ');
06386 disconnect( kapp->clipboard(), SIGNAL( selectionChanged()), this, SLOT( slotClearSelection()));
06387 kapp->clipboard()->setText(text,QClipboard::Selection);
06388 connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
06389 #endif
06390
06391 emitSelectionChanged();
06392
06393 }
06394 #endif
06395 d->m_initialNode = 0;
06396 d->m_initialOffset = 0;
06397
06398 }
06399
06400 void KHTMLPart::khtmlDrawContentsEvent( khtml::DrawContentsEvent * )
06401 {
06402 }
06403
06404 void KHTMLPart::guiActivateEvent( KParts::GUIActivateEvent *event )
06405 {
06406 if ( event->activated() )
06407 {
06408 emitSelectionChanged();
06409 emit d->m_extension->enableAction( "print", d->m_doc != 0 );
06410
06411 if ( !d->m_settings->autoLoadImages() && d->m_paLoadImages )
06412 {
06413 QPtrList<KAction> lst;
06414 lst.append( d->m_paLoadImages );
06415 plugActionList( "loadImages", lst );
06416 }
06417 }
06418 }
06419
06420 void KHTMLPart::slotPrintFrame()
06421 {
06422 if ( d->m_frames.count() == 0 )
06423 return;
06424
06425 KParts::ReadOnlyPart *frame = currentFrame();
06426 if (!frame)
06427 return;
06428
06429 KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject( frame );
06430
06431 if ( !ext )
06432 return;
06433
06434 QMetaObject *mo = ext->metaObject();
06435
06436 int idx = mo->findSlot( "print()", true );
06437 if ( idx >= 0 ) {
06438 QUObject o[ 1 ];
06439 ext->qt_invoke( idx, o );
06440 }
06441 }
06442
06443 void KHTMLPart::slotSelectAll()
06444 {
06445 KParts::ReadOnlyPart *part = currentFrame();
06446 if (part && part->inherits("KHTMLPart"))
06447 static_cast<KHTMLPart *>(part)->selectAll();
06448 }
06449
06450 void KHTMLPart::startAutoScroll()
06451 {
06452 connect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
06453 d->m_scrollTimer.start(100, false);
06454 }
06455
06456 void KHTMLPart::stopAutoScroll()
06457 {
06458 disconnect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
06459 if (d->m_scrollTimer.isActive())
06460 d->m_scrollTimer.stop();
06461 }
06462
06463
06464 void KHTMLPart::slotAutoScroll()
06465 {
06466 if (d->m_view)
06467 d->m_view->doAutoScroll();
06468 else
06469 stopAutoScroll();
06470 }
06471
06472 void KHTMLPart::selectAll()
06473 {
06474 if (!d->m_doc) return;
06475
06476 NodeImpl *first;
06477 if (d->m_doc->isHTMLDocument())
06478 first = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
06479 else
06480 first = d->m_doc;
06481 NodeImpl *next;
06482
06483
06484
06485 while ( first && !(first->renderer()
06486 && ((first->nodeType() == Node::TEXT_NODE || first->nodeType() == Node::CDATA_SECTION_NODE)
06487 || (first->renderer()->isReplaced() && !first->renderer()->firstChild()))))
06488 {
06489 next = first->firstChild();
06490 if ( !next ) next = first->nextSibling();
06491 while( first && !next )
06492 {
06493 first = first->parentNode();
06494 if ( first )
06495 next = first->nextSibling();
06496 }
06497 first = next;
06498 }
06499
06500 NodeImpl *last;
06501 if (d->m_doc->isHTMLDocument())
06502 last = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
06503 else
06504 last = d->m_doc;
06505
06506
06507
06508
06509 while ( last && !(last->renderer()
06510 && ((last->nodeType() == Node::TEXT_NODE || last->nodeType() == Node::CDATA_SECTION_NODE)
06511 || (last->renderer()->isReplaced() && !last->renderer()->lastChild()))))
06512 {
06513 next = last->lastChild();
06514 if ( !next ) next = last->previousSibling();
06515 while ( last && !next )
06516 {
06517 last = last->parentNode();
06518 if ( last )
06519 next = last->previousSibling();
06520 }
06521 last = next;
06522 }
06523
06524 if ( !first || !last )
06525 return;
06526 Q_ASSERT(first->renderer());
06527 Q_ASSERT(last->renderer());
06528 d->m_selectionStart = first;
06529 d->m_startOffset = 0;
06530 d->m_selectionEnd = last;
06531 d->m_endOffset = last->nodeValue().length();
06532 d->m_startBeforeEnd = true;
06533
06534 d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
06535 d->m_selectionEnd.handle(), d->m_endOffset );
06536
06537 emitSelectionChanged();
06538 }
06539
06540 bool KHTMLPart::checkLinkSecurity(const KURL &linkURL,const QString &message, const QString &button)
06541 {
06542 bool linkAllowed = true;
06543
06544 if ( d->m_doc )
06545 linkAllowed = kapp && kapp->authorizeURLAction("redirect", url(), linkURL);
06546
06547 if ( !linkAllowed ) {
06548 khtml::Tokenizer *tokenizer = d->m_doc->tokenizer();
06549 if (tokenizer)
06550 tokenizer->setOnHold(true);
06551
06552 int response = KMessageBox::Cancel;
06553 if (!message.isEmpty())
06554 {
06555 response = KMessageBox::warningContinueCancel( 0,
06556 message.arg(linkURL.htmlURL()),
06557 i18n( "Security Warning" ),
06558 button);
06559 }
06560 else
06561 {
06562 KMessageBox::error( 0,
06563 i18n( "<qt>Access by untrusted page to<BR><B>%1</B><BR> denied.").arg(linkURL.htmlURL()),
06564 i18n( "Security Alert" ));
06565 }
06566
06567 if (tokenizer)
06568 tokenizer->setOnHold(false);
06569 return (response==KMessageBox::Continue);
06570 }
06571 return true;
06572 }
06573
06574 void KHTMLPart::slotPartRemoved( KParts::Part *part )
06575 {
06576
06577 if ( part == d->m_activeFrame )
06578 {
06579 d->m_activeFrame = 0L;
06580 if ( !part->inherits( "KHTMLPart" ) )
06581 {
06582 if (factory()) {
06583 factory()->removeClient( part );
06584 }
06585 if (childClients()->containsRef(part)) {
06586 removeChildClient( part );
06587 }
06588 }
06589 }
06590 }
06591
06592 void KHTMLPart::slotActiveFrameChanged( KParts::Part *part )
06593 {
06594
06595 if ( part == this )
06596 {
06597 kdError(6050) << "strange error! we activated ourselves" << endl;
06598 assert( false );
06599 return;
06600 }
06601
06602 if ( d->m_activeFrame && d->m_activeFrame->widget() && d->m_activeFrame->widget()->inherits( "QFrame" ) )
06603 {
06604 QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
06605 if (frame->frameStyle() != QFrame::NoFrame)
06606 {
06607 frame->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken);
06608 frame->repaint();
06609 }
06610 }
06611
06612 if( d->m_activeFrame && !d->m_activeFrame->inherits( "KHTMLPart" ) )
06613 {
06614 if (factory()) {
06615 factory()->removeClient( d->m_activeFrame );
06616 }
06617 removeChildClient( d->m_activeFrame );
06618 }
06619 if( part && !part->inherits( "KHTMLPart" ) )
06620 {
06621 if (factory()) {
06622 factory()->addClient( part );
06623 }
06624 insertChildClient( part );
06625 }
06626
06627
06628 d->m_activeFrame = part;
06629
06630 if ( d->m_activeFrame && d->m_activeFrame->widget()->inherits( "QFrame" ) )
06631 {
06632 QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
06633 if (frame->frameStyle() != QFrame::NoFrame)
06634 {
06635 frame->setFrameStyle( QFrame::StyledPanel | QFrame::Plain);
06636 frame->repaint();
06637 }
06638 kdDebug(6050) << "new active frame " << d->m_activeFrame << endl;
06639 }
06640
06641 updateActions();
06642
06643
06644 d->m_extension->setExtensionProxy( KParts::BrowserExtension::childObject( d->m_activeFrame ) );
06645 }
06646
06647 void KHTMLPart::setActiveNode(const DOM::Node &node)
06648 {
06649 if (!d->m_doc || !d->m_view)
06650 return;
06651
06652
06653 d->m_doc->setFocusNode(node.handle());
06654
06655
06656 QRect rect = node.handle()->getRect();
06657 d->m_view->ensureVisible(rect.right(), rect.bottom());
06658 d->m_view->ensureVisible(rect.left(), rect.top());
06659 }
06660
06661 DOM::Node KHTMLPart::activeNode() const
06662 {
06663 return DOM::Node(d->m_doc?d->m_doc->focusNode():0);
06664 }
06665
06666 DOM::EventListener *KHTMLPart::createHTMLEventListener( QString code, QString name )
06667 {
06668 KJSProxy *proxy = jScript();
06669
06670 if (!proxy)
06671 return 0;
06672
06673 return proxy->createHTMLEventHandler( m_url.url(), name, code );
06674 }
06675
06676 KHTMLPart *KHTMLPart::opener()
06677 {
06678 return d->m_opener;
06679 }
06680
06681 void KHTMLPart::setOpener(KHTMLPart *_opener)
06682 {
06683 d->m_opener = _opener;
06684 }
06685
06686 bool KHTMLPart::openedByJS()
06687 {
06688 return d->m_openedByJS;
06689 }
06690
06691 void KHTMLPart::setOpenedByJS(bool _openedByJS)
06692 {
06693 d->m_openedByJS = _openedByJS;
06694 }
06695
06696 void KHTMLPart::preloadStyleSheet(const QString &url, const QString &stylesheet)
06697 {
06698 khtml::Cache::preloadStyleSheet(url, stylesheet);
06699 }
06700
06701 void KHTMLPart::preloadScript(const QString &url, const QString &script)
06702 {
06703 khtml::Cache::preloadScript(url, script);
06704 }
06705
06706 QCString KHTMLPart::dcopObjectId() const
06707 {
06708 QCString id;
06709 id.sprintf("html-widget%d", d->m_dcop_counter);
06710 return id;
06711 }
06712
06713 long KHTMLPart::cacheId() const
06714 {
06715 return d->m_cacheId;
06716 }
06717
06718 bool KHTMLPart::restored() const
06719 {
06720 return d->m_restored;
06721 }
06722
06723 bool KHTMLPart::pluginPageQuestionAsked(const QString& mimetype) const
06724 {
06725
06726 KHTMLPart* parent = const_cast<KHTMLPart *>(this)->parentPart();
06727 if ( parent )
06728 return parent->pluginPageQuestionAsked(mimetype);
06729
06730 return d->m_pluginPageQuestionAsked.contains(mimetype);
06731 }
06732
06733 void KHTMLPart::setPluginPageQuestionAsked(const QString& mimetype)
06734 {
06735 if ( parentPart() )
06736 parentPart()->setPluginPageQuestionAsked(mimetype);
06737
06738 d->m_pluginPageQuestionAsked.append(mimetype);
06739 }
06740
06741 void KHTMLPart::slotAutomaticDetectionLanguage( int _id )
06742 {
06743 d->m_automaticDetection->setItemChecked( _id, true );
06744
06745 switch ( _id ) {
06746 case 0 :
06747 d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
06748 break;
06749 case 1 :
06750 d->m_autoDetectLanguage = khtml::Decoder::Arabic;
06751 break;
06752 case 2 :
06753 d->m_autoDetectLanguage = khtml::Decoder::Baltic;
06754 break;
06755 case 3 :
06756 d->m_autoDetectLanguage = khtml::Decoder::CentralEuropean;
06757 break;
06758 case 4 :
06759 d->m_autoDetectLanguage = khtml::Decoder::Chinese;
06760 break;
06761 case 5 :
06762 d->m_autoDetectLanguage = khtml::Decoder::Greek;
06763 break;
06764 case 6 :
06765 d->m_autoDetectLanguage = khtml::Decoder::Hebrew;
06766 break;
06767 case 7 :
06768 d->m_autoDetectLanguage = khtml::Decoder::Japanese;
06769 break;
06770 case 8 :
06771 d->m_autoDetectLanguage = khtml::Decoder::Korean;
06772 break;
06773 case 9 :
06774 d->m_autoDetectLanguage = khtml::Decoder::Russian;
06775 break;
06776 case 10 :
06777 d->m_autoDetectLanguage = khtml::Decoder::Thai;
06778 break;
06779 case 11 :
06780 d->m_autoDetectLanguage = khtml::Decoder::Turkish;
06781 break;
06782 case 12 :
06783 d->m_autoDetectLanguage = khtml::Decoder::Ukrainian;
06784 break;
06785 case 13 :
06786 d->m_autoDetectLanguage = khtml::Decoder::Unicode;
06787 break;
06788 case 14 :
06789 d->m_autoDetectLanguage = khtml::Decoder::WesternEuropean;
06790 break;
06791 default :
06792 d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
06793 break;
06794 }
06795
06796 for ( int i = 0; i <= 14; ++i ) {
06797 if ( i != _id )
06798 d->m_automaticDetection->setItemChecked( i, false );
06799 }
06800
06801 d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );
06802
06803 setEncoding( QString::null, false );
06804
06805 if( d->m_manualDetection )
06806 d->m_manualDetection->setCurrentItem( -1 );
06807 d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), false );
06808 }
06809
06810 khtml::Decoder *KHTMLPart::createDecoder()
06811 {
06812 khtml::Decoder *dec = new khtml::Decoder();
06813 if( !d->m_encoding.isNull() )
06814 dec->setEncoding( d->m_encoding.latin1(),
06815 d->m_haveEncoding ? khtml::Decoder::UserChosenEncoding : khtml::Decoder::EncodingFromHTTPHeader);
06816 else {
06817
06818 const char *defaultEncoding = (parentPart() && parentPart()->d->m_decoder)
06819 ? parentPart()->d->m_decoder->encoding() : settings()->encoding().latin1();
06820 dec->setEncoding(defaultEncoding, khtml::Decoder::DefaultEncoding);
06821 }
06822 #ifdef APPLE_CHANGES
06823 if (d->m_doc)
06824 d->m_doc->setDecoder(d->m_decoder);
06825 #endif
06826 dec->setAutoDetectLanguage( d->m_autoDetectLanguage );
06827 return dec;
06828 }
06829
06830 void KHTMLPart::emitCaretPositionChanged(const DOM::Node &node, long offset) {
06831 emit caretPositionChanged(node, offset);
06832 }
06833
06834 void KHTMLPart::restoreScrollPosition()
06835 {
06836 KParts::URLArgs args = d->m_extension->urlArgs();
06837
06838 if ( m_url.hasRef() && !d->m_restoreScrollPosition && !args.reload) {
06839 if ( !d->m_doc || !d->m_doc->parsing() )
06840 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
06841 if ( !gotoAnchor(m_url.encodedHtmlRef()) )
06842 gotoAnchor(m_url.htmlRef());
06843 return;
06844 }
06845
06846
06847
06848
06849
06850 if (d->m_view->contentsHeight() - d->m_view->visibleHeight() >= args.yOffset
06851 || d->m_bComplete) {
06852 d->m_view->setContentsPos(args.xOffset, args.yOffset);
06853 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
06854 }
06855 }
06856
06857
06858 void KHTMLPart::openWallet(DOM::HTMLFormElementImpl *form)
06859 {
06860 KHTMLPart *p;
06861
06862 for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
06863 }
06864
06865 if (p) {
06866 p->openWallet(form);
06867 return;
06868 }
06869
06870 if (onlyLocalReferences()) {
06871 return;
06872 }
06873
06874 if (d->m_wallet) {
06875 if (d->m_bWalletOpened) {
06876 if (d->m_wallet->isOpen()) {
06877 form->walletOpened(d->m_wallet);
06878 return;
06879 }
06880 d->m_wallet->deleteLater();
06881 d->m_wallet = 0L;
06882 d->m_bWalletOpened = false;
06883 }
06884 }
06885
06886 if (!d->m_wq) {
06887 KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
06888 d->m_wq = new KHTMLWalletQueue(this);
06889 d->m_wq->wallet = wallet;
06890 connect(wallet, SIGNAL(walletOpened(bool)), d->m_wq, SLOT(walletOpened(bool)));
06891 connect(d->m_wq, SIGNAL(walletOpened(KWallet::Wallet*)), this, SLOT(walletOpened(KWallet::Wallet*)));
06892 }
06893 assert(form);
06894 d->m_wq->callers.append(KHTMLWalletQueue::Caller(form, form->getDocument()));
06895 }
06896
06897
06898 void KHTMLPart::saveToWallet(const QString& key, const QMap<QString,QString>& data)
06899 {
06900 KHTMLPart *p;
06901
06902 for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
06903 }
06904
06905 if (p) {
06906 p->saveToWallet(key, data);
06907 return;
06908 }
06909
06910 if (d->m_wallet) {
06911 if (d->m_bWalletOpened) {
06912 if (d->m_wallet->isOpen()) {
06913 if (!d->m_wallet->hasFolder(KWallet::Wallet::FormDataFolder())) {
06914 d->m_wallet->createFolder(KWallet::Wallet::FormDataFolder());
06915 }
06916 d->m_wallet->setFolder(KWallet::Wallet::FormDataFolder());
06917 d->m_wallet->writeMap(key, data);
06918 return;
06919 }
06920 d->m_wallet->deleteLater();
06921 d->m_wallet = 0L;
06922 d->m_bWalletOpened = false;
06923 }
06924 }
06925
06926 if (!d->m_wq) {
06927 KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
06928 d->m_wq = new KHTMLWalletQueue(this);
06929 d->m_wq->wallet = wallet;
06930 connect(wallet, SIGNAL(walletOpened(bool)), d->m_wq, SLOT(walletOpened(bool)));
06931 connect(d->m_wq, SIGNAL(walletOpened(KWallet::Wallet*)), this, SLOT(walletOpened(KWallet::Wallet*)));
06932 }
06933 d->m_wq->savers.append(qMakePair(key, data));
06934 }
06935
06936
06937 void KHTMLPart::dequeueWallet(DOM::HTMLFormElementImpl *form) {
06938 KHTMLPart *p;
06939
06940 for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
06941 }
06942
06943 if (p) {
06944 p->dequeueWallet(form);
06945 return;
06946 }
06947
06948 if (d->m_wq) {
06949 d->m_wq->callers.remove(KHTMLWalletQueue::Caller(form, form->getDocument()));
06950 }
06951 }
06952
06953
06954 void KHTMLPart::walletOpened(KWallet::Wallet *wallet) {
06955 assert(!d->m_wallet);
06956 assert(d->m_wq);
06957
06958 d->m_wq->deleteLater();
06959 d->m_wq = 0L;
06960
06961 if (!wallet) {
06962 d->m_bWalletOpened = false;
06963 return;
06964 }
06965
06966 d->m_wallet = wallet;
06967 d->m_bWalletOpened = true;
06968 connect(d->m_wallet, SIGNAL(walletClosed()), SLOT(slotWalletClosed()));
06969
06970 if (!d->m_statusBarWalletLabel) {
06971 d->m_statusBarWalletLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
06972 d->m_statusBarWalletLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
06973 d->m_statusBarWalletLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
06974 d->m_statusBarWalletLabel->setUseCursor(false);
06975 d->m_statusBarExtension->addStatusBarItem(d->m_statusBarWalletLabel, 0, false);
06976 d->m_statusBarWalletLabel->setPixmap(SmallIcon("wallet_open", instance()));
06977 connect(d->m_statusBarWalletLabel, SIGNAL(leftClickedURL()), SLOT(launchWalletManager()));
06978 connect(d->m_statusBarWalletLabel, SIGNAL(rightClickedURL()), SLOT(walletMenu()));
06979 } else {
06980 QToolTip::remove(d->m_statusBarWalletLabel);
06981 }
06982 QToolTip::add(d->m_statusBarWalletLabel, i18n("The wallet '%1' is open and being used for form data and passwords.").arg(KWallet::Wallet::NetworkWallet()));
06983 }
06984
06985
06986 KWallet::Wallet *KHTMLPart::wallet()
06987 {
06988 KHTMLPart *p;
06989
06990 for (p = parentPart(); p && p->parentPart(); p = p->parentPart())
06991 ;
06992
06993 if (p)
06994 return p->wallet();
06995
06996 return d->m_wallet;
06997 }
06998
06999
07000 void KHTMLPart::slotWalletClosed()
07001 {
07002 if (d->m_wallet) {
07003 d->m_wallet->deleteLater();
07004 d->m_wallet = 0L;
07005 }
07006 d->m_bWalletOpened = false;
07007 if (d->m_statusBarWalletLabel) {
07008 d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarWalletLabel);
07009 delete d->m_statusBarWalletLabel;
07010 d->m_statusBarWalletLabel = 0L;
07011 }
07012 }
07013
07014 void KHTMLPart::launchWalletManager()
07015 {
07016 if (!DCOPClient::mainClient()->isApplicationRegistered("kwalletmanager")) {
07017 KApplication::startServiceByDesktopName("kwalletmanager_show");
07018 } else {
07019 DCOPRef r("kwalletmanager", "kwalletmanager-mainwindow#1");
07020 r.send("show");
07021 r.send("raise");
07022 }
07023 }
07024
07025 void KHTMLPart::walletMenu()
07026 {
07027 KPopupMenu *m = new KPopupMenu(0L);
07028 m->insertItem(i18n("&Close Wallet"), this, SLOT(slotWalletClosed()));
07029 m->popup(QCursor::pos());
07030 }
07031
07032 void KHTMLPart::slotToggleCaretMode()
07033 {
07034 setCaretMode(d->m_paToggleCaretMode->isChecked());
07035 }
07036
07037 void KHTMLPart::setFormNotification(KHTMLPart::FormNotification fn) {
07038 d->m_formNotification = fn;
07039 }
07040
07041 KHTMLPart::FormNotification KHTMLPart::formNotification() const {
07042 return d->m_formNotification;
07043 }
07044
07045 KURL KHTMLPart::toplevelURL()
07046 {
07047 KHTMLPart* part = this;
07048 while (part->parentPart())
07049 part = part->parentPart();
07050
07051 if (!part)
07052 return KURL();
07053
07054 return part->url();
07055 }
07056
07057 bool KHTMLPart::isModified() const
07058 {
07059 if ( !d->m_doc )
07060 return false;
07061
07062 return d->m_doc->unsubmittedFormChanges();
07063 }
07064
07065 void KHTMLPart::setDebugScript( bool enable )
07066 {
07067 unplugActionList( "debugScriptList" );
07068 if ( enable ) {
07069 if (!d->m_paDebugScript) {
07070 d->m_paDebugScript = new KAction( i18n( "JavaScript &Debugger" ), 0, this, SLOT( slotDebugScript() ), actionCollection(), "debugScript" );
07071 }
07072 d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
07073 QPtrList<KAction> lst;
07074 lst.append( d->m_paDebugScript );
07075 plugActionList( "debugScriptList", lst );
07076 }
07077 d->m_bJScriptDebugEnabled = enable;
07078 }
07079
07080 void KHTMLPart::setSuppressedPopupIndicator( bool enable )
07081 {
07082 if ( parentPart() ) {
07083 parentPart()->setSuppressedPopupIndicator( enable );
07084 return;
07085 }
07086
07087 if ( enable && !d->m_statusBarPopupLabel ) {
07088 d->m_statusBarPopupLabel = new KURLLabel( d->m_statusBarExtension->statusBar() );
07089 d->m_statusBarPopupLabel->setFixedHeight( instance()->iconLoader()->currentSize( KIcon::Small) );
07090 d->m_statusBarPopupLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ));
07091 d->m_statusBarPopupLabel->setUseCursor( false );
07092 d->m_statusBarExtension->addStatusBarItem( d->m_statusBarPopupLabel, 0, false );
07093 d->m_statusBarPopupLabel->setPixmap( SmallIcon( "window_suppressed", instance() ) );
07094 QToolTip::add( d->m_statusBarPopupLabel, i18n("Konqueror prevented this site from opening a popup window." ) );
07095 } else if ( !enable && d->m_statusBarPopupLabel ) {
07096 QToolTip::remove( d->m_statusBarPopupLabel );
07097 d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarPopupLabel );
07098 delete d->m_statusBarPopupLabel;
07099 d->m_statusBarPopupLabel = 0L;
07100 }
07101 }
07102
07103 using namespace KParts;
07104 #include "khtml_part.moc"
07105 #include "khtmlpart_p.moc"