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