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 view()->updateFindAheadTimeout();
02944 long options = 0;
02945 if ( d->m_findDialog )
02946 {
02947 if ( d->m_find->pattern() != d->m_findDialog->pattern() ) {
02948 d->m_find->setPattern( d->m_findDialog->pattern() );
02949 d->m_find->resetCounts();
02950 }
02951 options = d->m_findDialog->options();
02952 if ( d->m_lastFindState.options != options )
02953 {
02954 d->m_find->setOptions( options );
02955
02956 if ( options & KFindDialog::SelectedText )
02957 Q_ASSERT( hasSelection() );
02958
02959 long difference = d->m_lastFindState.options ^ options;
02960 if ( difference & (KFindDialog::SelectedText | KFindDialog::FromCursor ) )
02961 {
02962
02963 (void) initFindNode( options & KFindDialog::SelectedText,
02964 options & KFindDialog::FindBackwards,
02965 options & KFindDialog::FromCursor );
02966 }
02967 d->m_lastFindState.options = options;
02968 }
02969 } else
02970 options = d->m_lastFindState.options;
02971
02972 KFind::Result res = KFind::NoMatch;
02973 khtml::RenderObject* obj = d->m_findNode ? d->m_findNode->renderer() : 0;
02974 khtml::RenderObject* end = d->m_findNodeEnd ? d->m_findNodeEnd->renderer() : 0;
02975 khtml::RenderTextArea *tmpTextArea=0L;
02976
02977 while( res == KFind::NoMatch )
02978 {
02979 if ( d->m_find->needData() )
02980 {
02981 if ( !obj ) {
02982
02983 break;
02984 }
02985
02986
02987
02988
02989
02990 d->m_stringPortions.clear();
02991 int newLinePos = -1;
02992 QString str;
02993 DOM::NodeImpl* lastNode = d->m_findNode;
02994 while ( obj && newLinePos == -1 )
02995 {
02996
02997 QString s;
02998 bool renderAreaText = obj->parent() && (QCString(obj->parent()->renderName())== "RenderTextArea");
02999 bool renderLineText = (QCString(obj->renderName())== "RenderLineEdit");
03000 if ( renderAreaText )
03001 {
03002 khtml::RenderTextArea *parent= static_cast<khtml::RenderTextArea *>(obj->parent());
03003 s = parent->text();
03004 s = s.replace(0xa0, ' ');
03005 tmpTextArea = parent;
03006 }
03007 else if ( renderLineText )
03008 {
03009 khtml::RenderLineEdit *parentLine= static_cast<khtml::RenderLineEdit *>(obj);
03010 s = parentLine->widget()->text();
03011 s = s.replace(0xa0, ' ');
03012 }
03013 else if ( obj->isText() )
03014 {
03015 bool isLink = false;
03016
03017
03018 if ( options & FindLinksOnly )
03019 {
03020 DOM::NodeImpl *parent = obj->element();
03021 while ( parent )
03022 {
03023 if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
03024 {
03025 isLink = true;
03026 break;
03027 }
03028 parent = parent->parentNode();
03029 }
03030 }
03031 else
03032 {
03033 isLink = true;
03034 }
03035
03036 if ( isLink && obj->parent()!=tmpTextArea )
03037 {
03038 s = static_cast<khtml::RenderText *>(obj)->data().string();
03039 s = s.replace(0xa0, ' ');
03040 }
03041 }
03042 else if ( obj->isBR() )
03043 s = '\n';
03044 else if ( !obj->isInline() && !str.isEmpty() )
03045 s = '\n';
03046
03047 if ( lastNode == d->m_findNodeEnd )
03048 s.truncate( d->m_findPosEnd );
03049 if ( !s.isEmpty() )
03050 {
03051 newLinePos = s.find( '\n' );
03052 int index = str.length();
03053 if ( newLinePos != -1 )
03054 newLinePos += index;
03055 str += s;
03056
03057 d->m_stringPortions.append( KHTMLPartPrivate::StringPortion( index, lastNode ) );
03058 }
03059
03060 if ( obj == end )
03061 obj = 0L;
03062 else
03063 {
03064
03065
03066 do {
03067
03068
03069
03070 obj = (options & KFindDialog::FindBackwards) ? obj->objectAbove() : obj->objectBelow();
03071 } while ( obj && ( !obj->element() || obj->isInlineContinuation() ) );
03072 }
03073 if ( obj )
03074 lastNode = obj->element();
03075 else
03076 lastNode = 0;
03077 }
03078
03079 if ( !str.isEmpty() )
03080 {
03081 d->m_find->setData( str, d->m_findPos );
03082 }
03083
03084 d->m_findPos = -1;
03085 d->m_findNode = lastNode;
03086 }
03087 if ( !d->m_find->needData() )
03088 {
03089
03090 res = d->m_find->find();
03091 }
03092 }
03093
03094 if ( res == KFind::NoMatch )
03095 {
03096 kdDebug() << "No more matches." << endl;
03097 if ( !(options & FindNoPopups) && d->m_find->shouldRestart() )
03098 {
03099
03100 initFindNode( false, options & KFindDialog::FindBackwards, false );
03101 findTextNext();
03102 }
03103 else
03104 {
03105
03106
03107
03108 initFindNode( false, options & KFindDialog::FindBackwards, false );
03109 d->m_find->resetCounts();
03110 slotClearSelection();
03111 }
03112 kdDebug() << "Dialog closed." << endl;
03113 }
03114
03115 return res == KFind::Match;
03116 }
03117
03118 void KHTMLPart::slotHighlight( const QString& , int index, int length )
03119 {
03120
03121 QValueList<KHTMLPartPrivate::StringPortion>::Iterator it = d->m_stringPortions.begin();
03122 const QValueList<KHTMLPartPrivate::StringPortion>::Iterator itEnd = d->m_stringPortions.end();
03123 QValueList<KHTMLPartPrivate::StringPortion>::Iterator prev = it;
03124
03125 while ( it != itEnd && (*it).index <= index )
03126 {
03127 prev = it;
03128 ++it;
03129 }
03130 Q_ASSERT ( prev != itEnd );
03131 DOM::NodeImpl* node = (*prev).node;
03132 Q_ASSERT( node );
03133
03134 d->m_selectionStart = node;
03135 d->m_startOffset = index - (*prev).index;
03136
03137 khtml::RenderObject* obj = node->renderer();
03138 khtml::RenderTextArea *parent = 0L;
03139 khtml::RenderLineEdit *parentLine = 0L;
03140 bool renderLineText =false;
03141
03142 QRect highlightedRect;
03143 bool renderAreaText =false;
03144 Q_ASSERT( obj );
03145 if ( obj )
03146 {
03147 int x = 0, y = 0;
03148 renderAreaText = (QCString(obj->parent()->renderName())== "RenderTextArea");
03149 renderLineText = (QCString(obj->renderName())== "RenderLineEdit");
03150
03151
03152 if( renderAreaText )
03153 parent= static_cast<khtml::RenderTextArea *>(obj->parent());
03154 if ( renderLineText )
03155 parentLine= static_cast<khtml::RenderLineEdit *>(obj);
03156 if ( !renderLineText )
03157
03158
03159 {
03160 int dummy;
03161 static_cast<khtml::RenderText *>(node->renderer())
03162 ->caretPos( d->m_startOffset, false, x, y, dummy, dummy );
03163
03164 if ( x != -1 || y != -1 )
03165 {
03166 int gox = d->m_view->contentsX();
03167 if (x+50 > d->m_view->contentsX() + d->m_view->visibleWidth())
03168 gox = x - d->m_view->visibleWidth() + 50;
03169 if (x-10 < d->m_view->contentsX())
03170 gox = x - d->m_view->visibleWidth() - 10;
03171 if (gox < 0) gox = 0;
03172 d->m_view->setContentsPos(gox, y-50);
03173 highlightedRect.setTopLeft( d->m_view->mapToGlobal(QPoint(x, y)) );
03174 }
03175 }
03176 }
03177
03178 it = prev;
03179 while ( it != itEnd && (*it).index < index + length )
03180 {
03181 prev = it;
03182 ++it;
03183 }
03184 Q_ASSERT ( prev != itEnd );
03185
03186 d->m_selectionEnd = (*prev).node;
03187 d->m_endOffset = index + length - (*prev).index;
03188 d->m_startBeforeEnd = true;
03189
03190
03191 if(d->m_selectionStart == d->m_selectionEnd)
03192 {
03193 bool isLink = false;
03194
03195
03196 DOM::NodeImpl *parent = d->m_selectionStart.handle();
03197 while ( parent )
03198 {
03199 if ( parent->nodeType() == Node::ELEMENT_NODE && parent->id() == ID_A )
03200 {
03201 isLink = true;
03202 break;
03203 }
03204 parent = parent->parentNode();
03205 }
03206
03207 if(isLink == true)
03208 {
03209 d->m_doc->setFocusNode( parent );
03210 }
03211 }
03212
03213 #if 0
03214 kdDebug(6050) << "slotHighlight: " << d->m_selectionStart.handle() << "," << d->m_startOffset << " - " <<
03215 d->m_selectionEnd.handle() << "," << d->m_endOffset << endl;
03216 it = d->m_stringPortions.begin();
03217 for ( ; it != d->m_stringPortions.end() ; ++it )
03218 kdDebug(6050) << " StringPortion: from index=" << (*it).index << " -> node=" << (*it).node << endl;
03219 #endif
03220 if( renderAreaText )
03221 {
03222 if( parent )
03223 parent->highLightWord( length, d->m_endOffset-length );
03224 }
03225 else if ( renderLineText )
03226 {
03227 if( parentLine )
03228 parentLine->highLightWord( length, d->m_endOffset-length );
03229 }
03230 else
03231 {
03232 d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
03233 d->m_selectionEnd.handle(), d->m_endOffset );
03234 if (d->m_selectionEnd.handle()->renderer() )
03235 {
03236 int x, y, height, dummy;
03237 static_cast<khtml::RenderText *>(d->m_selectionEnd.handle()->renderer())
03238 ->caretPos( d->m_endOffset, false, x, y, dummy, height );
03239
03240 if ( x != -1 || y != -1 )
03241 {
03242
03243
03244 highlightedRect.setBottomRight( d->m_view->mapToGlobal( QPoint(x, y+height) ) );
03245 }
03246 }
03247 }
03248 emitSelectionChanged();
03249
03250
03251 if ( d->m_findDialog && !highlightedRect.isNull() )
03252 {
03253 highlightedRect.moveBy( -d->m_view->contentsX(), -d->m_view->contentsY() );
03254
03255 KDialog::avoidArea( d->m_findDialog, highlightedRect );
03256 }
03257 }
03258
03259 QString KHTMLPart::selectedTextAsHTML() const
03260 {
03261 if(!hasSelection()) {
03262 kdDebug() << "selectedTextAsHTML(): selection is not valid. Returning empty selection" << endl;
03263 return QString::null;
03264 }
03265 if(d->m_startOffset < 0 || d->m_endOffset <0) {
03266 kdDebug() << "invalid values for end/startOffset " << d->m_startOffset << " " << d->m_endOffset << endl;
03267 return QString::null;
03268 }
03269 DOM::Range r = selection();
03270 if(r.isNull() || r.isDetached())
03271 return QString::null;
03272 int exceptioncode = 0;
03273 return r.handle()->toHTML(exceptioncode).string();
03274 }
03275
03276 QString KHTMLPart::selectedText() const
03277 {
03278 bool hasNewLine = true;
03279 bool seenTDTag = false;
03280 QString text;
03281 DOM::Node n = d->m_selectionStart;
03282 while(!n.isNull()) {
03283 if(n.nodeType() == DOM::Node::TEXT_NODE && n.handle()->renderer()) {
03284 DOM::DOMStringImpl *dstr = static_cast<DOM::TextImpl*>(n.handle())->renderString();
03285 QString str(dstr->s, dstr->l);
03286 if(!str.isEmpty()) {
03287 if(seenTDTag) {
03288 text += " ";
03289 seenTDTag = false;
03290 }
03291 hasNewLine = false;
03292 if(n == d->m_selectionStart && n == d->m_selectionEnd)
03293 text = str.mid(d->m_startOffset, d->m_endOffset - d->m_startOffset);
03294 else if(n == d->m_selectionStart)
03295 text = str.mid(d->m_startOffset);
03296 else if(n == d->m_selectionEnd)
03297 text += str.left(d->m_endOffset);
03298 else
03299 text += str;
03300 }
03301 }
03302 else {
03303
03304 unsigned short id = n.elementId();
03305 switch(id) {
03306 case ID_TEXTAREA:
03307 text += static_cast<HTMLTextAreaElementImpl*>(n.handle())->value().string();
03308 break;
03309 case ID_INPUT:
03310 text += static_cast<HTMLInputElementImpl*>(n.handle())->value().string();
03311 break;
03312 case ID_SELECT:
03313 text += static_cast<HTMLSelectElementImpl*>(n.handle())->value().string();
03314 break;
03315 case ID_BR:
03316 text += "\n";
03317 hasNewLine = true;
03318 break;
03319 case ID_IMG:
03320 text += static_cast<HTMLImageElementImpl*>(n.handle())->altText().string();
03321 break;
03322 case ID_TD:
03323 break;
03324 case ID_TH:
03325 case ID_HR:
03326 case ID_OL:
03327 case ID_UL:
03328 case ID_LI:
03329 case ID_DD:
03330 case ID_DL:
03331 case ID_DT:
03332 case ID_PRE:
03333 case ID_BLOCKQUOTE:
03334 case ID_DIV:
03335 if (!hasNewLine)
03336 text += "\n";
03337 hasNewLine = true;
03338 break;
03339 case ID_P:
03340 case ID_TR:
03341 case ID_H1:
03342 case ID_H2:
03343 case ID_H3:
03344 case ID_H4:
03345 case ID_H5:
03346 case ID_H6:
03347 if (!hasNewLine)
03348 text += "\n";
03349
03350 hasNewLine = true;
03351 break;
03352 }
03353 }
03354 if(n == d->m_selectionEnd) break;
03355 DOM::Node next = n.firstChild();
03356 if(next.isNull()) next = n.nextSibling();
03357 while( next.isNull() && !n.parentNode().isNull() ) {
03358 n = n.parentNode();
03359 next = n.nextSibling();
03360 unsigned short id = n.elementId();
03361 switch(id) {
03362 case ID_TD:
03363 seenTDTag = true;
03364 break;
03365 case ID_TH:
03366 case ID_HR:
03367 case ID_OL:
03368 case ID_UL:
03369 case ID_LI:
03370 case ID_DD:
03371 case ID_DL:
03372 case ID_DT:
03373 case ID_PRE:
03374 case ID_BLOCKQUOTE:
03375 case ID_DIV:
03376 seenTDTag = false;
03377 if (!hasNewLine)
03378 text += "\n";
03379 hasNewLine = true;
03380 break;
03381 case ID_P:
03382 case ID_TR:
03383 case ID_H1:
03384 case ID_H2:
03385 case ID_H3:
03386 case ID_H4:
03387 case ID_H5:
03388 case ID_H6:
03389 if (!hasNewLine)
03390 text += "\n";
03391
03392 hasNewLine = true;
03393 break;
03394 }
03395 }
03396
03397 n = next;
03398 }
03399
03400 if(text.isEmpty())
03401 return QString::null;
03402
03403 int start = 0;
03404 int end = text.length();
03405
03406
03407 while ((start < end) && (text[start] == '\n'))
03408 ++start;
03409
03410
03411 while ((start < (end-1)) && (text[end-1] == '\n') && (text[end-2] == '\n'))
03412 --end;
03413
03414 return text.mid(start, end-start);
03415 }
03416
03417 bool KHTMLPart::hasSelection() const
03418 {
03419 if ( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
03420 return false;
03421 if ( d->m_selectionStart == d->m_selectionEnd &&
03422 d->m_startOffset == d->m_endOffset )
03423 return false;
03424 return true;
03425 }
03426
03427 DOM::Range KHTMLPart::selection() const
03428 {
03429 if( d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() )
03430 return DOM::Range();
03431 DOM::Range r = document().createRange();
03432 RangeImpl *rng = r.handle();
03433 int exception = 0;
03434 NodeImpl *n = d->m_selectionStart.handle();
03435 if(!n->parentNode() ||
03436 !n->renderer() ||
03437 (!n->renderer()->isReplaced() && !n->renderer()->isBR())) {
03438 rng->setStart( n, d->m_startOffset, exception );
03439 if(exception) {
03440 kdDebug(6000) << "1 -selection() threw the exception " << exception << ". Returning empty range." << endl;
03441 return DOM::Range();
03442 }
03443 } else {
03444 int o_start = 0;
03445 while ((n = n->previousSibling()))
03446 o_start++;
03447 rng->setStart( d->m_selectionStart.parentNode().handle(), o_start + d->m_startOffset, exception );
03448 if(exception) {
03449 kdDebug(6000) << "2 - selection() threw the exception " << exception << ". Returning empty range." << endl;
03450 return DOM::Range();
03451 }
03452
03453 }
03454
03455 n = d->m_selectionEnd.handle();
03456 if(!n->parentNode() ||
03457 !n->renderer() ||
03458 (!n->renderer()->isReplaced() && !n->renderer()->isBR())) {
03459
03460 rng->setEnd( n, d->m_endOffset, exception );
03461 if(exception) {
03462 kdDebug(6000) << "3 - selection() threw the exception " << exception << ". Returning empty range." << endl;
03463 return DOM::Range();
03464 }
03465
03466 } else {
03467 int o_end = 0;
03468 while ((n = n->previousSibling()))
03469 o_end++;
03470 rng->setEnd( d->m_selectionEnd.parentNode().handle(), o_end + d->m_endOffset, exception);
03471 if(exception) {
03472 kdDebug(6000) << "4 - selection() threw the exception " << exception << ". Returning empty range." << endl;
03473 return DOM::Range();
03474 }
03475
03476 }
03477
03478 return r;
03479 }
03480
03481 void KHTMLPart::selection(DOM::Node &s, long &so, DOM::Node &e, long &eo) const
03482 {
03483 s = d->m_selectionStart;
03484 so = d->m_startOffset;
03485 e = d->m_selectionEnd;
03486 eo = d->m_endOffset;
03487 }
03488
03489 void KHTMLPart::setSelection( const DOM::Range &r )
03490 {
03491
03492
03493 if ( r.collapsed() )
03494 slotClearSelection();
03495 else {
03496 d->m_selectionStart = r.startContainer();
03497 d->m_startOffset = r.startOffset();
03498 d->m_selectionEnd = r.endContainer();
03499 d->m_endOffset = r.endOffset();
03500 d->m_doc->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
03501 d->m_selectionEnd.handle(),d->m_endOffset);
03502 #ifndef KHTML_NO_CARET
03503 bool v = d->m_view->placeCaret();
03504 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
03505 #endif
03506 }
03507 }
03508
03509 void KHTMLPart::slotClearSelection()
03510 {
03511 bool hadSelection = hasSelection();
03512 #ifndef KHTML_NO_CARET
03513
03514
03515
03516 #else
03517 d->m_selectionStart = 0;
03518 d->m_startOffset = 0;
03519 d->m_selectionEnd = 0;
03520 d->m_endOffset = 0;
03521 #endif
03522 if ( d->m_doc ) d->m_doc->clearSelection();
03523 if ( hadSelection )
03524 emitSelectionChanged();
03525 #ifndef KHTML_NO_CARET
03526 bool v = d->m_view->placeCaret();
03527 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
03528 #endif
03529 }
03530
03531 void KHTMLPart::resetHoverText()
03532 {
03533 if( !d->m_overURL.isEmpty() )
03534 {
03535 d->m_overURL = d->m_overURLTarget = QString::null;
03536 emit onURL( QString::null );
03537
03538 setStatusBarText(QString::null, BarHoverText);
03539 emit d->m_extension->mouseOverInfo(0);
03540 }
03541 }
03542
03543 void KHTMLPart::overURL( const QString &url, const QString &target, bool )
03544 {
03545 KURL u = completeURL(url);
03546
03547
03548 if ( url.isEmpty() )
03549 u.setFileName( url );
03550
03551 emit onURL( url );
03552
03553 if ( url.isEmpty() ) {
03554 setStatusBarText(u.htmlURL(), BarHoverText);
03555 return;
03556 }
03557
03558 if (url.find( QString::fromLatin1( "javascript:" ),0, false ) == 0 ) {
03559 QString jscode = KURL::decode_string( url.mid( url.find( "javascript:", 0, false ) ) );
03560 jscode = KStringHandler::rsqueeze( jscode, 80 );
03561 if (url.startsWith("javascript:window.open"))
03562 jscode += i18n(" (In new window)");
03563 setStatusBarText( QStyleSheet::escape( jscode ), BarHoverText );
03564 return;
03565 }
03566
03567 KFileItem item(u, QString::null, KFileItem::Unknown);
03568 emit d->m_extension->mouseOverInfo(&item);
03569
03570 QString com;
03571
03572 KMimeType::Ptr typ = KMimeType::findByURL( u );
03573
03574 if ( typ )
03575 com = typ->comment( u, false );
03576
03577 if ( !u.isValid() ) {
03578 setStatusBarText(u.htmlURL(), BarHoverText);
03579 return;
03580 }
03581
03582 if ( u.isLocalFile() )
03583 {
03584
03585
03586 QCString path = QFile::encodeName( u.path() );
03587
03588 struct stat buff;
03589 bool ok = !stat( path.data(), &buff );
03590
03591 struct stat lbuff;
03592 if (ok) ok = !lstat( path.data(), &lbuff );
03593
03594 QString text = u.htmlURL();
03595 QString text2 = text;
03596
03597 if (ok && S_ISLNK( lbuff.st_mode ) )
03598 {
03599 QString tmp;
03600 if ( com.isNull() )
03601 tmp = i18n( "Symbolic Link");
03602 else
03603 tmp = i18n("%1 (Link)").arg(com);
03604 char buff_two[1024];
03605 text += " -> ";
03606 int n = readlink ( path.data(), buff_two, 1022);
03607 if (n == -1)
03608 {
03609 text2 += " ";
03610 text2 += tmp;
03611 setStatusBarText(text2, BarHoverText);
03612 return;
03613 }
03614 buff_two[n] = 0;
03615
03616 text += buff_two;
03617 text += " ";
03618 text += tmp;
03619 }
03620 else if ( ok && S_ISREG( buff.st_mode ) )
03621 {
03622 if (buff.st_size < 1024)
03623 text = i18n("%2 (%1 bytes)").arg((long) buff.st_size).arg(text2);
03624 else
03625 {
03626 float d = (float) buff.st_size/1024.0;
03627 text = i18n("%2 (%1 K)").arg(KGlobal::locale()->formatNumber(d, 2)).arg(text2);
03628 }
03629 text += " ";
03630 text += com;
03631 }
03632 else if ( ok && S_ISDIR( buff.st_mode ) )
03633 {
03634 text += " ";
03635 text += com;
03636 }
03637 else
03638 {
03639 text += " ";
03640 text += com;
03641 }
03642 setStatusBarText(text, BarHoverText);
03643 }
03644 else
03645 {
03646 QString extra;
03647 if (target.lower() == "_blank")
03648 {
03649 extra = i18n(" (In new window)");
03650 }
03651 else if (!target.isEmpty() &&
03652 (target.lower() != "_top") &&
03653 (target.lower() != "_self") &&
03654 (target.lower() != "_parent"))
03655 {
03656 KHTMLPart *p = this;
03657 while (p->parentPart())
03658 p = p->parentPart();
03659 if (!p->frameExists(target))
03660 extra = i18n(" (In new window)");
03661 else
03662 extra = i18n(" (In other frame)");
03663 }
03664
03665 if (u.protocol() == QString::fromLatin1("mailto")) {
03666 QString mailtoMsg ;
03667 mailtoMsg += i18n("Email to: ") + KURL::decode_string(u.path());
03668 QStringList queries = QStringList::split('&', u.query().mid(1));
03669 QStringList::Iterator it = queries.begin();
03670 const QStringList::Iterator itEnd = queries.end();
03671 for (; it != itEnd; ++it)
03672 if ((*it).startsWith(QString::fromLatin1("subject=")))
03673 mailtoMsg += i18n(" - Subject: ") + KURL::decode_string((*it).mid(8));
03674 else if ((*it).startsWith(QString::fromLatin1("cc=")))
03675 mailtoMsg += i18n(" - CC: ") + KURL::decode_string((*it).mid(3));
03676 else if ((*it).startsWith(QString::fromLatin1("bcc=")))
03677 mailtoMsg += i18n(" - BCC: ") + KURL::decode_string((*it).mid(4));
03678 mailtoMsg = QStyleSheet::escape(mailtoMsg);
03679 mailtoMsg.replace(QRegExp("([\n\r\t]|[ ]{10})"), QString::null);
03680 setStatusBarText("<qt>"+mailtoMsg, BarHoverText);
03681 return;
03682 }
03683
03684 #if 0
03685 else if (u.protocol() == QString::fromLatin1("http")) {
03686 DOM::Node hrefNode = nodeUnderMouse().parentNode();
03687 while (hrefNode.nodeName().string() != QString::fromLatin1("A") && !hrefNode.isNull())
03688 hrefNode = hrefNode.parentNode();
03689
03690 if (!hrefNode.isNull()) {
03691 DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
03692 if (!hreflangNode.isNull()) {
03693 QString countryCode = hreflangNode.nodeValue().string().lower();
03694
03695 if (countryCode == QString::fromLatin1("en"))
03696 countryCode = QString::fromLatin1("gb");
03697 QString flagImg = QString::fromLatin1("<img src=%1>").arg(
03698 locate("locale", QString::fromLatin1("l10n/")
03699 + countryCode
03700 + QString::fromLatin1("/flag.png")));
03701 emit setStatusBarText(flagImg + u.prettyURL() + extra);
03702 }
03703 }
03704 }
03705 #endif
03706 setStatusBarText(u.htmlURL() + extra, BarHoverText);
03707 }
03708 }
03709
03710
03711
03712
03713
03714 void KHTMLPart::urlSelected( const QString &url, int button, int state, const QString &_target, KParts::URLArgs args )
03715 {
03716 bool hasTarget = false;
03717
03718 QString target = _target;
03719 if ( target.isEmpty() && d->m_doc )
03720 target = d->m_doc->baseTarget();
03721 if ( !target.isEmpty() )
03722 hasTarget = true;
03723
03724 if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
03725 {
03726 crossFrameExecuteScript( target, KURL::decode_string( url.mid( 11 ) ) );
03727 return;
03728 }
03729
03730 KURL cURL = completeURL(url);
03731
03732 if ( url.isEmpty() )
03733 cURL.setFileName( url );
03734
03735 if ( !cURL.isValid() )
03736
03737 return;
03738
03739 kdDebug(6050) << this << " urlSelected: complete URL:" << cURL.url() << " target=" << target << endl;
03740
03741 if ( state & ControlButton )
03742 {
03743 args.setNewTab(true);
03744 emit d->m_extension->createNewWindow( cURL, args );
03745 return;
03746 }
03747
03748 if ( button == LeftButton && ( state & ShiftButton ) )
03749 {
03750 KIO::MetaData metaData;
03751 metaData["referrer"] = d->m_referrer;
03752 KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), cURL, metaData );
03753 return;
03754 }
03755
03756 if (!checkLinkSecurity(cURL,
03757 i18n( "<qt>This untrusted page links to<BR><B>%1</B>.<BR>Do you want to follow the link?" ),
03758 i18n( "Follow" )))
03759 return;
03760
03761 args.frameName = target;
03762
03763 args.metaData().insert("main_frame_request",
03764 parentPart() == 0 ? "TRUE":"FALSE");
03765 args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
03766 args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
03767 args.metaData().insert("PropagateHttpHeader", "true");
03768 args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
03769 args.metaData().insert("ssl_activate_warnings", "TRUE");
03770
03771 if ( hasTarget && target != "_self" && target != "_top" && target != "_blank" && target != "_parent" )
03772 {
03773
03774 khtml::ChildFrame *frame = recursiveFrameRequest( this, cURL, args, false );
03775 if ( frame )
03776 {
03777 args.metaData()["referrer"] = d->m_referrer;
03778 requestObject( frame, cURL, args );
03779 return;
03780 }
03781 }
03782
03783 if ( !d->m_bComplete && !hasTarget )
03784 closeURL();
03785
03786 if (!d->m_referrer.isEmpty() && !args.metaData().contains("referrer"))
03787 args.metaData()["referrer"] = d->m_referrer;
03788
03789 if ( button == NoButton && (state & ShiftButton) && (state & ControlButton) )
03790 {
03791 emit d->m_extension->createNewWindow( cURL, args );
03792 return;
03793 }
03794
03795 if ( state & ShiftButton)
03796 {
03797 KParts::WindowArgs winArgs;
03798 winArgs.lowerWindow = true;
03799 KParts::ReadOnlyPart *newPart = 0;
03800 emit d->m_extension->createNewWindow( cURL, args, winArgs, newPart );
03801 return;
03802 }
03803
03804 view()->viewport()->unsetCursor();
03805 emit d->m_extension->openURLRequest( cURL, args );
03806 }
03807
03808 void KHTMLPart::slotViewDocumentSource()
03809 {
03810 KURL url(m_url);
03811 bool isTempFile = false;
03812 if (!(url.isLocalFile()) && KHTMLPageCache::self()->isComplete(d->m_cacheId))
03813 {
03814 KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
03815 if (sourceFile.status() == 0)
03816 {
03817 KHTMLPageCache::self()->saveData(d->m_cacheId, sourceFile.dataStream());
03818 url = KURL();
03819 url.setPath(sourceFile.name());
03820 isTempFile = true;
03821 }
03822 }
03823
03824 (void) KRun::runURL( url, QString::fromLatin1("text/plain"), isTempFile );
03825 }
03826
03827 void KHTMLPart::slotViewPageInfo()
03828 {
03829 KHTMLInfoDlg *dlg = new KHTMLInfoDlg(NULL, "KHTML Page Info Dialog", false, WDestructiveClose);
03830 dlg->_close->setGuiItem(KStdGuiItem::close());
03831
03832 if (d->m_doc)
03833 dlg->_title->setText(d->m_doc->title().string());
03834
03835
03836 if ( parentPart() && d->m_doc && d->m_doc->isHTMLDocument() ) {
03837 dlg->setCaption(i18n("Frame Information"));
03838 }
03839
03840 QString editStr = QString::null;
03841
03842 if (!d->m_pageServices.isEmpty())
03843 editStr = i18n(" <a href=\"%1\">[Properties]</a>").arg(d->m_pageServices);
03844
03845 QString squeezedURL = KStringHandler::csqueeze( url().prettyURL(), 80 );
03846 dlg->_url->setText("<a href=\"" + url().url() + "\">" + squeezedURL + "</a>" + editStr);
03847 if (lastModified().isEmpty())
03848 {
03849 dlg->_lastModified->hide();
03850 dlg->_lmLabel->hide();
03851 }
03852 else
03853 dlg->_lastModified->setText(lastModified());
03854
03855 const QString& enc = encoding();
03856 if (enc.isEmpty()) {
03857 dlg->_eLabel->hide();
03858 dlg->_encoding->hide();
03859 } else {
03860 dlg->_encoding->setText(enc);
03861 }
03862
03863 const QStringList headers = QStringList::split("\n", d->m_httpHeaders);
03864
03865 QStringList::ConstIterator it = headers.begin();
03866 const QStringList::ConstIterator itEnd = headers.end();
03867
03868 for (; it != itEnd; ++it) {
03869 const QStringList header = QStringList::split(QRegExp(":[ ]+"), *it);
03870 if (header.count() != 2)
03871 continue;
03872 new QListViewItem(dlg->_headers, header[0], header[1]);
03873 }
03874
03875 dlg->show();
03876
03877 }
03878
03879
03880 void KHTMLPart::slotViewFrameSource()
03881 {
03882 KParts::ReadOnlyPart *frame = currentFrame();
03883 if ( !frame )
03884 return;
03885
03886 KURL url = frame->url();
03887 bool isTempFile = false;
03888 if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
03889 {
03890 long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;
03891
03892 if (KHTMLPageCache::self()->isComplete(cacheId))
03893 {
03894 KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
03895 if (sourceFile.status() == 0)
03896 {
03897 KHTMLPageCache::self()->saveData(cacheId, sourceFile.dataStream());
03898 url = KURL();
03899 url.setPath(sourceFile.name());
03900 isTempFile = true;
03901 }
03902 }
03903 }
03904
03905 (void) KRun::runURL( url, QString::fromLatin1("text/plain"), isTempFile );
03906 }
03907
03908 KURL KHTMLPart::backgroundURL() const
03909 {
03910
03911 if (!d->m_doc || !d->m_doc->isHTMLDocument())
03912 return KURL();
03913
03914 QString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
03915
03916 return KURL( m_url, relURL );
03917 }
03918
03919 void KHTMLPart::slotSaveBackground()
03920 {
03921 KIO::MetaData metaData;
03922 metaData["referrer"] = d->m_referrer;
03923 KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save Background Image As"), backgroundURL(), metaData );
03924 }
03925
03926 void KHTMLPart::slotSaveDocument()
03927 {
03928 KURL srcURL( m_url );
03929
03930 if ( srcURL.fileName(false).isEmpty() )
03931 srcURL.setFileName( "index.html" );
03932
03933 KIO::MetaData metaData;
03934
03935 KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, "text/html", d->m_cacheId );
03936 }
03937
03938 void KHTMLPart::slotSecurity()
03939 {
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958 KSSLInfoDlg *kid = new KSSLInfoDlg(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );
03959
03960 if (d->m_bSecurityInQuestion)
03961 kid->setSecurityInQuestion(true);
03962
03963 if (d->m_ssl_in_use) {
03964 KSSLCertificate *x = KSSLCertificate::fromString(d->m_ssl_peer_certificate.local8Bit());
03965 if (x) {
03966
03967 const QStringList cl = QStringList::split(QString("\n"), d->m_ssl_peer_chain);
03968 QPtrList<KSSLCertificate> ncl;
03969
03970 ncl.setAutoDelete(true);
03971 QStringList::ConstIterator it = cl.begin();
03972 const QStringList::ConstIterator itEnd = cl.end();
03973 for (; it != itEnd; ++it) {
03974 KSSLCertificate* const y = KSSLCertificate::fromString((*it).local8Bit());
03975 if (y) ncl.append(y);
03976 }
03977
03978 if (ncl.count() > 0)
03979 x->chain().setChain(ncl);
03980
03981 kid->setup(x,
03982 d->m_ssl_peer_ip,
03983 m_url.url(),
03984 d->m_ssl_cipher,
03985 d->m_ssl_cipher_desc,
03986 d->m_ssl_cipher_version,
03987 d->m_ssl_cipher_used_bits.toInt(),
03988 d->m_ssl_cipher_bits.toInt(),
03989 (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt()
03990 );
03991 kid->exec();
03992 delete x;
03993 } else kid->exec();
03994 } else kid->exec();
03995 }
03996
03997 void KHTMLPart::slotSaveFrame()
03998 {
03999 KParts::ReadOnlyPart *frame = currentFrame();
04000 if ( !frame )
04001 return;
04002
04003 KURL srcURL( frame->url() );
04004
04005 if ( srcURL.fileName(false).isEmpty() )
04006 srcURL.setFileName( "index.html" );
04007
04008 KIO::MetaData metaData;
04009
04010 KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save Frame As" ), srcURL, metaData, "text/html" );
04011 }
04012
04013 void KHTMLPart::slotSetEncoding()
04014 {
04015 d->m_automaticDetection->setItemChecked( int( d->m_autoDetectLanguage ), false );
04016 d->m_paSetEncoding->popupMenu()->setItemChecked( 0, false );
04017 d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), true );
04018
04019 QString enc = KGlobal::charsets()->encodingForName( d->m_manualDetection->currentText() );
04020 setEncoding( enc, true );
04021 }
04022
04023 void KHTMLPart::slotUseStylesheet()
04024 {
04025 if (d->m_doc)
04026 {
04027 bool autoselect = (d->m_paUseStylesheet->currentItem() == 0);
04028 d->m_sheetUsed = autoselect ? QString() : d->m_paUseStylesheet->currentText();
04029 d->m_doc->updateStyleSelector();
04030 }
04031 }
04032
04033 void KHTMLPart::updateActions()
04034 {
04035 bool frames = false;
04036
04037 QValueList<khtml::ChildFrame*>::ConstIterator it = d->m_frames.begin();
04038 const QValueList<khtml::ChildFrame*>::ConstIterator end = d->m_frames.end();
04039 for (; it != end; ++it )
04040 if ( (*it)->m_type == khtml::ChildFrame::Frame )
04041 {
04042 frames = true;
04043 break;
04044 }
04045
04046 d->m_paViewFrame->setEnabled( frames );
04047 d->m_paSaveFrame->setEnabled( frames );
04048
04049 if ( frames )
04050 d->m_paFind->setText( i18n( "&Find in Frame..." ) );
04051 else
04052 d->m_paFind->setText( i18n( "&Find..." ) );
04053
04054 KParts::Part *frame = 0;
04055
04056 if ( frames )
04057 frame = currentFrame();
04058
04059 bool enableFindAndSelectAll = true;
04060
04061 if ( frame )
04062 enableFindAndSelectAll = frame->inherits( "KHTMLPart" );
04063
04064 d->m_paFind->setEnabled( enableFindAndSelectAll );
04065 d->m_paSelectAll->setEnabled( enableFindAndSelectAll );
04066
04067 bool enablePrintFrame = false;
04068
04069 if ( frame )
04070 {
04071 QObject *ext = KParts::BrowserExtension::childObject( frame );
04072 if ( ext )
04073 enablePrintFrame = ext->metaObject()->slotNames().contains( "print()" );
04074 }
04075
04076 d->m_paPrintFrame->setEnabled( enablePrintFrame );
04077
04078 QString bgURL;
04079
04080
04081 if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
04082 bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
04083
04084 d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );
04085
04086 if ( d->m_paDebugScript )
04087 d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
04088 }
04089
04090 KParts::LiveConnectExtension *KHTMLPart::liveConnectExtension( const khtml::RenderPart *frame) const {
04091 const ConstFrameIt end = d->m_objects.end();
04092 for(ConstFrameIt it = d->m_objects.begin(); it != end; ++it )
04093 if ((*it)->m_frame == frame)
04094 return (*it)->m_liveconnect;
04095 return 0L;
04096 }
04097
04098 bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName,
04099 const QStringList ¶ms, bool isIFrame )
04100 {
04101
04102 FrameIt it = d->m_frames.find( frameName );
04103 if ( it == d->m_frames.end() )
04104 {
04105 khtml::ChildFrame * child = new khtml::ChildFrame;
04106
04107 child->m_name = frameName;
04108 it = d->m_frames.append( child );
04109 }
04110
04111 (*it)->m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
04112 (*it)->m_frame = frame;
04113 (*it)->m_params = params;
04114
04115
04116 if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
04117 {
04118 QVariant res = executeScript( DOM::Node(frame->element()), KURL::decode_string( url.right( url.length() - 11) ) );
04119 KURL myurl;
04120 myurl.setProtocol("javascript");
04121 if ( res.type() == QVariant::String )
04122 myurl.setPath(res.asString());
04123 return processObjectRequest(*it, myurl, QString("text/html") );
04124 }
04125 KURL u = url.isEmpty() ? KURL() : completeURL( url );
04126 return requestObject( *it, u );
04127 }
04128
04129 QString KHTMLPart::requestFrameName()
04130 {
04131 return QString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
04132 }
04133
04134 bool KHTMLPart::requestObject( khtml::RenderPart *frame, const QString &url, const QString &serviceType,
04135 const QStringList ¶ms )
04136 {
04137
04138 khtml::ChildFrame *child = new khtml::ChildFrame;
04139 FrameIt it = d->m_objects.append( child );
04140 (*it)->m_frame = frame;
04141 (*it)->m_type = khtml::ChildFrame::Object;
04142 (*it)->m_params = params;
04143
04144 KParts::URLArgs args;
04145 args.serviceType = serviceType;
04146 if (!requestObject( *it, completeURL( url ), args ) && !(*it)->m_run) {
04147 (*it)->m_bCompleted = true;
04148 return false;
04149 }
04150 return true;
04151 }
04152
04153 bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &_args )
04154 {
04155 if (!checkLinkSecurity(url))
04156 {
04157 kdDebug(6005) << this << " KHTMLPart::requestObject checkLinkSecurity refused" << endl;
04158 return false;
04159 }
04160 if ( child->m_bPreloaded )
04161 {
04162 kdDebug(6005) << "KHTMLPart::requestObject preload" << endl;
04163 if ( child->m_frame && child->m_part )
04164 child->m_frame->setWidget( child->m_part->widget() );
04165
04166 child->m_bPreloaded = false;
04167 return true;
04168 }
04169
04170
04171
04172 KParts::URLArgs args( _args );
04173
04174 if ( child->m_run )
04175 child->m_run->abort();
04176
04177 if ( child->m_part && !args.reload && urlcmp( child->m_part->url().url(), url.url(), true, true ) )
04178 args.serviceType = child->m_serviceType;
04179
04180 child->m_args = args;
04181 child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload);
04182 child->m_serviceName = QString::null;
04183 if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
04184 child->m_args.metaData()["referrer"] = d->m_referrer;
04185
04186 child->m_args.metaData().insert("PropagateHttpHeader", "true");
04187 child->m_args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
04188 child->m_args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
04189 child->m_args.metaData().insert("main_frame_request",
04190 parentPart() == 0 ? "TRUE":"FALSE");
04191 child->m_args.metaData().insert("ssl_was_in_use",
04192 d->m_ssl_in_use ? "TRUE":"FALSE");
04193 child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
04194 child->m_args.metaData().insert("cross-domain", toplevelURL().url());
04195
04196
04197 if ((url.isEmpty() || url.url() == "about:blank") && args.serviceType.isEmpty())
04198 args.serviceType = QString::fromLatin1( "text/html" );
04199
04200 if ( args.serviceType.isEmpty() ) {
04201 kdDebug(6050) << "Running new KHTMLRun for " << this << " and child=" << child << endl;
04202 child->m_run = new KHTMLRun( this, child, url, child->m_args, true );
04203 d->m_bComplete = false;
04204 return false;
04205 } else {
04206 return processObjectRequest( child, url, args.serviceType );
04207 }
04208 }
04209
04210 bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url, const QString &mimetype )
04211 {
04212
04213
04214
04215
04216
04217 KURL url( _url );
04218
04219
04220 if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) )
04221 {
04222 child->m_bCompleted = true;
04223 checkCompleted();
04224 return true;
04225 }
04226
04227 if (child->m_bNotify)
04228 {
04229 child->m_bNotify = false;
04230 if ( !child->m_args.lockHistory() )
04231 emit d->m_extension->openURLNotify();
04232 }
04233
04234 if ( child->m_serviceType != mimetype || !child->m_part )
04235 {
04236
04237
04238
04239 if ( child->m_type != khtml::ChildFrame::Object )
04240 {
04241 QString suggestedFilename;
04242 if ( child->m_run )
04243 suggestedFilename = child->m_run->suggestedFilename();
04244
04245 KParts::BrowserRun::AskSaveResult res = KParts::BrowserRun::askEmbedOrSave(
04246 url, mimetype, suggestedFilename );
04247 switch( res ) {
04248 case KParts::BrowserRun::Save:
04249 KHTMLPopupGUIClient::saveURL( widget(), i18n( "Save As" ), url, child->m_args.metaData(), QString::null, 0, suggestedFilename);
04250
04251 case KParts::BrowserRun::Cancel:
04252 child->m_bCompleted = true;
04253 checkCompleted();
04254 return true;
04255 default:
04256 break;
04257 }
04258 }
04259
04260 QStringList dummy;
04261 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 );
04262
04263 if ( !part )
04264 {
04265 if ( child->m_frame )
04266 if (child->m_frame->partLoadingErrorNotify( child, url, mimetype ))
04267 return true;
04268
04269 checkEmitLoadEvent();
04270 return false;
04271 }
04272
04273
04274 if ( child->m_part )
04275 {
04276 if (!::qt_cast<KHTMLPart*>(child->m_part) && child->m_jscript)
04277 child->m_jscript->clear();
04278 partManager()->removePart( (KParts::ReadOnlyPart *)child->m_part );
04279 delete (KParts::ReadOnlyPart *)child->m_part;
04280 if (child->m_liveconnect) {
04281 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 &)));
04282 child->m_liveconnect = 0L;
04283 }
04284 }
04285
04286 child->m_serviceType = mimetype;
04287 if ( child->m_frame )
04288 child->m_frame->setWidget( part->widget() );
04289
04290 if ( child->m_type != khtml::ChildFrame::Object )
04291 partManager()->addPart( part, false );
04292
04293
04294
04295 child->m_part = part;
04296
04297 if (::qt_cast<KHTMLPart*>(part)) {
04298 static_cast<KHTMLPart*>(part)->d->m_frame = child;
04299 } else if (child->m_frame) {
04300 child->m_liveconnect = KParts::LiveConnectExtension::childObject(part);
04301 if (child->m_liveconnect)
04302 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 &)));
04303 }
04304
04305 connect( part, SIGNAL( started( KIO::Job *) ),
04306 this, SLOT( slotChildStarted( KIO::Job *) ) );
04307 connect( part, SIGNAL( completed() ),
04308 this, SLOT( slotChildCompleted() ) );
04309 connect( part, SIGNAL( completed(bool) ),
04310 this, SLOT( slotChildCompleted(bool) ) );
04311 connect( part, SIGNAL( setStatusBarText( const QString & ) ),
04312 this, SIGNAL( setStatusBarText( const QString & ) ) );
04313 if ( part->inherits( "KHTMLPart" ) )
04314 {
04315 connect( this, SIGNAL( completed() ),
04316 part, SLOT( slotParentCompleted() ) );
04317 connect( this, SIGNAL( completed(bool) ),
04318 part, SLOT( slotParentCompleted() ) );
04319
04320
04321 connect( part, SIGNAL( docCreated() ),
04322 this, SLOT( slotChildDocCreated() ) );
04323 }
04324
04325 child->m_extension = KParts::BrowserExtension::childObject( part );
04326
04327 if ( child->m_extension )
04328 {
04329 connect( child->m_extension, SIGNAL( openURLNotify() ),
04330 d->m_extension, SIGNAL( openURLNotify() ) );
04331
04332 connect( child->m_extension, SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
04333 this, SLOT( slotChildURLRequest( const KURL &, const KParts::URLArgs & ) ) );
04334
04335 connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
04336 d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
04337 connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
04338 d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );
04339
04340 connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ),
04341 d->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ) );
04342 connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ),
04343 d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) );
04344 connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ),
04345 d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags ) ) );
04346 connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ),
04347 d->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) );
04348 connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ),
04349 d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) );
04350 connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ),
04351 d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const KParts::URLArgs &, KParts::BrowserExtension::PopupFlags, mode_t ) ) );
04352
04353 connect( child->m_extension, SIGNAL( infoMessage( const QString & ) ),
04354 d->m_extension, SIGNAL( infoMessage( const QString & ) ) );
04355
04356 connect( child->m_extension, SIGNAL( requestFocus( KParts::ReadOnlyPart * ) ),
04357 this, SLOT( slotRequestFocus( KParts::ReadOnlyPart * ) ) );
04358
04359 child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
04360 }
04361 }
04362 else if ( child->m_frame && child->m_part &&
04363 child->m_frame->widget() != child->m_part->widget() )
04364 child->m_frame->setWidget( child->m_part->widget() );
04365
04366 checkEmitLoadEvent();
04367
04368
04369 if ( !child->m_part )
04370 return false;
04371
04372 if ( child->m_bPreloaded )
04373 {
04374 if ( child->m_frame && child->m_part )
04375 child->m_frame->setWidget( child->m_part->widget() );
04376
04377 child->m_bPreloaded = false;
04378 return true;
04379 }
04380
04381 child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload);
04382
04383
04384
04385
04386
04387 child->m_args.serviceType = mimetype;
04388
04389
04390 child->m_bCompleted = child->m_type == khtml::ChildFrame::Object;
04391
04392 if ( child->m_extension )
04393 child->m_extension->setURLArgs( child->m_args );
04394
04395 if(url.protocol() == "javascript" || url.url() == "about:blank") {
04396 if (!child->m_part->inherits("KHTMLPart"))
04397 return false;
04398
04399 KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));
04400
04401 p->begin();
04402 if (d->m_doc && p->d->m_doc)
04403 p->d->m_doc->setBaseURL(d->m_doc->baseURL());
04404 if (!url.url().startsWith("about:")) {
04405 p->write(url.path());
04406 } else {
04407 p->m_url = url;
04408
04409 p->write("<HTML><TITLE></TITLE><BODY></BODY></HTML>");
04410 }
04411 p->end();
04412 return true;
04413 }
04414 else if ( !url.isEmpty() )
04415 {
04416
04417 bool b = child->m_part->openURL( url );
04418 if (child->m_bCompleted)
04419 checkCompleted();
04420 return b;
04421 }
04422 else
04423 {
04424 child->m_bCompleted = true;
04425 checkCompleted();
04426 return true;
04427 }
04428 }
04429
04430 KParts::ReadOnlyPart *KHTMLPart::createPart( QWidget *parentWidget, const char *widgetName,
04431 QObject *parent, const char *name, const QString &mimetype,
04432 QString &serviceName, QStringList &serviceTypes,
04433 const QStringList ¶ms )
04434 {
04435 QString constr;
04436 if ( !serviceName.isEmpty() )
04437 constr.append( QString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );
04438
04439 KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, QString::null );
04440
04441 if ( offers.isEmpty() ) {
04442 int pos = mimetype.find( "-plugin" );
04443 if (pos < 0)
04444 return 0L;
04445 QString stripped_mime = mimetype.left( pos );
04446 offers = KTrader::self()->query( stripped_mime, "KParts/ReadOnlyPart", constr, QString::null );
04447 if ( offers.isEmpty() )
04448 return 0L;
04449 }
04450
04451 KTrader::OfferList::ConstIterator it = offers.begin();
04452 const KTrader::OfferList::ConstIterator itEnd = offers.end();
04453 for ( ; it != itEnd; ++it )
04454 {
04455 KService::Ptr service = (*it);
04456
04457 KLibFactory* const factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) );
04458 if ( factory ) {
04459 KParts::ReadOnlyPart *res = 0L;
04460
04461 const char *className = "KParts::ReadOnlyPart";
04462 if ( service->serviceTypes().contains( "Browser/View" ) )
04463 className = "Browser/View";
04464
04465 if ( factory->inherits( "KParts::Factory" ) )
04466 res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
04467 else
04468 res = static_cast<KParts::ReadOnlyPart *>(factory->create( parentWidget, widgetName, className ));
04469
04470 if ( res ) {
04471 serviceTypes = service->serviceTypes();
04472 serviceName = service->name();
04473 return res;
04474 }
04475 } else {
04476
04477 kdWarning() << QString("There was an error loading the module %1.\nThe diagnostics is:\n%2")
04478 .arg(service->name()).arg(KLibLoader::self()->lastErrorMessage()) << endl;
04479 }
04480 }
04481 return 0;
04482 }
04483
04484 KParts::PartManager *KHTMLPart::partManager()
04485 {
04486 if ( !d->m_manager && d->m_view )
04487 {
04488 d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
04489 d->m_manager->setAllowNestedParts( true );
04490 connect( d->m_manager, SIGNAL( activePartChanged( KParts::Part * ) ),
04491 this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
04492 connect( d->m_manager, SIGNAL( partRemoved( KParts::Part * ) ),
04493 this, SLOT( slotPartRemoved( KParts::Part * ) ) );
04494 }
04495
04496 return d->m_manager;
04497 }
04498
04499 void KHTMLPart::submitFormAgain()
04500 {
04501 if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
04502 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 );
04503
04504 delete d->m_submitForm;
04505 d->m_submitForm = 0;
04506 disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
04507 }
04508
04509 void KHTMLPart::submitFormProxy( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
04510 {
04511 submitForm(action, url, formData, _target, contentType, boundary);
04512 }
04513
04514 void KHTMLPart::submitForm( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
04515 {
04516 kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
04517 if (d->m_formNotification == KHTMLPart::Only) {
04518 emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
04519 return;
04520 } else if (d->m_formNotification == KHTMLPart::Before) {
04521 emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
04522 }
04523
04524 KURL u = completeURL( url );
04525
04526 if ( !u.isValid() )
04527 {
04528
04529 return;
04530 }
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544 if (!d->m_submitForm) {
04545 if (u.protocol() != "https" && u.protocol() != "mailto") {
04546 if (d->m_ssl_in_use) {
04547 int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning: This is a secure form but it is attempting to send your data back unencrypted."
04548 "\nA third party may be able to intercept and view this information."
04549 "\nAre you sure you wish to continue?"),
04550 i18n("Network Transmission"),KGuiItem(i18n("&Send Unencrypted")));
04551 if (rc == KMessageBox::Cancel)
04552 return;
04553 } else {
04554 KSSLSettings kss(true);
04555 if (kss.warnOnUnencrypted()) {
04556 int rc = KMessageBox::warningContinueCancel(NULL,
04557 i18n("Warning: Your data is about to be transmitted across the network unencrypted."
04558 "\nAre you sure you wish to continue?"),
04559 i18n("Network Transmission"),
04560 KGuiItem(i18n("&Send Unencrypted")),
04561 "WarnOnUnencryptedForm");
04562
04563 KConfig *config = kapp->config();
04564 QString grpNotifMsgs = QString::fromLatin1("Notification Messages");
04565 KConfigGroupSaver saver( config, grpNotifMsgs );
04566
04567 if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
04568 config->deleteEntry("WarnOnUnencryptedForm");
04569 config->sync();
04570 kss.setWarnOnUnencrypted(false);
04571 kss.save();
04572 }
04573 if (rc == KMessageBox::Cancel)
04574 return;
04575 }
04576 }
04577 }
04578
04579 if (u.protocol() == "mailto") {
04580 int rc = KMessageBox::warningContinueCancel(NULL,
04581 i18n("This site is attempting to submit form data via email.\n"
04582 "Do you want to continue?"),
04583 i18n("Network Transmission"),
04584 KGuiItem(i18n("&Send Email")),
04585 "WarnTriedEmailSubmit");
04586
04587 if (rc == KMessageBox::Cancel) {
04588 return;
04589 }
04590 }
04591 }
04592
04593
04594
04595
04596 QString urlstring = u.url();
04597
04598 if ( urlstring.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
04599 urlstring = KURL::decode_string(urlstring);
04600 crossFrameExecuteScript( _target, urlstring.right( urlstring.length() - 11) );
04601 return;
04602 }
04603
04604 if (!checkLinkSecurity(u,
04605 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?" ),
04606 i18n( "Submit" )))
04607 return;
04608
04609 KParts::URLArgs args;
04610
04611 if (!d->m_referrer.isEmpty())
04612 args.metaData()["referrer"] = d->m_referrer;
04613
04614 args.metaData().insert("PropagateHttpHeader", "true");
04615 args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
04616 args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
04617 args.metaData().insert("main_frame_request",
04618 parentPart() == 0 ? "TRUE":"FALSE");
04619 args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
04620 args.metaData().insert("ssl_activate_warnings", "TRUE");
04621
04622
04623
04624 args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
04625
04626
04627 if (u.protocol() == "mailto") {
04628
04629 QString q = u.query().mid(1);
04630 QStringList nvps = QStringList::split("&", q);
04631 bool triedToAttach = false;
04632
04633 QStringList::Iterator nvp = nvps.begin();
04634 const QStringList::Iterator nvpEnd = nvps.end();
04635
04636
04637
04638
04639 while (nvp != nvpEnd) {
04640 const QStringList pair = QStringList::split("=", *nvp);
04641 if (pair.count() >= 2) {
04642 if (pair.first().lower() == "attach") {
04643 nvp = nvps.remove(nvp);
04644 triedToAttach = true;
04645 } else {
04646 ++nvp;
04647 }
04648 } else {
04649 ++nvp;
04650 }
04651 }
04652
04653 if (triedToAttach)
04654 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");
04655
04656
04657 QString bodyEnc;
04658 if (contentType.lower() == "multipart/form-data") {
04659
04660 bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
04661 formData.size()));
04662 } else if (contentType.lower() == "text/plain") {
04663
04664 QString tmpbody = QString::fromLatin1(formData.data(),
04665 formData.size());
04666 tmpbody.replace(QRegExp("[&]"), "\n");
04667 tmpbody.replace(QRegExp("[+]"), " ");
04668 tmpbody = KURL::decode_string(tmpbody);
04669 bodyEnc = KURL::encode_string(tmpbody);
04670 } else {
04671 bodyEnc = KURL::encode_string(QString::fromLatin1(formData.data(),
04672 formData.size()));
04673 }
04674
04675 nvps.append(QString("body=%1").arg(bodyEnc));
04676 q = nvps.join("&");
04677 u.setQuery(q);
04678 }
04679
04680 if ( strcmp( action, "get" ) == 0 ) {
04681 if (u.protocol() != "mailto")
04682 u.setQuery( QString::fromLatin1( formData.data(), formData.size() ) );
04683 args.setDoPost( false );
04684 }
04685 else {
04686 args.postData = formData;
04687 args.setDoPost( true );
04688
04689
04690 if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
04691 args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
04692 else
04693 args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
04694 }
04695
04696 if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
04697 if( d->m_submitForm ) {
04698 kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
04699 return;
04700 }
04701 d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
04702 d->m_submitForm->submitAction = action;
04703 d->m_submitForm->submitUrl = url;
04704 d->m_submitForm->submitFormData = formData;
04705 d->m_submitForm->target = _target;
04706 d->m_submitForm->submitContentType = contentType;
04707 d->m_submitForm->submitBoundary = boundary;
04708 connect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
04709 }
04710 else
04711 {
04712 emit d->m_extension->openURLRequest( u, args );
04713 }
04714 }
04715
04716 void KHTMLPart::popupMenu( const QString &linkUrl )
04717 {
04718 KURL popupURL;
04719 KURL linkKURL;
04720 KParts::URLArgs args;
04721 QString referrer;
04722 KParts::BrowserExtension::PopupFlags itemflags=KParts::BrowserExtension::ShowBookmark | KParts::BrowserExtension::ShowReload;
04723
04724 if ( linkUrl.isEmpty() ) {
04725 KHTMLPart* khtmlPart = this;
04726 while ( khtmlPart->parentPart() )
04727 {
04728 khtmlPart=khtmlPart->parentPart();
04729 }
04730 popupURL = khtmlPart->url();
04731 referrer = khtmlPart->pageReferrer();
04732 if (hasSelection())
04733 itemflags = KParts::BrowserExtension::ShowTextSelectionItems;
04734 else
04735 itemflags |= KParts::BrowserExtension::ShowNavigationItems;
04736 } else {
04737 popupURL = completeURL( linkUrl );
04738 linkKURL = popupURL;
04739 referrer = this->referrer();
04740
04741 if (!(d->m_strSelectedURLTarget).isEmpty() &&
04742 (d->m_strSelectedURLTarget.lower() != "_top") &&
04743 (d->m_strSelectedURLTarget.lower() != "_self") &&
04744 (d->m_strSelectedURLTarget.lower() != "_parent")) {
04745 if (d->m_strSelectedURLTarget.lower() == "_blank")
04746 args.setForcesNewWindow(true);
04747 else {
04748 KHTMLPart *p = this;
04749 while (p->parentPart())
04750 p = p->parentPart();
04751 if (!p->frameExists(d->m_strSelectedURLTarget))
04752 args.setForcesNewWindow(true);
04753 }
04754 }
04755 }
04756
04757
04758
04759 KHTMLPopupGUIClient* client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
04760 QGuardedPtr<QObject> guard( client );
04761
04762 QString mimetype = QString::fromLatin1( "text/html" );
04763 args.metaData()["referrer"] = referrer;
04764
04765 if (!linkUrl.isEmpty())
04766 {
04767 if (popupURL.isLocalFile())
04768 {
04769 mimetype = KMimeType::findByURL(popupURL,0,true,false)->name();
04770 }
04771 else
04772 {
04773 const QString fname(popupURL.fileName(false));
04774 if (!fname.isEmpty() && !popupURL.hasRef() && popupURL.query().isEmpty())
04775 {
04776 KMimeType::Ptr pmt = KMimeType::findByPath(fname,0,true);
04777
04778
04779
04780
04781
04782 if (pmt->name() != KMimeType::defaultMimeType() &&
04783 !pmt->is("application/x-perl") &&
04784 !pmt->is("application/x-perl-module") &&
04785 !pmt->is("application/x-php") &&
04786 !pmt->is("application/x-python-bytecode") &&
04787 !pmt->is("application/x-python") &&
04788 !pmt->is("application/x-shellscript"))
04789 mimetype = pmt->name();
04790 }
04791 }
04792 }
04793
04794 args.serviceType = mimetype;
04795
04796 emit d->m_extension->popupMenu( client, QCursor::pos(), popupURL, args, itemflags, S_IFREG );
04797
04798 if ( !guard.isNull() ) {
04799 delete client;
04800 emit popupMenu(linkUrl, QCursor::pos());
04801 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
04802 }
04803 }
04804
04805 void KHTMLPart::slotParentCompleted()
04806 {
04807
04808 if ( !d->m_redirectURL.isEmpty() && !d->m_redirectionTimer.isActive() )
04809 {
04810
04811 d->m_redirectionTimer.start( 1000 * d->m_delayRedirect, true );
04812 }
04813 }
04814
04815 void KHTMLPart::slotChildStarted( KIO::Job *job )
04816 {
04817 khtml::ChildFrame *child = frame( sender() );
04818
04819 assert( child );
04820
04821 child->m_bCompleted = false;
04822
04823 if ( d->m_bComplete )
04824 {
04825 #if 0
04826
04827 if ( !parentPart() )
04828 {
04829 emit d->m_extension->openURLNotify();
04830 }
04831 #endif
04832 d->m_bComplete = false;
04833 emit started( job );
04834 }
04835 }
04836
04837 void KHTMLPart::slotChildCompleted()
04838 {
04839 slotChildCompleted( false );
04840 }
04841
04842 void KHTMLPart::slotChildCompleted( bool pendingAction )
04843 {
04844 khtml::ChildFrame *child = frame( sender() );
04845
04846 if ( child ) {
04847 kdDebug(6050) << this << " slotChildCompleted child=" << child << " m_frame=" << child->m_frame << endl;
04848 child->m_bCompleted = true;
04849 child->m_bPendingRedirection = pendingAction;
04850 child->m_args = KParts::URLArgs();
04851 }
04852 checkCompleted();
04853 }
04854
04855 void KHTMLPart::slotChildDocCreated()
04856 {
04857 const KHTMLPart* htmlFrame = static_cast<const KHTMLPart *>(sender());
04858
04859
04860
04861 if ( d->m_doc && d->m_doc->isHTMLDocument() )
04862 {
04863 if ( sender()->inherits("KHTMLPart") )
04864 {
04865 DOMString domain = static_cast<HTMLDocumentImpl*>(d->m_doc)->domain();
04866 if (htmlFrame->d->m_doc && htmlFrame->d->m_doc->isHTMLDocument() )
04867
04868 static_cast<HTMLDocumentImpl*>(htmlFrame->d->m_doc)->setDomain( domain );
04869 }
04870 }
04871
04872 disconnect( htmlFrame, SIGNAL( docCreated() ), this, SLOT( slotChildDocCreated() ) );
04873 }
04874
04875 void KHTMLPart::slotChildURLRequest( const KURL &url, const KParts::URLArgs &args )
04876 {
04877 khtml::ChildFrame *child = frame( sender()->parent() );
04878 KHTMLPart *callingHtmlPart = const_cast<KHTMLPart *>(dynamic_cast<const KHTMLPart *>(sender()->parent()));
04879
04880
04881 QString urlStr = url.url();
04882 if ( urlStr.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
04883 QString script = KURL::decode_string( urlStr.right( urlStr.length() - 11 ) );
04884 executeScript( DOM::Node(), script );
04885 return;
04886 }
04887
04888 QString frameName = args.frameName.lower();
04889 if ( !frameName.isEmpty() ) {
04890 if ( frameName == QString::fromLatin1( "_top" ) )
04891 {
04892 emit d->m_extension->openURLRequest( url, args );
04893 return;
04894 }
04895 else if ( frameName == QString::fromLatin1( "_blank" ) )
04896 {
04897 emit d->m_extension->createNewWindow( url, args );
04898 return;
04899 }
04900 else if ( frameName == QString::fromLatin1( "_parent" ) )
04901 {
04902 KParts::URLArgs newArgs( args );
04903 newArgs.frameName = QString::null;
04904
04905 emit d->m_extension->openURLRequest( url, newArgs );
04906 return;
04907 }
04908 else if ( frameName != QString::fromLatin1( "_self" ) )
04909 {
04910 khtml::ChildFrame *_frame = recursiveFrameRequest( callingHtmlPart, url, args );
04911
04912 if ( !_frame )
04913 {
04914 emit d->m_extension->openURLRequest( url, args );
04915 return;
04916 }
04917
04918 child = _frame;
04919 }
04920 }
04921
04922 if ( child && child->m_type != khtml::ChildFrame::Object ) {
04923
04924 child->m_bNotify = true;
04925 requestObject( child, url, args );
04926 } else if ( frameName== "_self" )
04927 {
04928 KParts::URLArgs newArgs( args );
04929 newArgs.frameName = QString::null;
04930 emit d->m_extension->openURLRequest( url, newArgs );
04931 }
04932 }
04933
04934 void KHTMLPart::slotRequestFocus( KParts::ReadOnlyPart * )
04935 {
04936 emit d->m_extension->requestFocus(this);
04937 }
04938
04939 khtml::ChildFrame *KHTMLPart::frame( const QObject *obj )
04940 {
04941 assert( obj->inherits( "KParts::ReadOnlyPart" ) );
04942 const KParts::ReadOnlyPart* const part = static_cast<const KParts::ReadOnlyPart *>( obj );
04943
04944 FrameIt it = d->m_frames.begin();
04945 const FrameIt end = d->m_frames.end();
04946 for (; it != end; ++it )
04947 if ( (KParts::ReadOnlyPart *)(*it)->m_part == part )
04948 return *it;
04949
04950 FrameIt oi = d->m_objects.begin();
04951 const FrameIt oiEnd = d->m_objects.end();
04952 for (; oi != oiEnd; ++oi )
04953 if ( (KParts::ReadOnlyPart *)(*oi)->m_part == part )
04954 return *oi;
04955
04956 return 0L;
04957 }
04958
04959
04960
04961 bool KHTMLPart::checkFrameAccess(KHTMLPart *callingHtmlPart)
04962 {
04963 if (callingHtmlPart == this)
04964 return true;
04965
04966 if (htmlDocument().isNull()) {
04967 #ifdef DEBUG_FINDFRAME
04968 kdDebug(6050) << "KHTMLPart::checkFrameAccess: Empty part " << this << " URL = " << m_url << endl;
04969 #endif
04970 return false;
04971 }
04972
04973
04974 if (callingHtmlPart && !callingHtmlPart->htmlDocument().isNull() &&
04975 !htmlDocument().isNull()) {
04976 DOM::DOMString actDomain = callingHtmlPart->htmlDocument().domain();
04977 DOM::DOMString destDomain = htmlDocument().domain();
04978
04979 #ifdef DEBUG_FINDFRAME
04980 kdDebug(6050) << "KHTMLPart::checkFrameAccess: actDomain = '" << actDomain.string() << "' destDomain = '" << destDomain.string() << "'" << endl;
04981 #endif
04982
04983 if (actDomain == destDomain)
04984 return true;
04985 }
04986 #ifdef DEBUG_FINDFRAME
04987 else
04988 {
04989 kdDebug(6050) << "KHTMLPart::checkFrameAccess: Unknown part/domain " << callingHtmlPart << " tries to access part " << this << endl;
04990 }
04991 #endif
04992 return false;
04993 }
04994
04995 KHTMLPart *
04996 KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame )
04997 {
04998 #ifdef DEBUG_FINDFRAME
04999 kdDebug(6050) << "KHTMLPart::findFrameParent: this = " << this << " URL = " << m_url << " name = " << name() << " findFrameParent( " << f << " )" << endl;
05000 #endif
05001
05002 KHTMLPart* const callingHtmlPart = dynamic_cast<KHTMLPart *>(callingPart);
05003
05004 if (!checkFrameAccess(callingHtmlPart))
05005 return 0;
05006
05007 if (!childFrame && !parentPart() && (name() == f))
05008 return this;
05009
05010 FrameIt it = d->m_frames.find( f );
05011 const FrameIt end = d->m_frames.end();
05012 if ( it != end )
05013 {
05014 #ifdef DEBUG_FINDFRAME
05015 kdDebug(6050) << "KHTMLPart::findFrameParent: FOUND!" << endl;
05016 #endif
05017 if (childFrame)
05018 *childFrame = *it;
05019 return this;
05020 }
05021
05022 it = d->m_frames.begin();
05023 for (; it != end; ++it )
05024 {
05025 KParts::ReadOnlyPart* const p = (*it)->m_part;
05026 if ( p && p->inherits( "KHTMLPart" ))
05027 {
05028 KHTMLPart* const frameParent = static_cast<KHTMLPart*>(p)->findFrameParent(callingPart, f, childFrame);
05029 if (frameParent)
05030 return frameParent;
05031 }
05032 }
05033 return 0;
05034 }
05035
05036
05037 KHTMLPart *KHTMLPart::findFrame( const QString &f )
05038 {
05039 khtml::ChildFrame *childFrame;
05040 KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame);
05041 if (parentFrame)
05042 {
05043 KParts::ReadOnlyPart *p = childFrame->m_part;
05044 if ( p && p->inherits( "KHTMLPart" ))
05045 return static_cast<KHTMLPart *>(p);
05046 }
05047 return 0;
05048 }
05049
05050 KParts::ReadOnlyPart *KHTMLPart::findFramePart(const QString &f)
05051 {
05052 khtml::ChildFrame *childFrame;
05053 return findFrameParent(this, f, &childFrame) ? static_cast<KParts::ReadOnlyPart *>(childFrame->m_part) : 0L;
05054 }
05055
05056 KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
05057 {
05058 KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
05059
05060
05061
05062 while ( part && part->inherits("KHTMLPart") &&
05063 static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
05064 KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
05065 part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
05066 if ( !part ) return frameset;
05067 }
05068 return part;
05069 }
05070
05071 bool KHTMLPart::frameExists( const QString &frameName )
05072 {
05073 ConstFrameIt it = d->m_frames.find( frameName );
05074 if ( it == d->m_frames.end() )
05075 return false;
05076
05077
05078
05079
05080 return (!(*it)->m_frame.isNull());
05081 }
05082
05083 KJSProxy *KHTMLPart::framejScript(KParts::ReadOnlyPart *framePart)
05084 {
05085 KHTMLPart* const kp = ::qt_cast<KHTMLPart*>(framePart);
05086 if (kp)
05087 return kp->jScript();
05088
05089 FrameIt it = d->m_frames.begin();
05090 const FrameIt itEnd = d->m_frames.end();
05091
05092 for (; it != itEnd; ++it)
05093 if (framePart == (*it)->m_part) {
05094 if (!(*it)->m_jscript)
05095 createJScript(*it);
05096 return (*it)->m_jscript;
05097 }
05098 return 0L;
05099 }
05100
05101 KHTMLPart *KHTMLPart::parentPart()
05102 {
05103 return ::qt_cast<KHTMLPart *>( parent() );
05104 }
05105
05106 khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KURL &url,
05107 const KParts::URLArgs &args, bool callParent )
05108 {
05109 #ifdef DEBUG_FINDFRAME
05110 kdDebug( 6050 ) << "KHTMLPart::recursiveFrameRequest this = " << this << ", frame = " << args.frameName << ", url = " << url << endl;
05111 #endif
05112 khtml::ChildFrame *childFrame;
05113 KHTMLPart *childPart = findFrameParent(callingHtmlPart, args.frameName, &childFrame);
05114 if (childPart)
05115 {
05116 if (childPart == this)
05117 return childFrame;
05118
05119 childPart->requestObject( childFrame, url, args );
05120 return 0;
05121 }
05122
05123 if ( parentPart() && callParent )
05124 {
05125 khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, callParent );
05126
05127 if ( res )
05128 parentPart()->requestObject( res, url, args );
05129 }
05130
05131 return 0L;
05132 }
05133
05134 #ifndef NDEBUG
05135 static int s_saveStateIndentLevel = 0;
05136 #endif
05137
05138 void KHTMLPart::saveState( QDataStream &stream )
05139 {
05140 #ifndef NDEBUG
05141 QString indent = QString().leftJustify( s_saveStateIndentLevel * 4, ' ' );
05142 const int indentLevel = s_saveStateIndentLevel++;
05143 kdDebug( 6050 ) << indent << "saveState this=" << this << " '" << name() << "' saving URL " << m_url.url() << endl;
05144 #endif
05145
05146 stream << m_url << (Q_INT32)d->m_view->contentsX() << (Q_INT32)d->m_view->contentsY()
05147 << (Q_INT32) d->m_view->contentsWidth() << (Q_INT32) d->m_view->contentsHeight() << (Q_INT32) d->m_view->marginWidth() << (Q_INT32) d->m_view->marginHeight();
05148
05149
05150 int focusNodeNumber;
05151 if (!d->m_focusNodeRestored)
05152 focusNodeNumber = d->m_focusNodeNumber;
05153 else if (d->m_doc && d->m_doc->focusNode())
05154 focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
05155 else
05156 focusNodeNumber = -1;
05157 stream << focusNodeNumber;
05158
05159
05160 stream << d->m_cacheId;
05161
05162
05163 QStringList docState;
05164 if (d->m_doc)
05165 {
05166 docState = d->m_doc->docState();
05167 }
05168 stream << d->m_encoding << d->m_sheetUsed << docState;
05169
05170 stream << d->m_zoomFactor;
05171
05172 stream << d->m_httpHeaders;
05173 stream << d->m_pageServices;
05174 stream << d->m_pageReferrer;
05175
05176
05177 stream << d->m_ssl_in_use
05178 << d->m_ssl_peer_certificate
05179 << d->m_ssl_peer_chain
05180 << d->m_ssl_peer_ip
05181 << d->m_ssl_cipher
05182 << d->m_ssl_cipher_desc
05183 << d->m_ssl_cipher_version
05184 << d->m_ssl_cipher_used_bits
05185 << d->m_ssl_cipher_bits
05186 << d->m_ssl_cert_state
05187 << d->m_ssl_parent_ip
05188 << d->m_ssl_parent_cert;
05189
05190
05191 QStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
05192 KURL::List frameURLLst;
05193 QValueList<QByteArray> frameStateBufferLst;
05194
05195 ConstFrameIt it = d->m_frames.begin();
05196 const ConstFrameIt end = d->m_frames.end();
05197 for (; it != end; ++it )
05198 {
05199 if ( !(*it)->m_part )
05200 continue;
05201
05202 frameNameLst << (*it)->m_name;
05203 frameServiceTypeLst << (*it)->m_serviceType;
05204 frameServiceNameLst << (*it)->m_serviceName;
05205 frameURLLst << (*it)->m_part->url();
05206
05207 QByteArray state;
05208 QDataStream frameStream( state, IO_WriteOnly );
05209
05210 if ( (*it)->m_extension )
05211 (*it)->m_extension->saveState( frameStream );
05212
05213 frameStateBufferLst << state;
05214 }
05215
05216
05217 stream << (Q_UINT32) frameNameLst.count();
05218 stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst;
05219 #ifndef NDEBUG
05220 s_saveStateIndentLevel = indentLevel;
05221 #endif
05222 }
05223
05224 void KHTMLPart::restoreState( QDataStream &stream )
05225 {
05226 KURL u;
05227 Q_INT32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
05228 Q_UINT32 frameCount;
05229 QStringList frameNames, frameServiceTypes, docState, frameServiceNames;
05230 KURL::List frameURLs;
05231 QValueList<QByteArray> frameStateBuffers;
05232 QValueList<int> fSizes;
05233 QString encoding, sheetUsed;
05234 long old_cacheId = d->m_cacheId;
05235
05236 stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
05237
05238 d->m_view->setMarginWidth( mWidth );
05239 d->m_view->setMarginHeight( mHeight );
05240
05241
05242
05243 stream >> d->m_focusNodeNumber;
05244 d->m_focusNodeRestored = false;
05245
05246 stream >> d->m_cacheId;
05247
05248 stream >> encoding >> sheetUsed >> docState;
05249
05250 d->m_encoding = encoding;
05251 d->m_sheetUsed = sheetUsed;
05252
05253 int zoomFactor;
05254 stream >> zoomFactor;
05255 setZoomFactor(zoomFactor);
05256
05257 stream >> d->m_httpHeaders;
05258 stream >> d->m_pageServices;
05259 stream >> d->m_pageReferrer;
05260
05261
05262 stream >> d->m_ssl_in_use
05263 >> d->m_ssl_peer_certificate
05264 >> d->m_ssl_peer_chain
05265 >> d->m_ssl_peer_ip
05266 >> d->m_ssl_cipher
05267 >> d->m_ssl_cipher_desc
05268 >> d->m_ssl_cipher_version
05269 >> d->m_ssl_cipher_used_bits
05270 >> d->m_ssl_cipher_bits
05271 >> d->m_ssl_cert_state
05272 >> d->m_ssl_parent_ip
05273 >> d->m_ssl_parent_cert;
05274
05275 setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );
05276
05277 stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
05278 >> frameURLs >> frameStateBuffers;
05279
05280 d->m_bComplete = false;
05281 d->m_bLoadEventEmitted = false;
05282
05283
05284
05285
05286
05287 if (d->m_cacheId == old_cacheId)
05288 {
05289
05290 d->m_redirectionTimer.stop();
05291
05292 FrameIt fIt = d->m_frames.begin();
05293 const FrameIt fEnd = d->m_frames.end();
05294
05295 for (; fIt != fEnd; ++fIt )
05296 (*fIt)->m_bCompleted = false;
05297
05298 fIt = d->m_frames.begin();
05299
05300 QStringList::ConstIterator fNameIt = frameNames.begin();
05301 QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
05302 QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
05303 KURL::List::ConstIterator fURLIt = frameURLs.begin();
05304 QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
05305
05306 for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
05307 {
05308 khtml::ChildFrame* const child = *fIt;
05309
05310
05311
05312 if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
05313 {
05314 child->m_bPreloaded = true;
05315 child->m_name = *fNameIt;
05316 child->m_serviceName = *fServiceNameIt;
05317 processObjectRequest( child, *fURLIt, *fServiceTypeIt );
05318 }
05319 if ( child->m_part )
05320 {
05321 child->m_bCompleted = false;
05322 if ( child->m_extension && !(*fBufferIt).isEmpty() )
05323 {
05324 QDataStream frameStream( *fBufferIt, IO_ReadOnly );
05325 child->m_extension->restoreState( frameStream );
05326 }
05327 else
05328 child->m_part->openURL( *fURLIt );
05329 }
05330 }
05331
05332 KParts::URLArgs args( d->m_extension->urlArgs() );
05333 args.xOffset = xOffset;
05334 args.yOffset = yOffset;
05335 args.docState = docState;
05336 d->m_extension->setURLArgs( args );
05337
05338 d->m_view->resizeContents( wContents, hContents);
05339 d->m_view->setContentsPos( xOffset, yOffset );
05340
05341 m_url = u;
05342 }
05343 else
05344 {
05345
05346 closeURL();
05347
05348
05349 d->m_bCleared = false;
05350 clear();
05351 d->m_encoding = encoding;
05352 d->m_sheetUsed = sheetUsed;
05353
05354 QStringList::ConstIterator fNameIt = frameNames.begin();
05355 const QStringList::ConstIterator fNameEnd = frameNames.end();
05356
05357 QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.begin();
05358 QStringList::ConstIterator fServiceNameIt = frameServiceNames.begin();
05359 KURL::List::ConstIterator fURLIt = frameURLs.begin();
05360 QValueList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.begin();
05361
05362 for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt )
05363 {
05364 khtml::ChildFrame* const newChild = new khtml::ChildFrame;
05365 newChild->m_bPreloaded = true;
05366 newChild->m_name = *fNameIt;
05367 newChild->m_serviceName = *fServiceNameIt;
05368
05369
05370
05371 const FrameIt childFrame = d->m_frames.append( newChild );
05372
05373 processObjectRequest( *childFrame, *fURLIt, *fServiceTypeIt );
05374
05375 (*childFrame)->m_bPreloaded = true;
05376
05377 if ( (*childFrame)->m_part )
05378 {
05379 if ( (*childFrame)->m_extension )
05380 if ( (*childFrame)->m_extension && !(*fBufferIt).isEmpty() )
05381 {
05382 QDataStream frameStream( *fBufferIt, IO_ReadOnly );
05383 (*childFrame)->m_extension->restoreState( frameStream );
05384 }
05385 else
05386 (*childFrame)->m_part->openURL( *fURLIt );
05387 }
05388 }
05389
05390 KParts::URLArgs args( d->m_extension->urlArgs() );
05391 args.xOffset = xOffset;
05392 args.yOffset = yOffset;
05393 args.docState = docState;
05394
05395 d->m_extension->setURLArgs( args );
05396 if (!KHTMLPageCache::self()->isComplete(d->m_cacheId))
05397 {
05398 d->m_restored = true;
05399 openURL( u );
05400 d->m_restored = false;
05401 }
05402 else
05403 {
05404 restoreURL( u );
05405 }
05406 }
05407
05408 }
05409
05410 void KHTMLPart::show()
05411 {
05412 if ( d->m_view )
05413 d->m_view->show();
05414 }
05415
05416 void KHTMLPart::hide()
05417 {
05418 if ( d->m_view )
05419 d->m_view->hide();
05420 }
05421
05422 DOM::Node KHTMLPart::nodeUnderMouse() const
05423 {
05424 return d->m_view->nodeUnderMouse();
05425 }
05426
05427 DOM::Node KHTMLPart::nonSharedNodeUnderMouse() const
05428 {
05429 return d->m_view->nonSharedNodeUnderMouse();
05430 }
05431
05432 void KHTMLPart::emitSelectionChanged()
05433 {
05434 emit d->m_extension->enableAction( "copy", hasSelection() );
05435 if ( d->m_findDialog )
05436 d->m_findDialog->setHasSelection( hasSelection() );
05437
05438 emit d->m_extension->selectionInfo( selectedText() );
05439 emit selectionChanged();
05440 }
05441
05442 int KHTMLPart::zoomFactor() const
05443 {
05444 return d->m_zoomFactor;
05445 }
05446
05447
05448 static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
05449 static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
05450 static const int minZoom = 20;
05451 static const int maxZoom = 300;
05452
05453
05454 extern const int KDE_NO_EXPORT fastZoomSizes[] = { 20, 50, 75, 90, 100, 120, 150, 200, 300 };
05455 extern const int KDE_NO_EXPORT fastZoomSizeCount = sizeof fastZoomSizes / sizeof fastZoomSizes[0];
05456
05457 void KHTMLPart::slotIncZoom()
05458 {
05459 zoomIn(zoomSizes, zoomSizeCount);
05460 }
05461
05462 void KHTMLPart::slotDecZoom()
05463 {
05464 zoomOut(zoomSizes, zoomSizeCount);
05465 }
05466
05467 void KHTMLPart::slotIncZoomFast()
05468 {
05469 zoomIn(fastZoomSizes, fastZoomSizeCount);
05470 }
05471
05472 void KHTMLPart::slotDecZoomFast()
05473 {
05474 zoomOut(fastZoomSizes, fastZoomSizeCount);
05475 }
05476
05477 void KHTMLPart::zoomIn(const int stepping[], int count)
05478 {
05479 int zoomFactor = d->m_zoomFactor;
05480
05481 if (zoomFactor < maxZoom) {
05482
05483 for (int i = 0; i < count; ++i)
05484 if (stepping[i] > zoomFactor) {
05485 zoomFactor = stepping[i];
05486 break;
05487 }
05488 setZoomFactor(zoomFactor);
05489 }
05490 }
05491
05492 void KHTMLPart::zoomOut(const int stepping[], int count)
05493 {
05494 int zoomFactor = d->m_zoomFactor;
05495 if (zoomFactor > minZoom) {
05496
05497 for (int i = count-1; i >= 0; --i)
05498 if (stepping[i] < zoomFactor) {
05499 zoomFactor = stepping[i];
05500 break;
05501 }
05502 setZoomFactor(zoomFactor);
05503 }
05504 }
05505
05506 void KHTMLPart::setZoomFactor (int percent)
05507 {
05508 if (percent < minZoom) percent = minZoom;
05509 if (percent > maxZoom) percent = maxZoom;
05510 if (d->m_zoomFactor == percent) return;
05511 d->m_zoomFactor = percent;
05512
05513 if(d->m_doc) {
05514 QApplication::setOverrideCursor( waitCursor );
05515 if (d->m_doc->styleSelector())
05516 d->m_doc->styleSelector()->computeFontSizes(d->m_doc->paintDeviceMetrics(), d->m_zoomFactor);
05517 d->m_doc->recalcStyle( NodeImpl::Force );
05518 QApplication::restoreOverrideCursor();
05519 }
05520
05521 ConstFrameIt it = d->m_frames.begin();
05522 const ConstFrameIt end = d->m_frames.end();
05523 for (; it != end; ++it )
05524 if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
05525 KParts::ReadOnlyPart* const p = ( *it )->m_part;
05526 static_cast<KHTMLPart*>( p )->setZoomFactor(d->m_zoomFactor);
05527 }
05528
05529 if ( d->m_guiProfile == BrowserViewGUI ) {
05530 d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
05531 d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
05532 }
05533 }
05534
05535 void KHTMLPart::slotZoomView( int delta )
05536 {
05537 if ( delta < 0 )
05538 slotIncZoom();
05539 else
05540 slotDecZoom();
05541 }
05542
05543 void KHTMLPart::setStatusBarText( const QString& text, StatusBarPriority p)
05544 {
05545 if (!d->m_statusMessagesEnabled)
05546 return;
05547
05548 d->m_statusBarText[p] = text;
05549
05550
05551 QString tobe = d->m_statusBarText[BarHoverText];
05552 if (tobe.isEmpty())
05553 tobe = d->m_statusBarText[BarOverrideText];
05554 if (tobe.isEmpty()) {
05555 tobe = d->m_statusBarText[BarDefaultText];
05556 if (!tobe.isEmpty() && d->m_jobspeed)
05557 tobe += " ";
05558 if (d->m_jobspeed)
05559 tobe += i18n( "(%1/s)" ).arg( KIO::convertSize( d->m_jobspeed ) );
05560 }
05561 tobe = "<qt>"+tobe;
05562
05563 emit ReadOnlyPart::setStatusBarText(tobe);
05564 }
05565
05566
05567 void KHTMLPart::setJSStatusBarText( const QString &text )
05568 {
05569 setStatusBarText(text, BarOverrideText);
05570 }
05571
05572 void KHTMLPart::setJSDefaultStatusBarText( const QString &text )
05573 {
05574 setStatusBarText(text, BarDefaultText);
05575 }
05576
05577 QString KHTMLPart::jsStatusBarText() const
05578 {
05579 return d->m_statusBarText[BarOverrideText];
05580 }
05581
05582 QString KHTMLPart::jsDefaultStatusBarText() const
05583 {
05584 return d->m_statusBarText[BarDefaultText];
05585 }
05586
05587 QString KHTMLPart::referrer() const
05588 {
05589 return d->m_referrer;
05590 }
05591
05592 QString KHTMLPart::pageReferrer() const
05593 {
05594 KURL referrerURL = KURL( d->m_pageReferrer );
05595 if (referrerURL.isValid())
05596 {
05597 QString protocol = referrerURL.protocol();
05598
05599 if ((protocol == "http") ||
05600 ((protocol == "https") && (m_url.protocol() == "https")))
05601 {
05602 referrerURL.setRef(QString::null);
05603 referrerURL.setUser(QString::null);
05604 referrerURL.setPass(QString::null);
05605 return referrerURL.url();
05606 }
05607 }
05608
05609 return QString::null;
05610 }
05611
05612
05613 QString KHTMLPart::lastModified() const
05614 {
05615 if ( d->m_lastModified.isEmpty() && m_url.isLocalFile() ) {
05616
05617
05618
05619 QDateTime lastModif = QFileInfo( m_url.path() ).lastModified();
05620 d->m_lastModified = lastModif.toString( Qt::LocalDate );
05621 }
05622
05623 return d->m_lastModified;
05624 }
05625
05626 void KHTMLPart::slotLoadImages()
05627 {
05628 if (d->m_doc )
05629 d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );
05630
05631 ConstFrameIt it = d->m_frames.begin();
05632 const ConstFrameIt end = d->m_frames.end();
05633 for (; it != end; ++it )
05634 if ( !( *it )->m_part.isNull() && (*it)->m_part->inherits( "KHTMLPart" ) ) {
05635 KParts::ReadOnlyPart* const p = ( *it )->m_part;
05636 static_cast<KHTMLPart*>( p )->slotLoadImages();
05637 }
05638 }
05639
05640 void KHTMLPart::reparseConfiguration()
05641 {
05642 KHTMLSettings *settings = KHTMLFactory::defaultHTMLSettings();
05643 settings->init();
05644
05645 setAutoloadImages( settings->autoLoadImages() );
05646 if (d->m_doc)
05647 d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );
05648
05649 d->m_bOpenMiddleClick = settings->isOpenMiddleClickEnabled();
05650 d->m_bBackRightClick = settings->isBackRightClickEnabled();
05651 d->m_bJScriptEnabled = settings->isJavaScriptEnabled(m_url.host());
05652 setDebugScript( settings->isJavaScriptDebugEnabled() );
05653 d->m_bJavaEnabled = settings->isJavaEnabled(m_url.host());
05654 d->m_bPluginsEnabled = settings->isPluginsEnabled(m_url.host());
05655 d->m_metaRefreshEnabled = settings->isAutoDelayedActionsEnabled ();
05656
05657 delete d->m_settings;
05658 d->m_settings = new KHTMLSettings(*KHTMLFactory::defaultHTMLSettings());
05659
05660 QApplication::setOverrideCursor( waitCursor );
05661 khtml::CSSStyleSelector::reparseConfiguration();
05662 if(d->m_doc) d->m_doc->updateStyleSelector();
05663 QApplication::restoreOverrideCursor();
05664 }
05665
05666 QStringList KHTMLPart::frameNames() const
05667 {
05668 QStringList res;
05669
05670 ConstFrameIt it = d->m_frames.begin();
05671 const ConstFrameIt end = d->m_frames.end();
05672 for (; it != end; ++it )
05673 if (!(*it)->m_bPreloaded)
05674 res += (*it)->m_name;
05675
05676 return res;
05677 }
05678
05679 QPtrList<KParts::ReadOnlyPart> KHTMLPart::frames() const
05680 {
05681 QPtrList<KParts::ReadOnlyPart> res;
05682
05683 ConstFrameIt it = d->m_frames.begin();
05684 const ConstFrameIt end = d->m_frames.end();
05685 for (; it != end; ++it )
05686 if (!(*it)->m_bPreloaded)
05687 res.append( (*it)->m_part );
05688
05689 return res;
05690 }
05691
05692 bool KHTMLPart::openURLInFrame( const KURL &url, const KParts::URLArgs &urlArgs )
05693 {
05694 kdDebug( 6050 ) << this << "KHTMLPart::openURLInFrame " << url << endl;
05695 FrameIt it = d->m_frames.find( urlArgs.frameName );
05696
05697 if ( it == d->m_frames.end() )
05698 return false;
05699
05700
05701 if ( !urlArgs.lockHistory() )
05702 emit d->m_extension->openURLNotify();
05703
05704 requestObject( *it, url, urlArgs );
05705
05706 return true;
05707 }
05708
05709 void KHTMLPart::setDNDEnabled( bool b )
05710 {
05711 d->m_bDnd = b;
05712 }
05713
05714 bool KHTMLPart::dndEnabled() const
05715 {
05716 return d->m_bDnd;
05717 }
05718
05719 void KHTMLPart::customEvent( QCustomEvent *event )
05720 {
05721 if ( khtml::MousePressEvent::test( event ) )
05722 {
05723 khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
05724 return;
05725 }
05726
05727 if ( khtml::MouseDoubleClickEvent::test( event ) )
05728 {
05729 khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
05730 return;
05731 }
05732
05733 if ( khtml::MouseMoveEvent::test( event ) )
05734 {
05735 khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
05736 return;
05737 }
05738
05739 if ( khtml::MouseReleaseEvent::test( event ) )
05740 {
05741 khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
05742 return;
05743 }
05744
05745 if ( khtml::DrawContentsEvent::test( event ) )
05746 {
05747 khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
05748 return;
05749 }
05750
05751 KParts::ReadOnlyPart::customEvent( event );
05752 }
05753
05759 static bool firstRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
05760 {
05761 for (khtml::RenderObject *n = renderNode; n; n = n->nextSibling()) {
05762 if (n->isText()) {
05763 khtml::RenderText* const textRenderer = static_cast<khtml::RenderText *>(n);
05764 const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
05765 const unsigned lim = runs.count();
05766 for (unsigned i = 0; i != lim; ++i) {
05767 if (runs[i]->m_y == y) {
05768 startNode = textRenderer->element();
05769 startOffset = runs[i]->m_start;
05770 return true;
05771 }
05772 }
05773 }
05774
05775 if (firstRunAt(n->firstChild(), y, startNode, startOffset)) {
05776 return true;
05777 }
05778 }
05779
05780 return false;
05781 }
05782
05788 static bool lastRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset)
05789 {
05790 khtml::RenderObject *n = renderNode;
05791 if (!n) {
05792 return false;
05793 }
05794 khtml::RenderObject *next;
05795 while ((next = n->nextSibling())) {
05796 n = next;
05797 }
05798
05799 while (1) {
05800 if (lastRunAt(n->firstChild(), y, endNode, endOffset)) {
05801 return true;
05802 }
05803
05804 if (n->isText()) {
05805 khtml::RenderText* const textRenderer = static_cast<khtml::RenderText *>(n);
05806 const khtml::InlineTextBoxArray &runs = textRenderer->inlineTextBoxes();
05807 for (int i = (int)runs.count()-1; i >= 0; --i) {
05808 if (runs[i]->m_y == y) {
05809 endNode = textRenderer->element();
05810 endOffset = runs[i]->m_start + runs[i]->m_len;
05811 return true;
05812 }
05813 }
05814 }
05815
05816 if (n == renderNode) {
05817 return false;
05818 }
05819
05820 n = n->previousSibling();
05821 }
05822 }
05823
05824 void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
05825 {
05826 DOM::DOMString url = event->url();
05827 QMouseEvent *_mouse = event->qmouseEvent();
05828 DOM::Node innerNode = event->innerNode();
05829 d->m_mousePressNode = innerNode;
05830
05831 d->m_dragStartPos = _mouse->pos();
05832
05833 if ( !event->url().isNull() ) {
05834 d->m_strSelectedURL = event->url().string();
05835 d->m_strSelectedURLTarget = event->target().string();
05836 }
05837 else
05838 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
05839
05840 if ( _mouse->button() == LeftButton ||
05841 _mouse->button() == MidButton )
05842 {
05843 d->m_bMousePressed = true;
05844
05845 #ifndef KHTML_NO_SELECTION
05846 if ( _mouse->button() == LeftButton )
05847 {
05848 if ( (!d->m_strSelectedURL.isNull() && !isEditable())
05849 || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) )
05850 return;
05851 if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
05852 int offset = 0;
05853 DOM::NodeImpl* node = 0;
05854 khtml::RenderObject::SelPointState state;
05855 innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
05856 event->absX()-innerNode.handle()->renderer()->xPos(),
05857 event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state );
05858 d->m_extendMode = d->ExtendByChar;
05859 #ifdef KHTML_NO_CARET
05860 d->m_selectionStart = node;
05861 d->m_startOffset = offset;
05862
05863
05864
05865
05866
05867 d->m_selectionEnd = d->m_selectionStart;
05868 d->m_endOffset = d->m_startOffset;
05869 d->m_doc->clearSelection();
05870 #else // KHTML_NO_CARET
05871 d->m_view->moveCaretTo(node, offset, (_mouse->state() & ShiftButton) == 0);
05872 #endif // KHTML_NO_CARET
05873 d->m_initialNode = d->m_selectionStart;
05874 d->m_initialOffset = d->m_startOffset;
05875
05876 }
05877 else
05878 {
05879 #ifndef KHTML_NO_CARET
05880
05881 #else
05882 d->m_selectionStart = DOM::Node();
05883 d->m_selectionEnd = DOM::Node();
05884 #endif
05885 }
05886 emitSelectionChanged();
05887 startAutoScroll();
05888 }
05889 #else
05890 d->m_dragLastPos = _mouse->globalPos();
05891 #endif
05892 }
05893
05894 if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
05895 {
05896 d->m_bRightMousePressed = true;
05897 } else if ( _mouse->button() == RightButton )
05898 {
05899 popupMenu( d->m_strSelectedURL );
05900
05901 }
05902 }
05903
05904 void KHTMLPart::khtmlMouseDoubleClickEvent( khtml::MouseDoubleClickEvent *event )
05905 {
05906 QMouseEvent *_mouse = event->qmouseEvent();
05907 if ( _mouse->button() == LeftButton )
05908 {
05909 d->m_bMousePressed = true;
05910 DOM::Node innerNode = event->innerNode();
05911
05912 if ( !innerNode.isNull() && innerNode.handle()->renderer()) {
05913 int offset = 0;
05914 DOM::NodeImpl* node = 0;
05915 khtml::RenderObject::SelPointState state;
05916 innerNode.handle()->renderer()->checkSelectionPoint( event->x(), event->y(),
05917 event->absX()-innerNode.handle()->renderer()->xPos(),
05918 event->absY()-innerNode.handle()->renderer()->yPos(), node, offset, state);
05919
05920
05921
05922 if ( node && node->renderer() )
05923 {
05924
05925 bool selectLine = (event->clickCount() == 3);
05926 d->m_extendMode = selectLine ? d->ExtendByLine : d->ExtendByWord;
05927
05928
05929 if (_mouse->state() & ShiftButton) {
05930 d->caretNode() = node;
05931 d->caretOffset() = offset;
05932 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
05933 d->m_selectionStart.handle(), d->m_startOffset,
05934 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
05935 d->m_initialNode = d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd;
05936 d->m_initialOffset = d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset;
05937 } else {
05938 d->m_selectionStart = d->m_selectionEnd = node;
05939 d->m_startOffset = d->m_endOffset = offset;
05940 d->m_startBeforeEnd = true;
05941 d->m_initialNode = node;
05942 d->m_initialOffset = offset;
05943 }
05944
05945
05946
05947 extendSelection( d->m_selectionStart.handle(), d->m_startOffset, d->m_selectionStart, d->m_startOffset, !d->m_startBeforeEnd, selectLine );
05948
05949 extendSelection( d->m_selectionEnd.handle(), d->m_endOffset, d->m_selectionEnd, d->m_endOffset, d->m_startBeforeEnd, selectLine );
05950
05951
05952
05953
05954 emitSelectionChanged();
05955 d->m_doc
05956 ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
05957 d->m_selectionEnd.handle(),d->m_endOffset);
05958 #ifndef KHTML_NO_CARET
05959 bool v = d->m_view->placeCaret();
05960 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
05961 #endif
05962 startAutoScroll();
05963 }
05964 }
05965 }
05966 }
05967
05968 void KHTMLPart::extendSelection( DOM::NodeImpl* node, long offset, DOM::Node& selectionNode, long& selectionOffset, bool right, bool selectLines )
05969 {
05970 khtml::RenderObject* obj = node->renderer();
05971
05972 if (obj->isText() && selectLines) {
05973 int pos;
05974 khtml::RenderText *renderer = static_cast<khtml::RenderText *>(obj);
05975 khtml::InlineTextBox *run = renderer->findInlineTextBox( offset, pos );
05976 DOMString t = node->nodeValue();
05977 DOM::NodeImpl* selNode = 0;
05978 long selOfs = 0;
05979
05980 if (!run)
05981 return;
05982
05983 int selectionPointY = run->m_y;
05984
05985
05986 khtml::RenderObject *renderNode = renderer;
05987 while (renderNode && renderNode->isInline())
05988 renderNode = renderNode->parent();
05989
05990 renderNode = renderNode->firstChild();
05991
05992 if (right) {
05993
05994
05995 if (!lastRunAt (renderNode, selectionPointY, selNode, selOfs))
05996 return;
05997 } else {
05998
05999
06000 if (!firstRunAt (renderNode, selectionPointY, selNode, selOfs))
06001 return;
06002 }
06003
06004 selectionNode = selNode;
06005 selectionOffset = selOfs;
06006 return;
06007 }
06008
06009 QString str;
06010 int len = 0;
06011 if ( obj->isText() ) {
06012 str = static_cast<khtml::RenderText *>(obj)->data().string();
06013 len = str.length();
06014 }
06015
06016 QChar ch;
06017 do {
06018
06019 if ( node ) {
06020 selectionNode = node;
06021 selectionOffset = offset;
06022 }
06023
06024
06025 while ( obj && ( (right && offset >= len-1) || (!right && offset <= 0) ) )
06026 {
06027 obj = right ? obj->objectBelow() : obj->objectAbove();
06028
06029 if ( obj ) {
06030
06031 str = QString::null;
06032 if ( obj->isText() )
06033 str = static_cast<khtml::RenderText *>(obj)->data().string();
06034 else if ( obj->isBR() )
06035 str = '\n';
06036 else if ( !obj->isInline() ) {
06037 obj = 0L;
06038 break;
06039 }
06040 len = str.length();
06041
06042
06043 if ( right )
06044 offset = -1;
06045 else
06046 offset = len;
06047 }
06048 }
06049 if ( !obj )
06050 break;
06051 node = obj->element();
06052 if ( right )
06053 {
06054 Q_ASSERT( offset < len-1 );
06055 ++offset;
06056 }
06057 else
06058 {
06059 Q_ASSERT( offset > 0 );
06060 --offset;
06061 }
06062
06063
06064 ch = str[ offset ];
06065
06066 } while ( !ch.isSpace() && !ch.isPunct() );
06067
06068
06069 if (right) ++selectionOffset;
06070 }
06071
06072 #ifndef KHTML_NO_SELECTION
06073 void KHTMLPart::extendSelectionTo(int x, int y, int absX, int absY, const DOM::Node &innerNode)
06074 {
06075 int offset;
06076
06077 DOM::NodeImpl* node=0;
06078 khtml::RenderObject::SelPointState state;
06079 innerNode.handle()->renderer()->checkSelectionPoint( x, y,
06080 absX-innerNode.handle()->renderer()->xPos(),
06081 absY-innerNode.handle()->renderer()->yPos(), node, offset, state);
06082 if (!node || !node->renderer()) return;
06083
06084
06085
06086
06087 bool withinNode = innerNode == node;
06088
06089
06090
06091 if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
06092 d->m_initialNode.isNull() ||
06093 !d->m_selectionStart.handle()->renderer() ||
06094 !d->m_selectionEnd.handle()->renderer()) return;
06095
06096 if (d->m_extendMode != d->ExtendByChar) {
06097
06098 bool caretBeforeInit = RangeImpl::compareBoundaryPoints(
06099 d->caretNode().handle(), d->caretOffset(),
06100 d->m_initialNode.handle(), d->m_initialOffset) <= 0;
06101 bool nodeBeforeInit = RangeImpl::compareBoundaryPoints(node, offset,
06102 d->m_initialNode.handle(), d->m_initialOffset) <= 0;
06103
06104 if (caretBeforeInit != nodeBeforeInit) {
06105
06106 extendSelection(d->m_initialNode.handle(), d->m_initialOffset,
06107 d->m_extendAtEnd ? d->m_selectionStart : d->m_selectionEnd,
06108 d->m_extendAtEnd ? d->m_startOffset : d->m_endOffset,
06109 nodeBeforeInit, d->m_extendMode == d->ExtendByLine);
06110 }
06111 }
06112
06113 d->caretNode() = node;
06114 d->caretOffset() = offset;
06115
06116
06117 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
06118 d->m_selectionStart.handle(), d->m_startOffset,
06119 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
06120
06121 if ( !d->m_selectionStart.isNull() && !d->m_selectionEnd.isNull() )
06122 {
06123
06124 if (d->m_extendMode != d->ExtendByChar && withinNode)
06125 extendSelection( node, offset, d->caretNode(), d->caretOffset(), d->m_startBeforeEnd ^ !d->m_extendAtEnd, d->m_extendMode == d->ExtendByLine );
06126
06127 if (d->m_selectionEnd == d->m_selectionStart && d->m_endOffset < d->m_startOffset)
06128 d->m_doc
06129 ->setSelection(d->m_selectionStart.handle(),d->m_endOffset,
06130 d->m_selectionEnd.handle(),d->m_startOffset);
06131 else if (d->m_startBeforeEnd)
06132 d->m_doc
06133 ->setSelection(d->m_selectionStart.handle(),d->m_startOffset,
06134 d->m_selectionEnd.handle(),d->m_endOffset);
06135 else
06136 d->m_doc
06137 ->setSelection(d->m_selectionEnd.handle(),d->m_endOffset,
06138 d->m_selectionStart.handle(),d->m_startOffset);
06139 }
06140 #ifndef KHTML_NO_CARET
06141 d->m_view->placeCaret();
06142 #endif
06143 }
06144
06145 bool KHTMLPart::isExtendingSelection() const
06146 {
06147
06148
06149
06150 return d->m_bMousePressed;
06151 }
06152 #endif // KHTML_NO_SELECTION
06153
06154 void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
06155 {
06156 QMouseEvent *_mouse = event->qmouseEvent();
06157
06158 if( d->m_bRightMousePressed && parentPart() != 0 && d->m_bBackRightClick )
06159 {
06160 popupMenu( d->m_strSelectedURL );
06161 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
06162 d->m_bRightMousePressed = false;
06163 }
06164
06165 DOM::DOMString url = event->url();
06166 DOM::DOMString target = event->target();
06167 DOM::Node innerNode = event->innerNode();
06168
06169 #ifndef QT_NO_DRAGANDDROP
06170 if( d->m_bDnd && d->m_bMousePressed &&
06171 ( (!d->m_strSelectedURL.isEmpty() && !isEditable())
06172 || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) ) ) {
06173 if ( ( d->m_dragStartPos - _mouse->pos() ).manhattanLength() <= KGlobalSettings::dndEventDelay() )
06174 return;
06175
06176 QPixmap pix;
06177 HTMLImageElementImpl *img = 0L;
06178 QDragObject *drag = 0;
06179 KURL u;
06180
06181
06182
06183
06184
06185 if ( url.length() == 0 && innerNode.handle() && innerNode.handle()->id() == ID_IMG )
06186 {
06187 img = static_cast<HTMLImageElementImpl *>(innerNode.handle());
06188 u = KURL( completeURL( khtml::parseURL(img->getAttribute(ATTR_SRC)).string() ) );
06189 pix = KMimeType::mimeType("image/png")->pixmap(KIcon::Desktop);
06190 }
06191 else
06192 {
06193
06194 u = completeURL( d->m_strSelectedURL );
06195 pix = KMimeType::pixmapForURL(u, 0, KIcon::Desktop, KIcon::SizeMedium);
06196 }
06197
06198 u.setPass(QString::null);
06199
06200 KURLDrag* urlDrag = new KURLDrag( u, img ? 0 : d->m_view->viewport() );
06201 if ( !d->m_referrer.isEmpty() )
06202 urlDrag->metaData()["referrer"] = d->m_referrer;
06203
06204 if( img && img->complete()) {
06205 KMultipleDrag *mdrag = new KMultipleDrag( d->m_view->viewport() );
06206 mdrag->addDragObject( new QImageDrag( img->currentImage(), 0L ) );
06207 mdrag->addDragObject( urlDrag );
06208 drag = mdrag;
06209 }
06210 else
06211 drag = urlDrag;
06212
06213 if ( !pix.isNull() )
06214 drag->setPixmap( pix );
06215
06216 stopAutoScroll();
06217 if(drag)
06218 drag->drag();
06219
06220
06221 d->m_bMousePressed = false;
06222 d->m_strSelectedURL = d->m_strSelectedURLTarget = QString::null;
06223 return;
06224 }
06225 #endif
06226
06227
06228 if ( !d->m_bMousePressed )
06229 {
06230
06231 if ( url.length() )
06232 {
06233 bool shiftPressed = ( _mouse->state() & ShiftButton );
06234
06235
06236 if ( !innerNode.isNull() && innerNode.elementId() == ID_IMG )
06237 {
06238 HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(innerNode.handle());
06239 if ( i && i->isServerMap() )
06240 {
06241 khtml::RenderObject *r = i->renderer();
06242 if(r)
06243 {
06244 int absx, absy, vx, vy;
06245 r->absolutePosition(absx, absy);
06246 view()->contentsToViewport( absx, absy, vx, vy );
06247
06248 int x(_mouse->x() - vx), y(_mouse->y() - vy);
06249
06250 d->m_overURL = url.string() + QString("?%1,%2").arg(x).arg(y);
06251 d->m_overURLTarget = target.string();
06252 overURL( d->m_overURL, target.string(), shiftPressed );
06253 return;
06254 }
06255 }
06256 }
06257
06258
06259 if ( d->m_overURL.isEmpty() || d->m_overURL != url || d->m_overURLTarget != target )
06260 {
06261 d->m_overURL = url.string();
06262 d->m_overURLTarget = target.string();
06263 overURL( d->m_overURL, target.string(), shiftPressed );
06264 }
06265 }
06266 else
06267 {
06268
06269 resetHoverText();
06270 }
06271 }
06272 else {
06273 #ifndef KHTML_NO_SELECTION
06274
06275 if( d->m_bMousePressed && innerNode.handle() && innerNode.handle()->renderer() &&
06276 ( (_mouse->state() & LeftButton) != 0 )) {
06277 extendSelectionTo(event->x(), event->y(),
06278 event->absX(), event->absY(), innerNode);
06279 #else
06280 if ( d->m_doc && d->m_view ) {
06281 QPoint diff( _mouse->globalPos() - d->m_dragLastPos );
06282
06283 if ( abs( diff.x() ) > 64 || abs( diff.y() ) > 64 ) {
06284 d->m_view->scrollBy( -diff.x(), -diff.y() );
06285 d->m_dragLastPos = _mouse->globalPos();
06286 }
06287 #endif
06288 }
06289 }
06290
06291 }
06292
06293 void KHTMLPart::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent *event )
06294 {
06295 DOM::Node innerNode = event->innerNode();
06296 d->m_mousePressNode = DOM::Node();
06297
06298 if ( d->m_bMousePressed ) {
06299 setStatusBarText(QString::null, BarHoverText);
06300 stopAutoScroll();
06301 }
06302
06303
06304
06305 d->m_bMousePressed = false;
06306
06307 QMouseEvent *_mouse = event->qmouseEvent();
06308 if ( _mouse->button() == RightButton && parentPart() != 0 && d->m_bBackRightClick )
06309 {
06310 d->m_bRightMousePressed = false;
06311 KParts::BrowserInterface *tmp_iface = d->m_extension->browserInterface();
06312 if( tmp_iface ) {
06313 tmp_iface->callMethod( "goHistory(int)", -1 );
06314 }
06315 }
06316 #ifndef QT_NO_CLIPBOARD
06317 if ((d->m_guiProfile == BrowserViewGUI) && (_mouse->button() == MidButton) && (event->url().isNull())) {
06318 kdDebug( 6050 ) << "KHTMLPart::khtmlMouseReleaseEvent() MMB shouldOpen="
06319 << d->m_bOpenMiddleClick << endl;
06320
06321 if (d->m_bOpenMiddleClick) {
06322 KHTMLPart *p = this;
06323 while (p->parentPart()) p = p->parentPart();
06324 p->d->m_extension->pasteRequest();
06325 }
06326 }
06327 #endif
06328
06329 #ifndef KHTML_NO_SELECTION
06330
06331 if(d->m_selectionStart == d->m_selectionEnd && d->m_startOffset == d->m_endOffset) {
06332 #ifndef KHTML_NO_CARET
06333 d->m_extendAtEnd = true;
06334 #else
06335 d->m_selectionStart = 0;
06336 d->m_selectionEnd = 0;
06337 d->m_startOffset = 0;
06338 d->m_endOffset = 0;
06339 #endif
06340 emitSelectionChanged();
06341 } else {
06342
06343
06344 DOM::Node n = d->m_selectionStart;
06345 d->m_startBeforeEnd = false;
06346 if( d->m_selectionStart == d->m_selectionEnd ) {
06347 if( d->m_startOffset < d->m_endOffset )
06348 d->m_startBeforeEnd = true;
06349 } else {
06350 #if 0
06351 while(!n.isNull()) {
06352 if(n == d->m_selectionEnd) {
06353 d->m_startBeforeEnd = true;
06354 break;
06355 }
06356 DOM::Node next = n.firstChild();
06357 if(next.isNull()) next = n.nextSibling();
06358 while( next.isNull() && !n.parentNode().isNull() ) {
06359 n = n.parentNode();
06360 next = n.nextSibling();
06361 }
06362 n = next;
06363 }
06364 #else
06365
06366 if (d->m_selectionStart.isNull() || d->m_selectionEnd.isNull() ||
06367 !d->m_selectionStart.handle()->renderer() ||
06368 !d->m_selectionEnd.handle()->renderer()) return;
06369 d->m_startBeforeEnd = RangeImpl::compareBoundaryPoints(
06370 d->m_selectionStart.handle(), d->m_startOffset,
06371 d->m_selectionEnd.handle(), d->m_endOffset) <= 0;
06372 #endif
06373 }
06374 if(!d->m_startBeforeEnd)
06375 {
06376 DOM::Node tmpNode = d->m_selectionStart;
06377 int tmpOffset = d->m_startOffset;
06378 d->m_selectionStart = d->m_selectionEnd;
06379 d->m_startOffset = d->m_endOffset;
06380 d->m_selectionEnd = tmpNode;
06381 d->m_endOffset = tmpOffset;
06382 d->m_startBeforeEnd = true;
06383 d->m_extendAtEnd = !d->m_extendAtEnd;
06384 }
06385 #ifndef KHTML_NO_CARET
06386 bool v = d->m_view->placeCaret();
06387 emitCaretPositionChanged(v ? d->caretNode() : 0, d->caretOffset());
06388 #endif
06389
06390 #ifndef QT_NO_CLIPBOARD
06391 QString text = selectedText();
06392 text.replace(QChar(0xa0), ' ');
06393 disconnect( kapp->clipboard(), SIGNAL( selectionChanged()), this, SLOT( slotClearSelection()));
06394 kapp->clipboard()->setText(text,QClipboard::Selection);
06395 connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
06396 #endif
06397
06398 emitSelectionChanged();
06399
06400 }
06401 #endif
06402 d->m_initialNode = 0;
06403 d->m_initialOffset = 0;
06404
06405 }
06406
06407 void KHTMLPart::khtmlDrawContentsEvent( khtml::DrawContentsEvent * )
06408 {
06409 }
06410
06411 void KHTMLPart::guiActivateEvent( KParts::GUIActivateEvent *event )
06412 {
06413 if ( event->activated() )
06414 {
06415 emitSelectionChanged();
06416 emit d->m_extension->enableAction( "print", d->m_doc != 0 );
06417
06418 if ( !d->m_settings->autoLoadImages() && d->m_paLoadImages )
06419 {
06420 QPtrList<KAction> lst;
06421 lst.append( d->m_paLoadImages );
06422 plugActionList( "loadImages", lst );
06423 }
06424 }
06425 }
06426
06427 void KHTMLPart::slotPrintFrame()
06428 {
06429 if ( d->m_frames.count() == 0 )
06430 return;
06431
06432 KParts::ReadOnlyPart *frame = currentFrame();
06433 if (!frame)
06434 return;
06435
06436 KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject( frame );
06437
06438 if ( !ext )
06439 return;
06440
06441 QMetaObject *mo = ext->metaObject();
06442
06443 int idx = mo->findSlot( "print()", true );
06444 if ( idx >= 0 ) {
06445 QUObject o[ 1 ];
06446 ext->qt_invoke( idx, o );
06447 }
06448 }
06449
06450 void KHTMLPart::slotSelectAll()
06451 {
06452 KParts::ReadOnlyPart *part = currentFrame();
06453 if (part && part->inherits("KHTMLPart"))
06454 static_cast<KHTMLPart *>(part)->selectAll();
06455 }
06456
06457 void KHTMLPart::startAutoScroll()
06458 {
06459 connect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
06460 d->m_scrollTimer.start(100, false);
06461 }
06462
06463 void KHTMLPart::stopAutoScroll()
06464 {
06465 disconnect(&d->m_scrollTimer, SIGNAL( timeout() ), this, SLOT( slotAutoScroll() ));
06466 if (d->m_scrollTimer.isActive())
06467 d->m_scrollTimer.stop();
06468 }
06469
06470
06471 void KHTMLPart::slotAutoScroll()
06472 {
06473 if (d->m_view)
06474 d->m_view->doAutoScroll();
06475 else
06476 stopAutoScroll();
06477 }
06478
06479 void KHTMLPart::selectAll()
06480 {
06481 if (!d->m_doc) return;
06482
06483 NodeImpl *first;
06484 if (d->m_doc->isHTMLDocument())
06485 first = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
06486 else
06487 first = d->m_doc;
06488 NodeImpl *next;
06489
06490
06491
06492 while ( first && !(first->renderer()
06493 && ((first->nodeType() == Node::TEXT_NODE || first->nodeType() == Node::CDATA_SECTION_NODE)
06494 || (first->renderer()->isReplaced() && !first->renderer()->firstChild()))))
06495 {
06496 next = first->firstChild();
06497 if ( !next ) next = first->nextSibling();
06498 while( first && !next )
06499 {
06500 first = first->parentNode();
06501 if ( first )
06502 next = first->nextSibling();
06503 }
06504 first = next;
06505 }
06506
06507 NodeImpl *last;
06508 if (d->m_doc->isHTMLDocument())
06509 last = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
06510 else
06511 last = d->m_doc;
06512
06513
06514
06515
06516 while ( last && !(last->renderer()
06517 && ((last->nodeType() == Node::TEXT_NODE || last->nodeType() == Node::CDATA_SECTION_NODE)
06518 || (last->renderer()->isReplaced() && !last->renderer()->lastChild()))))
06519 {
06520 next = last->lastChild();
06521 if ( !next ) next = last->previousSibling();
06522 while ( last && !next )
06523 {
06524 last = last->parentNode();
06525 if ( last )
06526 next = last->previousSibling();
06527 }
06528 last = next;
06529 }
06530
06531 if ( !first || !last )
06532 return;
06533 Q_ASSERT(first->renderer());
06534 Q_ASSERT(last->renderer());
06535 d->m_selectionStart = first;
06536 d->m_startOffset = 0;
06537 d->m_selectionEnd = last;
06538 d->m_endOffset = last->nodeValue().length();
06539 d->m_startBeforeEnd = true;
06540
06541 d->m_doc->setSelection( d->m_selectionStart.handle(), d->m_startOffset,
06542 d->m_selectionEnd.handle(), d->m_endOffset );
06543
06544 emitSelectionChanged();
06545 }
06546
06547 bool KHTMLPart::checkLinkSecurity(const KURL &linkURL,const QString &message, const QString &button)
06548 {
06549 bool linkAllowed = true;
06550
06551 if ( d->m_doc )
06552 linkAllowed = kapp && kapp->authorizeURLAction("redirect", url(), linkURL);
06553
06554 if ( !linkAllowed ) {
06555 khtml::Tokenizer *tokenizer = d->m_doc->tokenizer();
06556 if (tokenizer)
06557 tokenizer->setOnHold(true);
06558
06559 int response = KMessageBox::Cancel;
06560 if (!message.isEmpty())
06561 {
06562 response = KMessageBox::warningContinueCancel( 0,
06563 message.arg(linkURL.htmlURL()),
06564 i18n( "Security Warning" ),
06565 button);
06566 }
06567 else
06568 {
06569 KMessageBox::error( 0,
06570 i18n( "<qt>Access by untrusted page to<BR><B>%1</B><BR> denied.").arg(linkURL.htmlURL()),
06571 i18n( "Security Alert" ));
06572 }
06573
06574 if (tokenizer)
06575 tokenizer->setOnHold(false);
06576 return (response==KMessageBox::Continue);
06577 }
06578 return true;
06579 }
06580
06581 void KHTMLPart::slotPartRemoved( KParts::Part *part )
06582 {
06583
06584 if ( part == d->m_activeFrame )
06585 {
06586 d->m_activeFrame = 0L;
06587 if ( !part->inherits( "KHTMLPart" ) )
06588 {
06589 if (factory()) {
06590 factory()->removeClient( part );
06591 }
06592 if (childClients()->containsRef(part)) {
06593 removeChildClient( part );
06594 }
06595 }
06596 }
06597 }
06598
06599 void KHTMLPart::slotActiveFrameChanged( KParts::Part *part )
06600 {
06601
06602 if ( part == this )
06603 {
06604 kdError(6050) << "strange error! we activated ourselves" << endl;
06605 assert( false );
06606 return;
06607 }
06608
06609 if ( d->m_activeFrame && d->m_activeFrame->widget() && d->m_activeFrame->widget()->inherits( "QFrame" ) )
06610 {
06611 QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
06612 if (frame->frameStyle() != QFrame::NoFrame)
06613 {
06614 frame->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken);
06615 frame->repaint();
06616 }
06617 }
06618
06619 if( d->m_activeFrame && !d->m_activeFrame->inherits( "KHTMLPart" ) )
06620 {
06621 if (factory()) {
06622 factory()->removeClient( d->m_activeFrame );
06623 }
06624 removeChildClient( d->m_activeFrame );
06625 }
06626 if( part && !part->inherits( "KHTMLPart" ) )
06627 {
06628 if (factory()) {
06629 factory()->addClient( part );
06630 }
06631 insertChildClient( part );
06632 }
06633
06634
06635 d->m_activeFrame = part;
06636
06637 if ( d->m_activeFrame && d->m_activeFrame->widget()->inherits( "QFrame" ) )
06638 {
06639 QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
06640 if (frame->frameStyle() != QFrame::NoFrame)
06641 {
06642 frame->setFrameStyle( QFrame::StyledPanel | QFrame::Plain);
06643 frame->repaint();
06644 }
06645 kdDebug(6050) << "new active frame " << d->m_activeFrame << endl;
06646 }
06647
06648 updateActions();
06649
06650
06651 d->m_extension->setExtensionProxy( KParts::BrowserExtension::childObject( d->m_activeFrame ) );
06652 }
06653
06654 void KHTMLPart::setActiveNode(const DOM::Node &node)
06655 {
06656 if (!d->m_doc || !d->m_view)
06657 return;
06658
06659
06660 d->m_doc->setFocusNode(node.handle());
06661
06662
06663 QRect rect = node.handle()->getRect();
06664 d->m_view->ensureVisible(rect.right(), rect.bottom());
06665 d->m_view->ensureVisible(rect.left(), rect.top());
06666 }
06667
06668 DOM::Node KHTMLPart::activeNode() const
06669 {
06670 return DOM::Node(d->m_doc?d->m_doc->focusNode():0);
06671 }
06672
06673 DOM::EventListener *KHTMLPart::createHTMLEventListener( QString code, QString name )
06674 {
06675 KJSProxy *proxy = jScript();
06676
06677 if (!proxy)
06678 return 0;
06679
06680 return proxy->createHTMLEventHandler( m_url.url(), name, code );
06681 }
06682
06683 KHTMLPart *KHTMLPart::opener()
06684 {
06685 return d->m_opener;
06686 }
06687
06688 void KHTMLPart::setOpener(KHTMLPart *_opener)
06689 {
06690 d->m_opener = _opener;
06691 }
06692
06693 bool KHTMLPart::openedByJS()
06694 {
06695 return d->m_openedByJS;
06696 }
06697
06698 void KHTMLPart::setOpenedByJS(bool _openedByJS)
06699 {
06700 d->m_openedByJS = _openedByJS;
06701 }
06702
06703 void KHTMLPart::preloadStyleSheet(const QString &url, const QString &stylesheet)
06704 {
06705 khtml::Cache::preloadStyleSheet(url, stylesheet);
06706 }
06707
06708 void KHTMLPart::preloadScript(const QString &url, const QString &script)
06709 {
06710 khtml::Cache::preloadScript(url, script);
06711 }
06712
06713 QCString KHTMLPart::dcopObjectId() const
06714 {
06715 QCString id;
06716 id.sprintf("html-widget%d", d->m_dcop_counter);
06717 return id;
06718 }
06719
06720 long KHTMLPart::cacheId() const
06721 {
06722 return d->m_cacheId;
06723 }
06724
06725 bool KHTMLPart::restored() const
06726 {
06727 return d->m_restored;
06728 }
06729
06730 bool KHTMLPart::pluginPageQuestionAsked(const QString& mimetype) const
06731 {
06732
06733 KHTMLPart* parent = const_cast<KHTMLPart *>(this)->parentPart();
06734 if ( parent )
06735 return parent->pluginPageQuestionAsked(mimetype);
06736
06737 return d->m_pluginPageQuestionAsked.contains(mimetype);
06738 }
06739
06740 void KHTMLPart::setPluginPageQuestionAsked(const QString& mimetype)
06741 {
06742 if ( parentPart() )
06743 parentPart()->setPluginPageQuestionAsked(mimetype);
06744
06745 d->m_pluginPageQuestionAsked.append(mimetype);
06746 }
06747
06748 void KHTMLPart::slotAutomaticDetectionLanguage( int _id )
06749 {
06750 d->m_automaticDetection->setItemChecked( _id, true );
06751
06752 switch ( _id ) {
06753 case 0 :
06754 d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
06755 break;
06756 case 1 :
06757 d->m_autoDetectLanguage = khtml::Decoder::Arabic;
06758 break;
06759 case 2 :
06760 d->m_autoDetectLanguage = khtml::Decoder::Baltic;
06761 break;
06762 case 3 :
06763 d->m_autoDetectLanguage = khtml::Decoder::CentralEuropean;
06764 break;
06765 case 4 :
06766 d->m_autoDetectLanguage = khtml::Decoder::Chinese;
06767 break;
06768 case 5 :
06769 d->m_autoDetectLanguage = khtml::Decoder::Greek;
06770 break;
06771 case 6 :
06772 d->m_autoDetectLanguage = khtml::Decoder::Hebrew;
06773 break;
06774 case 7 :
06775 d->m_autoDetectLanguage = khtml::Decoder::Japanese;
06776 break;
06777 case 8 :
06778 d->m_autoDetectLanguage = khtml::Decoder::Korean;
06779 break;
06780 case 9 :
06781 d->m_autoDetectLanguage = khtml::Decoder::Russian;
06782 break;
06783 case 10 :
06784 d->m_autoDetectLanguage = khtml::Decoder::Thai;
06785 break;
06786 case 11 :
06787 d->m_autoDetectLanguage = khtml::Decoder::Turkish;
06788 break;
06789 case 12 :
06790 d->m_autoDetectLanguage = khtml::Decoder::Ukrainian;
06791 break;
06792 case 13 :
06793 d->m_autoDetectLanguage = khtml::Decoder::Unicode;
06794 break;
06795 case 14 :
06796 d->m_autoDetectLanguage = khtml::Decoder::WesternEuropean;
06797 break;
06798 default :
06799 d->m_autoDetectLanguage = khtml::Decoder::SemiautomaticDetection;
06800 break;
06801 }
06802
06803 for ( int i = 0; i <= 14; ++i ) {
06804 if ( i != _id )
06805 d->m_automaticDetection->setItemChecked( i, false );
06806 }
06807
06808 d->m_paSetEncoding->popupMenu()->setItemChecked( 0, true );
06809
06810 setEncoding( QString::null, false );
06811
06812 if( d->m_manualDetection )
06813 d->m_manualDetection->setCurrentItem( -1 );
06814 d->m_paSetEncoding->popupMenu()->setItemChecked( d->m_paSetEncoding->popupMenu()->idAt( 2 ), false );
06815 }
06816
06817 khtml::Decoder *KHTMLPart::createDecoder()
06818 {
06819 khtml::Decoder *dec = new khtml::Decoder();
06820 if( !d->m_encoding.isNull() )
06821 dec->setEncoding( d->m_encoding.latin1(),
06822 d->m_haveEncoding ? khtml::Decoder::UserChosenEncoding : khtml::Decoder::EncodingFromHTTPHeader);
06823 else {
06824
06825 const char *defaultEncoding = (parentPart() && parentPart()->d->m_decoder)
06826 ? parentPart()->d->m_decoder->encoding() : settings()->encoding().latin1();
06827 dec->setEncoding(defaultEncoding, khtml::Decoder::DefaultEncoding);
06828 }
06829 #ifdef APPLE_CHANGES
06830 if (d->m_doc)
06831 d->m_doc->setDecoder(d->m_decoder);
06832 #endif
06833 dec->setAutoDetectLanguage( d->m_autoDetectLanguage );
06834 return dec;
06835 }
06836
06837 void KHTMLPart::emitCaretPositionChanged(const DOM::Node &node, long offset) {
06838 emit caretPositionChanged(node, offset);
06839 }
06840
06841 void KHTMLPart::restoreScrollPosition()
06842 {
06843 KParts::URLArgs args = d->m_extension->urlArgs();
06844
06845 if ( m_url.hasRef() && !d->m_restoreScrollPosition && !args.reload) {
06846 if ( !d->m_doc || !d->m_doc->parsing() )
06847 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
06848 if ( !gotoAnchor(m_url.encodedHtmlRef()) )
06849 gotoAnchor(m_url.htmlRef());
06850 return;
06851 }
06852
06853
06854
06855
06856
06857 if (d->m_view->contentsHeight() - d->m_view->visibleHeight() >= args.yOffset
06858 || d->m_bComplete) {
06859 d->m_view->setContentsPos(args.xOffset, args.yOffset);
06860 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
06861 }
06862 }
06863
06864
06865 void KHTMLPart::openWallet(DOM::HTMLFormElementImpl *form)
06866 {
06867 KHTMLPart *p;
06868
06869 for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
06870 }
06871
06872 if (p) {
06873 p->openWallet(form);
06874 return;
06875 }
06876
06877 if (onlyLocalReferences()) {
06878 return;
06879 }
06880
06881 if (d->m_wallet) {
06882 if (d->m_bWalletOpened) {
06883 if (d->m_wallet->isOpen()) {
06884 form->walletOpened(d->m_wallet);
06885 return;
06886 }
06887 d->m_wallet->deleteLater();
06888 d->m_wallet = 0L;
06889 d->m_bWalletOpened = false;
06890 }
06891 }
06892
06893 if (!d->m_wq) {
06894 KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
06895 d->m_wq = new KHTMLWalletQueue(this);
06896 d->m_wq->wallet = wallet;
06897 connect(wallet, SIGNAL(walletOpened(bool)), d->m_wq, SLOT(walletOpened(bool)));
06898 connect(d->m_wq, SIGNAL(walletOpened(KWallet::Wallet*)), this, SLOT(walletOpened(KWallet::Wallet*)));
06899 }
06900 assert(form);
06901 d->m_wq->callers.append(KHTMLWalletQueue::Caller(form, form->getDocument()));
06902 }
06903
06904
06905 void KHTMLPart::saveToWallet(const QString& key, const QMap<QString,QString>& data)
06906 {
06907 KHTMLPart *p;
06908
06909 for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
06910 }
06911
06912 if (p) {
06913 p->saveToWallet(key, data);
06914 return;
06915 }
06916
06917 if (d->m_wallet) {
06918 if (d->m_bWalletOpened) {
06919 if (d->m_wallet->isOpen()) {
06920 if (!d->m_wallet->hasFolder(KWallet::Wallet::FormDataFolder())) {
06921 d->m_wallet->createFolder(KWallet::Wallet::FormDataFolder());
06922 }
06923 d->m_wallet->setFolder(KWallet::Wallet::FormDataFolder());
06924 d->m_wallet->writeMap(key, data);
06925 return;
06926 }
06927 d->m_wallet->deleteLater();
06928 d->m_wallet = 0L;
06929 d->m_bWalletOpened = false;
06930 }
06931 }
06932
06933 if (!d->m_wq) {
06934 KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
06935 d->m_wq = new KHTMLWalletQueue(this);
06936 d->m_wq->wallet = wallet;
06937 connect(wallet, SIGNAL(walletOpened(bool)), d->m_wq, SLOT(walletOpened(bool)));
06938 connect(d->m_wq, SIGNAL(walletOpened(KWallet::Wallet*)), this, SLOT(walletOpened(KWallet::Wallet*)));
06939 }
06940 d->m_wq->savers.append(qMakePair(key, data));
06941 }
06942
06943
06944 void KHTMLPart::dequeueWallet(DOM::HTMLFormElementImpl *form) {
06945 KHTMLPart *p;
06946
06947 for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
06948 }
06949
06950 if (p) {
06951 p->dequeueWallet(form);
06952 return;
06953 }
06954
06955 if (d->m_wq) {
06956 d->m_wq->callers.remove(KHTMLWalletQueue::Caller(form, form->getDocument()));
06957 }
06958 }
06959
06960
06961 void KHTMLPart::walletOpened(KWallet::Wallet *wallet) {
06962 assert(!d->m_wallet);
06963 assert(d->m_wq);
06964
06965 d->m_wq->deleteLater();
06966 d->m_wq = 0L;
06967
06968 if (!wallet) {
06969 d->m_bWalletOpened = false;
06970 return;
06971 }
06972
06973 d->m_wallet = wallet;
06974 d->m_bWalletOpened = true;
06975 connect(d->m_wallet, SIGNAL(walletClosed()), SLOT(slotWalletClosed()));
06976
06977 if (!d->m_statusBarWalletLabel) {
06978 d->m_statusBarWalletLabel = new KURLLabel(d->m_statusBarExtension->statusBar());
06979 d->m_statusBarWalletLabel->setFixedHeight(instance()->iconLoader()->currentSize(KIcon::Small));
06980 d->m_statusBarWalletLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
06981 d->m_statusBarWalletLabel->setUseCursor(false);
06982 d->m_statusBarExtension->addStatusBarItem(d->m_statusBarWalletLabel, 0, false);
06983 d->m_statusBarWalletLabel->setPixmap(SmallIcon("wallet_open", instance()));
06984 connect(d->m_statusBarWalletLabel, SIGNAL(leftClickedURL()), SLOT(launchWalletManager()));
06985 connect(d->m_statusBarWalletLabel, SIGNAL(rightClickedURL()), SLOT(walletMenu()));
06986 } else {
06987 QToolTip::remove(d->m_statusBarWalletLabel);
06988 }
06989 QToolTip::add(d->m_statusBarWalletLabel, i18n("The wallet '%1' is open and being used for form data and passwords.").arg(KWallet::Wallet::NetworkWallet()));
06990 }
06991
06992
06993 KWallet::Wallet *KHTMLPart::wallet()
06994 {
06995 KHTMLPart *p;
06996
06997 for (p = parentPart(); p && p->parentPart(); p = p->parentPart())
06998 ;
06999
07000 if (p)
07001 return p->wallet();
07002
07003 return d->m_wallet;
07004 }
07005
07006
07007 void KHTMLPart::slotWalletClosed()
07008 {
07009 if (d->m_wallet) {
07010 d->m_wallet->deleteLater();
07011 d->m_wallet = 0L;
07012 }
07013 d->m_bWalletOpened = false;
07014 if (d->m_statusBarWalletLabel) {
07015 d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarWalletLabel);
07016 delete d->m_statusBarWalletLabel;
07017 d->m_statusBarWalletLabel = 0L;
07018 }
07019 }
07020
07021 void KHTMLPart::launchWalletManager()
07022 {
07023 if (!DCOPClient::mainClient()->isApplicationRegistered("kwalletmanager")) {
07024 KApplication::startServiceByDesktopName("kwalletmanager_show");
07025 } else {
07026 DCOPRef r("kwalletmanager", "kwalletmanager-mainwindow#1");
07027 r.send("show");
07028 r.send("raise");
07029 }
07030 }
07031
07032 void KHTMLPart::walletMenu()
07033 {
07034 KPopupMenu *m = new KPopupMenu(0L);
07035 m->insertItem(i18n("&Close Wallet"), this, SLOT(slotWalletClosed()));
07036 m->popup(QCursor::pos());
07037 }
07038
07039 void KHTMLPart::slotToggleCaretMode()
07040 {
07041 setCaretMode(d->m_paToggleCaretMode->isChecked());
07042 }
07043
07044 void KHTMLPart::setFormNotification(KHTMLPart::FormNotification fn) {
07045 d->m_formNotification = fn;
07046 }
07047
07048 KHTMLPart::FormNotification KHTMLPart::formNotification() const {
07049 return d->m_formNotification;
07050 }
07051
07052 KURL KHTMLPart::toplevelURL()
07053 {
07054 KHTMLPart* part = this;
07055 while (part->parentPart())
07056 part = part->parentPart();
07057
07058 if (!part)
07059 return KURL();
07060
07061 return part->url();
07062 }
07063
07064 bool KHTMLPart::isModified() const
07065 {
07066 if ( !d->m_doc )
07067 return false;
07068
07069 return d->m_doc->unsubmittedFormChanges();
07070 }
07071
07072 void KHTMLPart::setDebugScript( bool enable )
07073 {
07074 unplugActionList( "debugScriptList" );
07075 if ( enable ) {
07076 if (!d->m_paDebugScript) {
07077 d->m_paDebugScript = new KAction( i18n( "JavaScript &Debugger" ), 0, this, SLOT( slotDebugScript() ), actionCollection(), "debugScript" );
07078 }
07079 d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
07080 QPtrList<KAction> lst;
07081 lst.append( d->m_paDebugScript );
07082 plugActionList( "debugScriptList", lst );
07083 }
07084 d->m_bJScriptDebugEnabled = enable;
07085 }
07086
07087 void KHTMLPart::setSuppressedPopupIndicator( bool enable )
07088 {
07089 if ( parentPart() ) {
07090 parentPart()->setSuppressedPopupIndicator( enable );
07091 return;
07092 }
07093
07094 if ( enable && !d->m_statusBarPopupLabel ) {
07095 d->m_statusBarPopupLabel = new KURLLabel( d->m_statusBarExtension->statusBar() );
07096 d->m_statusBarPopupLabel->setFixedHeight( instance()->iconLoader()->currentSize( KIcon::Small) );
07097 d->m_statusBarPopupLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ));
07098 d->m_statusBarPopupLabel->setUseCursor( false );
07099 d->m_statusBarExtension->addStatusBarItem( d->m_statusBarPopupLabel, 0, false );
07100 d->m_statusBarPopupLabel->setPixmap( SmallIcon( "window_suppressed", instance() ) );
07101 QToolTip::add( d->m_statusBarPopupLabel, i18n("Konqueror prevented this site from opening a popup window." ) );
07102 } else if ( !enable && d->m_statusBarPopupLabel ) {
07103 QToolTip::remove( d->m_statusBarPopupLabel );
07104 d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarPopupLabel );
07105 delete d->m_statusBarPopupLabel;
07106 d->m_statusBarPopupLabel = 0L;
07107 }
07108 }
07109
07110 using namespace KParts;
07111 #include "khtml_part.moc"
07112 #include "khtmlpart_p.moc"