• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KHTML

  • khtml
khtml_part.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 *
3 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
4 * 1999 Lars Knoll <knoll@kde.org>
5 * 1999 Antti Koivisto <koivisto@kde.org>
6 * 2000 Simon Hausmann <hausmann@kde.org>
7 * 2000 Stefan Schimanski <1Stein@gmx.de>
8 * 2001-2005 George Staikos <staikos@kde.org>
9 * 2001-2003 Dirk Mueller <mueller@kde.org>
10 * 2000-2005 David Faure <faure@kde.org>
11 * 2002 Apple Computer, Inc.
12 * 2010 Maksim Orlovich (maksim@kde.org)
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Library General Public
16 * License as published by the Free Software Foundation; either
17 * version 2 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public License
25 * along with this library; see the file COPYING.LIB. If not, write to
26 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 * Boston, MA 02110-1301, USA.
28 */
29
30//#define SPEED_DEBUG
31#include "khtml_part.h"
32
33#include "ui_htmlpageinfo.h"
34
35#include "khtmlviewbar.h"
36#include "khtml_pagecache.h"
37
38#include "dom/dom_string.h"
39#include "dom/dom_element.h"
40#include "dom/dom_exception.h"
41#include "dom/html_document.h"
42#include "dom/dom2_range.h"
43#include "editing/editor.h"
44#include "html/html_documentimpl.h"
45#include "html/html_baseimpl.h"
46#include "html/html_objectimpl.h"
47#include "html/html_miscimpl.h"
48#include "html/html_imageimpl.h"
49#include "imload/imagemanager.h"
50#include "rendering/render_text.h"
51#include "rendering/render_frames.h"
52#include "rendering/render_layer.h"
53#include "rendering/render_position.h"
54#include "misc/loader.h"
55#include "misc/khtml_partaccessor.h"
56#include "xml/dom2_eventsimpl.h"
57#include "xml/dom2_rangeimpl.h"
58#include "xml/xml_tokenizer.h"
59#include "css/cssstyleselector.h"
60using namespace DOM;
61
62#include "khtmlview.h"
63#include <kparts/partmanager.h>
64#include <kparts/browseropenorsavequestion.h>
65#include <kacceleratormanager.h>
66#include "ecma/kjs_proxy.h"
67#include "ecma/kjs_window.h"
68#include "ecma/kjs_events.h"
69#include "khtml_settings.h"
70#include "kjserrordlg.h"
71
72#include <kjs/function.h>
73#include <kjs/interpreter.h>
74
75#include <sys/types.h>
76#include <assert.h>
77#include <unistd.h>
78
79#include <config.h>
80
81#include <kstandarddirs.h>
82#include <kstringhandler.h>
83#include <kio/job.h>
84#include <kio/jobuidelegate.h>
85#include <kio/global.h>
86#include <kio/netaccess.h>
87#include <kio/hostinfo_p.h>
88#include <kprotocolmanager.h>
89#include <kdebug.h>
90#include <kicon.h>
91#include <kiconloader.h>
92#include <klocale.h>
93#include <kmessagebox.h>
94#include <kstandardaction.h>
95#include <kstandardguiitem.h>
96#include <kactioncollection.h>
97#include <kfiledialog.h>
98#include <kmimetypetrader.h>
99#include <ktemporaryfile.h>
100#include <kglobalsettings.h>
101#include <ktoolinvocation.h>
102#include <kauthorized.h>
103#include <kparts/browserinterface.h>
104#include <kparts/scriptableextension.h>
105#include <kde_file.h>
106#include <kactionmenu.h>
107#include <ktoggleaction.h>
108#include <kcodecaction.h>
109#include <kselectaction.h>
110
111#include <ksslinfodialog.h>
112#include <ksslsettings.h>
113
114#include <kfileitem.h>
115#include <kurifilter.h>
116#include <kstatusbar.h>
117#include <kurllabel.h>
118
119#include <QtGui/QClipboard>
120#include <QtGui/QToolTip>
121#include <QtCore/QFile>
122#include <QtCore/QMetaEnum>
123#include <QtGui/QTextDocument>
124#include <QtCore/QDate>
125#include <QtNetwork/QSslCertificate>
126
127#include "khtmlpart_p.h"
128#include "khtml_iface.h"
129#include "kpassivepopup.h"
130#include "kmenu.h"
131#include "rendering/render_form.h"
132#include <kwindowsystem.h>
133#include <kconfiggroup.h>
134
135#include "ecma/debugger/debugwindow.h"
136
137// SVG
138#include <svg/SVGDocument.h>
139
140bool KHTMLPartPrivate::s_dnsInitialised = false;
141
142// DNS prefetch settings
143static const int sMaxDNSPrefetchPerPage = 42;
144static const int sDNSPrefetchTimerDelay = 200;
145static const int sDNSTTLSeconds = 400;
146static const int sDNSCacheSize = 500;
147
148
149namespace khtml {
150
151 class PartStyleSheetLoader : public CachedObjectClient
152 {
153 public:
154 PartStyleSheetLoader(KHTMLPart *part, DOM::DOMString url, DocLoader* dl)
155 {
156 m_part = part;
157 m_cachedSheet = dl->requestStyleSheet(url, QString(), "text/css",
158 true /* "user sheet" */);
159 if (m_cachedSheet)
160 m_cachedSheet->ref( this );
161 }
162 virtual ~PartStyleSheetLoader()
163 {
164 if ( m_cachedSheet ) m_cachedSheet->deref(this);
165 }
166 virtual void setStyleSheet(const DOM::DOMString&, const DOM::DOMString &sheet, const DOM::DOMString &, const DOM::DOMString &/*mimetype*/)
167 {
168 if ( m_part )
169 m_part->setUserStyleSheet( sheet.string() );
170
171 delete this;
172 }
173 virtual void error( int, const QString& ) {
174 delete this;
175 }
176 QPointer<KHTMLPart> m_part;
177 khtml::CachedCSSStyleSheet *m_cachedSheet;
178 };
179}
180
181KHTMLPart::KHTMLPart( QWidget *parentWidget, QObject *parent, GUIProfile prof )
182: KParts::ReadOnlyPart( parent )
183{
184 d = 0;
185 KHTMLGlobal::registerPart( this );
186 setComponentData( KHTMLGlobal::componentData(), false );
187 init( new KHTMLView( this, parentWidget ), prof );
188}
189
190KHTMLPart::KHTMLPart( KHTMLView *view, QObject *parent, GUIProfile prof )
191: KParts::ReadOnlyPart( parent )
192{
193 d = 0;
194 KHTMLGlobal::registerPart( this );
195 setComponentData( KHTMLGlobal::componentData(), false );
196 assert( view );
197 if (!view->part())
198 view->setPart( this );
199 init( view, prof );
200}
201
202void KHTMLPart::init( KHTMLView *view, GUIProfile prof )
203{
204 if ( prof == DefaultGUI )
205 setXMLFile( "khtml.rc" );
206 else if ( prof == BrowserViewGUI )
207 setXMLFile( "khtml_browser.rc" );
208
209 d = new KHTMLPartPrivate(this, parent());
210
211 d->m_view = view;
212
213 if (!parentPart()) {
214 QWidget *widget = new QWidget( view->parentWidget() );
215 widget->setObjectName("khtml_part_widget");
216 QVBoxLayout *layout = new QVBoxLayout( widget );
217 layout->setContentsMargins( 0, 0, 0, 0 );
218 layout->setSpacing( 0 );
219 widget->setLayout( layout );
220
221 d->m_topViewBar = new KHTMLViewBar( KHTMLViewBar::Top, d->m_view, widget );
222 d->m_bottomViewBar = new KHTMLViewBar( KHTMLViewBar::Bottom, d->m_view, widget );
223
224 layout->addWidget( d->m_topViewBar );
225 layout->addWidget( d->m_view );
226 layout->addWidget( d->m_bottomViewBar );
227 setWidget( widget );
228 widget->setFocusProxy( d->m_view );
229 } else {
230 setWidget( view );
231 }
232
233 d->m_guiProfile = prof;
234 d->m_extension = new KHTMLPartBrowserExtension( this );
235 d->m_extension->setObjectName( "KHTMLBrowserExtension" );
236 d->m_hostExtension = new KHTMLPartBrowserHostExtension( this );
237 d->m_statusBarExtension = new KParts::StatusBarExtension( this );
238 d->m_scriptableExtension = new KJS::KHTMLPartScriptable( this );
239 new KHTMLTextExtension( this );
240 new KHTMLHtmlExtension( this );
241 d->m_statusBarPopupLabel = 0L;
242 d->m_openableSuppressedPopups = 0;
243
244 d->m_paLoadImages = 0;
245 d->m_paDebugScript = 0;
246 d->m_bMousePressed = false;
247 d->m_bRightMousePressed = false;
248 d->m_bCleared = false;
249
250 if ( prof == BrowserViewGUI ) {
251 d->m_paViewDocument = new KAction( i18n( "View Do&cument Source" ), this );
252 actionCollection()->addAction( "viewDocumentSource", d->m_paViewDocument );
253 connect( d->m_paViewDocument, SIGNAL(triggered(bool)), this, SLOT(slotViewDocumentSource()) );
254 if (!parentPart()) {
255 d->m_paViewDocument->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_U) );
256 }
257
258 d->m_paViewFrame = new KAction( i18n( "View Frame Source" ), this );
259 actionCollection()->addAction( "viewFrameSource", d->m_paViewFrame );
260 connect( d->m_paViewFrame, SIGNAL(triggered(bool)), this, SLOT(slotViewFrameSource()) );
261 if (!parentPart()) {
262 d->m_paViewFrame->setShortcut( QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_U) );
263 }
264
265 d->m_paViewInfo = new KAction( i18n( "View Document Information" ), this );
266 actionCollection()->addAction( "viewPageInfo", d->m_paViewInfo );
267 if (!parentPart()) {
268 d->m_paViewInfo->setShortcut( QKeySequence(Qt::CTRL+Qt::Key_I) );
269 }
270 connect( d->m_paViewInfo, SIGNAL(triggered(bool)), this, SLOT(slotViewPageInfo()) );
271
272 d->m_paSaveBackground = new KAction( i18n( "Save &Background Image As..." ), this );
273 actionCollection()->addAction( "saveBackground", d->m_paSaveBackground );
274 connect( d->m_paSaveBackground, SIGNAL(triggered(bool)), this, SLOT(slotSaveBackground()) );
275
276 d->m_paSaveDocument = actionCollection()->addAction( KStandardAction::SaveAs, "saveDocument",
277 this, SLOT(slotSaveDocument()) );
278 if ( parentPart() )
279 d->m_paSaveDocument->setShortcuts( KShortcut() ); // avoid clashes
280
281 d->m_paSaveFrame = new KAction( i18n( "Save &Frame As..." ), this );
282 actionCollection()->addAction( "saveFrame", d->m_paSaveFrame );
283 connect( d->m_paSaveFrame, SIGNAL(triggered(bool)), this, SLOT(slotSaveFrame()) );
284 } else {
285 d->m_paViewDocument = 0;
286 d->m_paViewFrame = 0;
287 d->m_paViewInfo = 0;
288 d->m_paSaveBackground = 0;
289 d->m_paSaveDocument = 0;
290 d->m_paSaveFrame = 0;
291 }
292
293 d->m_paSecurity = new KAction( i18n( "SSL" ), this );
294 actionCollection()->addAction( "security", d->m_paSecurity );
295 connect( d->m_paSecurity, SIGNAL(triggered(bool)), this, SLOT(slotSecurity()) );
296
297 d->m_paDebugRenderTree = new KAction( i18n( "Print Rendering Tree to STDOUT" ), this );
298 actionCollection()->addAction( "debugRenderTree", d->m_paDebugRenderTree );
299 connect( d->m_paDebugRenderTree, SIGNAL(triggered(bool)), this, SLOT(slotDebugRenderTree()) );
300
301 d->m_paDebugDOMTree = new KAction( i18n( "Print DOM Tree to STDOUT" ), this );
302 actionCollection()->addAction( "debugDOMTree", d->m_paDebugDOMTree );
303 connect( d->m_paDebugDOMTree, SIGNAL(triggered(bool)), this, SLOT(slotDebugDOMTree()) );
304
305 KAction* paDebugFrameTree = new KAction( i18n( "Print frame tree to STDOUT" ), this );
306 actionCollection()->addAction( "debugFrameTree", paDebugFrameTree );
307 connect( paDebugFrameTree, SIGNAL(triggered(bool)), this, SLOT(slotDebugFrameTree()) );
308
309 d->m_paStopAnimations = new KAction( i18n( "Stop Animated Images" ), this );
310 actionCollection()->addAction( "stopAnimations", d->m_paStopAnimations );
311 connect( d->m_paStopAnimations, SIGNAL(triggered(bool)), this, SLOT(slotStopAnimations()) );
312
313 d->m_paSetEncoding = new KCodecAction( KIcon("character-set"), i18n( "Set &Encoding" ), this, true );
314 actionCollection()->addAction( "setEncoding", d->m_paSetEncoding );
315// d->m_paSetEncoding->setDelayed( false );
316
317 connect( d->m_paSetEncoding, SIGNAL(triggered(QString)), this, SLOT(slotSetEncoding(QString)));
318 connect( d->m_paSetEncoding, SIGNAL(triggered(KEncodingDetector::AutoDetectScript)), this, SLOT(slotAutomaticDetectionLanguage(KEncodingDetector::AutoDetectScript)));
319
320 if ( KGlobal::config()->hasGroup( "HTML Settings" ) ) {
321 KConfigGroup config( KGlobal::config(), "HTML Settings" );
322
323 d->m_autoDetectLanguage = static_cast<KEncodingDetector::AutoDetectScript>(config.readEntry( "AutomaticDetectionLanguage", /*static_cast<int>(language) */0));
324 if (d->m_autoDetectLanguage==KEncodingDetector::None) {
325 const QByteArray name = KGlobal::locale()->encoding().toLower();
326// kWarning() << "00000000 ";
327 if (name.endsWith("1251")||name.startsWith("koi")||name=="iso-8859-5")
328 d->m_autoDetectLanguage=KEncodingDetector::Cyrillic;
329 else if (name.endsWith("1256")||name=="iso-8859-6")
330 d->m_autoDetectLanguage=KEncodingDetector::Arabic;
331 else if (name.endsWith("1257")||name=="iso-8859-13"||name=="iso-8859-4")
332 d->m_autoDetectLanguage=KEncodingDetector::Baltic;
333 else if (name.endsWith("1250")|| name=="ibm852" || name=="iso-8859-2" || name=="iso-8859-3" )
334 d->m_autoDetectLanguage=KEncodingDetector::CentralEuropean;
335 else if (name.endsWith("1253")|| name=="iso-8859-7" )
336 d->m_autoDetectLanguage=KEncodingDetector::Greek;
337 else if (name.endsWith("1255")|| name=="iso-8859-8" || name=="iso-8859-8-i" )
338 d->m_autoDetectLanguage=KEncodingDetector::Hebrew;
339 else if (name=="jis7" || name=="eucjp" || name=="sjis" )
340 d->m_autoDetectLanguage=KEncodingDetector::Japanese;
341 else if (name.endsWith("1254")|| name=="iso-8859-9" )
342 d->m_autoDetectLanguage=KEncodingDetector::Turkish;
343 else if (name.endsWith("1252")|| name=="iso-8859-1" || name=="iso-8859-15" )
344 d->m_autoDetectLanguage=KEncodingDetector::WesternEuropean;
345 else
346 d->m_autoDetectLanguage=KEncodingDetector::SemiautomaticDetection;
347// kWarning() << "0000000end " << d->m_autoDetectLanguage << " " << KGlobal::locale()->encodingMib();
348 }
349 d->m_paSetEncoding->setCurrentAutoDetectScript(d->m_autoDetectLanguage);
350 }
351
352 d->m_paUseStylesheet = new KSelectAction( i18n( "Use S&tylesheet"), this );
353 actionCollection()->addAction( "useStylesheet", d->m_paUseStylesheet );
354 connect( d->m_paUseStylesheet, SIGNAL(triggered(int)), this, SLOT(slotUseStylesheet()) );
355
356 if ( prof == BrowserViewGUI ) {
357 d->m_paIncZoomFactor = new KHTMLZoomFactorAction( this, true, "format-font-size-more", i18n( "Enlarge Font" ), this );
358 actionCollection()->addAction( "incFontSizes", d->m_paIncZoomFactor );
359 connect(d->m_paIncZoomFactor, SIGNAL(triggered(bool)), SLOT(slotIncFontSizeFast()));
360 d->m_paIncZoomFactor->setWhatsThis( i18n( "<qt>Enlarge Font<br /><br />"
361 "Make the font in this window bigger. "
362 "Click and hold down the mouse button for a menu with all available font sizes.</qt>" ) );
363
364 d->m_paDecZoomFactor = new KHTMLZoomFactorAction( this, false, "format-font-size-less", i18n( "Shrink Font" ), this );
365 actionCollection()->addAction( "decFontSizes", d->m_paDecZoomFactor );
366 connect(d->m_paDecZoomFactor, SIGNAL(triggered(bool)), SLOT(slotDecFontSizeFast()));
367 d->m_paDecZoomFactor->setWhatsThis( i18n( "<qt>Shrink Font<br /><br />"
368 "Make the font in this window smaller. "
369 "Click and hold down the mouse button for a menu with all available font sizes.</qt>" ) );
370 if (!parentPart()) {
371 // For framesets, this action also affects frames, so only
372 // the frameset needs to define a shortcut for the action.
373
374 // TODO: Why also CTRL+=? Because of http://trolltech.com/developer/knowledgebase/524/?
375 // Nobody else does it...
376 d->m_paIncZoomFactor->setShortcut( KShortcut("CTRL++; CTRL+=") );
377 d->m_paDecZoomFactor->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_Minus) );
378 }
379 }
380
381 d->m_paFind = actionCollection()->addAction( KStandardAction::Find, "find", this, SLOT(slotFind()) );
382 d->m_paFind->setWhatsThis( i18n( "<qt>Find text<br /><br />"
383 "Shows a dialog that allows you to find text on the displayed page.</qt>" ) );
384
385 d->m_paFindNext = actionCollection()->addAction( KStandardAction::FindNext, "findNext", this, SLOT(slotFindNext()) );
386 d->m_paFindNext->setWhatsThis( i18n( "<qt>Find next<br /><br />"
387 "Find the next occurrence of the text that you "
388 "have found using the <b>Find Text</b> function.</qt>" ) );
389
390 d->m_paFindPrev = actionCollection()->addAction( KStandardAction::FindPrev, "findPrevious",
391 this, SLOT(slotFindPrev()) );
392 d->m_paFindPrev->setWhatsThis( i18n( "<qt>Find previous<br /><br />"
393 "Find the previous occurrence of the text that you "
394 "have found using the <b>Find Text</b> function.</qt>" ) );
395
396 // These two actions aren't visible in the menus, but exist for the (configurable) shortcut
397 d->m_paFindAheadText = new KAction( i18n("Find Text as You Type"), this );
398 actionCollection()->addAction( "findAheadText", d->m_paFindAheadText );
399 d->m_paFindAheadText->setShortcuts( KShortcut( '/' ) );
400 d->m_paFindAheadText->setHelpText(i18n("This shortcut shows the find bar, for finding text in the displayed page. It cancels the effect of \"Find Links as You Type\", which sets the \"Find links only\" option."));
401 connect( d->m_paFindAheadText, SIGNAL(triggered(bool)), this, SLOT(slotFindAheadText()) );
402
403 d->m_paFindAheadLinks = new KAction( i18n("Find Links as You Type"), this );
404 actionCollection()->addAction( "findAheadLink", d->m_paFindAheadLinks );
405 // The issue is that it sets the (sticky) option FindLinksOnly, so
406 // if you trigger this shortcut once by mistake, Esc and Ctrl+F will still have the option set.
407 // Better let advanced users configure a shortcut for this advanced option
408 //d->m_paFindAheadLinks->setShortcuts( KShortcut( '\'' ) );
409 d->m_paFindAheadLinks->setHelpText(i18n("This shortcut shows the find bar, and sets the option \"Find links only\"."));
410 connect( d->m_paFindAheadLinks, SIGNAL(triggered(bool)), this, SLOT(slotFindAheadLink()) );
411
412 if ( parentPart() )
413 {
414 d->m_paFind->setShortcuts( KShortcut() ); // avoid clashes
415 d->m_paFindNext->setShortcuts( KShortcut() ); // avoid clashes
416 d->m_paFindPrev->setShortcuts( KShortcut() ); // avoid clashes
417 d->m_paFindAheadText->setShortcuts( KShortcut());
418 d->m_paFindAheadLinks->setShortcuts( KShortcut());
419 }
420
421 d->m_paPrintFrame = new KAction( i18n( "Print Frame..." ), this );
422 actionCollection()->addAction( "printFrame", d->m_paPrintFrame );
423 d->m_paPrintFrame->setIcon( KIcon( "document-print-frame" ) );
424 connect( d->m_paPrintFrame, SIGNAL(triggered(bool)), this, SLOT(slotPrintFrame()) );
425 d->m_paPrintFrame->setWhatsThis( i18n( "<qt>Print Frame<br /><br />"
426 "Some pages have several frames. To print only a single frame, click "
427 "on it and then use this function.</qt>" ) );
428
429 // Warning: The name selectAll is used hardcoded by some 3rd parties to remove the
430 // shortcut for selectAll so they do not get ambigous shortcuts. Renaming it
431 // will either crash or render useless that workaround. It would be better
432 // to use the name KStandardAction::name(KStandardAction::SelectAll) but we
433 // can't for the same reason.
434 d->m_paSelectAll = actionCollection()->addAction( KStandardAction::SelectAll, "selectAll",
435 this, SLOT(slotSelectAll()) );
436 if ( parentPart() ) // Only the frameset has the shortcut, but the slot uses the current frame.
437 d->m_paSelectAll->setShortcuts( KShortcut() ); // avoid clashes
438
439 d->m_paToggleCaretMode = new KToggleAction(i18n("Toggle Caret Mode"), this );
440 actionCollection()->addAction( "caretMode", d->m_paToggleCaretMode );
441 d->m_paToggleCaretMode->setShortcut( QKeySequence(Qt::Key_F7) );
442 connect( d->m_paToggleCaretMode, SIGNAL(triggered(bool)), this, SLOT(slotToggleCaretMode()) );
443 d->m_paToggleCaretMode->setChecked(isCaretMode());
444 if (parentPart())
445 d->m_paToggleCaretMode->setShortcut(KShortcut()); // avoid clashes
446
447 // set the default java(script) flags according to the current host.
448 d->m_bOpenMiddleClick = d->m_settings->isOpenMiddleClickEnabled();
449 d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
450 setDebugScript( d->m_settings->isJavaScriptDebugEnabled() );
451 d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
452 d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();
453
454 // Set the meta-refresh flag...
455 d->m_metaRefreshEnabled = d->m_settings->isAutoDelayedActionsEnabled ();
456
457 KHTMLSettings::KSmoothScrollingMode ssm = d->m_settings->smoothScrolling();
458 if (ssm == KHTMLSettings::KSmoothScrollingDisabled)
459 d->m_view->setSmoothScrollingModeDefault(KHTMLView::SSMDisabled);
460 else if (ssm == KHTMLSettings::KSmoothScrollingWhenEfficient)
461 d->m_view->setSmoothScrollingModeDefault(KHTMLView::SSMWhenEfficient);
462 else
463 d->m_view->setSmoothScrollingModeDefault(KHTMLView::SSMEnabled);
464
465 if (d->m_bDNSPrefetchIsDefault && !onlyLocalReferences()) {
466 KHTMLSettings::KDNSPrefetch dpm = d->m_settings->dnsPrefetch();
467 if (dpm == KHTMLSettings::KDNSPrefetchDisabled)
468 d->m_bDNSPrefetch = DNSPrefetchDisabled;
469 else if (dpm == KHTMLSettings::KDNSPrefetchOnlyWWWAndSLD)
470 d->m_bDNSPrefetch = DNSPrefetchOnlyWWWAndSLD;
471 else
472 d->m_bDNSPrefetch = DNSPrefetchEnabled;
473 }
474
475 if (!KHTMLPartPrivate::s_dnsInitialised && d->m_bDNSPrefetch != DNSPrefetchDisabled) {
476 KIO::HostInfo::setCacheSize( sDNSCacheSize );
477 KIO::HostInfo::setTTL( sDNSTTLSeconds );
478 KHTMLPartPrivate::s_dnsInitialised = true;
479 }
480
481 // all shortcuts should only be active, when this part has focus
482 foreach ( QAction *action, actionCollection ()->actions () ) {
483 action->setShortcutContext ( Qt::WidgetWithChildrenShortcut );
484 }
485 actionCollection()->associateWidget(view);
486
487 connect( view, SIGNAL(zoomView(int)), SLOT(slotZoomView(int)) );
488
489 connect( this, SIGNAL(completed()),
490 this, SLOT(updateActions()) );
491 connect( this, SIGNAL(completed(bool)),
492 this, SLOT(updateActions()) );
493 connect( this, SIGNAL(started(KIO::Job*)),
494 this, SLOT(updateActions()) );
495
496 // #### FIXME: the process wide loader is going to signal every part about every loaded object.
497 // That's quite inefficient. Should be per-document-tree somehow. Even signaling to
498 // child parts that a request from an ancestor has loaded is inefficent..
499 connect( khtml::Cache::loader(), SIGNAL(requestStarted(khtml::DocLoader*,khtml::CachedObject*)),
500 this, SLOT(slotLoaderRequestStarted(khtml::DocLoader*,khtml::CachedObject*)) );
501 connect( khtml::Cache::loader(), SIGNAL(requestDone(khtml::DocLoader*,khtml::CachedObject*)),
502 this, SLOT(slotLoaderRequestDone(khtml::DocLoader*,khtml::CachedObject*)) );
503 connect( khtml::Cache::loader(), SIGNAL(requestFailed(khtml::DocLoader*,khtml::CachedObject*)),
504 this, SLOT(slotLoaderRequestDone(khtml::DocLoader*,khtml::CachedObject*)) );
505
506 connect ( &d->m_progressUpdateTimer, SIGNAL(timeout()), this, SLOT(slotProgressUpdate()) );
507
508 findTextBegin(); //reset find variables
509
510 connect( &d->m_redirectionTimer, SIGNAL(timeout()),
511 this, SLOT(slotRedirect()) );
512
513 if (QDBusConnection::sessionBus().isConnected()) {
514 new KHTMLPartIface(this); // our "adaptor"
515 for (int i = 1; ; ++i)
516 if (QDBusConnection::sessionBus().registerObject(QString("/KHTML/%1/widget").arg(i), this))
517 break;
518 else if (i == 0xffff)
519 kFatal() << "Something is very wrong in KHTMLPart!";
520 }
521
522 if (prof == BrowserViewGUI && !parentPart())
523 loadPlugins();
524
525 // "khtml" catalog does not exist, our translations are in kdelibs.
526 // removing this catalog from KGlobal::locale() prevents problems
527 // with changing the language in applications at runtime -Thomas Reitelbach
528 // DF: a better fix would be to set the right catalog name in the KComponentData!
529 KGlobal::locale()->removeCatalog("khtml");
530}
531
532KHTMLPart::~KHTMLPart()
533{
534 kDebug(6050) << this;
535 KConfigGroup config( KGlobal::config(), "HTML Settings" );
536 config.writeEntry( "AutomaticDetectionLanguage", int(d->m_autoDetectLanguage) );
537
538 if (d->m_manager) { // the PartManager for this part's children
539 d->m_manager->removePart(this);
540 }
541
542 slotWalletClosed();
543 if (!parentPart()) { // only delete it if the top khtml_part closes
544 removeJSErrorExtension();
545 }
546
547 stopAutoScroll();
548 d->m_redirectionTimer.stop();
549
550 if (!d->m_bComplete)
551 closeUrl();
552
553 disconnect( khtml::Cache::loader(), SIGNAL(requestStarted(khtml::DocLoader*,khtml::CachedObject*)),
554 this, SLOT(slotLoaderRequestStarted(khtml::DocLoader*,khtml::CachedObject*)) );
555 disconnect( khtml::Cache::loader(), SIGNAL(requestDone(khtml::DocLoader*,khtml::CachedObject*)),
556 this, SLOT(slotLoaderRequestDone(khtml::DocLoader*,khtml::CachedObject*)) );
557 disconnect( khtml::Cache::loader(), SIGNAL(requestFailed(khtml::DocLoader*,khtml::CachedObject*)),
558 this, SLOT(slotLoaderRequestDone(khtml::DocLoader*,khtml::CachedObject*)) );
559
560 clear();
561 hide();
562
563 if ( d->m_view )
564 {
565 d->m_view->m_part = 0;
566 }
567
568 // Have to delete this here since we forward declare it in khtmlpart_p and
569 // at least some compilers won't call the destructor in this case.
570 delete d->m_jsedlg;
571 d->m_jsedlg = 0;
572
573 if (!parentPart()) // only delete d->m_frame if the top khtml_part closes
574 delete d->m_frame;
575 else if (d->m_frame && d->m_frame->m_run) // for kids, they may get detached while
576 d->m_frame->m_run.data()->abort(); // resolving mimetype; cancel that if needed
577 delete d; d = 0;
578 KHTMLGlobal::deregisterPart( this );
579}
580
581bool KHTMLPart::restoreURL( const KUrl &url )
582{
583 kDebug( 6050 ) << url;
584
585 d->m_redirectionTimer.stop();
586
587 /*
588 * That's not a good idea as it will call closeUrl() on all
589 * child frames, preventing them from further loading. This
590 * method gets called from restoreState() in case of a full frameset
591 * restoral, and restoreState() calls closeUrl() before restoring
592 * anyway.
593 kDebug( 6050 ) << "closing old URL";
594 closeUrl();
595 */
596
597 d->m_bComplete = false;
598 d->m_bLoadEventEmitted = false;
599 d->m_workingURL = url;
600
601 // set the java(script) flags according to the current host.
602 d->m_bJScriptEnabled = KHTMLGlobal::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
603 setDebugScript( KHTMLGlobal::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
604 d->m_bJavaEnabled = KHTMLGlobal::defaultHTMLSettings()->isJavaEnabled(url.host());
605 d->m_bPluginsEnabled = KHTMLGlobal::defaultHTMLSettings()->isPluginsEnabled(url.host());
606
607 setUrl(url);
608
609 d->m_restoreScrollPosition = true;
610 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
611 connect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
612
613 KHTMLPageCache::self()->fetchData( d->m_cacheId, this, SLOT(slotRestoreData(QByteArray)));
614
615 emit started( 0L );
616
617 return true;
618}
619
620bool KHTMLPartPrivate::isLocalAnchorJump( const KUrl& url )
621{
622 // kio_help actually uses fragments to identify different pages, so
623 // always reload with it.
624 if (url.protocol() == QLatin1String("help"))
625 return false;
626
627 return url.hasRef() && url.equals( q->url(),
628 KUrl::CompareWithoutTrailingSlash | KUrl::CompareWithoutFragment | KUrl::AllowEmptyPath );
629}
630
631void KHTMLPartPrivate::executeAnchorJump( const KUrl& url, bool lockHistory )
632{
633 DOM::HashChangeEventImpl *hashChangeEvImpl = 0;
634 const QString &oldRef = q->url().ref();
635 const QString &newRef = url.ref();
636 const bool hashChanged = (oldRef != newRef) || (oldRef.isNull() && newRef.isEmpty());
637
638 if (hashChanged) {
639 // Note: we want to emit openUrlNotify first thing to make the history capture the old state,
640 // however do not update history if a lock was explicitly requested, e.g. Location.replace()
641 if (!lockHistory) {
642 emit m_extension->openUrlNotify();
643 }
644 // Create hashchange event
645 hashChangeEvImpl = new DOM::HashChangeEventImpl();
646 hashChangeEvImpl->initHashChangeEvent("hashchange",
647 true, //bubble
648 false, //cancelable
649 q->url().url(), //oldURL
650 url.url() //newURL
651 );
652 }
653
654 if (!q->gotoAnchor(newRef)) // encoded fragment
655 q->gotoAnchor(url.htmlRef()); // not encoded fragment
656
657 q->setUrl(url);
658 emit m_extension->setLocationBarUrl( url.prettyUrl() );
659
660 if (hashChangeEvImpl) {
661 m_doc->dispatchWindowEvent(hashChangeEvImpl);
662 }
663}
664
665bool KHTMLPart::openUrl( const KUrl &url )
666{
667 kDebug( 6050 ) << this << "opening" << url;
668#ifndef KHTML_NO_WALLET
669 // Wallet forms are per page, so clear it when loading a different page if we
670 // are not an iframe (because we store walletforms only on the topmost part).
671 if(!parentPart())
672 d->m_walletForms.clear();
673#endif
674 d->m_redirectionTimer.stop();
675
676 // check to see if this is an "error://" URL. This is caused when an error
677 // occurs before this part was loaded (e.g. KonqRun), and is passed to
678 // khtmlpart so that it can display the error.
679 if ( url.protocol() == "error" ) {
680 closeUrl();
681
682 if( d->m_bJScriptEnabled ) {
683 d->m_statusBarText[BarOverrideText].clear();
684 d->m_statusBarText[BarDefaultText].clear();
685 }
686
692 KUrl::List urls = KUrl::split( url );
693 //kDebug(6050) << "Handling error URL. URL count:" << urls.count();
694
695 if ( !urls.isEmpty() ) {
696 const KUrl mainURL = urls.first();
697 int error = mainURL.queryItem( "error" ).toInt();
698 // error=0 isn't a valid error code, so 0 means it's missing from the URL
699 if ( error == 0 ) error = KIO::ERR_UNKNOWN;
700 const QString errorText = mainURL.queryItem( "errText" );
701 urls.pop_front();
702 d->m_workingURL = KUrl::join( urls );
703 //kDebug(6050) << "Emitting fixed URL " << d->m_workingURL.prettyUrl();
704 emit d->m_extension->setLocationBarUrl( d->m_workingURL.prettyUrl() );
705 htmlError( error, errorText, d->m_workingURL );
706 return true;
707 }
708 }
709
710 if (!parentPart()) { // only do it for toplevel part
711 QString host = url.isLocalFile() ? "localhost" : url.host();
712 QString userAgent = KProtocolManager::userAgentForHost(host);
713 if (userAgent != KProtocolManager::userAgentForHost(QString())) {
714 if (!d->m_statusBarUALabel) {
715 d->m_statusBarUALabel = new KUrlLabel(d->m_statusBarExtension->statusBar());
716 d->m_statusBarUALabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum));
717 d->m_statusBarUALabel->setUseCursor(false);
718 d->m_statusBarExtension->addStatusBarItem(d->m_statusBarUALabel, 0, false);
719 d->m_statusBarUALabel->setPixmap(SmallIcon("preferences-web-browser-identification"));
720 }
721 d->m_statusBarUALabel->setToolTip(i18n("The fake user-agent '%1' is in use.", userAgent));
722 } else if (d->m_statusBarUALabel) {
723 d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarUALabel);
724 delete d->m_statusBarUALabel;
725 d->m_statusBarUALabel = 0L;
726 }
727 }
728
729 KParts::BrowserArguments browserArgs( d->m_extension->browserArguments() );
730 KParts::OpenUrlArguments args( arguments() );
731
732 // in case
733 // a) we have no frameset (don't test m_frames.count(), iframes get in there)
734 // b) the url is identical with the currently displayed one (except for the htmlref!)
735 // c) the url request is not a POST operation and
736 // d) the caller did not request to reload the page
737 // e) there was no HTTP redirection meanwhile (testcase: webmin's software/tree.cgi)
738 // => we don't reload the whole document and
739 // we just jump to the requested html anchor
740 bool isFrameSet = false;
741 if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
742 HTMLDocumentImpl* htmlDoc = static_cast<HTMLDocumentImpl*>(d->m_doc);
743 isFrameSet = htmlDoc->body() && (htmlDoc->body()->id() == ID_FRAMESET);
744 }
745
746 if (isFrameSet && d->isLocalAnchorJump(url) && browserArgs.softReload)
747 {
748 QList<khtml::ChildFrame*>::Iterator it = d->m_frames.begin();
749 const QList<khtml::ChildFrame*>::Iterator end = d->m_frames.end();
750 for (; it != end; ++it) {
751 KHTMLPart* const part = qobject_cast<KHTMLPart *>( (*it)->m_part.data() );
752 if (part)
753 {
754 // We are reloading frames to make them jump into offsets.
755 KParts::OpenUrlArguments partargs( part->arguments() );
756 partargs.setReload( true );
757 part->setArguments( partargs );
758
759 part->openUrl( part->url() );
760 }
761 }/*next it*/
762 return true;
763 }
764
765 if ( url.hasRef() && !isFrameSet )
766 {
767 bool noReloadForced = !args.reload() && !browserArgs.redirectedRequest() && !browserArgs.doPost();
768 if ( noReloadForced && d->isLocalAnchorJump(url) )
769 {
770 kDebug( 6050 ) << "jumping to anchor. m_url = " << url;
771 setUrl(url);
772 emit started( 0 );
773
774 if ( !gotoAnchor( url.encodedHtmlRef()) )
775 gotoAnchor( url.htmlRef() );
776
777 d->m_bComplete = true;
778 if (d->m_doc)
779 d->m_doc->setParsing(false);
780
781 kDebug( 6050 ) << "completed...";
782 emit completed();
783 return true;
784 }
785 }
786
787 // Save offset of viewport when page is reloaded to be compliant
788 // to every other capable browser out there.
789 if (args.reload()) {
790 args.setXOffset( d->m_view->contentsX() );
791 args.setYOffset( d->m_view->contentsY() );
792 setArguments(args);
793 }
794
795 if (!d->m_restored)
796 closeUrl();
797
798 d->m_restoreScrollPosition = d->m_restored;
799 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
800 connect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
801
802 // Classify the mimetype. Some, like images and plugins are handled
803 // by wrapping things up in tags, so we want to plain output the HTML,
804 // and not start the job and all that (since we would want the
805 // KPart or whatever to load it).
806 // This is also the only place we need to do this, as it's for
807 // internal iframe use, not any other clients.
808 MimeType type = d->classifyMimeType(args.mimeType());
809
810 if (type == MimeImage || type == MimeOther) {
811 begin(url, args.xOffset(), args.yOffset());
812 write(QString::fromLatin1("<html><head></head><body>"));
813 if (type == MimeImage)
814 write(QString::fromLatin1("<img "));
815 else
816 write(QString::fromLatin1("<embed "));
817 write(QString::fromLatin1("src=\""));
818
819 assert(url.url().indexOf('"') == -1);
820 write(url.url());
821
822 write(QString::fromLatin1("\">"));
823 end();
824 return true;
825 }
826
827
828 // initializing m_url to the new url breaks relative links when opening such a link after this call and _before_ begin() is called (when the first
829 // data arrives) (Simon)
830 d->m_workingURL = url;
831 if(url.protocol().startsWith( "http" ) && !url.host().isEmpty() &&
832 url.path().isEmpty()) {
833 d->m_workingURL.setPath("/");
834 emit d->m_extension->setLocationBarUrl( d->m_workingURL.prettyUrl() );
835 }
836 setUrl(d->m_workingURL);
837
838 QMap<QString,QString>& metaData = args.metaData();
839 metaData.insert("main_frame_request", parentPart() == 0 ? "TRUE" : "FALSE" );
840 metaData.insert("ssl_parent_ip", d->m_ssl_parent_ip);
841 metaData.insert("ssl_parent_cert", d->m_ssl_parent_cert);
842 metaData.insert("PropagateHttpHeader", "true");
843 metaData.insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE" : "FALSE" );
844 metaData.insert("ssl_activate_warnings", "TRUE" );
845 metaData.insert("cross-domain", toplevelURL().url());
846
847 if (d->m_restored)
848 {
849 metaData.insert("referrer", d->m_pageReferrer);
850 d->m_cachePolicy = KIO::CC_Cache;
851 }
852 else if (args.reload() && !browserArgs.softReload)
853 d->m_cachePolicy = KIO::CC_Reload;
854 else
855 d->m_cachePolicy = KProtocolManager::cacheControl();
856
857 if ( browserArgs.doPost() && (url.protocol().startsWith("http")) )
858 {
859 d->m_job = KIO::http_post( url, browserArgs.postData, KIO::HideProgressInfo );
860 d->m_job->addMetaData("content-type", browserArgs.contentType() );
861 }
862 else
863 {
864 d->m_job = KIO::get( url, KIO::NoReload, KIO::HideProgressInfo );
865 d->m_job->addMetaData("cache", KIO::getCacheControlString(d->m_cachePolicy));
866 }
867
868 if (widget())
869 d->m_job->ui()->setWindow(widget()->topLevelWidget());
870 d->m_job->addMetaData(metaData);
871
872 connect( d->m_job, SIGNAL(result(KJob*)),
873 SLOT(slotFinished(KJob*)) );
874 connect( d->m_job, SIGNAL(data(KIO::Job*,QByteArray)),
875 SLOT(slotData(KIO::Job*,QByteArray)) );
876 connect ( d->m_job, SIGNAL(infoMessage(KJob*,QString,QString)),
877 SLOT(slotInfoMessage(KJob*,QString)) );
878 connect( d->m_job, SIGNAL(redirection(KIO::Job*,KUrl)),
879 SLOT(slotRedirection(KIO::Job*,KUrl)) );
880
881 d->m_bComplete = false;
882 d->m_bLoadEventEmitted = false;
883
884 // delete old status bar msg's from kjs (if it _was_ activated on last URL)
885 if( d->m_bJScriptEnabled ) {
886 d->m_statusBarText[BarOverrideText].clear();
887 d->m_statusBarText[BarDefaultText].clear();
888 }
889
890 // set the javascript flags according to the current url
891 d->m_bJScriptEnabled = KHTMLGlobal::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
892 setDebugScript( KHTMLGlobal::defaultHTMLSettings()->isJavaScriptDebugEnabled() );
893 d->m_bJavaEnabled = KHTMLGlobal::defaultHTMLSettings()->isJavaEnabled(url.host());
894 d->m_bPluginsEnabled = KHTMLGlobal::defaultHTMLSettings()->isPluginsEnabled(url.host());
895
896
897 connect( d->m_job, SIGNAL(speed(KJob*,ulong)),
898 this, SLOT(slotJobSpeed(KJob*,ulong)) );
899
900 connect( d->m_job, SIGNAL(percent(KJob*,ulong)),
901 this, SLOT(slotJobPercent(KJob*,ulong)) );
902
903 connect( d->m_job, SIGNAL(result(KJob*)),
904 this, SLOT(slotJobDone(KJob*)) );
905
906 d->m_jobspeed = 0;
907
908 // If this was an explicit reload and the user style sheet should be used,
909 // do a stat to see whether the stylesheet was changed in the meanwhile.
910 if ( args.reload() && !settings()->userStyleSheet().isEmpty() ) {
911 KUrl url( settings()->userStyleSheet() );
912 KIO::StatJob *job = KIO::stat( url, KIO::HideProgressInfo );
913 connect( job, SIGNAL(result(KJob*)),
914 this, SLOT(slotUserSheetStatDone(KJob*)) );
915 }
916 startingJob( d->m_job );
917 emit started( 0L );
918
919 return true;
920}
921
922bool KHTMLPart::closeUrl()
923{
924 if ( d->m_job )
925 {
926 KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
927 d->m_job->kill();
928 d->m_job = 0;
929 }
930
931 if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
932 HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc );
933
934 if ( hdoc->body() && d->m_bLoadEventEmitted ) {
935 hdoc->body()->dispatchWindowEvent( EventImpl::UNLOAD_EVENT, false, false );
936 if ( d->m_doc )
937 d->m_doc->updateRendering();
938 d->m_bLoadEventEmitted = false;
939 }
940 }
941
942 d->m_bComplete = true; // to avoid emitting completed() in slotFinishedParsing() (David)
943 d->m_bLoadEventEmitted = true; // don't want that one either
944 d->m_cachePolicy = KProtocolManager::cacheControl(); // reset cache policy
945
946 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
947
948 KHTMLPageCache::self()->cancelFetch(this);
949 if ( d->m_doc && d->m_doc->parsing() )
950 {
951 kDebug( 6050 ) << " was still parsing... calling end ";
952 slotFinishedParsing();
953 d->m_doc->setParsing(false);
954 }
955
956 if ( !d->m_workingURL.isEmpty() )
957 {
958 // Aborted before starting to render
959 kDebug( 6050 ) << "Aborted before starting to render, reverting location bar to " << url().prettyUrl();
960 emit d->m_extension->setLocationBarUrl( url().prettyUrl() );
961 }
962
963 d->m_workingURL = KUrl();
964
965 if ( d->m_doc && d->m_doc->docLoader() )
966 khtml::Cache::loader()->cancelRequests( d->m_doc->docLoader() );
967
968 // tell all subframes to stop as well
969 {
970 ConstFrameIt it = d->m_frames.constBegin();
971 const ConstFrameIt end = d->m_frames.constEnd();
972 for (; it != end; ++it )
973 {
974 if ( (*it)->m_run )
975 (*it)->m_run.data()->abort();
976 if ( !( *it )->m_part.isNull() )
977 ( *it )->m_part.data()->closeUrl();
978 }
979 }
980 // tell all objects to stop as well
981 {
982 ConstFrameIt it = d->m_objects.constBegin();
983 const ConstFrameIt end = d->m_objects.constEnd();
984 for (; it != end; ++it)
985 {
986 if ( !( *it )->m_part.isNull() )
987 ( *it )->m_part.data()->closeUrl();
988 }
989 }
990 // Stop any started redirections as well!! (DA)
991 if ( d && d->m_redirectionTimer.isActive() )
992 d->m_redirectionTimer.stop();
993
994 // null node activated.
995 emit nodeActivated(Node());
996
997 // make sure before clear() runs, we pop out of a dialog's message loop
998 if ( d->m_view )
999 d->m_view->closeChildDialogs();
1000
1001 return true;
1002}
1003
1004DOM::HTMLDocument KHTMLPart::htmlDocument() const
1005{
1006 if (d->m_doc && d->m_doc->isHTMLDocument())
1007 return static_cast<HTMLDocumentImpl*>(d->m_doc);
1008 else
1009 return static_cast<HTMLDocumentImpl*>(0);
1010}
1011
1012DOM::Document KHTMLPart::document() const
1013{
1014 return d->m_doc;
1015}
1016
1017QString KHTMLPart::documentSource() const
1018{
1019 QString sourceStr;
1020 if ( !( url().isLocalFile() ) && KHTMLPageCache::self()->isComplete( d->m_cacheId ) )
1021 {
1022 QByteArray sourceArray;
1023 QDataStream dataStream( &sourceArray, QIODevice::WriteOnly );
1024 KHTMLPageCache::self()->saveData( d->m_cacheId, &dataStream );
1025 QTextStream stream( sourceArray, QIODevice::ReadOnly );
1026 stream.setCodec( QTextCodec::codecForName( encoding().toLatin1().constData() ) );
1027 sourceStr = stream.readAll();
1028 } else
1029 {
1030 QString tmpFile;
1031 if( KIO::NetAccess::download( url(), tmpFile, NULL ) )
1032 {
1033 QFile f( tmpFile );
1034 if ( f.open( QIODevice::ReadOnly ) )
1035 {
1036 QTextStream stream( &f );
1037 stream.setCodec( QTextCodec::codecForName( encoding().toLatin1().constData() ) );
1038 sourceStr = stream.readAll();
1039 f.close();
1040 }
1041 KIO::NetAccess::removeTempFile( tmpFile );
1042 }
1043 }
1044
1045 return sourceStr;
1046}
1047
1048
1049KParts::BrowserExtension *KHTMLPart::browserExtension() const
1050{
1051 return d->m_extension;
1052}
1053
1054KParts::BrowserHostExtension *KHTMLPart::browserHostExtension() const
1055{
1056 return d->m_hostExtension;
1057}
1058
1059KHTMLView *KHTMLPart::view() const
1060{
1061 return d->m_view;
1062}
1063
1064KHTMLViewBar *KHTMLPart::pTopViewBar() const
1065{
1066 if (const_cast<KHTMLPart*>(this)->parentPart())
1067 return const_cast<KHTMLPart*>(this)->parentPart()->pTopViewBar();
1068 return d->m_topViewBar;
1069}
1070
1071KHTMLViewBar *KHTMLPart::pBottomViewBar() const
1072{
1073 if (const_cast<KHTMLPart*>(this)->parentPart())
1074 return const_cast<KHTMLPart*>(this)->parentPart()->pBottomViewBar();
1075 return d->m_bottomViewBar;
1076}
1077
1078void KHTMLPart::setStatusMessagesEnabled( bool enable )
1079{
1080 d->m_statusMessagesEnabled = enable;
1081}
1082
1083KJS::Interpreter *KHTMLPart::jScriptInterpreter()
1084{
1085 KJSProxy *proxy = jScript();
1086 if (!proxy || proxy->paused())
1087 return 0;
1088
1089 return proxy->interpreter();
1090}
1091
1092bool KHTMLPart::statusMessagesEnabled() const
1093{
1094 return d->m_statusMessagesEnabled;
1095}
1096
1097void KHTMLPart::setJScriptEnabled( bool enable )
1098{
1099 if ( !enable && jScriptEnabled() && d->m_frame && d->m_frame->m_jscript ) {
1100 d->m_frame->m_jscript->clear();
1101 }
1102 d->m_bJScriptForce = enable;
1103 d->m_bJScriptOverride = true;
1104}
1105
1106bool KHTMLPart::jScriptEnabled() const
1107{
1108 if(onlyLocalReferences()) return false;
1109
1110 if ( d->m_bJScriptOverride )
1111 return d->m_bJScriptForce;
1112 return d->m_bJScriptEnabled;
1113}
1114
1115void KHTMLPart::setDNSPrefetch( DNSPrefetch pmode )
1116{
1117 d->m_bDNSPrefetch = pmode;
1118 d->m_bDNSPrefetchIsDefault = false;
1119}
1120
1121KHTMLPart::DNSPrefetch KHTMLPart::dnsPrefetch() const
1122{
1123 if (onlyLocalReferences())
1124 return DNSPrefetchDisabled;
1125 return d->m_bDNSPrefetch;
1126}
1127
1128void KHTMLPart::setMetaRefreshEnabled( bool enable )
1129{
1130 d->m_metaRefreshEnabled = enable;
1131}
1132
1133bool KHTMLPart::metaRefreshEnabled() const
1134{
1135 return d->m_metaRefreshEnabled;
1136}
1137
1138KJSProxy *KHTMLPart::jScript()
1139{
1140 if (!jScriptEnabled()) return 0;
1141
1142 if ( !d->m_frame ) {
1143 KHTMLPart * p = parentPart();
1144 if (!p) {
1145 d->m_frame = new khtml::ChildFrame;
1146 d->m_frame->m_part = this;
1147 } else {
1148 ConstFrameIt it = p->d->m_frames.constBegin();
1149 const ConstFrameIt end = p->d->m_frames.constEnd();
1150 for (; it != end; ++it)
1151 if ((*it)->m_part.data() == this) {
1152 d->m_frame = *it;
1153 break;
1154 }
1155 }
1156 if ( !d->m_frame )
1157 return 0;
1158 }
1159 if ( !d->m_frame->m_jscript )
1160 d->m_frame->m_jscript = new KJSProxy(d->m_frame);
1161 d->m_frame->m_jscript->setDebugEnabled(d->m_bJScriptDebugEnabled);
1162
1163 return d->m_frame->m_jscript;
1164}
1165
1166QVariant KHTMLPart::crossFrameExecuteScript(const QString& target, const QString& script)
1167{
1168 KHTMLPart* destpart = this;
1169
1170 QString trg = target.toLower();
1171
1172 if (target == "_top") {
1173 while (destpart->parentPart())
1174 destpart = destpart->parentPart();
1175 }
1176 else if (target == "_parent") {
1177 if (parentPart())
1178 destpart = parentPart();
1179 }
1180 else if (target == "_self" || target == "_blank") {
1181 // we always allow these
1182 }
1183 else {
1184 destpart = findFrame(target);
1185 if (!destpart)
1186 destpart = this;
1187 }
1188
1189 // easy way out?
1190 if (destpart == this)
1191 return executeScript(DOM::Node(), script);
1192
1193 // now compare the domains
1194 if (destpart->checkFrameAccess(this))
1195 return destpart->executeScript(DOM::Node(), script);
1196
1197 // eww, something went wrong. better execute it in our frame
1198 return executeScript(DOM::Node(), script);
1199}
1200
1201//Enable this to see all JS scripts being executed
1202//#define KJS_VERBOSE
1203
1204KJSErrorDlg *KHTMLPart::jsErrorExtension() {
1205 if (!d->m_settings->jsErrorsEnabled()) {
1206 return 0L;
1207 }
1208
1209 if (parentPart()) {
1210 return parentPart()->jsErrorExtension();
1211 }
1212
1213 if (!d->m_statusBarJSErrorLabel) {
1214 d->m_statusBarJSErrorLabel = new KUrlLabel(d->m_statusBarExtension->statusBar());
1215 d->m_statusBarJSErrorLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum));
1216 d->m_statusBarJSErrorLabel->setUseCursor(false);
1217 d->m_statusBarExtension->addStatusBarItem(d->m_statusBarJSErrorLabel, 0, false);
1218 d->m_statusBarJSErrorLabel->setToolTip(i18n("This web page contains coding errors."));
1219 d->m_statusBarJSErrorLabel->setPixmap(SmallIcon("script-error"));
1220 connect(d->m_statusBarJSErrorLabel, SIGNAL(leftClickedUrl()), SLOT(launchJSErrorDialog()));
1221 connect(d->m_statusBarJSErrorLabel, SIGNAL(rightClickedUrl()), SLOT(jsErrorDialogContextMenu()));
1222 }
1223 if (!d->m_jsedlg) {
1224 d->m_jsedlg = new KJSErrorDlg;
1225 d->m_jsedlg->setURL(url().prettyUrl());
1226 if (KGlobalSettings::showIconsOnPushButtons()) {
1227 d->m_jsedlg->_clear->setIcon(KIcon("edit-clear-locationbar-ltr"));
1228 d->m_jsedlg->_close->setIcon(KIcon("window-close"));
1229 }
1230 }
1231 return d->m_jsedlg;
1232}
1233
1234void KHTMLPart::removeJSErrorExtension() {
1235 if (parentPart()) {
1236 parentPart()->removeJSErrorExtension();
1237 return;
1238 }
1239 if (d->m_statusBarJSErrorLabel != 0) {
1240 d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarJSErrorLabel );
1241 delete d->m_statusBarJSErrorLabel;
1242 d->m_statusBarJSErrorLabel = 0;
1243 }
1244 delete d->m_jsedlg;
1245 d->m_jsedlg = 0;
1246}
1247
1248void KHTMLPart::disableJSErrorExtension() {
1249 removeJSErrorExtension();
1250 // These two lines are really kind of hacky, and it sucks to do this inside
1251 // KHTML but I don't know of anything that's reasonably easy as an alternative
1252 // right now. It makes me wonder if there should be a more clean way to
1253 // contact all running "KHTML" instance as opposed to Konqueror instances too.
1254 d->m_settings->setJSErrorsEnabled(false);
1255 emit configurationChanged();
1256}
1257
1258void KHTMLPart::jsErrorDialogContextMenu() {
1259 KMenu *m = new KMenu(0L);
1260 m->addAction(i18n("&Hide Errors"), this, SLOT(removeJSErrorExtension()));
1261 m->addAction(i18n("&Disable Error Reporting"), this, SLOT(disableJSErrorExtension()));
1262 m->popup(QCursor::pos());
1263}
1264
1265void KHTMLPart::launchJSErrorDialog() {
1266 KJSErrorDlg *dlg = jsErrorExtension();
1267 if (dlg) {
1268 dlg->show();
1269 dlg->raise();
1270 }
1271}
1272
1273void KHTMLPart::launchJSConfigDialog() {
1274 QStringList args;
1275 args << "khtml_java_js";
1276 KToolInvocation::kdeinitExec( "kcmshell4", args );
1277}
1278
1279QVariant KHTMLPart::executeScript(const QString& filename, int baseLine, const DOM::Node& n, const QString& script)
1280{
1281#ifdef KJS_VERBOSE
1282 // The script is now printed by KJS's Parser::parse
1283 kDebug(6070) << "executeScript: caller='" << objectName() << "' filename=" << filename << " baseLine=" << baseLine /*<< " script=" << script*/;
1284#endif
1285 KJSProxy *proxy = jScript();
1286
1287 if (!proxy || proxy->paused())
1288 return QVariant();
1289
1290 KJS::Completion comp;
1291 QVariant ret = proxy->evaluate(filename, baseLine, script, n, &comp);
1292
1293 /*
1294 * Error handling
1295 */
1296 if (comp.complType() == KJS::Throw && comp.value()) {
1297 KJSErrorDlg *dlg = jsErrorExtension();
1298 if (dlg) {
1299 QString msg = KJSDebugger::DebugWindow::exceptionToString(
1300 proxy->interpreter()->globalExec(), comp.value());
1301 dlg->addError(i18n("<qt><b>Error</b>: %1: %2</qt>",
1302 Qt::escape(filename), Qt::escape(msg)));
1303 }
1304 }
1305
1306 // Handle immediate redirects now (e.g. location='foo')
1307 if ( !d->m_redirectURL.isEmpty() && d->m_delayRedirect == -1 )
1308 {
1309 kDebug(6070) << "executeScript done, handling immediate redirection NOW";
1310 // Must abort tokenizer, no further script must execute.
1311 khtml::Tokenizer* t = d->m_doc->tokenizer();
1312 if(t)
1313 t->abort();
1314 d->m_redirectionTimer.setSingleShot( true );
1315 d->m_redirectionTimer.start( 0 );
1316 }
1317
1318 return ret;
1319}
1320
1321QVariant KHTMLPart::executeScript( const QString &script )
1322{
1323 return executeScript( DOM::Node(), script );
1324}
1325
1326QVariant KHTMLPart::executeScript( const DOM::Node &n, const QString &script )
1327{
1328#ifdef KJS_VERBOSE
1329 kDebug(6070) << "caller=" << objectName() << "node=" << n.nodeName().string().toLatin1().constData() << "(" << (n.isNull() ? 0 : n.nodeType()) << ") " /* << script */;
1330#endif
1331 KJSProxy *proxy = jScript();
1332
1333 if (!proxy || proxy->paused())
1334 return QVariant();
1335
1336 ++(d->m_runningScripts);
1337 KJS::Completion comp;
1338 const QVariant ret = proxy->evaluate( QString(), 1, script, n, &comp );
1339 --(d->m_runningScripts);
1340
1341 /*
1342 * Error handling
1343 */
1344 if (comp.complType() == KJS::Throw && comp.value()) {
1345 KJSErrorDlg *dlg = jsErrorExtension();
1346 if (dlg) {
1347 QString msg = KJSDebugger::DebugWindow::exceptionToString(
1348 proxy->interpreter()->globalExec(), comp.value());
1349 dlg->addError(i18n("<qt><b>Error</b>: node %1: %2</qt>",
1350 n.nodeName().string(), Qt::escape(msg)));
1351 }
1352 }
1353
1354 if (!d->m_runningScripts && d->m_doc && !d->m_doc->parsing() && d->m_submitForm )
1355 submitFormAgain();
1356
1357#ifdef KJS_VERBOSE
1358 kDebug(6070) << "done";
1359#endif
1360 return ret;
1361}
1362
1363void KHTMLPart::setJavaEnabled( bool enable )
1364{
1365 d->m_bJavaForce = enable;
1366 d->m_bJavaOverride = true;
1367}
1368
1369bool KHTMLPart::javaEnabled() const
1370{
1371 if (onlyLocalReferences()) return false;
1372
1373#ifndef Q_WS_QWS
1374 if( d->m_bJavaOverride )
1375 return d->m_bJavaForce;
1376 return d->m_bJavaEnabled;
1377#else
1378 return false;
1379#endif
1380}
1381
1382void KHTMLPart::setPluginsEnabled( bool enable )
1383{
1384 d->m_bPluginsForce = enable;
1385 d->m_bPluginsOverride = true;
1386}
1387
1388bool KHTMLPart::pluginsEnabled() const
1389{
1390 if (onlyLocalReferences()) return false;
1391
1392 if ( d->m_bPluginsOverride )
1393 return d->m_bPluginsForce;
1394 return d->m_bPluginsEnabled;
1395}
1396
1397static int s_DOMTreeIndentLevel = 0;
1398
1399void KHTMLPart::slotDebugDOMTree()
1400{
1401 if ( d->m_doc )
1402 qDebug("%s", d->m_doc->toString().string().toLatin1().constData());
1403
1404 // Now print the contents of the frames that contain HTML
1405
1406 const int indentLevel = s_DOMTreeIndentLevel++;
1407
1408 ConstFrameIt it = d->m_frames.constBegin();
1409 const ConstFrameIt end = d->m_frames.constEnd();
1410 for (; it != end; ++it )
1411 if ( !( *it )->m_part.isNull() && (*it)->m_part.data()->inherits( "KHTMLPart" ) ) {
1412 KParts::ReadOnlyPart* const p = ( *it )->m_part.data();
1413 kDebug(6050) << QString().leftJustified(s_DOMTreeIndentLevel*4,' ') << "FRAME " << p->objectName() << " ";
1414 static_cast<KHTMLPart*>( p )->slotDebugDOMTree();
1415 }
1416 s_DOMTreeIndentLevel = indentLevel;
1417}
1418
1419void KHTMLPart::slotDebugScript()
1420{
1421 if (jScript())
1422 jScript()->showDebugWindow();
1423}
1424
1425void KHTMLPart::slotDebugRenderTree()
1426{
1427#ifndef NDEBUG
1428 if ( d->m_doc ) {
1429 d->m_doc->renderer()->printTree();
1430 // dump out the contents of the rendering & DOM trees
1431// QString dumps;
1432// QTextStream outputStream(&dumps,QIODevice::WriteOnly);
1433// d->m_doc->renderer()->layer()->dump( outputStream );
1434// kDebug() << "dump output:" << "\n" + dumps;
1435// d->m_doc->renderer()->printLineBoxTree();
1436 }
1437#endif
1438}
1439
1440void KHTMLPart::slotDebugFrameTree()
1441{
1442 khtml::ChildFrame::dumpFrameTree(this);
1443}
1444
1445void KHTMLPart::slotStopAnimations()
1446{
1447 stopAnimations();
1448}
1449
1450void KHTMLPart::setAutoloadImages( bool enable )
1451{
1452 if ( d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable )
1453 return;
1454
1455 if ( d->m_doc )
1456 d->m_doc->docLoader()->setAutoloadImages( enable );
1457
1458 unplugActionList( "loadImages" );
1459
1460 if ( enable ) {
1461 delete d->m_paLoadImages;
1462 d->m_paLoadImages = 0;
1463 }
1464 else if ( !d->m_paLoadImages ) {
1465 d->m_paLoadImages = new KAction( i18n( "Display Images on Page" ), this );
1466 actionCollection()->addAction( "loadImages", d->m_paLoadImages );
1467 d->m_paLoadImages->setIcon( KIcon( "image-loading" ) );
1468 connect( d->m_paLoadImages, SIGNAL(triggered(bool)), this, SLOT(slotLoadImages()) );
1469 }
1470
1471 if ( d->m_paLoadImages ) {
1472 QList<QAction*> lst;
1473 lst.append( d->m_paLoadImages );
1474 plugActionList( "loadImages", lst );
1475 }
1476}
1477
1478bool KHTMLPart::autoloadImages() const
1479{
1480 if ( d->m_doc )
1481 return d->m_doc->docLoader()->autoloadImages();
1482
1483 return true;
1484}
1485
1486void KHTMLPart::clear()
1487{
1488 if ( d->m_bCleared )
1489 return;
1490
1491 d->m_bCleared = true;
1492
1493 d->m_bClearing = true;
1494
1495 {
1496 ConstFrameIt it = d->m_frames.constBegin();
1497 const ConstFrameIt end = d->m_frames.constEnd();
1498 for(; it != end; ++it )
1499 {
1500 // Stop HTMLRun jobs for frames
1501 if ( (*it)->m_run )
1502 (*it)->m_run.data()->abort();
1503 }
1504 }
1505
1506 {
1507 ConstFrameIt it = d->m_objects.constBegin();
1508 const ConstFrameIt end = d->m_objects.constEnd();
1509 for(; it != end; ++it )
1510 {
1511 // Stop HTMLRun jobs for objects
1512 if ( (*it)->m_run )
1513 (*it)->m_run.data()->abort();
1514 }
1515 }
1516
1517
1518 findTextBegin(); // resets d->m_findNode and d->m_findPos
1519 d->m_mousePressNode = DOM::Node();
1520
1521
1522 if ( d->m_doc )
1523 {
1524 if (d->m_doc->attached()) //the view may have detached it already
1525 d->m_doc->detach();
1526 }
1527
1528 // Moving past doc so that onUnload works.
1529 if ( d->m_frame && d->m_frame->m_jscript )
1530 d->m_frame->m_jscript->clear();
1531
1532 // stopping marquees
1533 if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->layer())
1534 d->m_doc->renderer()->layer()->suspendMarquees();
1535
1536 if ( d->m_view )
1537 d->m_view->clear();
1538
1539 // do not dereference the document before the jscript and view are cleared, as some destructors
1540 // might still try to access the document.
1541 if ( d->m_doc ) {
1542 d->m_doc->deref();
1543 }
1544 d->m_doc = 0;
1545
1546 delete d->m_decoder;
1547 d->m_decoder = 0;
1548
1549 // We don't want to change between parts if we are going to delete all of them anyway
1550 if (partManager()) {
1551 disconnect( partManager(), SIGNAL(activePartChanged(KParts::Part*)),
1552 this, SLOT(slotActiveFrameChanged(KParts::Part*)) );
1553 }
1554
1555 if (d->m_frames.count())
1556 {
1557 const KHTMLFrameList frames = d->m_frames;
1558 d->m_frames.clear();
1559 ConstFrameIt it = frames.begin();
1560 const ConstFrameIt end = frames.end();
1561 for(; it != end; ++it )
1562 {
1563 if ( (*it)->m_part )
1564 {
1565 partManager()->removePart( (*it)->m_part.data() );
1566 delete (*it)->m_part.data();
1567 }
1568 delete *it;
1569 }
1570 }
1571 d->m_suppressedPopupOriginParts.clear();
1572
1573 if (d->m_objects.count())
1574 {
1575 KHTMLFrameList objects = d->m_objects;
1576 d->m_objects.clear();
1577 ConstFrameIt oi = objects.constBegin();
1578 const ConstFrameIt oiEnd = objects.constEnd();
1579
1580 for (; oi != oiEnd; ++oi )
1581 {
1582 delete (*oi)->m_part.data();
1583 delete *oi;
1584 }
1585 }
1586
1587 // Listen to part changes again
1588 if (partManager()) {
1589 connect( partManager(), SIGNAL(activePartChanged(KParts::Part*)),
1590 this, SLOT(slotActiveFrameChanged(KParts::Part*)) );
1591 }
1592
1593 d->clearRedirection();
1594 d->m_redirectLockHistory = true;
1595 d->m_bClearing = false;
1596 d->m_frameNameId = 1;
1597 d->m_bFirstData = true;
1598
1599 d->m_bMousePressed = false;
1600
1601 if (d->editor_context.m_caretBlinkTimer >= 0)
1602 killTimer(d->editor_context.m_caretBlinkTimer);
1603 d->editor_context.reset();
1604#ifndef QT_NO_CLIPBOARD
1605 connect( qApp->clipboard(), SIGNAL(selectionChanged()), SLOT(slotClearSelection()));
1606#endif
1607
1608 d->m_jobPercent = 0;
1609
1610 if ( !d->m_haveEncoding )
1611 d->m_encoding.clear();
1612
1613 d->m_DNSPrefetchQueue.clear();
1614 if (d->m_DNSPrefetchTimer > 0)
1615 killTimer(d->m_DNSPrefetchTimer);
1616 d->m_DNSPrefetchTimer = -1;
1617 d->m_lookedupHosts.clear();
1618 if (d->m_DNSTTLTimer > 0)
1619 killTimer(d->m_DNSTTLTimer);
1620 d->m_DNSTTLTimer = -1;
1621 d->m_numDNSPrefetchedNames = 0;
1622
1623#ifdef SPEED_DEBUG
1624 d->m_parsetime.restart();
1625#endif
1626}
1627
1628bool KHTMLPart::openFile()
1629{
1630 return true;
1631}
1632
1633DOM::HTMLDocumentImpl *KHTMLPart::docImpl() const
1634{
1635 if ( d && d->m_doc && d->m_doc->isHTMLDocument() )
1636 return static_cast<HTMLDocumentImpl*>(d->m_doc);
1637 return 0;
1638}
1639
1640DOM::DocumentImpl *KHTMLPart::xmlDocImpl() const
1641{
1642 if ( d )
1643 return d->m_doc;
1644 return 0;
1645}
1646
1647void KHTMLPart::slotInfoMessage(KJob* kio_job, const QString& msg)
1648{
1649 assert(d->m_job == kio_job);
1650 Q_ASSERT(kio_job);
1651 Q_UNUSED(kio_job);
1652
1653 if (!parentPart())
1654 setStatusBarText(msg, BarDefaultText);
1655}
1656
1657void KHTMLPart::setPageSecurity( PageSecurity sec )
1658{
1659 emit d->m_extension->setPageSecurity( sec );
1660}
1661
1662void KHTMLPart::slotData( KIO::Job* kio_job, const QByteArray &data )
1663{
1664 assert ( d->m_job == kio_job );
1665 Q_ASSERT(kio_job);
1666 Q_UNUSED(kio_job);
1667
1668 //kDebug( 6050 ) << "slotData: " << data.size();
1669 // The first data ?
1670 if ( !d->m_workingURL.isEmpty() )
1671 {
1672 //kDebug( 6050 ) << "begin!";
1673
1674 // We must suspend KIO while we're inside begin() because it can cause
1675 // crashes if a window (such as kjsdebugger) goes back into the event loop,
1676 // more data arrives, and begin() gets called again (re-entered).
1677 d->m_job->suspend();
1678 begin( d->m_workingURL, arguments().xOffset(), arguments().yOffset() );
1679 d->m_job->resume();
1680
1681 // CC_Refresh means : always send the server an If-Modified-Since conditional request.
1682 // This is the default cache setting and correspond to the KCM's "Keep cache in sync".
1683 // CC_Verify means : only send a conditional request if the cache expiry date is passed.
1684 // It doesn't have a KCM setter.
1685 // We override the first to the second, except when doing a soft-reload.
1686 if (d->m_cachePolicy == KIO::CC_Refresh && !d->m_extension->browserArguments().softReload)
1687 d->m_doc->docLoader()->setCachePolicy(KIO::CC_Verify);
1688 else
1689 d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
1690
1691 d->m_workingURL = KUrl();
1692
1693 d->m_cacheId = KHTMLPageCache::self()->createCacheEntry();
1694
1695 // When the first data arrives, the metadata has just been made available
1696 d->m_httpHeaders = d->m_job->queryMetaData("HTTP-Headers");
1697 time_t cacheCreationDate = d->m_job->queryMetaData("cache-creation-date").toLong();
1698 d->m_doc->docLoader()->setCacheCreationDate(cacheCreationDate);
1699
1700 d->m_pageServices = d->m_job->queryMetaData("PageServices");
1701 d->m_pageReferrer = d->m_job->queryMetaData("referrer");
1702 d->m_ssl_in_use = (d->m_job->queryMetaData("ssl_in_use") == "TRUE");
1703
1704 {
1705 KHTMLPart *p = parentPart();
1706 if (p && p->d->m_ssl_in_use != d->m_ssl_in_use) {
1707 while (p->parentPart()) p = p->parentPart();
1708
1709 p->setPageSecurity( NotCrypted );
1710 }
1711 }
1712
1713 setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );
1714
1715 // Shouldn't all of this be done only if ssl_in_use == true ? (DF)
1716 d->m_ssl_parent_ip = d->m_job->queryMetaData("ssl_parent_ip");
1717 d->m_ssl_parent_cert = d->m_job->queryMetaData("ssl_parent_cert");
1718 d->m_ssl_peer_chain = d->m_job->queryMetaData("ssl_peer_chain");
1719 d->m_ssl_peer_ip = d->m_job->queryMetaData("ssl_peer_ip");
1720 d->m_ssl_cipher = d->m_job->queryMetaData("ssl_cipher");
1721 d->m_ssl_protocol_version = d->m_job->queryMetaData("ssl_protocol_version");
1722 d->m_ssl_cipher_used_bits = d->m_job->queryMetaData("ssl_cipher_used_bits");
1723 d->m_ssl_cipher_bits = d->m_job->queryMetaData("ssl_cipher_bits");
1724 d->m_ssl_cert_errors = d->m_job->queryMetaData("ssl_cert_errors");
1725
1726 // Check for charset meta-data
1727 QString qData = d->m_job->queryMetaData("charset");
1728 if ( !qData.isEmpty() && !d->m_haveEncoding ) // only use information if the user didn't override the settings
1729 d->m_encoding = qData;
1730
1731
1732 // Support for http-refresh
1733 qData = d->m_job->queryMetaData("http-refresh");
1734 if( !qData.isEmpty())
1735 d->m_doc->processHttpEquiv("refresh", qData);
1736
1737 // DISABLED: Support Content-Location per section 14.14 of RFC 2616.
1738 // See BR# 51185,BR# 82747
1739 /*
1740 QString baseURL = d->m_job->queryMetaData ("content-location");
1741 if (!baseURL.isEmpty())
1742 d->m_doc->setBaseURL(KUrl( d->m_doc->completeURL(baseURL) ));
1743 */
1744
1745 // Support for Content-Language
1746 QString language = d->m_job->queryMetaData("content-language");
1747 if (!language.isEmpty())
1748 d->m_doc->setContentLanguage(language);
1749
1750 if ( !url().isLocalFile() )
1751 {
1752 // Support for http last-modified
1753 d->m_lastModified = d->m_job->queryMetaData("modified");
1754 }
1755 else
1756 d->m_lastModified.clear(); // done on-demand by lastModified()
1757 }
1758
1759 KHTMLPageCache::self()->addData(d->m_cacheId, data);
1760 write( data.data(), data.size() );
1761}
1762
1763void KHTMLPart::slotRestoreData(const QByteArray &data )
1764{
1765 // The first data ?
1766 if ( !d->m_workingURL.isEmpty() )
1767 {
1768 long saveCacheId = d->m_cacheId;
1769 QString savePageReferrer = d->m_pageReferrer;
1770 QString saveEncoding = d->m_encoding;
1771 begin( d->m_workingURL, arguments().xOffset(), arguments().yOffset() );
1772 d->m_encoding = saveEncoding;
1773 d->m_pageReferrer = savePageReferrer;
1774 d->m_cacheId = saveCacheId;
1775 d->m_workingURL = KUrl();
1776 }
1777
1778 //kDebug( 6050 ) << data.size();
1779 write( data.data(), data.size() );
1780
1781 if (data.size() == 0)
1782 {
1783 //kDebug( 6050 ) << "<<end of data>>";
1784 // End of data.
1785 if (d->m_doc && d->m_doc->parsing())
1786 end(); //will emit completed()
1787 }
1788}
1789
1790void KHTMLPart::showError( KJob* job )
1791{
1792 kDebug(6050) << "d->m_bParsing=" << (d->m_doc && d->m_doc->parsing()) << " d->m_bComplete=" << d->m_bComplete
1793 << " d->m_bCleared=" << d->m_bCleared;
1794
1795 if (job->error() == KIO::ERR_NO_CONTENT)
1796 return;
1797
1798 if ( (d->m_doc && d->m_doc->parsing()) || d->m_workingURL.isEmpty() ) // if we got any data already
1799 job->uiDelegate()->showErrorMessage();
1800 else
1801 {
1802 htmlError( job->error(), job->errorText(), d->m_workingURL );
1803 }
1804}
1805
1806// This is a protected method, placed here because of it's relevance to showError
1807void KHTMLPart::htmlError( int errorCode, const QString& text, const KUrl& reqUrl )
1808{
1809 kDebug(6050) << "errorCode" << errorCode << "text" << text;
1810 // make sure we're not executing any embedded JS
1811 bool bJSFO = d->m_bJScriptForce;
1812 bool bJSOO = d->m_bJScriptOverride;
1813 d->m_bJScriptForce = false;
1814 d->m_bJScriptOverride = true;
1815 begin();
1816
1817 QString errorName, techName, description;
1818 QStringList causes, solutions;
1819
1820 QByteArray raw = KIO::rawErrorDetail( errorCode, text, &reqUrl );
1821 QDataStream stream(raw);
1822
1823 stream >> errorName >> techName >> description >> causes >> solutions;
1824
1825 QString url, protocol, datetime;
1826
1827 // This is somewhat confusing, but we have to escape the externally-
1828 // controlled URL twice: once for i18n, and once for HTML.
1829 url = Qt::escape( Qt::escape( reqUrl.prettyUrl() ) );
1830 protocol = reqUrl.protocol();
1831 datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
1832 KLocale::LongDate );
1833
1834 QString filename( KStandardDirs::locate( "data", "khtml/error.html" ) );
1835 QFile file( filename );
1836 bool isOpened = file.open( QIODevice::ReadOnly );
1837 if ( !isOpened )
1838 kWarning(6050) << "Could not open error html template:" << filename;
1839
1840 QString html = QString( QLatin1String( file.readAll() ) );
1841
1842 html.replace( QLatin1String( "TITLE" ), i18n( "Error: %1 - %2", errorName, url ) );
1843 html.replace( QLatin1String( "DIRECTION" ), QApplication::isRightToLeft() ? "rtl" : "ltr" );
1844 html.replace( QLatin1String( "ICON_PATH" ), KIconLoader::global()->iconPath( "dialog-warning", -KIconLoader::SizeHuge ) );
1845
1846 QString doc = QLatin1String( "<h1>" );
1847 doc += i18n( "The requested operation could not be completed" );
1848 doc += QLatin1String( "</h1><h2>" );
1849 doc += errorName;
1850 doc += QLatin1String( "</h2>" );
1851 if ( !techName.isNull() ) {
1852 doc += QLatin1String( "<h2>" );
1853 doc += i18n( "Technical Reason: " );
1854 doc += techName;
1855 doc += QLatin1String( "</h2>" );
1856 }
1857 doc += QLatin1String( "<br clear=\"all\">" );
1858 doc += QLatin1String( "<h3>" );
1859 doc += i18n( "Details of the Request:" );
1860 doc += QLatin1String( "</h3><ul><li>" );
1861 doc += i18n( "URL: %1" , url );
1862 doc += QLatin1String( "</li><li>" );
1863 if ( !protocol.isNull() ) {
1864 doc += i18n( "Protocol: %1", protocol );
1865 doc += QLatin1String( "</li><li>" );
1866 }
1867 doc += i18n( "Date and Time: %1" , datetime );
1868 doc += QLatin1String( "</li><li>" );
1869 doc += i18n( "Additional Information: %1" , text );
1870 doc += QLatin1String( "</li></ul><h3>" );
1871 doc += i18n( "Description:" );
1872 doc += QLatin1String( "</h3><p>" );
1873 doc += description;
1874 doc += QLatin1String( "</p>" );
1875 if ( causes.count() ) {
1876 doc += QLatin1String( "<h3>" );
1877 doc += i18n( "Possible Causes:" );
1878 doc += QLatin1String( "</h3><ul><li>" );
1879 doc += causes.join( "</li><li>" );
1880 doc += QLatin1String( "</li></ul>" );
1881 }
1882 if ( solutions.count() ) {
1883 doc += QLatin1String( "<h3>" );
1884 doc += i18n( "Possible Solutions:" );
1885 doc += QLatin1String( "</h3><ul><li>" );
1886 doc += solutions.join( "</li><li>" );
1887 doc += QLatin1String( "</li></ul>" );
1888 }
1889
1890 html.replace( QLatin1String("TEXT"), doc );
1891
1892 write( html );
1893 end();
1894
1895 d->m_bJScriptForce = bJSFO;
1896 d->m_bJScriptOverride = bJSOO;
1897
1898 // make the working url the current url, so that reload works and
1899 // emit the progress signals to advance one step in the history
1900 // (so that 'back' works)
1901 setUrl(reqUrl); // same as d->m_workingURL
1902 d->m_workingURL = KUrl();
1903 emit started( 0 );
1904 emit completed();
1905}
1906
1907void KHTMLPart::slotFinished( KJob * job )
1908{
1909 d->m_job = 0L;
1910 d->m_jobspeed = 0L;
1911
1912 if (job->error())
1913 {
1914 KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
1915
1916 // The following catches errors that occur as a result of HTTP
1917 // to FTP redirections where the FTP URL is a directory. Since
1918 // KIO cannot change a redirection request from GET to LISTDIR,
1919 // we have to take care of it here once we know for sure it is
1920 // a directory...
1921 if (job->error() == KIO::ERR_IS_DIRECTORY)
1922 {
1923 emit canceled( job->errorString() );
1924 emit d->m_extension->openUrlRequest( d->m_workingURL );
1925 }
1926 else
1927 {
1928 emit canceled( job->errorString() );
1929 // TODO: what else ?
1930 checkCompleted();
1931 showError( job );
1932 }
1933
1934 return;
1935 }
1936 KIO::TransferJob *tjob = ::qobject_cast<KIO::TransferJob*>(job);
1937 if (tjob && tjob->isErrorPage()) {
1938 HTMLPartContainerElementImpl *elt = d->m_frame ?
1939 d->m_frame->m_partContainerElement.data() : 0;
1940
1941 if (!elt)
1942 return;
1943
1944 elt->partLoadingErrorNotify();
1945 checkCompleted();
1946 if (d->m_bComplete) return;
1947 }
1948
1949 //kDebug( 6050 ) << "slotFinished";
1950
1951 KHTMLPageCache::self()->endData(d->m_cacheId);
1952
1953 if ( d->m_doc && d->m_doc->docLoader()->expireDate() && url().protocol().startsWith("http"))
1954 KIO::http_update_cache(url(), false, d->m_doc->docLoader()->expireDate());
1955
1956 d->m_workingURL = KUrl();
1957
1958 if ( d->m_doc && d->m_doc->parsing())
1959 end(); //will emit completed()
1960}
1961
1962MimeType KHTMLPartPrivate::classifyMimeType(const QString& mimeStr)
1963{
1964 // See HTML5's "5.5.1 Navigating across documents" section.
1965 if (mimeStr == "application/xhtml+xml")
1966 return MimeXHTML;
1967 if (mimeStr == "image/svg+xml")
1968 return MimeSVG;
1969 if (mimeStr == "text/html" || mimeStr.isEmpty())
1970 return MimeHTML;
1971
1972 KMimeType::Ptr mime = KMimeType::mimeType(mimeStr, KMimeType::ResolveAliases);
1973 if ((mime && mime->is("text/xml")) || mimeStr.endsWith("+xml"))
1974 return MimeXML;
1975
1976 if (mime && mime->is("text/plain"))
1977 return MimeText;
1978
1979 if (khtmlImLoad::ImageManager::loaderDatabase()->supportedMimeTypes().contains(mimeStr))
1980 return MimeImage;
1981
1982 // Sometimes our subclasses like to handle custom mimetypes. In that case,
1983 // we want to handle them as HTML. We do that in the following cases:
1984 // 1) We're at top-level, so we were forced to open something
1985 // 2) We're an object --- this again means we were forced to open something,
1986 // as an iframe-generating-an-embed case would have us as an iframe
1987 if (!q->parentPart() || (m_frame && m_frame->m_type == khtml::ChildFrame::Object))
1988 return MimeHTML;
1989
1990 return MimeOther;
1991}
1992
1993void KHTMLPart::begin( const KUrl &url, int xOffset, int yOffset )
1994{
1995 if ( d->m_view->underMouse() )
1996 QToolTip::hideText(); // in case a previous tooltip is still shown
1997
1998 // No need to show this for a new page until an error is triggered
1999 if (!parentPart()) {
2000 removeJSErrorExtension();
2001 setSuppressedPopupIndicator( false );
2002 d->m_openableSuppressedPopups = 0;
2003 foreach ( KHTMLPart* part, d->m_suppressedPopupOriginParts ) {
2004 if (part) {
2005 KJS::Window *w = KJS::Window::retrieveWindow( part );
2006 if (w)
2007 w->forgetSuppressedWindows();
2008 }
2009 }
2010 }
2011
2012 d->m_bCleared = false;
2013 d->m_cacheId = 0;
2014 d->m_bComplete = false;
2015 d->m_bLoadEventEmitted = false;
2016 clear();
2017 d->m_bCleared = false;
2018
2019 if(url.isValid()) {
2020 QString urlString = url.url();
2021 KHTMLGlobal::vLinks()->insert( urlString );
2022 QString urlString2 = url.prettyUrl();
2023 if ( urlString != urlString2 ) {
2024 KHTMLGlobal::vLinks()->insert( urlString2 );
2025 }
2026 }
2027
2028 // ###
2029 //stopParser();
2030
2031 KParts::OpenUrlArguments args = arguments();
2032 args.setXOffset(xOffset);
2033 args.setYOffset(yOffset);
2034 setArguments(args);
2035
2036 d->m_pageReferrer.clear();
2037 d->m_referrer = url.protocol().startsWith("http") ? url.url() : "";
2038
2039 setUrl(url);
2040
2041 // Note: by now, any special mimetype besides plaintext would have been
2042 // handled specially inside openURL, so we handle their cases the same
2043 // as HTML.
2044 MimeType type = d->classifyMimeType(args.mimeType());
2045 switch (type) {
2046 case MimeSVG:
2047 d->m_doc = DOMImplementationImpl::createSVGDocument( d->m_view );
2048 break;
2049 case MimeXML: // any XML derivative, except XHTML or SVG
2050 // ### not sure if XHTML documents served as text/xml should use DocumentImpl or HTMLDocumentImpl
2051 d->m_doc = DOMImplementationImpl::createXMLDocument( d->m_view );
2052 break;
2053 case MimeText:
2054 d->m_doc = new HTMLTextDocumentImpl( d->m_view );
2055 break;
2056 case MimeXHTML:
2057 case MimeHTML:
2058 default:
2059 d->m_doc = DOMImplementationImpl::createHTMLDocument( d->m_view );
2060 // HTML or XHTML? (#86446)
2061 static_cast<HTMLDocumentImpl *>(d->m_doc)->setHTMLRequested( type != MimeXHTML );
2062 }
2063
2064 d->m_doc->ref();
2065 d->m_doc->setURL( url.url() );
2066 d->m_doc->open( );
2067 if (!d->m_doc->attached())
2068 d->m_doc->attach( );
2069 d->m_doc->setBaseURL( KUrl() );
2070 d->m_doc->docLoader()->setShowAnimations( KHTMLGlobal::defaultHTMLSettings()->showAnimations() );
2071 emit docCreated();
2072
2073 d->m_paUseStylesheet->setItems(QStringList());
2074 d->m_paUseStylesheet->setEnabled( false );
2075
2076 setAutoloadImages( KHTMLGlobal::defaultHTMLSettings()->autoLoadImages() );
2077 QString userStyleSheet = KHTMLGlobal::defaultHTMLSettings()->userStyleSheet();
2078 if ( !userStyleSheet.isEmpty() )
2079 setUserStyleSheet( KUrl( userStyleSheet ) );
2080
2081 d->m_doc->setRestoreState(d->m_extension->browserArguments().docState);
2082 connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
2083
2084 emit d->m_extension->enableAction( "print", true );
2085
2086 d->m_doc->setParsing(true);
2087}
2088
2089void KHTMLPart::write( const char *data, int len )
2090{
2091 if ( !d->m_decoder )
2092 d->m_decoder = createDecoder();
2093
2094 if ( len == -1 )
2095 len = strlen( data );
2096
2097 if ( len == 0 )
2098 return;
2099
2100 QString decoded=d->m_decoder->decodeWithBuffering(data,len);
2101
2102 if(decoded.isEmpty())
2103 return;
2104
2105 if(d->m_bFirstData)
2106 onFirstData();
2107
2108 khtml::Tokenizer* t = d->m_doc->tokenizer();
2109 if(t)
2110 t->write( decoded, true );
2111}
2112
2113// ### KDE5: remove
2114void KHTMLPart::setAlwaysHonourDoctype( bool b )
2115{
2116 d->m_bStrictModeQuirk = !b;
2117}
2118
2119void KHTMLPart::write( const QString &str )
2120{
2121 if ( str.isNull() )
2122 return;
2123
2124 if(d->m_bFirstData) {
2125 // determine the parse mode
2126 if (d->m_bStrictModeQuirk) {
2127 d->m_doc->setParseMode( DocumentImpl::Strict );
2128 d->m_bFirstData = false;
2129 } else {
2130 onFirstData();
2131 }
2132 }
2133 khtml::Tokenizer* t = d->m_doc->tokenizer();
2134 if(t)
2135 t->write( str, true );
2136}
2137
2138void KHTMLPart::end()
2139{
2140 if (d->m_doc) {
2141 if (d->m_decoder)
2142 {
2143 QString decoded=d->m_decoder->flush();
2144 if (d->m_bFirstData)
2145 onFirstData();
2146 if (!decoded.isEmpty())
2147 write(decoded);
2148 }
2149 d->m_doc->finishParsing();
2150 }
2151}
2152
2153void KHTMLPart::onFirstData()
2154{
2155 assert( d->m_bFirstData );
2156
2157 // determine the parse mode
2158 d->m_doc->determineParseMode();
2159 d->m_bFirstData = false;
2160
2161 // ### this is still quite hacky, but should work a lot better than the old solution
2162 // Note: decoder may be null if only write(QString) is used.
2163 if (d->m_decoder && d->m_decoder->visuallyOrdered())
2164 d->m_doc->setVisuallyOrdered();
2165 // ensure part and view shares zoom-level before styling
2166 updateZoomFactor();
2167 d->m_doc->recalcStyle( NodeImpl::Force );
2168}
2169
2170bool KHTMLPart::doOpenStream( const QString& mimeType )
2171{
2172 KMimeType::Ptr mime = KMimeType::mimeType(mimeType, KMimeType::ResolveAliases);
2173 if ( mime && ( mime->is( "text/html" ) || mime->is( "text/xml" ) ) )
2174 {
2175 begin( url() );
2176 return true;
2177 }
2178 return false;
2179}
2180
2181bool KHTMLPart::doWriteStream( const QByteArray& data )
2182{
2183 write( data.data(), data.size() );
2184 return true;
2185}
2186
2187bool KHTMLPart::doCloseStream()
2188{
2189 end();
2190 return true;
2191}
2192
2193
2194void KHTMLPart::paint(QPainter *p, const QRect &rc, int yOff, bool *more)
2195{
2196 if (!d->m_view) return;
2197 d->m_view->paint(p, rc, yOff, more);
2198}
2199
2200void KHTMLPart::stopAnimations()
2201{
2202 if ( d->m_doc )
2203 d->m_doc->docLoader()->setShowAnimations( KHTMLSettings::KAnimationDisabled );
2204
2205 ConstFrameIt it = d->m_frames.constBegin();
2206 const ConstFrameIt end = d->m_frames.constEnd();
2207 for (; it != end; ++it ) {
2208 if ( KHTMLPart* p = qobject_cast<KHTMLPart*>((*it)->m_part.data()) )
2209 p->stopAnimations();
2210 }
2211}
2212
2213void KHTMLPart::resetFromScript()
2214{
2215 closeUrl();
2216 d->m_bComplete = false;
2217 d->m_bLoadEventEmitted = false;
2218 disconnect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
2219 connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
2220 d->m_doc->setParsing(true);
2221
2222 emit started( 0L );
2223}
2224
2225void KHTMLPart::slotFinishedParsing()
2226{
2227 d->m_doc->setParsing(false);
2228 d->m_doc->dispatchHTMLEvent(EventImpl::KHTML_CONTENTLOADED_EVENT, true, false);
2229 checkEmitLoadEvent();
2230 disconnect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
2231
2232 if (!d->m_view)
2233 return; // We are probably being destructed.
2234
2235 checkCompleted();
2236}
2237
2238void KHTMLPart::slotLoaderRequestStarted( khtml::DocLoader* dl, khtml::CachedObject *obj )
2239{
2240 if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
2241 KHTMLPart* p = this;
2242 while ( p ) {
2243 KHTMLPart* const op = p;
2244 ++(p->d->m_totalObjectCount);
2245 p = p->parentPart();
2246 if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount
2247 && !op->d->m_progressUpdateTimer.isActive()) {
2248 op->d->m_progressUpdateTimer.setSingleShot( true );
2249 op->d->m_progressUpdateTimer.start( 200 );
2250 }
2251 }
2252 }
2253}
2254
2255static bool isAncestorOrSamePart(KHTMLPart* p1, KHTMLPart* p2)
2256{
2257 KHTMLPart* p = p2;
2258 do {
2259 if (p == p1)
2260 return true;
2261 } while ((p = p->parentPart()));
2262 return false;
2263}
2264
2265void KHTMLPart::slotLoaderRequestDone( khtml::DocLoader* dl, khtml::CachedObject *obj )
2266{
2267 if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
2268 KHTMLPart* p = this;
2269 while ( p ) {
2270 KHTMLPart* const op = p;
2271 ++(p->d->m_loadedObjects);
2272 p = p->parentPart();
2273 if ( !p && op->d->m_loadedObjects <= op->d->m_totalObjectCount && op->d->m_jobPercent <= 100
2274 && !op->d->m_progressUpdateTimer.isActive()) {
2275 op->d->m_progressUpdateTimer.setSingleShot( true );
2276 op->d->m_progressUpdateTimer.start( 200 );
2277 }
2278 }
2279 }
2281 // then our loading state can't possibly be affected : don't waste time checking for completion.
2282 if (!d->m_doc || !dl->doc()->part() || !isAncestorOrSamePart(this, dl->doc()->part()))
2283 return;
2284 checkCompleted();
2285}
2286
2287void KHTMLPart::slotProgressUpdate()
2288{
2289 int percent;
2290 if ( d->m_loadedObjects < d->m_totalObjectCount )
2291 percent = d->m_jobPercent / 4 + ( d->m_loadedObjects*300 ) / ( 4*d->m_totalObjectCount );
2292 else
2293 percent = d->m_jobPercent;
2294
2295 if( d->m_bComplete )
2296 percent = 100;
2297
2298 if (d->m_statusMessagesEnabled) {
2299 if( d->m_bComplete )
2300 emit d->m_extension->infoMessage( i18n( "Page loaded." ));
2301 else if ( d->m_loadedObjects < d->m_totalObjectCount && percent >= 75 )
2302 emit d->m_extension->infoMessage( i18np( "%1 Image of %2 loaded.", "%1 Images of %2 loaded.", d->m_loadedObjects, d->m_totalObjectCount) );
2303 }
2304
2305 emit d->m_extension->loadingProgress( percent );
2306}
2307
2308void KHTMLPart::slotJobSpeed( KJob* /*job*/, unsigned long speed )
2309{
2310 d->m_jobspeed = speed;
2311 if (!parentPart())
2312 setStatusBarText(jsStatusBarText(), BarOverrideText);
2313}
2314
2315void KHTMLPart::slotJobPercent( KJob* /*job*/, unsigned long percent )
2316{
2317 d->m_jobPercent = percent;
2318
2319 if ( !parentPart() ) {
2320 d->m_progressUpdateTimer.setSingleShot( true );
2321 d->m_progressUpdateTimer.start( 0 );
2322 }
2323}
2324
2325void KHTMLPart::slotJobDone( KJob* /*job*/ )
2326{
2327 d->m_jobPercent = 100;
2328
2329 if ( !parentPart() ) {
2330 d->m_progressUpdateTimer.setSingleShot( true );
2331 d->m_progressUpdateTimer.start( 0 );
2332 }
2333}
2334
2335void KHTMLPart::slotUserSheetStatDone( KJob *_job )
2336{
2337 using namespace KIO;
2338
2339 if ( _job->error() ) {
2340 showError( _job );
2341 return;
2342 }
2343
2344 const UDSEntry entry = dynamic_cast<KIO::StatJob *>( _job )->statResult();
2345 const time_t lastModified = entry.numberValue( KIO::UDSEntry::UDS_MODIFICATION_TIME, -1 );
2346
2347 // If the filesystem supports modification times, only reload the
2348 // user-defined stylesheet if necessary - otherwise always reload.
2349 if ( lastModified != static_cast<time_t>(-1) ) {
2350 if ( d->m_userStyleSheetLastModified >= lastModified ) {
2351 return;
2352 }
2353 d->m_userStyleSheetLastModified = lastModified;
2354 }
2355
2356 setUserStyleSheet( KUrl( settings()->userStyleSheet() ) );
2357}
2358
2359bool KHTMLPartPrivate::isFullyLoaded(bool* pendingRedirections) const
2360{
2361 *pendingRedirections = false;
2362
2363 // Any frame that hasn't completed yet ?
2364 ConstFrameIt it = m_frames.constBegin();
2365 const ConstFrameIt end = m_frames.constEnd();
2366 for (; it != end; ++it ) {
2367 if ( !(*it)->m_bCompleted || (*it)->m_run )
2368 {
2369 //kDebug( 6050 ) << this << " is waiting for " << (*it)->m_part;
2370 return false;
2371 }
2372 // Check for frames with pending redirections
2373 if ( (*it)->m_bPendingRedirection )
2374 *pendingRedirections = true;
2375 }
2376
2377 // Any object that hasn't completed yet ?
2378 {
2379 ConstFrameIt oi = m_objects.constBegin();
2380 const ConstFrameIt oiEnd = m_objects.constEnd();
2381
2382 for (; oi != oiEnd; ++oi )
2383 if ( !(*oi)->m_bCompleted )
2384 return false;
2385 }
2386
2387 // Are we still parsing
2388 if ( m_doc && m_doc->parsing() )
2389 return false;
2390
2391 // Still waiting for images/scripts from the loader ?
2392 int requests = 0;
2393 if ( m_doc && m_doc->docLoader() )
2394 requests = khtml::Cache::loader()->numRequests( m_doc->docLoader() );
2395
2396 if ( requests > 0 )
2397 {
2398 //kDebug(6050) << "still waiting for images/scripts from the loader - requests:" << requests;
2399 return false;
2400 }
2401
2402 return true;
2403}
2404
2405void KHTMLPart::checkCompleted()
2406{
2407// kDebug( 6050 ) << this;
2408// kDebug( 6050 ) << " parsing: " << (d->m_doc && d->m_doc->parsing());
2409// kDebug( 6050 ) << " complete: " << d->m_bComplete;
2410
2411 // restore the cursor position
2412 if (d->m_doc && !d->m_doc->parsing() && !d->m_focusNodeRestored)
2413 {
2414 if (d->m_focusNodeNumber >= 0)
2415 d->m_doc->setFocusNode(d->m_doc->nodeWithAbsIndex(d->m_focusNodeNumber));
2416
2417 d->m_focusNodeRestored = true;
2418 }
2419
2420 bool fullyLoaded, pendingChildRedirections;
2421 fullyLoaded = d->isFullyLoaded(&pendingChildRedirections);
2422
2423 // Are we still loading, or already have done the relevant work?
2424 if (!fullyLoaded || d->m_bComplete)
2425 return;
2426
2427 // OK, completed.
2428 // Now do what should be done when we are really completed.
2429 d->m_bComplete = true;
2430 d->m_cachePolicy = KProtocolManager::cacheControl(); // reset cache policy
2431 d->m_totalObjectCount = 0;
2432 d->m_loadedObjects = 0;
2433
2434 KHTMLPart* p = this;
2435 while ( p ) {
2436 KHTMLPart* op = p;
2437 p = p->parentPart();
2438 if ( !p && !op->d->m_progressUpdateTimer.isActive()) {
2439 op->d->m_progressUpdateTimer.setSingleShot( true );
2440 op->d->m_progressUpdateTimer.start( 0 );
2441 }
2442 }
2443
2444 checkEmitLoadEvent(); // if we didn't do it before
2445
2446 bool pendingAction = false;
2447
2448 if ( !d->m_redirectURL.isEmpty() )
2449 {
2450 // DA: Do not start redirection for frames here! That action is
2451 // deferred until the parent emits a completed signal.
2452 if ( parentPart() == 0 ) {
2453 //kDebug(6050) << this << " starting redirection timer";
2454 d->m_redirectionTimer.setSingleShot( true );
2455 d->m_redirectionTimer.start( qMax(0, 1000 * d->m_delayRedirect) );
2456 } else {
2457 //kDebug(6050) << this << " not toplevel -> not starting redirection timer. Waiting for slotParentCompleted.";
2458 }
2459
2460 pendingAction = true;
2461 }
2462 else if ( pendingChildRedirections )
2463 {
2464 pendingAction = true;
2465 }
2466
2467 // the view will emit completed on our behalf,
2468 // either now or at next repaint if one is pending
2469
2470 //kDebug(6050) << this << " asks the view to emit completed. pendingAction=" << pendingAction;
2471 d->m_view->complete( pendingAction );
2472
2473 // find the alternate stylesheets
2474 QStringList sheets;
2475 if (d->m_doc)
2476 sheets = d->m_doc->availableStyleSheets();
2477 sheets.prepend( i18n( "Automatic Detection" ) );
2478 d->m_paUseStylesheet->setItems( sheets );
2479
2480 d->m_paUseStylesheet->setEnabled( sheets.count() > 2);
2481 if (sheets.count() > 2)
2482 {
2483 d->m_paUseStylesheet->setCurrentItem(qMax(sheets.indexOf(d->m_sheetUsed), 0));
2484 slotUseStylesheet();
2485 }
2486
2487 setJSDefaultStatusBarText(QString());
2488
2489#ifdef SPEED_DEBUG
2490 if (!parentPart())
2491 kDebug(6080) << "DONE:" <<d->m_parsetime.elapsed();
2492#endif
2493}
2494
2495void KHTMLPart::checkEmitLoadEvent()
2496{
2497 bool fullyLoaded, pendingChildRedirections;
2498 fullyLoaded = d->isFullyLoaded(&pendingChildRedirections);
2499
2500 // ### might want to wait on pendingChildRedirections here, too
2501 if ( d->m_bLoadEventEmitted || !d->m_doc || !fullyLoaded ) return;
2502
2503 d->m_bLoadEventEmitted = true;
2504 if (d->m_doc)
2505 d->m_doc->close();
2506}
2507
2508const KHTMLSettings *KHTMLPart::settings() const
2509{
2510 return d->m_settings;
2511}
2512
2513#ifndef KDE_NO_COMPAT // KDE5: remove this ifndef, keep the method (renamed to baseUrl)
2514KUrl KHTMLPart::baseURL() const
2515{
2516 if ( !d->m_doc ) return KUrl();
2517
2518 return d->m_doc->baseURL();
2519}
2520#endif
2521
2522KUrl KHTMLPart::completeURL( const QString &url )
2523{
2524 if ( !d->m_doc ) return KUrl( url );
2525
2526#if 0
2527 if (d->m_decoder)
2528 return KUrl(d->m_doc->completeURL(url), d->m_decoder->codec()->mibEnum());
2529#endif
2530
2531 return KUrl( d->m_doc->completeURL( url ) );
2532}
2533
2534QString KHTMLPartPrivate::codeForJavaScriptURL(const QString &u)
2535{
2536 return KUrl::fromPercentEncoding( u.right( u.length() - 11 ).toUtf8() );
2537}
2538
2539void KHTMLPartPrivate::executeJavascriptURL(const QString &u)
2540{
2541 QString script = codeForJavaScriptURL(u);
2542 kDebug( 6050 ) << "script=" << script;
2543 QVariant res = q->executeScript( DOM::Node(), script );
2544 if ( res.type() == QVariant::String ) {
2545 q->begin( q->url() );
2546 q->setAlwaysHonourDoctype(); // Disable public API compat; it messes with doctype
2547 q->write( res.toString() );
2548 q->end();
2549 }
2550 emit q->completed();
2551}
2552
2553bool KHTMLPartPrivate::isJavaScriptURL(const QString& url)
2554{
2555 return url.indexOf( QLatin1String( "javascript:" ), 0, Qt::CaseInsensitive ) == 0;
2556}
2557
2558// Called by ecma/kjs_window in case of redirections from Javascript,
2559// and by xml/dom_docimpl.cpp in case of http-equiv meta refresh.
2560void KHTMLPart::scheduleRedirection( int delay, const QString &url, bool doLockHistory )
2561{
2562 kDebug(6050) << "delay=" << delay << " url=" << url << " from=" << this->url() << "parent=" << parentPart();
2563 kDebug(6050) << "current redirectURL=" << d->m_redirectURL << " with delay " << d->m_delayRedirect;
2564
2565 // In case of JS redirections, some, such as jump to anchors, and javascript:
2566 // evaluation should actually be handled immediately, and not waiting until
2567 // the end of the script. (Besides, we don't want to abort the tokenizer for those)
2568 if ( delay == -1 && d->isInPageURL(url) ) {
2569 d->executeInPageURL(url, doLockHistory);
2570 return;
2571 }
2572
2573 if( delay < 24*60*60 &&
2574 ( d->m_redirectURL.isEmpty() || delay <= d->m_delayRedirect) ) {
2575 d->m_delayRedirect = delay;
2576 d->m_redirectURL = url;
2577 d->m_redirectLockHistory = doLockHistory;
2578 kDebug(6050) << " d->m_bComplete=" << d->m_bComplete;
2579
2580 if ( d->m_bComplete ) {
2581 d->m_redirectionTimer.stop();
2582 d->m_redirectionTimer.setSingleShot( true );
2583 d->m_redirectionTimer.start( qMax(0, 1000 * d->m_delayRedirect) );
2584 }
2585 }
2586}
2587
2588void KHTMLPartPrivate::clearRedirection()
2589{
2590 m_delayRedirect = 0;
2591 m_redirectURL.clear();
2592 m_redirectionTimer.stop();
2593}
2594
2595void KHTMLPart::slotRedirect()
2596{
2597 kDebug(6050) << this;
2598 QString u = d->m_redirectURL;
2599 KUrl url( u );
2600 d->clearRedirection();
2601
2602 if ( d->isInPageURL(u) )
2603 {
2604 d->executeInPageURL(u, d->m_redirectLockHistory);
2605 return;
2606 }
2607
2608 KParts::OpenUrlArguments args;
2609 KUrl cUrl( this->url() );
2610
2611 // handle windows opened by JS
2612 if ( openedByJS() && d->m_opener )
2613 cUrl = d->m_opener->url();
2614
2615 if (!KAuthorized::authorizeUrlAction("redirect", cUrl, url))
2616 {
2617 kWarning(6050) << "KHTMLPart::scheduleRedirection: Redirection from " << cUrl << " to " << url << " REJECTED!";
2618 emit completed();
2619 return;
2620 }
2621
2622 if ( url.equals(this->url(),
2623 KUrl::CompareWithoutTrailingSlash | KUrl::CompareWithoutFragment | KUrl::AllowEmptyPath) )
2624 {
2625 args.metaData().insert("referrer", d->m_pageReferrer);
2626 }
2627
2628 // For javascript and META-tag based redirections:
2629 // - We don't take cross-domain-ness in consideration if we are the
2630 // toplevel frame because the new URL may be in a different domain as the current URL
2631 // but that's ok.
2632 // - If we are not the toplevel frame then we check against the toplevelURL()
2633 if (parentPart())
2634 args.metaData().insert("cross-domain", toplevelURL().url());
2635
2636 KParts::BrowserArguments browserArgs;
2637 browserArgs.setLockHistory( d->m_redirectLockHistory );
2638 // _self: make sure we don't use any <base target=>'s
2639
2640 if ( !urlSelected( u, 0, 0, "_self", args, browserArgs ) ) {
2641 // urlSelected didn't open a url, so emit completed ourselves
2642 emit completed();
2643 }
2644}
2645
2646void KHTMLPart::slotRedirection(KIO::Job*, const KUrl& url)
2647{
2648 // the slave told us that we got redirected
2649 //kDebug( 6050 ) << "redirection by KIO to" << url;
2650 emit d->m_extension->setLocationBarUrl( url.prettyUrl() );
2651 d->m_workingURL = url;
2652}
2653
2654bool KHTMLPart::setEncoding( const QString &name, bool override )
2655{
2656 d->m_encoding = name;
2657 d->m_haveEncoding = override;
2658
2659 if( !url().isEmpty() ) {
2660 // reload document
2661 closeUrl();
2662 KUrl oldUrl = url();
2663 setUrl(KUrl());
2664 d->m_restored = true;
2665 openUrl(oldUrl);
2666 d->m_restored = false;
2667 }
2668
2669 return true;
2670}
2671
2672QString KHTMLPart::encoding() const
2673{
2674 if(d->m_haveEncoding && !d->m_encoding.isEmpty())
2675 return d->m_encoding;
2676
2677 if(d->m_decoder && d->m_decoder->encoding())
2678 return QString(d->m_decoder->encoding());
2679
2680 return defaultEncoding();
2681}
2682
2683QString KHTMLPart::defaultEncoding() const
2684{
2685 QString encoding = settings()->encoding();
2686 if ( !encoding.isEmpty() )
2687 return encoding;
2688 // HTTP requires the default encoding to be latin1, when neither
2689 // the user nor the page requested a particular encoding.
2690 if ( url().protocol().startsWith( "http" ) )
2691 return "iso-8859-1";
2692 else
2693 return KGlobal::locale()->encoding();
2694}
2695
2696void KHTMLPart::setUserStyleSheet(const KUrl &url)
2697{
2698 if ( d->m_doc && d->m_doc->docLoader() )
2699 (void) new khtml::PartStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
2700}
2701
2702void KHTMLPart::setUserStyleSheet(const QString &styleSheet)
2703{
2704 if ( d->m_doc )
2705 d->m_doc->setUserStyleSheet( styleSheet );
2706}
2707
2708bool KHTMLPart::gotoAnchor( const QString &name )
2709{
2710 if (!d->m_doc)
2711 return false;
2712
2713 HTMLCollectionImpl *anchors = new HTMLCollectionImpl(d->m_doc, HTMLCollectionImpl::DOC_ANCHORS);
2714 anchors->ref();
2715 NodeImpl *n = anchors->namedItem(name);
2716 anchors->deref();
2717
2718 if(!n) {
2719 n = d->m_doc->getElementById( name );
2720 }
2721
2722 d->m_doc->setCSSTarget(n); // Setting to null will clear the current target.
2723
2724 // Implement the rule that "" and "top" both mean top of page.
2725 bool top = !n && (name.isEmpty() || name.toLower() == "top");
2726
2727 if (top) {
2728 d->m_view->setContentsPos( d->m_view->contentsX(), 0);
2729 return true;
2730 } else if (!n) {
2731 kDebug(6050) << name << "not found";
2732 return false;
2733 }
2734
2735 int x = 0, y = 0;
2736 int gox, dummy;
2737 HTMLElementImpl *a = static_cast<HTMLElementImpl *>(n);
2738
2739 a->getUpperLeftCorner(x, y);
2740 if (x <= d->m_view->contentsX())
2741 gox = x - 10;
2742 else {
2743 gox = d->m_view->contentsX();
2744 if ( x + 10 > d->m_view->contentsX()+d->m_view->visibleWidth()) {
2745 a->getLowerRightCorner(x, dummy);
2746 gox = x - d->m_view->visibleWidth() + 10;
2747 }
2748 }
2749
2750 d->m_view->setContentsPos(gox, y);
2751
2752 return true;
2753}
2754
2755bool KHTMLPart::nextAnchor()
2756{
2757 if (!d->m_doc)
2758 return false;
2759 d->m_view->focusNextPrevNode ( true );
2760
2761 return true;
2762}
2763
2764bool KHTMLPart::prevAnchor()
2765{
2766 if (!d->m_doc)
2767 return false;
2768 d->m_view->focusNextPrevNode ( false );
2769
2770 return true;
2771}
2772
2773void KHTMLPart::setStandardFont( const QString &name )
2774{
2775 d->m_settings->setStdFontName(name);
2776}
2777
2778void KHTMLPart::setFixedFont( const QString &name )
2779{
2780 d->m_settings->setFixedFontName(name);
2781}
2782
2783void KHTMLPart::setURLCursor( const QCursor &c )
2784{
2785 d->m_linkCursor = c;
2786}
2787
2788QCursor KHTMLPart::urlCursor() const
2789{
2790 return d->m_linkCursor;
2791}
2792
2793bool KHTMLPart::onlyLocalReferences() const
2794{
2795 return d->m_onlyLocalReferences;
2796}
2797
2798void KHTMLPart::setOnlyLocalReferences(bool enable)
2799{
2800 d->m_onlyLocalReferences = enable;
2801}
2802
2803bool KHTMLPart::forcePermitLocalImages() const
2804{
2805 return d->m_forcePermitLocalImages;
2806}
2807
2808void KHTMLPart::setForcePermitLocalImages(bool enable)
2809{
2810 d->m_forcePermitLocalImages = enable;
2811}
2812
2813void KHTMLPartPrivate::setFlagRecursively(
2814 bool KHTMLPartPrivate::*flag, bool value)
2815{
2816 // first set it on the current one
2817 this->*flag = value;
2818
2819 // descend into child frames recursively
2820 {
2821 QList<khtml::ChildFrame*>::Iterator it = m_frames.begin();
2822 const QList<khtml::ChildFrame*>::Iterator itEnd = m_frames.end();
2823 for (; it != itEnd; ++it) {
2824 KHTMLPart* const part = qobject_cast<KHTMLPart *>( (*it)->m_part.data() );
2825 if (part)
2826 part->d->setFlagRecursively(flag, value);
2827 }/*next it*/
2828 }
2829 // do the same again for objects
2830 {
2831 QList<khtml::ChildFrame*>::Iterator it = m_objects.begin();
2832 const QList<khtml::ChildFrame*>::Iterator itEnd = m_objects.end();
2833 for (; it != itEnd; ++it) {
2834 KHTMLPart* const part = qobject_cast<KHTMLPart *>( (*it)->m_part.data() );
2835 if (part)
2836 part->d->setFlagRecursively(flag, value);
2837 }/*next it*/
2838 }
2839}
2840
2841void KHTMLPart::initCaret()
2842{
2843 // initialize caret if not used yet
2844 if (d->editor_context.m_selection.state() == Selection::NONE) {
2845 if (d->m_doc) {
2846 NodeImpl *node;
2847 if (d->m_doc->isHTMLDocument()) {
2848 HTMLDocumentImpl* htmlDoc = static_cast<HTMLDocumentImpl*>(d->m_doc);
2849 node = htmlDoc->body();
2850 } else
2851 node = d->m_doc;
2852 if (!node) return;
2853 d->editor_context.m_selection.moveTo(Position(node, 0));
2854 d->editor_context.m_selection.setNeedsLayout();
2855 d->editor_context.m_selection.needsCaretRepaint();
2856 }
2857 }
2858}
2859
2860static void setCaretInvisibleIfNeeded(KHTMLPart *part)
2861{
2862 // On contenteditable nodes, don't hide the caret
2863 if (!khtml::KHTMLPartAccessor::caret(part).caretPos().node()->isContentEditable())
2864 part->setCaretVisible(false);
2865}
2866
2867void KHTMLPart::setCaretMode(bool enable)
2868{
2869 kDebug(6200) << enable;
2870 if (isCaretMode() == enable) return;
2871 d->setFlagRecursively(&KHTMLPartPrivate::m_caretMode, enable);
2872 // FIXME: this won't work on frames as expected
2873 if (!isEditable()) {
2874 if (enable) {
2875 initCaret();
2876 setCaretVisible(true);
2877// view()->ensureCaretVisible();
2878 } else {
2879 setCaretInvisibleIfNeeded(this);
2880 }
2881 }
2882}
2883
2884bool KHTMLPart::isCaretMode() const
2885{
2886 return d->m_caretMode;
2887}
2888
2889void KHTMLPart::setEditable(bool enable)
2890{
2891 if (isEditable() == enable) return;
2892 d->setFlagRecursively(&KHTMLPartPrivate::m_designMode, enable);
2893 // FIXME: this won't work on frames as expected
2894 if (!isCaretMode()) {
2895 if (enable) {
2896 initCaret();
2897 setCaretVisible(true);
2898// view()->ensureCaretVisible();
2899 } else
2900 setCaretInvisibleIfNeeded(this);
2901 }
2902}
2903
2904bool KHTMLPart::isEditable() const
2905{
2906 return d->m_designMode;
2907}
2908
2909khtml::EditorContext *KHTMLPart::editorContext() const {
2910 return &d->editor_context;
2911}
2912
2913void KHTMLPart::setCaretPosition(DOM::Node node, long offset, bool extendSelection)
2914{
2915 Q_UNUSED(node);
2916 Q_UNUSED(offset);
2917 Q_UNUSED(extendSelection);
2918#ifndef KHTML_NO_CARET
2919#if 0
2920 kDebug(6200) << "node: " << node.handle() << " nodeName: "
2921 << node.nodeName().string() << " offset: " << offset
2922 << " extendSelection " << extendSelection;
2923 if (view()->moveCaretTo(node.handle(), offset, !extendSelection))
2924 emitSelectionChanged();
2925 view()->ensureCaretVisible();
2926#endif
2927#endif // KHTML_NO_CARET
2928}
2929
2930KHTMLPart::CaretDisplayPolicy KHTMLPart::caretDisplayPolicyNonFocused() const
2931{
2932#if 0
2933#ifndef KHTML_NO_CARET
2934 return (CaretDisplayPolicy)view()->caretDisplayPolicyNonFocused();
2935#else // KHTML_NO_CARET
2936 return CaretInvisible;
2937#endif // KHTML_NO_CARET
2938#endif
2939 return CaretInvisible;
2940}
2941
2942void KHTMLPart::setCaretDisplayPolicyNonFocused(CaretDisplayPolicy policy)
2943{
2944 Q_UNUSED(policy);
2945#if 0
2946#ifndef KHTML_NO_CARET
2947 view()->setCaretDisplayPolicyNonFocused(policy);
2948#endif // KHTML_NO_CARET
2949#endif
2950}
2951
2952void KHTMLPart::setCaretVisible(bool show)
2953{
2954 if (show) {
2955 NodeImpl *caretNode = d->editor_context.m_selection.caretPos().node();
2956 if (isCaretMode() || (caretNode && caretNode->isContentEditable())) {
2957 invalidateSelection();
2958 enableFindAheadActions(false);
2959 }
2960 } else {
2961
2962 if (d->editor_context.m_caretBlinkTimer >= 0)
2963 killTimer(d->editor_context.m_caretBlinkTimer);
2964 clearCaretRectIfNeeded();
2965
2966 }
2967}
2968
2969void KHTMLPart::findTextBegin()
2970{
2971 d->m_find.findTextBegin();
2972}
2973
2974bool KHTMLPart::initFindNode( bool selection, bool reverse, bool fromCursor )
2975{
2976 return d->m_find.initFindNode(selection, reverse, fromCursor);
2977}
2978
2979void KHTMLPart::slotFind()
2980{
2981 KParts::ReadOnlyPart *part = currentFrame();
2982 if (!part)
2983 return;
2984 if (!part->inherits("KHTMLPart") )
2985 {
2986 kError(6000) << "part is a" << part->metaObject()->className() << ", can't do a search into it";
2987 return;
2988 }
2989 static_cast<KHTMLPart *>( part )->findText();
2990}
2991
2992void KHTMLPart::slotFindNext()
2993{
2994 KParts::ReadOnlyPart *part = currentFrame();
2995 if (!part)
2996 return;
2997 if (!part->inherits("KHTMLPart") )
2998 {
2999 kError(6000) << "part is a" << part->metaObject()->className() << ", can't do a search into it";
3000 return;
3001 }
3002 static_cast<KHTMLPart *>( part )->findTextNext();
3003}
3004
3005void KHTMLPart::slotFindPrev()
3006{
3007 KParts::ReadOnlyPart *part = currentFrame();
3008 if (!part)
3009 return;
3010 if (!part->inherits("KHTMLPart") )
3011 {
3012 kError(6000) << "part is a" << part->metaObject()->className() << ", can't do a search into it";
3013 return;
3014 }
3015 static_cast<KHTMLPart *>( part )->findTextNext( true ); // reverse
3016}
3017
3018void KHTMLPart::slotFindDone()
3019{
3020 // ### remove me
3021}
3022
3023void KHTMLPart::slotFindAheadText()
3024{
3025 KHTMLPart *part = qobject_cast<KHTMLPart*>(currentFrame());
3026 if (!part)
3027 return;
3028 part->findText();
3029 KHTMLFindBar* findBar = part->d->m_find.findBar();
3030 findBar->setOptions(findBar->options() & ~FindLinksOnly);
3031}
3032
3033void KHTMLPart::slotFindAheadLink()
3034{
3035 KHTMLPart *part = qobject_cast<KHTMLPart*>(currentFrame());
3036 if (!part)
3037 return;
3038 part->findText();
3039 KHTMLFindBar* findBar = part->d->m_find.findBar();
3040 findBar->setOptions(findBar->options() | FindLinksOnly);
3041}
3042
3043void KHTMLPart::enableFindAheadActions( bool )
3044{
3045 // ### remove me
3046}
3047
3048void KHTMLPart::slotFindDialogDestroyed()
3049{
3050 // ### remove me
3051}
3052
3053void KHTMLPart::findText()
3054{
3055 if (parentPart())
3056 return parentPart()->findText();
3057 d->m_find.activate();
3058}
3059
3060void KHTMLPart::findText( const QString &str, long options, QWidget *parent, KFindDialog *findDialog )
3061{
3062 if (parentPart())
3063 return parentPart()->findText(str, options, parent, findDialog);
3064 d->m_find.createNewKFind(str, options, parent, findDialog );
3065}
3066
3067// New method
3068bool KHTMLPart::findTextNext( bool reverse )
3069{
3070 if (parentPart())
3071 return parentPart()->findTextNext( reverse );
3072 return d->m_find.findTextNext( reverse );
3073}
3074
3075bool KHTMLPart::pFindTextNextInThisFrame( bool reverse )
3076{
3077 return d->m_find.findTextNext( reverse );
3078}
3079
3080QString KHTMLPart::selectedTextAsHTML() const
3081{
3082 const Selection &sel = d->editor_context.m_selection;
3083 if(!hasSelection()) {
3084 kDebug() << "Selection is not valid. Returning empty selection";
3085 return QString();
3086 }
3087 if(sel.start().offset() < 0 || sel.end().offset() < 0) {
3088 kDebug() << "invalid values for end/startOffset " << sel.start().offset() << " " << sel.end().offset();
3089 return QString();
3090 }
3091 DOM::Range r = selection();
3092 if(r.isNull() || r.isDetached())
3093 return QString();
3094 int exceptioncode = 0; //ignore the result
3095 return r.handle()->toHTML(exceptioncode).string();
3096}
3097
3098QString KHTMLPart::selectedText() const
3099{
3100 bool hasNewLine = true;
3101 bool seenTDTag = false;
3102 QString text;
3103 const Selection &sel = d->editor_context.m_selection;
3104 DOM::Node n = sel.start().node();
3105 while(!n.isNull()) {
3106 if(n.nodeType() == DOM::Node::TEXT_NODE && n.handle()->renderer()) {
3107 DOM::DOMStringImpl *dstr = static_cast<DOM::TextImpl*>(n.handle())->renderString();
3108 QString str(dstr->s, dstr->l);
3109 if(!str.isEmpty()) {
3110 if(seenTDTag) {
3111 text += " ";
3112 seenTDTag = false;
3113 }
3114 hasNewLine = false;
3115 if(n == sel.start().node() && n == sel.end().node()) {
3116 int s = khtml::RenderPosition::fromDOMPosition(sel.start()).renderedOffset();
3117 int e = khtml::RenderPosition::fromDOMPosition(sel.end()).renderedOffset();
3118 text = str.mid(s, e-s);
3119 } else if(n == sel.start().node()) {
3120 text = str.mid(khtml::RenderPosition::fromDOMPosition(sel.start()).renderedOffset());
3121 } else if(n == sel.end().node()) {
3122 text += str.left(khtml::RenderPosition::fromDOMPosition(sel.end()).renderedOffset());
3123 } else
3124 text += str;
3125 }
3126 }
3127 else {
3128 // This is our simple HTML -> ASCII transformation:
3129 unsigned short id = n.elementId();
3130 switch(id) {
3131 case ID_TEXTAREA:
3132 text += static_cast<HTMLTextAreaElementImpl*>(n.handle())->value().string();
3133 break;
3134 case ID_INPUT:
3135 if (static_cast<HTMLInputElementImpl*>(n.handle())->inputType() != HTMLInputElementImpl::PASSWORD)
3136 text += static_cast<HTMLInputElementImpl*>(n.handle())->value().string();
3137 break;
3138 case ID_SELECT:
3139 text += static_cast<HTMLSelectElementImpl*>(n.handle())->value().string();
3140 break;
3141 case ID_BR:
3142 text += "\n";
3143 hasNewLine = true;
3144 break;
3145 case ID_IMG:
3146 text += static_cast<HTMLImageElementImpl*>(n.handle())->altText().string();
3147 break;
3148 case ID_TD:
3149 break;
3150 case ID_TH:
3151 case ID_HR:
3152 case ID_OL:
3153 case ID_UL:
3154 case ID_LI:
3155 case ID_DD:
3156 case ID_DL:
3157 case ID_DT:
3158 case ID_PRE:
3159 case ID_LISTING:
3160 case ID_BLOCKQUOTE:
3161 case ID_DIV:
3162 if (!hasNewLine)
3163 text += "\n";
3164 hasNewLine = true;
3165 break;
3166 case ID_P:
3167 case ID_TR:
3168 case ID_H1:
3169 case ID_H2:
3170 case ID_H3:
3171 case ID_H4:
3172 case ID_H5:
3173 case ID_H6:
3174 if (!hasNewLine)
3175 text += "\n";
3176 hasNewLine = true;
3177 break;
3178 }
3179 }
3180 if(n == sel.end().node()) break;
3181 DOM::Node next = n.firstChild();
3182 if(next.isNull()) next = n.nextSibling();
3183 while( next.isNull() && !n.parentNode().isNull() ) {
3184 n = n.parentNode();
3185 next = n.nextSibling();
3186 unsigned short id = n.elementId();
3187 switch(id) {
3188 case ID_TD:
3189 seenTDTag = true; //Add two spaces after a td if then followed by text.
3190 break;
3191 case ID_TH:
3192 case ID_HR:
3193 case ID_OL:
3194 case ID_UL:
3195 case ID_LI:
3196 case ID_DD:
3197 case ID_DL:
3198 case ID_DT:
3199 case ID_PRE:
3200 case ID_LISTING:
3201 case ID_BLOCKQUOTE:
3202 case ID_DIV:
3203 seenTDTag = false;
3204 if (!hasNewLine)
3205 text += "\n";
3206 hasNewLine = true;
3207 break;
3208 case ID_P:
3209 case ID_TR:
3210 case ID_H1:
3211 case ID_H2:
3212 case ID_H3:
3213 case ID_H4:
3214 case ID_H5:
3215 case ID_H6:
3216 if (!hasNewLine)
3217 text += "\n";
3218// text += "\n";
3219 hasNewLine = true;
3220 break;
3221 }
3222 }
3223
3224 n = next;
3225 }
3226
3227 if(text.isEmpty())
3228 return QString();
3229
3230 int start = 0;
3231 int end = text.length();
3232
3233 // Strip leading LFs
3234 while ((start < end) && (text[start] == '\n'))
3235 ++start;
3236
3237 // Strip excessive trailing LFs
3238 while ((start < (end-1)) && (text[end-1] == '\n') && (text[end-2] == '\n'))
3239 --end;
3240
3241 return text.mid(start, end-start);
3242}
3243
3244QString KHTMLPart::simplifiedSelectedText() const
3245{
3246 QString text = selectedText();
3247 text.replace(QChar(0xa0), ' ');
3248 // remove leading and trailing whitespace
3249 while (!text.isEmpty() && text[0].isSpace())
3250 text = text.mid(1);
3251 while (!text.isEmpty() && text[text.length()-1].isSpace())
3252 text.truncate(text.length()-1);
3253 return text;
3254}
3255
3256bool KHTMLPart::hasSelection() const
3257{
3258 return !d->editor_context.m_selection.isEmpty() && !d->editor_context.m_selection.isCollapsed();
3259}
3260
3261DOM::Range KHTMLPart::selection() const
3262{
3263 return d->editor_context.m_selection.toRange();
3264}
3265
3266void KHTMLPart::selection(DOM::Node &s, long &so, DOM::Node &e, long &eo) const
3267{
3268 DOM::Range r = d->editor_context.m_selection.toRange();
3269 s = r.startContainer();
3270 so = r.startOffset();
3271 e = r.endContainer();
3272 eo = r.endOffset();
3273}
3274
3275void KHTMLPart::setSelection( const DOM::Range &r )
3276{
3277 setCaret(r);
3278}
3279
3280const Selection &KHTMLPart::caret() const
3281{
3282 return d->editor_context.m_selection;
3283}
3284
3285const Selection &KHTMLPart::dragCaret() const
3286{
3287 return d->editor_context.m_dragCaret;
3288}
3289
3290void KHTMLPart::setCaret(const Selection &s, bool closeTyping)
3291{
3292 if (d->editor_context.m_selection != s) {
3293 clearCaretRectIfNeeded();
3294 setFocusNodeIfNeeded(s);
3295 d->editor_context.m_selection = s;
3296 notifySelectionChanged(closeTyping);
3297 }
3298}
3299
3300void KHTMLPart::setDragCaret(const DOM::Selection &dragCaret)
3301{
3302 if (d->editor_context.m_dragCaret != dragCaret) {
3303 d->editor_context.m_dragCaret.needsCaretRepaint();
3304 d->editor_context.m_dragCaret = dragCaret;
3305 d->editor_context.m_dragCaret.needsCaretRepaint();
3306 }
3307}
3308
3309void KHTMLPart::clearSelection()
3310{
3311 clearCaretRectIfNeeded();
3312 setFocusNodeIfNeeded(d->editor_context.m_selection);
3313#ifdef APPLE_CHANGES
3314 d->editor_context.m_selection.clear();
3315#else
3316 d->editor_context.m_selection.collapse();
3317#endif
3318 notifySelectionChanged();
3319}
3320
3321void KHTMLPart::invalidateSelection()
3322{
3323 clearCaretRectIfNeeded();
3324 d->editor_context.m_selection.setNeedsLayout();
3325 selectionLayoutChanged();
3326}
3327
3328void KHTMLPart::setSelectionVisible(bool flag)
3329{
3330 if (d->editor_context.m_caretVisible == flag)
3331 return;
3332
3333 clearCaretRectIfNeeded();
3334 setFocusNodeIfNeeded(d->editor_context.m_selection);
3335 d->editor_context.m_caretVisible = flag;
3336// notifySelectionChanged();
3337}
3338
3339#if 1
3340void KHTMLPart::slotClearSelection()
3341{
3342 if (!isCaretMode()
3343 && d->editor_context.m_selection.state() != Selection::NONE
3344 && !d->editor_context.m_selection.caretPos().node()->isContentEditable())
3345 clearCaretRectIfNeeded();
3346 bool hadSelection = hasSelection();
3347#ifdef APPLE_CHANGES
3348 d->editor_context.m_selection.clear();
3349#else
3350 d->editor_context.m_selection.collapse();
3351#endif
3352 if (hadSelection)
3353 notifySelectionChanged();
3354}
3355#endif
3356
3357void KHTMLPart::clearCaretRectIfNeeded()
3358{
3359 if (d->editor_context.m_caretPaint) {
3360 d->editor_context.m_caretPaint = false;
3361 d->editor_context.m_selection.needsCaretRepaint();
3362 }
3363}
3364
3365void KHTMLPart::setFocusNodeIfNeeded(const Selection &s)
3366{
3367 if (!xmlDocImpl() || s.state() == Selection::NONE)
3368 return;
3369
3370 NodeImpl *n = s.start().node();
3371 NodeImpl *target = (n && n->isContentEditable()) ? n : 0;
3372 if (!target) {
3373 while (n && n != s.end().node()) {
3374 if (n->isContentEditable()) {
3375 target = n;
3376 break;
3377 }
3378 n = n->traverseNextNode();
3379 }
3380 }
3381 assert(target == 0 || target->isContentEditable());
3382
3383 if (target) {
3384 for ( ; target && !target->isFocusable(); target = target->parentNode())
3385 {}
3386 if (target && target->isMouseFocusable())
3387 xmlDocImpl()->setFocusNode(target);
3388 else if (!target || !target->focused())
3389 xmlDocImpl()->setFocusNode(0);
3390 }
3391}
3392
3393void KHTMLPart::selectionLayoutChanged()
3394{
3395 // kill any caret blink timer now running
3396 if (d->editor_context.m_caretBlinkTimer >= 0) {
3397 killTimer(d->editor_context.m_caretBlinkTimer);
3398 d->editor_context.m_caretBlinkTimer = -1;
3399 }
3400
3401 // see if a new caret blink timer needs to be started
3402 if (d->editor_context.m_caretVisible
3403 && d->editor_context.m_selection.state() != Selection::NONE) {
3404 d->editor_context.m_caretPaint = isCaretMode()
3405 || d->editor_context.m_selection.caretPos().node()->isContentEditable();
3406 if (d->editor_context.m_caretBlinks && d->editor_context.m_caretPaint)
3407 d->editor_context.m_caretBlinkTimer = startTimer(qApp->cursorFlashTime() / 2);
3408 d->editor_context.m_selection.needsCaretRepaint();
3409 // make sure that caret is visible
3410 QRect r(d->editor_context.m_selection.getRepaintRect());
3411 if (d->editor_context.m_caretPaint)
3412 d->m_view->ensureVisible(r.x(), r.y());
3413 }
3414
3415 if (d->m_doc)
3416 d->m_doc->updateSelection();
3417
3418 // Always clear the x position used for vertical arrow navigation.
3419 // It will be restored by the vertical arrow navigation code if necessary.
3420 d->editor_context.m_xPosForVerticalArrowNavigation = d->editor_context.NoXPosForVerticalArrowNavigation;
3421}
3422
3423void KHTMLPart::notifySelectionChanged(bool closeTyping)
3424{
3425 Editor *ed = d->editor_context.m_editor;
3426 selectionLayoutChanged();
3427 if (ed) {
3428 ed->clearTypingStyle();
3429
3430 if (closeTyping)
3431 ed->closeTyping();
3432 }
3433
3434 emitSelectionChanged();
3435}
3436
3437void KHTMLPart::timerEvent(QTimerEvent *e)
3438{
3439 if (e->timerId() == d->editor_context.m_caretBlinkTimer) {
3440 if (d->editor_context.m_caretBlinks &&
3441 d->editor_context.m_selection.state() != Selection::NONE) {
3442 d->editor_context.m_caretPaint = !d->editor_context.m_caretPaint;
3443 d->editor_context.m_selection.needsCaretRepaint();
3444 }
3445 } else if (e->timerId() == d->m_DNSPrefetchTimer) {
3446 // kDebug( 6050 ) << "will lookup " << d->m_DNSPrefetchQueue.head() << d->m_numDNSPrefetchedNames;
3447 KIO::HostInfo::prefetchHost( d->m_DNSPrefetchQueue.dequeue() );
3448 if (d->m_DNSPrefetchQueue.isEmpty()) {
3449 killTimer( d->m_DNSPrefetchTimer );
3450 d->m_DNSPrefetchTimer = -1;
3451 }
3452 } else if (e->timerId() == d->m_DNSTTLTimer) {
3453 foreach (const QString &name, d->m_lookedupHosts)
3454 d->m_DNSPrefetchQueue.enqueue(name);
3455 if (d->m_DNSPrefetchTimer <= 0)
3456 d->m_DNSPrefetchTimer = startTimer( sDNSPrefetchTimerDelay );
3457 }
3458}
3459
3460bool KHTMLPart::mayPrefetchHostname( const QString& name )
3461{
3462 if (d->m_bDNSPrefetch == DNSPrefetchDisabled)
3463 return false;
3464
3465 if (d->m_numDNSPrefetchedNames >= sMaxDNSPrefetchPerPage)
3466 return false;
3467
3468 if (d->m_bDNSPrefetch == DNSPrefetchOnlyWWWAndSLD) {
3469 int dots = name.count('.');
3470 if (dots > 2 || (dots == 2 && !name.startsWith("www.")))
3471 return false;
3472 }
3473
3474 if ( d->m_lookedupHosts.contains( name ) )
3475 return false;
3476
3477 d->m_DNSPrefetchQueue.enqueue( name );
3478 d->m_lookedupHosts.insert( name );
3479 d->m_numDNSPrefetchedNames++;
3480
3481 if (d->m_DNSPrefetchTimer < 1)
3482 d->m_DNSPrefetchTimer = startTimer( sDNSPrefetchTimerDelay );
3483 if (d->m_DNSTTLTimer < 1)
3484 d->m_DNSTTLTimer = startTimer( sDNSTTLSeconds*1000 + 1 );
3485
3486 return true;
3487}
3488
3489void KHTMLPart::paintCaret(QPainter *p, const QRect &rect) const
3490{
3491 if (d->editor_context.m_caretPaint)
3492 d->editor_context.m_selection.paintCaret(p, rect);
3493}
3494
3495void KHTMLPart::paintDragCaret(QPainter *p, const QRect &rect) const
3496{
3497 d->editor_context.m_dragCaret.paintCaret(p, rect);
3498}
3499
3500DOM::Editor *KHTMLPart::editor() const {
3501 if (!d->editor_context.m_editor)
3502 const_cast<KHTMLPart *>(this)->d->editor_context.m_editor = new DOM::Editor(const_cast<KHTMLPart *>(this));
3503 return d->editor_context.m_editor;
3504}
3505
3506void KHTMLPart::resetHoverText()
3507{
3508 if( !d->m_overURL.isEmpty() ) // Only if we were showing a link
3509 {
3510 d->m_overURL.clear();
3511 d->m_overURLTarget.clear();
3512 emit onURL( QString() );
3513 // revert to default statusbar text
3514 setStatusBarText(QString(), BarHoverText);
3515 emit d->m_extension->mouseOverInfo(KFileItem());
3516 }
3517}
3518
3519void KHTMLPart::overURL( const QString &url, const QString &target, bool /*shiftPressed*/ )
3520{
3521 KUrl u = completeURL(url);
3522
3523 // special case for <a href="">
3524 if ( url.isEmpty() )
3525 u.setFileName( url );
3526
3527 emit onURL( url );
3528
3529 if ( url.isEmpty() ) {
3530 setStatusBarText(Qt::escape(u.prettyUrl()), BarHoverText);
3531 return;
3532 }
3533
3534 if ( d->isJavaScriptURL(url) ) {
3535 QString jscode = d->codeForJavaScriptURL( url );
3536 jscode = KStringHandler::rsqueeze( jscode, 80 ); // truncate if too long
3537 if (url.startsWith("javascript:window.open"))
3538 jscode += i18n(" (In new window)");
3539 setStatusBarText( Qt::escape( jscode ), BarHoverText );
3540 return;
3541 }
3542
3543 KFileItem item(u, QString(), KFileItem::Unknown);
3544 emit d->m_extension->mouseOverInfo(item);
3545
3546 QString com;
3547
3548 KMimeType::Ptr typ = KMimeType::findByUrl( u );
3549
3550 if ( typ )
3551 com = typ->comment( u );
3552
3553 if ( !u.isValid() ) {
3554 setStatusBarText(Qt::escape(u.prettyUrl()), BarHoverText);
3555 return;
3556 }
3557
3558 if ( u.isLocalFile() )
3559 {
3560 // TODO : use KIO::stat() and create a KFileItem out of its result,
3561 // to use KFileItem::statusBarText()
3562 const QString path = QFile::encodeName( u.toLocalFile() );
3563
3564 KDE_struct_stat buff;
3565 bool ok = !KDE::stat( path, &buff );
3566
3567 KDE_struct_stat lbuff;
3568 if (ok) ok = !KDE::lstat( path, &lbuff );
3569
3570 QString text = Qt::escape(u.prettyUrl());
3571 QString text2 = text;
3572
3573 if (ok && S_ISLNK( lbuff.st_mode ) )
3574 {
3575 QString tmp;
3576 if ( com.isNull() )
3577 tmp = i18n( "Symbolic Link");
3578 else
3579 tmp = i18n("%1 (Link)", com);
3580 char buff_two[1024];
3581 text += " -> ";
3582 int n = readlink ( path.toLocal8Bit().data(), buff_two, 1022);
3583 if (n == -1)
3584 {
3585 text2 += " ";
3586 text2 += tmp;
3587 setStatusBarText(text2, BarHoverText);
3588 return;
3589 }
3590 buff_two[n] = 0;
3591
3592 text += buff_two;
3593 text += " ";
3594 text += tmp;
3595 }
3596 else if ( ok && S_ISREG( buff.st_mode ) )
3597 {
3598 if (buff.st_size < 1024)
3599 text = i18np("%2 (%1 byte)", "%2 (%1 bytes)", (long) buff.st_size, text2); // always put the URL last, in case it contains '%'
3600 else
3601 {
3602 float d = (float) buff.st_size/1024.0;
3603 text = i18n("%2 (%1 K)", KGlobal::locale()->formatNumber(d, 2), text2); // was %.2f
3604 }
3605 text += " ";
3606 text += com;
3607 }
3608 else if ( ok && S_ISDIR( buff.st_mode ) )
3609 {
3610 text += " ";
3611 text += com;
3612 }
3613 else
3614 {
3615 text += " ";
3616 text += com;
3617 }
3618 setStatusBarText(text, BarHoverText);
3619 }
3620 else
3621 {
3622 QString extra;
3623 if (target.toLower() == "_blank")
3624 {
3625 extra = i18n(" (In new window)");
3626 }
3627 else if (!target.isEmpty() &&
3628 (target.toLower() != "_top") &&
3629 (target.toLower() != "_self") &&
3630 (target.toLower() != "_parent"))
3631 {
3632 KHTMLPart *p = this;
3633 while (p->parentPart())
3634 p = p->parentPart();
3635 if (!p->frameExists(target))
3636 extra = i18n(" (In new window)");
3637 else
3638 extra = i18n(" (In other frame)");
3639 }
3640
3641 if (u.protocol() == QLatin1String("mailto")) {
3642 QString mailtoMsg /* = QString::fromLatin1("<img src=%1>").arg(locate("icon", QString::fromLatin1("locolor/16x16/actions/mail_send.png")))*/;
3643 mailtoMsg += i18n("Email to: ") + KUrl::fromPercentEncoding(u.path().toLatin1());
3644 const QStringList queries = u.query().mid(1).split('&');
3645 QStringList::ConstIterator it = queries.begin();
3646 const QStringList::ConstIterator itEnd = queries.end();
3647 for (; it != itEnd; ++it)
3648 if ((*it).startsWith(QLatin1String("subject=")))
3649 mailtoMsg += i18n(" - Subject: ") + KUrl::fromPercentEncoding((*it).mid(8).toLatin1());
3650 else if ((*it).startsWith(QLatin1String("cc=")))
3651 mailtoMsg += i18n(" - CC: ") + KUrl::fromPercentEncoding((*it).mid(3).toLatin1());
3652 else if ((*it).startsWith(QLatin1String("bcc=")))
3653 mailtoMsg += i18n(" - BCC: ") + KUrl::fromPercentEncoding((*it).mid(4).toLatin1());
3654 mailtoMsg = Qt::escape(mailtoMsg);
3655 mailtoMsg.replace(QRegExp("([\n\r\t]|[ ]{10})"), QString());
3656 setStatusBarText("<qt>"+mailtoMsg, BarHoverText);
3657 return;
3658 }
3659 // Is this check necessary at all? (Frerich)
3660#if 0
3661 else if (u.protocol() == QLatin1String("http")) {
3662 DOM::Node hrefNode = nodeUnderMouse().parentNode();
3663 while (hrefNode.nodeName().string() != QLatin1String("A") && !hrefNode.isNull())
3664 hrefNode = hrefNode.parentNode();
3665
3666 if (!hrefNode.isNull()) {
3667 DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
3668 if (!hreflangNode.isNull()) {
3669 QString countryCode = hreflangNode.nodeValue().string().toLower();
3670 // Map the language code to an appropriate country code.
3671 if (countryCode == QLatin1String("en"))
3672 countryCode = QLatin1String("gb");
3673 QString flagImg = QLatin1String("<img src=%1>").arg(
3674 locate("locale", QLatin1String("l10n/")
3675 + countryCode
3676 + QLatin1String("/flag.png")));
3677 emit setStatusBarText(flagImg + u.prettyUrl() + extra);
3678 }
3679 }
3680 }
3681#endif
3682 setStatusBarText(Qt::escape(u.prettyUrl()) + extra, BarHoverText);
3683 }
3684}
3685
3686//
3687// This executes in the active part on a click or other url selection action in
3688// that active part.
3689//
3690bool KHTMLPart::urlSelected( const QString &url, int button, int state, const QString &_target, const KParts::OpenUrlArguments& _args, const KParts::BrowserArguments& _browserArgs )
3691{
3692 KParts::OpenUrlArguments args = _args;
3693 KParts::BrowserArguments browserArgs = _browserArgs;
3694 bool hasTarget = false;
3695
3696 QString target = _target;
3697 if ( target.isEmpty() && d->m_doc )
3698 target = d->m_doc->baseTarget();
3699 if ( !target.isEmpty() )
3700 hasTarget = true;
3701
3702 if ( d->isJavaScriptURL(url) )
3703 {
3704 crossFrameExecuteScript( target, d->codeForJavaScriptURL(url) );
3705 return false;
3706 }
3707
3708 KUrl cURL = completeURL(url);
3709 // special case for <a href=""> (IE removes filename, mozilla doesn't)
3710 if ( url.isEmpty() )
3711 cURL.setFileName( url ); // removes filename
3712
3713 if ( !cURL.isValid() )
3714 // ### ERROR HANDLING
3715 return false;
3716
3717 kDebug(6050) << this << "complete URL:" << cURL.url() << "target=" << target;
3718
3719 if ( state & Qt::ControlModifier )
3720 {
3721 emit d->m_extension->createNewWindow( cURL, args, browserArgs );
3722 return true;
3723 }
3724
3725 if ( button == Qt::LeftButton && ( state & Qt::ShiftModifier ) )
3726 {
3727 KIO::MetaData metaData;
3728 metaData.insert( "referrer", d->m_referrer );
3729 KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), cURL, metaData );
3730 return false;
3731 }
3732
3733 if (!checkLinkSecurity(cURL,
3734 ki18n( "<qt>This untrusted page links to<br /><b>%1</b>.<br />Do you want to follow the link?</qt>" ),
3735 i18n( "Follow" )))
3736 return false;
3737
3738 browserArgs.frameName = target;
3739
3740 args.metaData().insert("main_frame_request",
3741 parentPart() == 0 ? "TRUE":"FALSE");
3742 args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
3743 args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
3744 args.metaData().insert("PropagateHttpHeader", "true");
3745 args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
3746 args.metaData().insert("ssl_activate_warnings", "TRUE");
3747
3748 if ( hasTarget && target != "_self" && target != "_top" && target != "_blank" && target != "_parent" )
3749 {
3750 // unknown frame names should open in a new window.
3751 khtml::ChildFrame *frame = recursiveFrameRequest( this, cURL, args, browserArgs, false );
3752 if ( frame )
3753 {
3754 args.metaData()["referrer"] = d->m_referrer;
3755 requestObject( frame, cURL, args, browserArgs );
3756 return true;
3757 }
3758 }
3759
3760 if (!d->m_referrer.isEmpty() && !args.metaData().contains("referrer"))
3761 args.metaData()["referrer"] = d->m_referrer;
3762
3763 if ( button == Qt::NoButton && (state & Qt::ShiftModifier) && (state & Qt::ControlModifier) )
3764 {
3765 emit d->m_extension->createNewWindow( cURL, args, browserArgs );
3766 return true;
3767 }
3768
3769 if ( state & Qt::ShiftModifier)
3770 {
3771 KParts::WindowArgs winArgs;
3772 winArgs.setLowerWindow(true);
3773 emit d->m_extension->createNewWindow( cURL, args, browserArgs, winArgs );
3774 return true;
3775 }
3776
3777 //If we're asked to open up an anchor in the current URL, in current window,
3778 //merely gotoanchor, and do not reload the new page. Note that this does
3779 //not apply if the URL is the same page, but without a ref
3780 if (cURL.hasRef() && (!hasTarget || target == "_self"))
3781 {
3782 if (d->isLocalAnchorJump(cURL))
3783 {
3784 d->executeAnchorJump(cURL, browserArgs.lockHistory() );
3785 return false; // we jumped, but we didn't open a URL
3786 }
3787 }
3788
3789 if ( !d->m_bComplete && !hasTarget )
3790 closeUrl();
3791
3792 view()->viewport()->unsetCursor();
3793 emit d->m_extension->openUrlRequest( cURL, args, browserArgs );
3794 return true;
3795}
3796
3797void KHTMLPart::slotViewDocumentSource()
3798{
3799 KUrl currentUrl(this->url());
3800 bool isTempFile = false;
3801 if (!(currentUrl.isLocalFile()) && KHTMLPageCache::self()->isComplete(d->m_cacheId))
3802 {
3803 KTemporaryFile sourceFile;
3804 sourceFile.setSuffix(defaultExtension());
3805 sourceFile.setAutoRemove(false);
3806 if (sourceFile.open())
3807 {
3808 QDataStream stream ( &sourceFile );
3809 KHTMLPageCache::self()->saveData(d->m_cacheId, &stream);
3810 currentUrl = KUrl();
3811 currentUrl.setPath(sourceFile.fileName());
3812 isTempFile = true;
3813 }
3814 }
3815
3816 (void) KRun::runUrl( currentUrl, QLatin1String("text/plain"), view(), isTempFile );
3817}
3818
3819void KHTMLPart::slotViewPageInfo()
3820{
3821 Ui_KHTMLInfoDlg ui;
3822
3823 QDialog *dlg = new QDialog(0);
3824 dlg->setAttribute(Qt::WA_DeleteOnClose);
3825 dlg->setObjectName("KHTML Page Info Dialog");
3826 ui.setupUi(dlg);
3827
3828 ui._close->setGuiItem(KStandardGuiItem::close());
3829 connect(ui._close, SIGNAL(clicked()), dlg, SLOT(accept()));
3830
3831 if (d->m_doc)
3832 ui._title->setText(d->m_doc->title().string().trimmed());
3833
3834 // If it's a frame, set the caption to "Frame Information"
3835 if ( parentPart() && d->m_doc && d->m_doc->isHTMLDocument() ) {
3836 dlg->setWindowTitle(i18n("Frame Information"));
3837 }
3838
3839 QString editStr;
3840
3841 if (!d->m_pageServices.isEmpty())
3842 editStr = i18n(" <a href=\"%1\">[Properties]</a>", d->m_pageServices);
3843
3844 QString squeezedURL = KStringHandler::csqueeze( url().prettyUrl(), 80 );
3845 ui._url->setText("<a href=\"" + url().url() + "\">" + squeezedURL + "</a>" + editStr);
3846 if (lastModified().isEmpty())
3847 {
3848 ui._lastModified->hide();
3849 ui._lmLabel->hide();
3850 }
3851 else
3852 ui._lastModified->setText(lastModified());
3853
3854 const QString& enc = encoding();
3855 if (enc.isEmpty()) {
3856 ui._eLabel->hide();
3857 ui._encoding->hide();
3858 } else {
3859 ui._encoding->setText(enc);
3860 }
3861
3862 if (!xmlDocImpl() || xmlDocImpl()->parseMode() == DOM::DocumentImpl::Unknown) {
3863 ui._mode->hide();
3864 ui._modeLabel->hide();
3865 } else {
3866 switch (xmlDocImpl()->parseMode()) {
3867 case DOM::DocumentImpl::Compat:
3868 ui._mode->setText(i18nc("HTML rendering mode (see http://en.wikipedia.org/wiki/Quirks_mode)", "Quirks"));
3869 break;
3870 case DOM::DocumentImpl::Transitional:
3871 ui._mode->setText(i18nc("HTML rendering mode (see http://en.wikipedia.org/wiki/Quirks_mode)", "Almost standards"));
3872 break;
3873 case DOM::DocumentImpl::Strict:
3874 default: // others handled above
3875 ui._mode->setText(i18nc("HTML rendering mode (see http://en.wikipedia.org/wiki/Quirks_mode)", "Strict"));
3876 break;
3877 }
3878 }
3879
3880 /* populate the list view now */
3881 const QStringList headers = d->m_httpHeaders.split("\n");
3882
3883 QStringList::ConstIterator it = headers.begin();
3884 const QStringList::ConstIterator itEnd = headers.end();
3885
3886 for (; it != itEnd; ++it) {
3887 const QStringList header = (*it).split(QRegExp(":[ ]+"));
3888 if (header.count() != 2)
3889 continue;
3890 QTreeWidgetItem *item = new QTreeWidgetItem(ui._headers);
3891 item->setText(0, header[0]);
3892 item->setText(1, header[1]);
3893 }
3894
3895 dlg->show();
3896 /* put no code here */
3897}
3898
3899
3900void KHTMLPart::slotViewFrameSource()
3901{
3902 KParts::ReadOnlyPart *frame = currentFrame();
3903 if ( !frame )
3904 return;
3905
3906 KUrl url = frame->url();
3907 bool isTempFile = false;
3908 if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
3909 {
3910 long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;
3911
3912 if (KHTMLPageCache::self()->isComplete(cacheId))
3913 {
3914 KTemporaryFile sourceFile;
3915 sourceFile.setSuffix(defaultExtension());
3916 sourceFile.setAutoRemove(false);
3917 if (sourceFile.open())
3918 {
3919 QDataStream stream ( &sourceFile );
3920 KHTMLPageCache::self()->saveData(cacheId, &stream);
3921 url = KUrl();
3922 url.setPath(sourceFile.fileName());
3923 isTempFile = true;
3924 }
3925 }
3926 }
3927
3928 (void) KRun::runUrl( url, QLatin1String("text/plain"), view(), isTempFile );
3929}
3930
3931KUrl KHTMLPart::backgroundURL() const
3932{
3933 // ### what about XML documents? get from CSS?
3934 if (!d->m_doc || !d->m_doc->isHTMLDocument())
3935 return KUrl();
3936
3937 QString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
3938
3939 return KUrl( url(), relURL );
3940}
3941
3942void KHTMLPart::slotSaveBackground()
3943{
3944 KIO::MetaData metaData;
3945 metaData["referrer"] = d->m_referrer;
3946 KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save Background Image As"), backgroundURL(), metaData );
3947}
3948
3949void KHTMLPart::slotSaveDocument()
3950{
3951 KUrl srcURL( url() );
3952
3953 if ( srcURL.fileName(KUrl::ObeyTrailingSlash).isEmpty() )
3954 srcURL.setFileName( "index" + defaultExtension() );
3955
3956 KIO::MetaData metaData;
3957 // Referre unknown?
3958 KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, "text/html", d->m_cacheId );
3959}
3960
3961void KHTMLPart::slotSecurity()
3962{
3963// kDebug( 6050 ) << "Meta Data:" << endl
3964// << d->m_ssl_peer_cert_subject
3965// << endl
3966// << d->m_ssl_peer_cert_issuer
3967// << endl
3968// << d->m_ssl_cipher
3969// << endl
3970// << d->m_ssl_cipher_desc
3971// << endl
3972// << d->m_ssl_cipher_version
3973// << endl
3974// << d->m_ssl_good_from
3975// << endl
3976// << d->m_ssl_good_until
3977// << endl
3978// << d->m_ssl_cert_state
3979// << endl;
3980
3981 //### reenable with new signature
3982#if 0
3983 KSslInfoDialog *kid = new KSslInfoDialog(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );
3984
3985 const QStringList sl = d->m_ssl_peer_chain.split('\n', QString::SkipEmptyParts);
3986 QList<QSslCertificate> certChain;
3987 bool certChainOk = d->m_ssl_in_use;
3988 if (certChainOk) {
3989 foreach (const QString &s, sl) {
3990 certChain.append(QSslCertificate(s.toLatin1())); //or is it toLocal8Bit or whatever?
3991 if (certChain.last().isNull()) {
3992 certChainOk = false;
3993 break;
3994 }
3995 }
3996 }
3997 if (certChainOk) {
3998 kid->setup(certChain,
3999 d->m_ssl_peer_ip,
4000 url().url(),
4001 d->m_ssl_cipher,
4002 d->m_ssl_cipher_desc,
4003 d->m_ssl_cipher_version,
4004 d->m_ssl_cipher_used_bits.toInt(),
4005 d->m_ssl_cipher_bits.toInt(),
4006 (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt());
4007 }
4008 kid->exec();
4009 //the dialog deletes itself on close
4010#endif
4011
4012 KSslInfoDialog *kid = new KSslInfoDialog(0);
4013 //### This is boilerplate code and it's copied from SlaveInterface.
4014 QStringList sl = d->m_ssl_peer_chain.split('\x01', QString::SkipEmptyParts);
4015 QList<QSslCertificate> certChain;
4016 bool decodedOk = true;
4017 foreach (const QString &s, sl) {
4018 certChain.append(QSslCertificate(s.toLatin1())); //or is it toLocal8Bit or whatever?
4019 if (certChain.last().isNull()) {
4020 decodedOk = false;
4021 break;
4022 }
4023 }
4024
4025 if (decodedOk || true /*H4X*/) {
4026 kid->setSslInfo(certChain,
4027 d->m_ssl_peer_ip,
4028 url().host(),
4029 d->m_ssl_protocol_version,
4030 d->m_ssl_cipher,
4031 d->m_ssl_cipher_used_bits.toInt(),
4032 d->m_ssl_cipher_bits.toInt(),
4033 KSslInfoDialog::errorsFromString(d->m_ssl_cert_errors));
4034 kDebug(7024) << "Showing SSL Info dialog";
4035 kid->exec();
4036 kDebug(7024) << "SSL Info dialog closed";
4037 } else {
4038 KMessageBox::information(0, i18n("The peer SSL certificate chain "
4039 "appears to be corrupt."),
4040 i18n("SSL"));
4041 }
4042}
4043
4044void KHTMLPart::slotSaveFrame()
4045{
4046 KParts::ReadOnlyPart *frame = currentFrame();
4047 if ( !frame )
4048 return;
4049
4050 KUrl srcURL( frame->url() );
4051
4052 if ( srcURL.fileName(KUrl::ObeyTrailingSlash).isEmpty() )
4053 srcURL.setFileName( "index" + defaultExtension() );
4054
4055 KIO::MetaData metaData;
4056 // Referrer unknown?
4057 KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save Frame As" ), srcURL, metaData, "text/html" );
4058}
4059
4060void KHTMLPart::slotSetEncoding(const QString &enc)
4061{
4062 d->m_autoDetectLanguage=KEncodingDetector::None;
4063 setEncoding( enc, true);
4064}
4065
4066void KHTMLPart::slotAutomaticDetectionLanguage(KEncodingDetector::AutoDetectScript scri)
4067{
4068 d->m_autoDetectLanguage=scri;
4069 setEncoding( QString(), false );
4070}
4071
4072void KHTMLPart::slotUseStylesheet()
4073{
4074 if (d->m_doc)
4075 {
4076 bool autoselect = (d->m_paUseStylesheet->currentItem() == 0);
4077 d->m_sheetUsed = autoselect ? QString() : d->m_paUseStylesheet->currentText();
4078 d->m_doc->updateStyleSelector();
4079 }
4080}
4081
4082void KHTMLPart::updateActions()
4083{
4084 bool frames = false;
4085
4086 QList<khtml::ChildFrame*>::ConstIterator it = d->m_frames.constBegin();
4087 const QList<khtml::ChildFrame*>::ConstIterator end = d->m_frames.constEnd();
4088 for (; it != end; ++it )
4089 if ( (*it)->m_type == khtml::ChildFrame::Frame )
4090 {
4091 frames = true;
4092 break;
4093 }
4094
4095 if (d->m_paViewFrame)
4096 d->m_paViewFrame->setEnabled( frames );
4097 if (d->m_paSaveFrame)
4098 d->m_paSaveFrame->setEnabled( frames );
4099
4100 if ( frames )
4101 d->m_paFind->setText( i18n( "&Find in Frame..." ) );
4102 else
4103 d->m_paFind->setText( i18n( "&Find..." ) );
4104
4105 KParts::Part *frame = 0;
4106
4107 if ( frames )
4108 frame = currentFrame();
4109
4110 bool enableFindAndSelectAll = true;
4111
4112 if ( frame )
4113 enableFindAndSelectAll = frame->inherits( "KHTMLPart" );
4114
4115 d->m_paFind->setEnabled( enableFindAndSelectAll );
4116 d->m_paSelectAll->setEnabled( enableFindAndSelectAll );
4117
4118 bool enablePrintFrame = false;
4119
4120 if ( frame )
4121 {
4122 QObject *ext = KParts::BrowserExtension::childObject( frame );
4123 if ( ext )
4124 enablePrintFrame = ext->metaObject()->indexOfSlot( "print()" ) != -1;
4125 }
4126
4127 d->m_paPrintFrame->setEnabled( enablePrintFrame );
4128
4129 QString bgURL;
4130
4131 // ### frames
4132 if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
4133 bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
4134
4135 if (d->m_paSaveBackground)
4136 d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );
4137
4138 if ( d->m_paDebugScript )
4139 d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
4140}
4141
4142KParts::ScriptableExtension *KHTMLPart::scriptableExtension( const DOM::NodeImpl *frame) {
4143 const ConstFrameIt end = d->m_objects.constEnd();
4144 for(ConstFrameIt it = d->m_objects.constBegin(); it != end; ++it )
4145 if ((*it)->m_partContainerElement.data() == frame)
4146 return (*it)->m_scriptable.data();
4147 return 0L;
4148}
4149
4150void KHTMLPart::loadFrameElement( DOM::HTMLPartContainerElementImpl *frame, const QString &url,
4151 const QString &frameName, const QStringList &params, bool isIFrame )
4152{
4153 //kDebug( 6050 ) << this << " requestFrame( ..., " << url << ", " << frameName << " )";
4154 khtml::ChildFrame* child;
4155
4156 FrameIt it = d->m_frames.find( frameName );
4157 if ( it == d->m_frames.end() ) {
4158 child = new khtml::ChildFrame;
4159 //kDebug( 6050 ) << "inserting new frame into frame map " << frameName;
4160 child->m_name = frameName;
4161 d->m_frames.insert( d->m_frames.end(), child );
4162 } else {
4163 child = *it;
4164 }
4165
4166 child->m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
4167 child->m_partContainerElement = frame;
4168 child->m_params = params;
4169
4170 // If we do not have a part, make sure we create one.
4171 if (!child->m_part) {
4172 QStringList dummy; // the list of servicetypes handled by the part is now unused.
4173 QString khtml = QString::fromLatin1("khtml");
4174 KParts::ReadOnlyPart* part = createPart(d->m_view->viewport(), this,
4175 QString::fromLatin1("text/html"),
4176 khtml, dummy, QStringList());
4177 // We navigate it to about:blank to setup an empty one, but we do it
4178 // before hooking up the signals and extensions, so that any sync emit
4179 // of completed by the kid doesn't cause us to be marked as completed.
4180 // (async ones are discovered by the presence of the KHTMLRun)
4181 // ### load event on the kid?
4182 navigateLocalProtocol(child, part, KUrl("about:blank"));
4183 connectToChildPart(child, part, "text/html" /* mimetype of the part, not what's being loaded */);
4184 }
4185
4186 KUrl u = url.isEmpty() ? KUrl() : completeURL( url );
4187
4188 // Since we don't specify args here a KHTMLRun will be used to determine the
4189 // mimetype, which will then be passed down at the bottom of processObjectRequest
4190 // inside URLArgs to the part. In our particular case, this means that we can
4191 // use that inside KHTMLPart::openUrl to route things appropriately.
4192 child->m_bCompleted = false;
4193 if (!requestObject( child, u ) && !child->m_run) {
4194 child->m_bCompleted = true;
4195 }
4196}
4197
4198QString KHTMLPart::requestFrameName()
4199{
4200 return QString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
4201}
4202
4203bool KHTMLPart::loadObjectElement( DOM::HTMLPartContainerElementImpl *frame, const QString &url,
4204 const QString &serviceType, const QStringList &params )
4205{
4206 //kDebug( 6031 ) << this << "frame=" << frame;
4207 khtml::ChildFrame *child = new khtml::ChildFrame;
4208 FrameIt it = d->m_objects.insert( d->m_objects.end(), child );
4209 (*it)->m_partContainerElement = frame;
4210 (*it)->m_type = khtml::ChildFrame::Object;
4211 (*it)->m_params = params;
4212
4213 KParts::OpenUrlArguments args;
4214 args.setMimeType(serviceType);
4215 if (!requestObject( *it, completeURL( url ), args ) && !(*it)->m_run) {
4216 (*it)->m_bCompleted = true;
4217 return false;
4218 }
4219 return true;
4220}
4221
4222bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KUrl &url, const KParts::OpenUrlArguments &_args,
4223 const KParts::BrowserArguments& browserArgs )
4224{
4225 // we always permit javascript: URLs here since they're basically just
4226 // empty pages (and checkLinkSecurity/KAuthorized doesn't know what to do with them)
4227 if (!d->isJavaScriptURL(url.url()) && !checkLinkSecurity(url))
4228 {
4229 kDebug(6031) << this << "checkLinkSecurity refused";
4230 return false;
4231 }
4232
4233 if (d->m_bClearing)
4234 {
4235 return false;
4236 }
4237
4238 if ( child->m_bPreloaded )
4239 {
4240 if ( child->m_partContainerElement && child->m_part )
4241 child->m_partContainerElement.data()->setWidget( child->m_part.data()->widget() );
4242
4243 child->m_bPreloaded = false;
4244 return true;
4245 }
4246
4247 //kDebug(6031) << "child=" << child << "child->m_part=" << child->m_part;
4248
4249 KParts::OpenUrlArguments args( _args );
4250
4251 if ( child->m_run ) {
4252 kDebug(6031) << "navigating ChildFrame while mimetype resolution was in progress...";
4253 child->m_run.data()->abort();
4254 }
4255
4256 // ### Dubious -- the whole dir/ vs. img thing
4257 if ( child->m_part && !args.reload() && child->m_part.data()->url().equals( url,
4258 KUrl::CompareWithoutTrailingSlash | KUrl::CompareWithoutFragment | KUrl::AllowEmptyPath ) )
4259 args.setMimeType(child->m_serviceType);
4260
4261 child->m_browserArgs = browserArgs;
4262 child->m_args = args;
4263
4264 // reload/soft-reload arguments are always inherited from parent
4265 child->m_args.setReload( arguments().reload() );
4266 child->m_browserArgs.softReload = d->m_extension->browserArguments().softReload;
4267
4268 child->m_serviceName.clear();
4269 if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
4270 child->m_args.metaData()["referrer"] = d->m_referrer;
4271
4272 child->m_args.metaData().insert("PropagateHttpHeader", "true");
4273 child->m_args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
4274 child->m_args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
4275 child->m_args.metaData().insert("main_frame_request",
4276 parentPart() == 0 ? "TRUE":"FALSE");
4277 child->m_args.metaData().insert("ssl_was_in_use",
4278 d->m_ssl_in_use ? "TRUE":"FALSE");
4279 child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
4280 child->m_args.metaData().insert("cross-domain", toplevelURL().url());
4281
4282 // We know the frame will be text/html if the HTML says <frame src=""> or <frame src="about:blank">,
4283 // no need to KHTMLRun to figure out the mimetype"
4284 // ### What if we're inside an XML document?
4285 if ((url.isEmpty() || url.url() == "about:blank" || url.protocol() == "javascript") && args.mimeType().isEmpty())
4286 args.setMimeType(QLatin1String("text/html"));
4287
4288 if ( args.mimeType().isEmpty() ) {
4289 kDebug(6031) << "Running new KHTMLRun for" << this << "and child=" << child;
4290 child->m_run = new KHTMLRun( this, child, url, child->m_args, child->m_browserArgs, true );
4291 d->m_bComplete = false; // ensures we stop it in checkCompleted...
4292 return false;
4293 } else {
4294 return processObjectRequest( child, url, args.mimeType() );
4295 }
4296}
4297
4298void KHTMLPart::childLoadFailure( khtml::ChildFrame *child )
4299{
4300 child->m_bCompleted = true;
4301 if ( child->m_partContainerElement )
4302 child->m_partContainerElement.data()->partLoadingErrorNotify();
4303
4304 checkCompleted();
4305}
4306
4307bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KUrl &_url, const QString &mimetype )
4308{
4309 kDebug( 6031 ) << "trying to create part for" << mimetype << _url;
4310
4311 // IMPORTANT: create a copy of the url here, because it is just a reference, which was likely to be given
4312 // by an emitting frame part (emit openUrlRequest( blahurl, ... ) . A few lines below we delete the part
4313 // though -> the reference becomes invalid -> crash is likely
4314 KUrl url( _url );
4315
4316 // khtmlrun called us with empty url + mimetype to indicate a loading error,
4317 // we obviosuly failed; but we can return true here since we don't want it
4318 // doing anything more, while childLoadFailure is enough to notify our kid.
4319 if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) ) {
4320 childLoadFailure(child);
4321 return true;
4322 }
4323
4324 // we also want to ignore any spurious requests due to closing when parser is being cleared. These should be
4325 // ignored entirely --- the tail end of ::clear will clean things up.
4326 if (d->m_bClearing)
4327 return false;
4328
4329 if (child->m_bNotify) {
4330 child->m_bNotify = false;
4331 if ( !child->m_browserArgs.lockHistory() )
4332 emit d->m_extension->openUrlNotify();
4333 }
4334
4335 // Now, depending on mimetype and current state of the world, we may have
4336 // to create a new part or ask the user to save things, etc.
4337 //
4338 // We need a new part if there isn't one at all (doh) or the one that's there
4339 // is not for the mimetype we're loading.
4340 //
4341 // For these new types, we may have to ask the user to save it or not
4342 // (we don't if it's navigating the same type).
4343 // Further, we will want to ask if content-disposition suggests we ask for
4344 // saving, even if we're re-navigating.
4345 if ( !child->m_part || child->m_serviceType != mimetype ||
4346 (child->m_run && child->m_run.data()->serverSuggestsSave())) {
4347 // We often get here if we didn't know the mimetype in advance, and had to rely
4348 // on KRun to figure it out. In this case, we let the element check if it wants to
4349 // handle this mimetype itself, for e.g. objects containing images.
4350 if ( child->m_partContainerElement &&
4351 child->m_partContainerElement.data()->mimetypeHandledInternally(mimetype) ) {
4352 child->m_bCompleted = true;
4353 checkCompleted();
4354 return true;
4355 }
4356
4357 // Before attempting to load a part, check if the user wants that.
4358 // Many don't like getting ZIP files embedded.
4359 // However we don't want to ask for flash and other plugin things.
4360 //
4361 // Note: this is fine for frames, since we will merely effectively ignore
4362 // the navigation if this happens
4363 if ( child->m_type != khtml::ChildFrame::Object && child->m_type != khtml::ChildFrame::IFrame ) {
4364 QString suggestedFileName;
4365 int disposition = 0;
4366 if ( KHTMLRun* run = child->m_run.data() ) {
4367 suggestedFileName = run->suggestedFileName();
4368 disposition = run->serverSuggestsSave() ?
4369 KParts::BrowserRun::AttachmentDisposition :
4370 KParts::BrowserRun::InlineDisposition;
4371 }
4372
4373 KParts::BrowserOpenOrSaveQuestion dlg( widget(), url, mimetype );
4374 dlg.setSuggestedFileName( suggestedFileName );
4375 const KParts::BrowserOpenOrSaveQuestion::Result res = dlg.askEmbedOrSave( disposition );
4376
4377 switch( res ) {
4378 case KParts::BrowserOpenOrSaveQuestion::Save:
4379 KHTMLPopupGUIClient::saveURL( widget(), i18n( "Save As" ), url, child->m_args.metaData(), QString(), 0, suggestedFileName );
4380 // fall-through
4381 case KParts::BrowserOpenOrSaveQuestion::Cancel:
4382 child->m_bCompleted = true;
4383 checkCompleted();
4384 return true; // done
4385 default: // Embed
4386 break;
4387 }
4388 }
4389
4390 // Now, for frames and iframes, we always create a KHTMLPart anyway,
4391 // doing it in advance when registering the frame. So we want the
4392 // actual creation only for objects here.
4393 if ( child->m_type == khtml::ChildFrame::Object ) {
4394 KMimeType::Ptr mime = KMimeType::mimeType(mimetype);
4395 if (mime) {
4396 // Even for objects, however, we want to force a KHTMLPart for
4397 // html & xml, even if the normally preferred part is another one,
4398 // so that we can script the target natively via contentDocument method.
4399 if (mime->is("text/html")
4400 || mime->is("application/xml")) { // this includes xhtml and svg
4401 child->m_serviceName = "khtml";
4402 } else {
4403 if (!pluginsEnabled()) {
4404 childLoadFailure(child);
4405 return false;
4406 }
4407 }
4408 }
4409
4410 QStringList dummy; // the list of servicetypes handled by the part is now unused.
4411 KParts::ReadOnlyPart *part = createPart( d->m_view->viewport(), this, mimetype, child->m_serviceName, dummy, child->m_params );
4412
4413 if ( !part ) {
4414 childLoadFailure(child);
4415 return false;
4416 }
4417
4418 connectToChildPart( child, part, mimetype );
4419 }
4420 }
4421
4422 checkEmitLoadEvent();
4423
4424 // Some JS code in the load event may have destroyed the part
4425 // In that case, abort
4426 if ( !child->m_part )
4427 return false;
4428
4429 if ( child->m_bPreloaded ) {
4430 if ( child->m_partContainerElement && child->m_part )
4431 child->m_partContainerElement.data()->setWidget( child->m_part.data()->widget() );
4432
4433 child->m_bPreloaded = false;
4434 return true;
4435 }
4436
4437 // reload/soft-reload arguments are always inherited from parent
4438 child->m_args.setReload( arguments().reload() );
4439 child->m_browserArgs.softReload = d->m_extension->browserArguments().softReload;
4440
4441 // make sure the part has a way to find out about the mimetype.
4442 // we actually set it in child->m_args in requestObject already,
4443 // but it's useless if we had to use a KHTMLRun instance, as the
4444 // point the run object is to find out exactly the mimetype.
4445 child->m_args.setMimeType(mimetype);
4446 child->m_part.data()->setArguments( child->m_args );
4447
4448 // if not a frame set child as completed
4449 // ### dubious.
4450 child->m_bCompleted = child->m_type == khtml::ChildFrame::Object;
4451
4452 if ( child->m_extension )
4453 child->m_extension.data()->setBrowserArguments( child->m_browserArgs );
4454
4455 return navigateChild( child, url );
4456}
4457
4458bool KHTMLPart::navigateLocalProtocol( khtml::ChildFrame* /*child*/, KParts::ReadOnlyPart *inPart,
4459 const KUrl& url )
4460{
4461 if (!qobject_cast<KHTMLPart*>(inPart))
4462 return false;
4463
4464 KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(inPart));
4465
4466 p->begin();
4467
4468 // We may have to re-propagate the domain here if we go here due to navigation
4469 d->propagateInitialDomainAndBaseTo(p);
4470
4471 // Support for javascript: sources
4472 if (d->isJavaScriptURL(url.url())) {
4473 // See if we want to replace content with javascript: output..
4474 QVariant res = p->executeScript( DOM::Node(),
4475 d->codeForJavaScriptURL(url.url()));
4476 if (res.type() == QVariant::String && p->d->m_redirectURL.isEmpty()) {
4477 p->begin();
4478 p->setAlwaysHonourDoctype(); // Disable public API compat; it messes with doctype
4479 // We recreated the document, so propagate domain again.
4480 d->propagateInitialDomainAndBaseTo(p);
4481 p->write( res.toString() );
4482 p->end();
4483 }
4484 } else {
4485 p->setUrl(url);
4486 // we need a body element. testcase: <iframe id="a"></iframe><script>alert(a.document.body);</script>
4487 p->write("<HTML><TITLE></TITLE><BODY></BODY></HTML>");
4488 }
4489 p->end();
4490 // we don't need to worry about child completion explicitly for KHTMLPart...
4491 // or do we?
4492 return true;
4493}
4494
4495bool KHTMLPart::navigateChild( khtml::ChildFrame *child, const KUrl& url )
4496{
4497 if (url.protocol() == "javascript" || url.url() == "about:blank") {
4498 return navigateLocalProtocol(child, child->m_part.data(), url);
4499 } else if ( !url.isEmpty() ) {
4500 kDebug( 6031 ) << "opening" << url << "in frame" << child->m_part;
4501 bool b = child->m_part.data()->openUrl( url );
4502 if (child->m_bCompleted)
4503 checkCompleted();
4504 return b;
4505 } else {
4506 // empty URL -> no need to navigate
4507 child->m_bCompleted = true;
4508 checkCompleted();
4509 return true;
4510 }
4511}
4512
4513void KHTMLPart::connectToChildPart( khtml::ChildFrame *child, KParts::ReadOnlyPart *part,
4514 const QString& mimetype)
4515{
4516 kDebug(6031) << "we:" << this << "kid:" << child << part << mimetype;
4517
4518 part->setObjectName( child->m_name );
4519
4520 // Cleanup any previous part for this childframe and its connections
4521 if ( KParts::ReadOnlyPart* p = child->m_part.data() ) {
4522 if (!qobject_cast<KHTMLPart*>(p) && child->m_jscript)
4523 child->m_jscript->clear();
4524 partManager()->removePart( p );
4525 delete p;
4526 child->m_scriptable.clear();
4527 }
4528
4529 child->m_part = part;
4530
4531 child->m_serviceType = mimetype;
4532 if ( child->m_partContainerElement && part->widget() )
4533 child->m_partContainerElement.data()->setWidget( part->widget() );
4534
4535 if ( child->m_type != khtml::ChildFrame::Object )
4536 partManager()->addPart( part, false );
4537// else
4538// kDebug(6031) << "AH! NO FRAME!!!!!";
4539
4540 if (qobject_cast<KHTMLPart*>(part)) {
4541 static_cast<KHTMLPart*>(part)->d->m_frame = child;
4542 } else if (child->m_partContainerElement) {
4543 // See if this can be scripted..
4544 KParts::ScriptableExtension* scriptExt = KParts::ScriptableExtension::childObject(part);
4545 if (!scriptExt) {
4546 // Try to fall back to LiveConnectExtension compat
4547 KParts::LiveConnectExtension* lc = KParts::LiveConnectExtension::childObject(part);
4548 if (lc)
4549 scriptExt = KParts::ScriptableExtension::adapterFromLiveConnect(part, lc);
4550 }
4551
4552 if (scriptExt)
4553 scriptExt->setHost(d->m_scriptableExtension);
4554 child->m_scriptable = scriptExt;
4555 }
4556 KParts::StatusBarExtension *sb = KParts::StatusBarExtension::childObject(part);
4557 if (sb)
4558 sb->setStatusBar( d->m_statusBarExtension->statusBar() );
4559
4560 connect( part, SIGNAL(started(KIO::Job*)),
4561 this, SLOT(slotChildStarted(KIO::Job*)) );
4562 connect( part, SIGNAL(completed()),
4563 this, SLOT(slotChildCompleted()) );
4564 connect( part, SIGNAL(completed(bool)),
4565 this, SLOT(slotChildCompleted(bool)) );
4566 connect( part, SIGNAL(setStatusBarText(QString)),
4567 this, SIGNAL(setStatusBarText(QString)) );
4568 if ( part->inherits( "KHTMLPart" ) )
4569 {
4570 connect( this, SIGNAL(completed()),
4571 part, SLOT(slotParentCompleted()) );
4572 connect( this, SIGNAL(completed(bool)),
4573 part, SLOT(slotParentCompleted()) );
4574 // As soon as the child's document is created, we need to set its domain
4575 // (but we do so only once, so it can't be simply done in the child)
4576 connect( part, SIGNAL(docCreated()),
4577 this, SLOT(slotChildDocCreated()) );
4578 }
4579
4580 child->m_extension = KParts::BrowserExtension::childObject( part );
4581
4582 if ( KParts::BrowserExtension* kidBrowserExt = child->m_extension.data() )
4583 {
4584 connect( kidBrowserExt, SIGNAL(openUrlNotify()),
4585 d->m_extension, SIGNAL(openUrlNotify()) );
4586
4587 connect( kidBrowserExt, SIGNAL(openUrlRequestDelayed(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments)),
4588 this, SLOT(slotChildURLRequest(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments)) );
4589
4590 connect( kidBrowserExt, SIGNAL(createNewWindow(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::WindowArgs,KParts::ReadOnlyPart**)),
4591 d->m_extension, SIGNAL(createNewWindow(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::WindowArgs,KParts::ReadOnlyPart**)) );
4592
4593 connect( kidBrowserExt, SIGNAL(popupMenu(QPoint,KFileItemList,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::BrowserExtension::PopupFlags,KParts::BrowserExtension::ActionGroupMap)),
4594 d->m_extension, SIGNAL(popupMenu(QPoint,KFileItemList,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::BrowserExtension::PopupFlags,KParts::BrowserExtension::ActionGroupMap)) );
4595 connect( kidBrowserExt, SIGNAL(popupMenu(QPoint,KUrl,mode_t,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::BrowserExtension::PopupFlags,KParts::BrowserExtension::ActionGroupMap)),
4596 d->m_extension, SIGNAL(popupMenu(QPoint,KUrl,mode_t,KParts::OpenUrlArguments,KParts::BrowserArguments,KParts::BrowserExtension::PopupFlags,KParts::BrowserExtension::ActionGroupMap)) );
4597
4598 connect( kidBrowserExt, SIGNAL(infoMessage(QString)),
4599 d->m_extension, SIGNAL(infoMessage(QString)) );
4600
4601 connect( kidBrowserExt, SIGNAL(requestFocus(KParts::ReadOnlyPart*)),
4602 this, SLOT(slotRequestFocus(KParts::ReadOnlyPart*)) );
4603
4604 kidBrowserExt->setBrowserInterface( d->m_extension->browserInterface() );
4605 }
4606}
4607
4608KParts::ReadOnlyPart *KHTMLPart::createPart( QWidget *parentWidget,
4609 QObject *parent, const QString &mimetype,
4610 QString &serviceName, QStringList &serviceTypes,
4611 const QStringList &params )
4612{
4613 QString constr;
4614 if ( !serviceName.isEmpty() )
4615 constr.append( QString::fromLatin1( "DesktopEntryName == '%1'" ).arg( serviceName ) );
4616
4617 KService::List offers = KMimeTypeTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr );
4618
4619 if ( offers.isEmpty() ) {
4620 int pos = mimetype.indexOf( "-plugin" );
4621 if (pos < 0)
4622 return 0L;
4623 QString stripped_mime = mimetype.left( pos );
4624 offers = KMimeTypeTrader::self()->query( stripped_mime, "KParts/ReadOnlyPart", constr );
4625 if ( offers.isEmpty() )
4626 return 0L;
4627 }
4628
4629 KService::List::ConstIterator it = offers.constBegin();
4630 const KService::List::ConstIterator itEnd = offers.constEnd();
4631 for ( ; it != itEnd; ++it )
4632 {
4633 KService::Ptr service = (*it);
4634
4635 KPluginLoader loader( *service, KHTMLGlobal::componentData() );
4636 KPluginFactory* const factory = loader.factory();
4637 if ( factory ) {
4638 // Turn params into a QVariantList as expected by KPluginFactory
4639 QVariantList variantlist;
4640 Q_FOREACH(const QString& str, params)
4641 variantlist << QVariant(str);
4642
4643 if ( service->serviceTypes().contains( "Browser/View" ) )
4644 variantlist << QString("Browser/View");
4645
4646 KParts::ReadOnlyPart* part = factory->create<KParts::ReadOnlyPart>(parentWidget, parent, QString(), variantlist);
4647 if ( part ) {
4648 serviceTypes = service->serviceTypes();
4649 serviceName = service->name();
4650 return part;
4651 }
4652 } else {
4653 // TODO KMessageBox::error and i18n, like in KonqFactory::createView?
4654 kWarning() << QString("There was an error loading the module %1.\nThe diagnostics is:\n%2")
4655 .arg(service->name()).arg(loader.errorString());
4656 }
4657 }
4658 return 0;
4659}
4660
4661KParts::PartManager *KHTMLPart::partManager()
4662{
4663 if ( !d->m_manager && d->m_view )
4664 {
4665 d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this );
4666 d->m_manager->setObjectName( "khtml part manager" );
4667 d->m_manager->setAllowNestedParts( true );
4668 connect( d->m_manager, SIGNAL(activePartChanged(KParts::Part*)),
4669 this, SLOT(slotActiveFrameChanged(KParts::Part*)) );
4670 connect( d->m_manager, SIGNAL(partRemoved(KParts::Part*)),
4671 this, SLOT(slotPartRemoved(KParts::Part*)) );
4672 }
4673
4674 return d->m_manager;
4675}
4676
4677void KHTMLPart::submitFormAgain()
4678{
4679 disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
4680 if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
4681 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 );
4682
4683 delete d->m_submitForm;
4684 d->m_submitForm = 0;
4685}
4686
4687void KHTMLPart::submitFormProxy( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
4688{
4689 submitForm(action, url, formData, _target, contentType, boundary);
4690}
4691
4692void KHTMLPart::submitForm( const char *action, const QString &url, const QByteArray &formData, const QString &_target, const QString& contentType, const QString& boundary )
4693{
4694 kDebug(6000) << this << "target=" << _target << "url=" << url;
4695 if (d->m_formNotification == KHTMLPart::Only) {
4696 emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
4697 return;
4698 } else if (d->m_formNotification == KHTMLPart::Before) {
4699 emit formSubmitNotification(action, url, formData, _target, contentType, boundary);
4700 }
4701
4702 KUrl u = completeURL( url );
4703
4704 if ( !u.isValid() )
4705 {
4706 // ### ERROR HANDLING!
4707 return;
4708 }
4709
4710 // Form security checks
4711 //
4712 /*
4713 * If these form security checks are still in this place in a month or two
4714 * I'm going to simply delete them.
4715 */
4716
4717 /* This is separate for a reason. It has to be _before_ all script, etc,
4718 * AND I don't want to break anything that uses checkLinkSecurity() in
4719 * other places.
4720 */
4721
4722 if (!d->m_submitForm) {
4723 if (u.protocol() != "https" && u.protocol() != "mailto") {
4724 if (d->m_ssl_in_use) { // Going from SSL -> nonSSL
4725 int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning: This is a secure form but it is attempting to send your data back unencrypted."
4726 "\nA third party may be able to intercept and view this information."
4727 "\nAre you sure you wish to continue?"),
4728 i18n("Network Transmission"),KGuiItem(i18n("&Send Unencrypted")));
4729 if (rc == KMessageBox::Cancel)
4730 return;
4731 } else { // Going from nonSSL -> nonSSL
4732 KSSLSettings kss(true);
4733 if (kss.warnOnUnencrypted()) {
4734 int rc = KMessageBox::warningContinueCancel(NULL,
4735 i18n("Warning: Your data is about to be transmitted across the network unencrypted."
4736 "\nAre you sure you wish to continue?"),
4737 i18n("Network Transmission"),
4738 KGuiItem(i18n("&Send Unencrypted")),
4739 KStandardGuiItem::cancel(),
4740 "WarnOnUnencryptedForm");
4741 // Move this setting into KSSL instead
4742 QString grpNotifMsgs = QLatin1String("Notification Messages");
4743 KConfigGroup cg( KGlobal::config(), grpNotifMsgs );
4744
4745 if (!cg.readEntry("WarnOnUnencryptedForm", true)) {
4746 cg.deleteEntry("WarnOnUnencryptedForm");
4747 cg.sync();
4748 kss.setWarnOnUnencrypted(false);
4749 kss.save();
4750 }
4751 if (rc == KMessageBox::Cancel)
4752 return;
4753 }
4754 }
4755 }
4756
4757 if (u.protocol() == "mailto") {
4758 int rc = KMessageBox::warningContinueCancel(NULL,
4759 i18n("This site is attempting to submit form data via email.\n"
4760 "Do you want to continue?"),
4761 i18n("Network Transmission"),
4762 KGuiItem(i18n("&Send Email")),
4763 KStandardGuiItem::cancel(),
4764 "WarnTriedEmailSubmit");
4765
4766 if (rc == KMessageBox::Cancel) {
4767 return;
4768 }
4769 }
4770 }
4771
4772 // End form security checks
4773 //
4774
4775 QString urlstring = u.url();
4776
4777 if ( d->isJavaScriptURL(urlstring) ) {
4778 crossFrameExecuteScript( _target, d->codeForJavaScriptURL(urlstring) );
4779 return;
4780 }
4781
4782 if (!checkLinkSecurity(u,
4783 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>" ),
4784 i18n( "Submit" )))
4785 return;
4786
4787 // OK. We're actually going to submit stuff. Clear any redirections,
4788 // we should win over them
4789 d->clearRedirection();
4790
4791 KParts::OpenUrlArguments args;
4792
4793 if (!d->m_referrer.isEmpty())
4794 args.metaData()["referrer"] = d->m_referrer;
4795
4796 args.metaData().insert("PropagateHttpHeader", "true");
4797 args.metaData().insert("ssl_parent_ip", d->m_ssl_parent_ip);
4798 args.metaData().insert("ssl_parent_cert", d->m_ssl_parent_cert);
4799 args.metaData().insert("main_frame_request",
4800 parentPart() == 0 ? "TRUE":"FALSE");
4801 args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
4802 args.metaData().insert("ssl_activate_warnings", "TRUE");
4803//WABA: When we post a form we should treat it as the main url
4804//the request should never be considered cross-domain
4805//args.metaData().insert("cross-domain", toplevelURL().url());
4806 KParts::BrowserArguments browserArgs;
4807 browserArgs.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
4808
4809 // Handle mailto: forms
4810 if (u.protocol() == "mailto") {
4811 // 1) Check for attach= and strip it
4812 QString q = u.query().mid(1);
4813 QStringList nvps = q.split("&");
4814 bool triedToAttach = false;
4815
4816 QStringList::Iterator nvp = nvps.begin();
4817 const QStringList::Iterator nvpEnd = nvps.end();
4818
4819// cannot be a for loop as if something is removed we don't want to do ++nvp, as
4820// remove returns an iterator pointing to the next item
4821
4822 while (nvp != nvpEnd) {
4823 const QStringList pair = (*nvp).split("=");
4824 if (pair.count() >= 2) {
4825 if (pair.first().toLower() == "attach") {
4826 nvp = nvps.erase(nvp);
4827 triedToAttach = true;
4828 } else {
4829 ++nvp;
4830 }
4831 } else {
4832 ++nvp;
4833 }
4834 }
4835
4836 if (triedToAttach)
4837 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");
4838
4839 // 2) Append body=
4840 QString bodyEnc;
4841 if (contentType.toLower() == "multipart/form-data") {
4842 // FIXME: is this correct? I suspect not
4843 bodyEnc = QLatin1String( KUrl::toPercentEncoding(QString::fromLatin1(formData.data(),
4844 formData.size())));
4845 } else if (contentType.toLower() == "text/plain") {
4846 // Convention seems to be to decode, and s/&/\n/
4847 QString tmpbody = QString::fromLatin1(formData.data(),
4848 formData.size());
4849 tmpbody.replace(QRegExp("[&]"), "\n");
4850 tmpbody.replace(QRegExp("[+]"), " ");
4851 tmpbody = KUrl::fromPercentEncoding(tmpbody.toLatin1()); // Decode the rest of it
4852 bodyEnc = QLatin1String( KUrl::toPercentEncoding(tmpbody) ); // Recode for the URL
4853 } else {
4854 bodyEnc = QLatin1String( KUrl::toPercentEncoding(QString::fromLatin1(formData.data(),
4855 formData.size())) );
4856 }
4857
4858 nvps.append(QString("body=%1").arg(bodyEnc));
4859 q = nvps.join("&");
4860 u.setQuery(q);
4861 }
4862
4863 if ( strcmp( action, "get" ) == 0 ) {
4864 if (u.protocol() != "mailto")
4865 u.setQuery( QString::fromLatin1( formData.data(), formData.size() ) );
4866 browserArgs.setDoPost( false );
4867 }
4868 else {
4869 browserArgs.postData = formData;
4870 browserArgs.setDoPost( true );
4871
4872 // construct some user headers if necessary
4873 if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
4874 browserArgs.setContentType( "Content-Type: application/x-www-form-urlencoded" );
4875 else // contentType must be "multipart/form-data"
4876 browserArgs.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
4877 }
4878
4879 if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
4880 if( d->m_submitForm ) {
4881 kDebug(6000) << "ABORTING!";
4882 return;
4883 }
4884 d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
4885 d->m_submitForm->submitAction = action;
4886 d->m_submitForm->submitUrl = url;
4887 d->m_submitForm->submitFormData = formData;
4888 d->m_submitForm->target = _target;
4889 d->m_submitForm->submitContentType = contentType;
4890 d->m_submitForm->submitBoundary = boundary;
4891 connect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
4892 }
4893 else
4894 {
4895 emit d->m_extension->openUrlRequest( u, args, browserArgs );
4896 }
4897}
4898
4899void KHTMLPart::popupMenu( const QString &linkUrl )
4900{
4901 KUrl popupURL;
4902 KUrl linkKUrl;
4903 KParts::OpenUrlArguments args;
4904 KParts::BrowserArguments browserArgs;
4905 QString referrer;
4906 KParts::BrowserExtension::PopupFlags itemflags=KParts::BrowserExtension::ShowBookmark | KParts::BrowserExtension::ShowReload;
4907
4908 if ( linkUrl.isEmpty() ) { // click on background
4909 KHTMLPart* khtmlPart = this;
4910 while ( khtmlPart->parentPart() )
4911 {
4912 khtmlPart=khtmlPart->parentPart();
4913 }
4914 popupURL = khtmlPart->url();
4915 referrer = khtmlPart->pageReferrer();
4916 if (hasSelection())
4917 itemflags = KParts::BrowserExtension::ShowTextSelectionItems;
4918 else
4919 itemflags |= KParts::BrowserExtension::ShowNavigationItems;
4920 } else { // click on link
4921 popupURL = completeURL( linkUrl );
4922 linkKUrl = popupURL;
4923 referrer = this->referrer();
4924 itemflags |= KParts::BrowserExtension::IsLink;
4925
4926 if (!(d->m_strSelectedURLTarget).isEmpty() &&
4927 (d->m_strSelectedURLTarget.toLower() != "_top") &&
4928 (d->m_strSelectedURLTarget.toLower() != "_self") &&
4929 (d->m_strSelectedURLTarget.toLower() != "_parent")) {
4930 if (d->m_strSelectedURLTarget.toLower() == "_blank")
4931 browserArgs.setForcesNewWindow(true);
4932 else {
4933 KHTMLPart *p = this;
4934 while (p->parentPart())
4935 p = p->parentPart();
4936 if (!p->frameExists(d->m_strSelectedURLTarget))
4937 browserArgs.setForcesNewWindow(true);
4938 }
4939 }
4940 }
4941
4942 // Danger, Will Robinson. The Popup might stay around for a much
4943 // longer time than KHTMLPart. Deal with it.
4944 KHTMLPopupGUIClient* client = new KHTMLPopupGUIClient( this, linkKUrl );
4945 QPointer<QObject> guard( client );
4946
4947 QString mimetype = QLatin1String( "text/html" );
4948 args.metaData()["referrer"] = referrer;
4949
4950 if (!linkUrl.isEmpty()) // over a link
4951 {
4952 if (popupURL.isLocalFile()) // safe to do this
4953 {
4954 mimetype = KMimeType::findByUrl(popupURL,0,true,false)->name();
4955 }
4956 else // look at "extension" of link
4957 {
4958 const QString fname(popupURL.fileName(KUrl::ObeyTrailingSlash));
4959 if (!fname.isEmpty() && !popupURL.hasRef() && popupURL.query().isEmpty())
4960 {
4961 KMimeType::Ptr pmt = KMimeType::findByPath(fname,0,true);
4962
4963 // Further check for mime types guessed from the extension which,
4964 // on a web page, are more likely to be a script delivering content
4965 // of undecidable type. If the mime type from the extension is one
4966 // of these, don't use it. Retain the original type 'text/html'.
4967 if (pmt->name() != KMimeType::defaultMimeType() &&
4968 !pmt->is("application/x-perl") &&
4969 !pmt->is("application/x-perl-module") &&
4970 !pmt->is("application/x-php") &&
4971 !pmt->is("application/x-python-bytecode") &&
4972 !pmt->is("application/x-python") &&
4973 !pmt->is("application/x-shellscript"))
4974 mimetype = pmt->name();
4975 }
4976 }
4977 }
4978
4979 args.setMimeType(mimetype);
4980
4981 emit d->m_extension->popupMenu( QCursor::pos(), popupURL, S_IFREG /*always a file*/,
4982 args, browserArgs, itemflags,
4983 client->actionGroups() );
4984
4985 if ( !guard.isNull() ) {
4986 delete client;
4987 emit popupMenu(linkUrl, QCursor::pos());
4988 d->m_strSelectedURL.clear();
4989 d->m_strSelectedURLTarget.clear();
4990 }
4991}
4992
4993void KHTMLPart::slotParentCompleted()
4994{
4995 //kDebug(6050) << this;
4996 if ( !d->m_redirectURL.isEmpty() && !d->m_redirectionTimer.isActive() )
4997 {
4998 //kDebug(6050) << this << ": starting timer for child redirection -> " << d->m_redirectURL;
4999 d->m_redirectionTimer.setSingleShot( true );
5000 d->m_redirectionTimer.start( qMax(0, 1000 * d->m_delayRedirect) );
5001 }
5002}
5003
5004void KHTMLPart::slotChildStarted( KIO::Job *job )
5005{
5006 khtml::ChildFrame *child = frame( sender() );
5007
5008 assert( child );
5009
5010 child->m_bCompleted = false;
5011
5012 if ( d->m_bComplete )
5013 {
5014#if 0
5015 // WABA: Looks like this belongs somewhere else
5016 if ( !parentPart() ) // "toplevel" html document? if yes, then notify the hosting browser about the document (url) changes
5017 {
5018 emit d->m_extension->openURLNotify();
5019 }
5020#endif
5021 d->m_bComplete = false;
5022 emit started( job );
5023 }
5024}
5025
5026void KHTMLPart::slotChildCompleted()
5027{
5028 slotChildCompleted( false );
5029}
5030
5031void KHTMLPart::slotChildCompleted( bool pendingAction )
5032{
5033 khtml::ChildFrame *child = frame( sender() );
5034
5035 if ( child ) {
5036 kDebug(6031) << this << "child=" << child << "m_partContainerElement=" << child->m_partContainerElement;
5037 child->m_bCompleted = true;
5038 child->m_bPendingRedirection = pendingAction;
5039 child->m_args = KParts::OpenUrlArguments();
5040 child->m_browserArgs = KParts::BrowserArguments();
5041 // dispatch load event. We don't do that for KHTMLPart's since their internal
5042 // load will be forwarded inside NodeImpl::dispatchWindowEvent
5043 if (!qobject_cast<KHTMLPart*>(child->m_part))
5044 QTimer::singleShot(0, child->m_partContainerElement.data(), SLOT(slotEmitLoadEvent()));
5045 }
5046 checkCompleted();
5047}
5048
5049void KHTMLPart::slotChildDocCreated()
5050{
5051 // Set domain to the frameset's domain
5052 // This must only be done when loading the frameset initially (#22039),
5053 // not when following a link in a frame (#44162).
5054 if (KHTMLPart* htmlFrame = qobject_cast<KHTMLPart*>(sender()))
5055 d->propagateInitialDomainAndBaseTo(htmlFrame);
5056
5057 // So it only happens once
5058 disconnect( sender(), SIGNAL(docCreated()), this, SLOT(slotChildDocCreated()) );
5059}
5060
5061void KHTMLPartPrivate::propagateInitialDomainAndBaseTo(KHTMLPart* kid)
5062{
5063 // This method is used to propagate our domain and base information for
5064 // child frames, to provide them for about: or JavaScript: URLs
5065 if ( m_doc && kid->d->m_doc ) {
5066 DocumentImpl* kidDoc = kid->d->m_doc;
5067 if ( kidDoc->origin()->isEmpty() ) {
5068 kidDoc->setOrigin ( m_doc->origin() );
5069 kidDoc->setBaseURL( m_doc->baseURL() );
5070 }
5071 }
5072}
5073
5074void KHTMLPart::slotChildURLRequest( const KUrl &url, const KParts::OpenUrlArguments& args, const KParts::BrowserArguments &browserArgs )
5075{
5076 khtml::ChildFrame *child = frame( sender()->parent() );
5077 KHTMLPart *callingHtmlPart = const_cast<KHTMLPart *>(dynamic_cast<const KHTMLPart *>(sender()->parent()));
5078
5079 // TODO: handle child target correctly! currently the script are always executed for the parent
5080 QString urlStr = url.url();
5081 if ( d->isJavaScriptURL(urlStr) ) {
5082 executeScript( DOM::Node(), d->codeForJavaScriptURL(urlStr) );
5083 return;
5084 }
5085
5086 QString frameName = browserArgs.frameName.toLower();
5087 if ( !frameName.isEmpty() ) {
5088 if ( frameName == QLatin1String( "_top" ) )
5089 {
5090 emit d->m_extension->openUrlRequest( url, args, browserArgs );
5091 return;
5092 }
5093 else if ( frameName == QLatin1String( "_blank" ) )
5094 {
5095 emit d->m_extension->createNewWindow( url, args, browserArgs );
5096 return;
5097 }
5098 else if ( frameName == QLatin1String( "_parent" ) )
5099 {
5100 KParts::BrowserArguments newBrowserArgs( browserArgs );
5101 newBrowserArgs.frameName.clear();
5102 emit d->m_extension->openUrlRequest( url, args, newBrowserArgs );
5103 return;
5104 }
5105 else if ( frameName != QLatin1String( "_self" ) )
5106 {
5107 khtml::ChildFrame *_frame = recursiveFrameRequest( callingHtmlPart, url, args, browserArgs );
5108
5109 if ( !_frame )
5110 {
5111 emit d->m_extension->openUrlRequest( url, args, browserArgs );
5112 return;
5113 }
5114
5115 child = _frame;
5116 }
5117 }
5118
5119 if ( child && child->m_type != khtml::ChildFrame::Object ) {
5120 // Inform someone that we are about to show something else.
5121 child->m_bNotify = true;
5122 requestObject( child, url, args, browserArgs );
5123 } else if ( frameName== "_self" ) // this is for embedded objects (via <object>) which want to replace the current document
5124 {
5125 KParts::BrowserArguments newBrowserArgs( browserArgs );
5126 newBrowserArgs.frameName.clear();
5127 emit d->m_extension->openUrlRequest( url, args, newBrowserArgs );
5128 }
5129}
5130
5131void KHTMLPart::slotRequestFocus( KParts::ReadOnlyPart * )
5132{
5133 emit d->m_extension->requestFocus(this);
5134}
5135
5136khtml::ChildFrame *KHTMLPart::frame( const QObject *obj )
5137{
5138 assert( obj->inherits( "KParts::ReadOnlyPart" ) );
5139 const KParts::ReadOnlyPart* const part = static_cast<const KParts::ReadOnlyPart *>( obj );
5140
5141 FrameIt it = d->m_frames.begin();
5142 const FrameIt end = d->m_frames.end();
5143 for (; it != end; ++it ) {
5144 if ((*it)->m_part.data() == part )
5145 return *it;
5146 }
5147
5148 FrameIt oi = d->m_objects.begin();
5149 const FrameIt oiEnd = d->m_objects.end();
5150 for (; oi != oiEnd; ++oi ) {
5151 if ((*oi)->m_part.data() == part)
5152 return *oi;
5153 }
5154
5155 return 0L;
5156}
5157
5158//#define DEBUG_FINDFRAME
5159
5160bool KHTMLPart::checkFrameAccess(KHTMLPart *callingHtmlPart)
5161{
5162 if (callingHtmlPart == this)
5163 return true; // trivial
5164
5165 if (!xmlDocImpl()) {
5166#ifdef DEBUG_FINDFRAME
5167 kDebug(6050) << "Empty part" << this << "URL = " << url();
5168#endif
5169 return false; // we are empty?
5170 }
5171
5172 // now compare the domains
5173 if (callingHtmlPart && callingHtmlPart->xmlDocImpl() && xmlDocImpl()) {
5174 khtml::SecurityOrigin* actDomain = callingHtmlPart->xmlDocImpl()->origin();
5175 khtml::SecurityOrigin* destDomain = xmlDocImpl()->origin();
5176
5177 if (actDomain->canAccess(destDomain))
5178 return true;
5179 }
5180#ifdef DEBUG_FINDFRAME
5181 else
5182 {
5183 kDebug(6050) << "Unknown part/domain" << callingHtmlPart << "tries to access part" << this;
5184 }
5185#endif
5186 return false;
5187}
5188
5189KHTMLPart *
5190KHTMLPart::findFrameParent( KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame )
5191{
5192 return d->findFrameParent(callingPart, f, childFrame, false);
5193}
5194
5195KHTMLPart* KHTMLPartPrivate::findFrameParent(KParts::ReadOnlyPart* callingPart,
5196 const QString& f, khtml::ChildFrame **childFrame, bool checkForNavigation)
5197{
5198#ifdef DEBUG_FINDFRAME
5199 kDebug(6050) << q << "URL =" << q->url() << "name =" << q->objectName() << "findFrameParent(" << f << ")";
5200#endif
5201 // Check access
5202 KHTMLPart* const callingHtmlPart = qobject_cast<KHTMLPart *>(callingPart);
5203
5204 if (!callingHtmlPart)
5205 return 0;
5206
5207 if (!checkForNavigation && !q->checkFrameAccess(callingHtmlPart))
5208 return 0;
5209
5210 if (!childFrame && !q->parentPart() && (q->objectName() == f)) {
5211 if (!checkForNavigation || callingHtmlPart->d->canNavigate(q))
5212 return q;
5213 }
5214
5215 FrameIt it = m_frames.find( f );
5216 const FrameIt end = m_frames.end();
5217 if ( it != end )
5218 {
5219#ifdef DEBUG_FINDFRAME
5220 kDebug(6050) << "FOUND!";
5221#endif
5222 if (!checkForNavigation || callingHtmlPart->d->canNavigate((*it)->m_part.data())) {
5223 if (childFrame)
5224 *childFrame = *it;
5225 return q;
5226 }
5227 }
5228
5229 it = m_frames.begin();
5230 for (; it != end; ++it )
5231 {
5232 if ( KHTMLPart* p = qobject_cast<KHTMLPart*>((*it)->m_part.data()) )
5233 {
5234 KHTMLPart* const frameParent = p->d->findFrameParent(callingPart, f, childFrame, checkForNavigation);
5235 if (frameParent)
5236 return frameParent;
5237 }
5238 }
5239 return 0;
5240}
5241
5242KHTMLPart* KHTMLPartPrivate::top()
5243{
5244 KHTMLPart* t = q;
5245 while (t->parentPart())
5246 t = t->parentPart();
5247 return t;
5248}
5249
5250bool KHTMLPartPrivate::canNavigate(KParts::ReadOnlyPart* bCand)
5251{
5252 if (!bCand) // No part here (e.g. invalid url), reuse that frame
5253 return true;
5254
5255 KHTMLPart* b = qobject_cast<KHTMLPart*>(bCand);
5256 if (!b) // Another kind of part? Not sure what to do...
5257 return false;
5258
5259 // HTML5 gives conditions for this (a) being able to navigate b
5260
5261 // 1) Same domain
5262 if (q->checkFrameAccess(b))
5263 return true;
5264
5265 // 2) A is nested, with B its top
5266 if (q->parentPart() && top() == b)
5267 return true;
5268
5269 // 3) B is 'auxilary' -- window.open with opener,
5270 // and A can navigate B's opener
5271 if (b->opener() && canNavigate(b->opener()))
5272 return true;
5273
5274 // 4) B is not top-level, but an ancestor of it has same origin as A
5275 for (KHTMLPart* anc = b->parentPart(); anc; anc = anc->parentPart()) {
5276 if (anc->checkFrameAccess(q))
5277 return true;
5278 }
5279
5280 return false;
5281}
5282
5283KHTMLPart *KHTMLPart::findFrame( const QString &f )
5284{
5285 khtml::ChildFrame *childFrame;
5286 KHTMLPart *parentFrame = findFrameParent(this, f, &childFrame);
5287 if (parentFrame)
5288 return qobject_cast<KHTMLPart*>(childFrame->m_part.data());
5289
5290 return 0;
5291}
5292
5293KParts::ReadOnlyPart *KHTMLPart::findFramePart(const QString &f)
5294{
5295 khtml::ChildFrame *childFrame;
5296 return findFrameParent(this, f, &childFrame) ? childFrame->m_part.data() : 0L;
5297}
5298
5299KParts::ReadOnlyPart *KHTMLPart::currentFrame() const
5300{
5301 KParts::ReadOnlyPart* part = (KParts::ReadOnlyPart*)(this);
5302 // Find active part in our frame manager, in case we are a frameset
5303 // and keep doing that (in case of nested framesets).
5304 // Just realized we could also do this recursively, calling part->currentFrame()...
5305 while ( part && part->inherits("KHTMLPart") &&
5306 static_cast<KHTMLPart *>(part)->d->m_frames.count() > 0 ) {
5307 KHTMLPart* frameset = static_cast<KHTMLPart *>(part);
5308 part = static_cast<KParts::ReadOnlyPart *>(frameset->partManager()->activePart());
5309 if ( !part ) return frameset;
5310 }
5311 return part;
5312}
5313
5314bool KHTMLPart::frameExists( const QString &frameName )
5315{
5316 FrameIt it = d->m_frames.find( frameName );
5317 if ( it == d->m_frames.end() )
5318 return false;
5319
5320 // WABA: We only return true if the child actually has a frame
5321 // set. Otherwise we might find our preloaded-selve.
5322 // This happens when we restore the frameset.
5323 return (!(*it)->m_partContainerElement.isNull());
5324}
5325
5326void KHTMLPartPrivate::renameFrameForContainer(DOM::HTMLPartContainerElementImpl* cont,
5327 const QString& newName)
5328{
5329 for (int i = 0; i < m_frames.size(); ++i) {
5330 khtml::ChildFrame* f = m_frames[i];
5331 if (f->m_partContainerElement.data() == cont)
5332 f->m_name = newName;
5333 }
5334}
5335
5336KJSProxy *KHTMLPart::framejScript(KParts::ReadOnlyPart *framePart)
5337{
5338 KHTMLPart* const kp = qobject_cast<KHTMLPart*>(framePart);
5339 if (kp)
5340 return kp->jScript();
5341
5342 FrameIt it = d->m_frames.begin();
5343 const FrameIt itEnd = d->m_frames.end();
5344
5345 for (; it != itEnd; ++it) {
5346 khtml::ChildFrame* frame = *it;
5347 if (framePart == frame->m_part.data()) {
5348 if (!frame->m_jscript)
5349 frame->m_jscript = new KJSProxy(frame);
5350 return frame->m_jscript;
5351 }
5352 }
5353 return 0L;
5354}
5355
5356KHTMLPart *KHTMLPart::parentPart()
5357{
5358 return qobject_cast<KHTMLPart*>( parent() );
5359}
5360
5361khtml::ChildFrame *KHTMLPart::recursiveFrameRequest( KHTMLPart *callingHtmlPart, const KUrl &url,
5362 const KParts::OpenUrlArguments &args,
5363 const KParts::BrowserArguments &browserArgs, bool callParent )
5364{
5365#ifdef DEBUG_FINDFRAME
5366 kDebug( 6050 ) << this << "frame = " << browserArgs.frameName << "url = " << url;
5367#endif
5368 khtml::ChildFrame *childFrame;
5369 KHTMLPart *childPart = findFrameParent(callingHtmlPart, browserArgs.frameName, &childFrame);
5370 if (childPart)
5371 {
5372 if (childPart == this)
5373 return childFrame;
5374
5375 childPart->requestObject( childFrame, url, args, browserArgs );
5376 return 0;
5377 }
5378
5379 if ( parentPart() && callParent )
5380 {
5381 khtml::ChildFrame *res = parentPart()->recursiveFrameRequest( callingHtmlPart, url, args, browserArgs, callParent );
5382
5383 if ( res )
5384 parentPart()->requestObject( res, url, args, browserArgs );
5385 }
5386
5387 return 0L;
5388}
5389
5390#ifdef DEBUG_SAVESTATE
5391static int s_saveStateIndentLevel = 0;
5392#endif
5393
5394void KHTMLPart::saveState( QDataStream &stream )
5395{
5396#ifdef DEBUG_SAVESTATE
5397 QString indent= QString().leftJustified( s_saveStateIndentLevel * 4, ' ' );
5398 const int indentLevel = s_saveStateIndentLevel++;
5399 kDebug( 6050 ) << indent << "saveState this=" << this << " '" << objectName() << "' saving URL " << url().url();
5400#endif
5401
5402 stream << url() << (qint32)d->m_view->contentsX() << (qint32)d->m_view->contentsY()
5403 << (qint32) d->m_view->contentsWidth() << (qint32) d->m_view->contentsHeight() << (qint32) d->m_view->marginWidth() << (qint32) d->m_view->marginHeight();
5404
5405 // save link cursor position
5406 int focusNodeNumber;
5407 if (!d->m_focusNodeRestored)
5408 focusNodeNumber = d->m_focusNodeNumber;
5409 else if (d->m_doc && d->m_doc->focusNode())
5410 focusNodeNumber = d->m_doc->nodeAbsIndex(d->m_doc->focusNode());
5411 else
5412 focusNodeNumber = -1;
5413 stream << focusNodeNumber;
5414
5415 // Save the doc's cache id.
5416 stream << d->m_cacheId;
5417
5418 // Save the state of the document (Most notably the state of any forms)
5419 QStringList docState;
5420 if (d->m_doc)
5421 {
5422 docState = d->m_doc->docState();
5423 }
5424 stream << d->m_encoding << d->m_sheetUsed << docState;
5425
5426 stream << d->m_zoomFactor;
5427 stream << d->m_fontScaleFactor;
5428
5429 stream << d->m_httpHeaders;
5430 stream << d->m_pageServices;
5431 stream << d->m_pageReferrer;
5432
5433 // Save ssl data
5434 stream << d->m_ssl_in_use
5435 << d->m_ssl_peer_chain
5436 << d->m_ssl_peer_ip
5437 << d->m_ssl_cipher
5438 << d->m_ssl_protocol_version
5439 << d->m_ssl_cipher_used_bits
5440 << d->m_ssl_cipher_bits
5441 << d->m_ssl_cert_errors
5442 << d->m_ssl_parent_ip
5443 << d->m_ssl_parent_cert;
5444
5445
5446 QStringList frameNameLst, frameServiceTypeLst, frameServiceNameLst;
5447 KUrl::List frameURLLst;
5448 QList<QByteArray> frameStateBufferLst;
5449 QList<int> frameTypeLst;
5450
5451 ConstFrameIt it = d->m_frames.constBegin();
5452 const ConstFrameIt end = d->m_frames.constEnd();
5453 for (; it != end; ++it )
5454 {
5455 if ( !(*it)->m_part )
5456 continue;
5457
5458 frameNameLst << (*it)->m_name;
5459 frameServiceTypeLst << (*it)->m_serviceType;
5460 frameServiceNameLst << (*it)->m_serviceName;
5461 frameURLLst << (*it)->m_part.data()->url();
5462
5463 QByteArray state;
5464 QDataStream frameStream( &state, QIODevice::WriteOnly );
5465
5466 if ( (*it)->m_extension )
5467 (*it)->m_extension.data()->saveState( frameStream );
5468
5469 frameStateBufferLst << state;
5470
5471 frameTypeLst << int( (*it)->m_type );
5472 }
5473
5474 // Save frame data
5475 stream << (quint32) frameNameLst.count();
5476 stream << frameNameLst << frameServiceTypeLst << frameServiceNameLst << frameURLLst << frameStateBufferLst << frameTypeLst;
5477#ifdef DEBUG_SAVESTATE
5478 s_saveStateIndentLevel = indentLevel;
5479#endif
5480}
5481
5482void KHTMLPart::restoreState( QDataStream &stream )
5483{
5484 KUrl u;
5485 qint32 xOffset, yOffset, wContents, hContents, mWidth, mHeight;
5486 quint32 frameCount;
5487 QStringList frameNames, frameServiceTypes, docState, frameServiceNames;
5488 QList<int> frameTypes;
5489 KUrl::List frameURLs;
5490 QList<QByteArray> frameStateBuffers;
5491 QList<int> fSizes;
5492 QString encoding, sheetUsed;
5493 long old_cacheId = d->m_cacheId;
5494
5495 stream >> u >> xOffset >> yOffset >> wContents >> hContents >> mWidth >> mHeight;
5496
5497 d->m_view->setMarginWidth( mWidth );
5498 d->m_view->setMarginHeight( mHeight );
5499
5500 // restore link cursor position
5501 // nth node is active. value is set in checkCompleted()
5502 stream >> d->m_focusNodeNumber;
5503 d->m_focusNodeRestored = false;
5504
5505 stream >> d->m_cacheId;
5506
5507 stream >> encoding >> sheetUsed >> docState;
5508
5509 d->m_encoding = encoding;
5510 d->m_sheetUsed = sheetUsed;
5511
5512 int zoomFactor;
5513 stream >> zoomFactor;
5514 setZoomFactor(zoomFactor);
5515
5516 int fontScaleFactor;
5517 stream >> fontScaleFactor;
5518 setFontScaleFactor(fontScaleFactor);
5519
5520 stream >> d->m_httpHeaders;
5521 stream >> d->m_pageServices;
5522 stream >> d->m_pageReferrer;
5523
5524 // Restore ssl data
5525 stream >> d->m_ssl_in_use
5526 >> d->m_ssl_peer_chain
5527 >> d->m_ssl_peer_ip
5528 >> d->m_ssl_cipher
5529 >> d->m_ssl_protocol_version
5530 >> d->m_ssl_cipher_used_bits
5531 >> d->m_ssl_cipher_bits
5532 >> d->m_ssl_cert_errors
5533 >> d->m_ssl_parent_ip
5534 >> d->m_ssl_parent_cert;
5535
5536 setPageSecurity( d->m_ssl_in_use ? Encrypted : NotCrypted );
5537
5538 stream >> frameCount >> frameNames >> frameServiceTypes >> frameServiceNames
5539 >> frameURLs >> frameStateBuffers >> frameTypes;
5540
5541 d->m_bComplete = false;
5542 d->m_bLoadEventEmitted = false;
5543
5544// kDebug( 6050 ) << "docState.count() = " << docState.count();
5545// kDebug( 6050 ) << "m_url " << url().url() << " <-> " << u.url();
5546// kDebug( 6050 ) << "m_frames.count() " << d->m_frames.count() << " <-> " << frameCount;
5547
5548 if (d->m_cacheId == old_cacheId && signed(frameCount) == d->m_frames.count())
5549 {
5550 // Partial restore
5551 d->m_redirectionTimer.stop();
5552
5553 FrameIt fIt = d->m_frames.begin();
5554 const FrameIt fEnd = d->m_frames.end();
5555
5556 for (; fIt != fEnd; ++fIt )
5557 (*fIt)->m_bCompleted = false;
5558
5559 fIt = d->m_frames.begin();
5560
5561 QStringList::ConstIterator fNameIt = frameNames.constBegin();
5562 QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.constBegin();
5563 QStringList::ConstIterator fServiceNameIt = frameServiceNames.constBegin();
5564 KUrl::List::ConstIterator fURLIt = frameURLs.constBegin();
5565 QList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.constBegin();
5566 QList<int>::ConstIterator fFrameTypeIt = frameTypes.constBegin();
5567
5568 for (; fIt != fEnd; ++fIt, ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt, ++fFrameTypeIt )
5569 {
5570 khtml::ChildFrame* const child = *fIt;
5571
5572// kDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt;
5573
5574 if ( child->m_name != *fNameIt || child->m_serviceType != *fServiceTypeIt )
5575 {
5576 child->m_bPreloaded = true;
5577 child->m_name = *fNameIt;
5578 child->m_serviceName = *fServiceNameIt;
5579 child->m_type = static_cast<khtml::ChildFrame::Type>(*fFrameTypeIt);
5580 processObjectRequest( child, *fURLIt, *fServiceTypeIt );
5581 }
5582 if ( child->m_part )
5583 {
5584 child->m_bCompleted = false;
5585 if ( child->m_extension && !(*fBufferIt).isEmpty() )
5586 {
5587 QDataStream frameStream( *fBufferIt );
5588 child->m_extension.data()->restoreState( frameStream );
5589 }
5590 else
5591 child->m_part.data()->openUrl( *fURLIt );
5592 }
5593 }
5594
5595 KParts::OpenUrlArguments args( arguments() );
5596 args.setXOffset(xOffset);
5597 args.setYOffset(yOffset);
5598 setArguments(args);
5599
5600 KParts::BrowserArguments browserArgs( d->m_extension->browserArguments() );
5601 browserArgs.docState = docState;
5602 d->m_extension->setBrowserArguments(browserArgs);
5603
5604 d->m_view->resizeContents( wContents, hContents );
5605 d->m_view->setContentsPos( xOffset, yOffset );
5606
5607 setUrl(u);
5608 }
5609 else
5610 {
5611 // Full restore.
5612 closeUrl();
5613 // We must force a clear because we want to be sure to delete all
5614 // frames.
5615 d->m_bCleared = false;
5616 clear();
5617 d->m_encoding = encoding;
5618 d->m_sheetUsed = sheetUsed;
5619
5620 QStringList::ConstIterator fNameIt = frameNames.constBegin();
5621 const QStringList::ConstIterator fNameEnd = frameNames.constEnd();
5622
5623 QStringList::ConstIterator fServiceTypeIt = frameServiceTypes.constBegin();
5624 QStringList::ConstIterator fServiceNameIt = frameServiceNames.constBegin();
5625 KUrl::List::ConstIterator fURLIt = frameURLs.constBegin();
5626 QList<QByteArray>::ConstIterator fBufferIt = frameStateBuffers.constBegin();
5627 QList<int>::ConstIterator fFrameTypeIt = frameTypes.constBegin();
5628
5629 for (; fNameIt != fNameEnd; ++fNameIt, ++fServiceTypeIt, ++fServiceNameIt, ++fURLIt, ++fBufferIt, ++fFrameTypeIt )
5630 {
5631 khtml::ChildFrame* const newChild = new khtml::ChildFrame;
5632 newChild->m_bPreloaded = true;
5633 newChild->m_name = *fNameIt;
5634 newChild->m_serviceName = *fServiceNameIt;
5635 newChild->m_type = static_cast<khtml::ChildFrame::Type>(*fFrameTypeIt);
5636
5637// kDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt;
5638
5639 const FrameIt childFrame = d->m_frames.insert( d->m_frames.end(), newChild );
5640
5641 processObjectRequest( *childFrame, *fURLIt, *fServiceTypeIt );
5642
5643 (*childFrame)->m_bPreloaded = true;
5644
5645 if ( (*childFrame)->m_part )
5646 {
5647 if ( (*childFrame)->m_extension && !(*fBufferIt).isEmpty() )
5648 {
5649 QDataStream frameStream( *fBufferIt );
5650 (*childFrame)->m_extension.data()->restoreState( frameStream );
5651 }
5652 else
5653 (*childFrame)->m_part.data()->openUrl( *fURLIt );
5654 }
5655 }
5656
5657 KParts::OpenUrlArguments args( arguments() );
5658 args.setXOffset(xOffset);
5659 args.setYOffset(yOffset);
5660 setArguments(args);
5661
5662 KParts::BrowserArguments browserArgs( d->m_extension->browserArguments() );
5663 browserArgs.docState = docState;
5664 d->m_extension->setBrowserArguments(browserArgs);
5665
5666 if (!KHTMLPageCache::self()->isComplete(d->m_cacheId))
5667 {
5668 d->m_restored = true;
5669 openUrl( u );
5670 d->m_restored = false;
5671 }
5672 else
5673 {
5674 restoreURL( u );
5675 }
5676 }
5677
5678}
5679
5680void KHTMLPart::show()
5681{
5682 if ( widget() )
5683 widget()->show();
5684}
5685
5686void KHTMLPart::hide()
5687{
5688 if ( widget() )
5689 widget()->hide();
5690}
5691
5692DOM::Node KHTMLPart::nodeUnderMouse() const
5693{
5694 return d->m_view->nodeUnderMouse();
5695}
5696
5697DOM::Node KHTMLPart::nonSharedNodeUnderMouse() const
5698{
5699 return d->m_view->nonSharedNodeUnderMouse();
5700}
5701
5702void KHTMLPart::emitSelectionChanged()
5703{
5704 // Don't emit signals about our selection if this is a frameset;
5705 // the active frame has the selection (#187403)
5706 if (!d->m_activeFrame)
5707 {
5708 emit d->m_extension->enableAction( "copy", hasSelection() );
5709 emit d->m_extension->selectionInfo( selectedText() );
5710 emit selectionChanged();
5711 }
5712}
5713
5714int KHTMLPart::zoomFactor() const
5715{
5716 return d->m_zoomFactor;
5717}
5718
5719// ### make the list configurable ?
5720static const int zoomSizes[] = { 20, 40, 60, 80, 90, 95, 100, 105, 110, 120, 140, 160, 180, 200, 250, 300 };
5721static const int zoomSizeCount = (sizeof(zoomSizes) / sizeof(int));
5722static const int minZoom = 20;
5723static const int maxZoom = 300;
5724
5725// My idea of useful stepping ;-) (LS)
5726extern const int KDE_NO_EXPORT fastZoomSizes[] = { 20, 50, 75, 90, 100, 120, 150, 200, 300 };
5727extern const int KDE_NO_EXPORT fastZoomSizeCount = sizeof fastZoomSizes / sizeof fastZoomSizes[0];
5728
5729void KHTMLPart::slotIncZoom()
5730{
5731 zoomIn(zoomSizes, zoomSizeCount);
5732}
5733
5734void KHTMLPart::slotDecZoom()
5735{
5736 zoomOut(zoomSizes, zoomSizeCount);
5737}
5738
5739void KHTMLPart::slotIncZoomFast()
5740{
5741 zoomIn(fastZoomSizes, fastZoomSizeCount);
5742}
5743
5744void KHTMLPart::slotDecZoomFast()
5745{
5746 zoomOut(fastZoomSizes, fastZoomSizeCount);
5747}
5748
5749void KHTMLPart::zoomIn(const int stepping[], int count)
5750{
5751 int zoomFactor = d->m_zoomFactor;
5752
5753 if (zoomFactor < maxZoom) {
5754 // find the entry nearest to the given zoomsizes
5755 for (int i = 0; i < count; ++i)
5756 if (stepping[i] > zoomFactor) {
5757 zoomFactor = stepping[i];
5758 break;
5759 }
5760 setZoomFactor(zoomFactor);
5761 }
5762}
5763
5764void KHTMLPart::zoomOut(const int stepping[], int count)
5765{
5766 int zoomFactor = d->m_zoomFactor;
5767 if (zoomFactor > minZoom) {
5768 // find the entry nearest to the given zoomsizes
5769 for (int i = count-1; i >= 0; --i)
5770 if (stepping[i] < zoomFactor) {
5771 zoomFactor = stepping[i];
5772 break;
5773 }
5774 setZoomFactor(zoomFactor);
5775 }
5776}
5777
5778void KHTMLPart::setZoomFactor (int percent)
5779{
5780 // ### zooming under 100% is majorly botched,
5781 // so disable that for now.
5782 if (percent < 100) percent = 100;
5783 // ### if (percent < minZoom) percent = minZoom;
5784
5785 if (percent > maxZoom) percent = maxZoom;
5786 if (d->m_zoomFactor == percent) return;
5787 d->m_zoomFactor = percent;
5788
5789 updateZoomFactor();
5790}
5791
5792
5793void KHTMLPart::updateZoomFactor ()
5794{
5795 if(d->m_view) {
5796 QApplication::setOverrideCursor( Qt::WaitCursor );
5797 d->m_view->setZoomLevel( d->m_zoomFactor );
5798 QApplication::restoreOverrideCursor();
5799 }
5800
5801 ConstFrameIt it = d->m_frames.constBegin();
5802 const ConstFrameIt end = d->m_frames.constEnd();
5803 for (; it != end; ++it ) {
5804 if ( KHTMLPart* p = qobject_cast<KHTMLPart*>((*it)->m_part.data()) )
5805 p->setZoomFactor(d->m_zoomFactor);
5806 }
5807
5808 if ( d->m_guiProfile == BrowserViewGUI ) {
5809 d->m_paDecZoomFactor->setEnabled( d->m_zoomFactor > minZoom );
5810 d->m_paIncZoomFactor->setEnabled( d->m_zoomFactor < maxZoom );
5811 }
5812}
5813
5814void KHTMLPart::slotIncFontSize()
5815{
5816 incFontSize(zoomSizes, zoomSizeCount);
5817}
5818
5819void KHTMLPart::slotDecFontSize()
5820{
5821 decFontSize(zoomSizes, zoomSizeCount);
5822}
5823
5824void KHTMLPart::slotIncFontSizeFast()
5825{
5826 incFontSize(fastZoomSizes, fastZoomSizeCount);
5827}
5828
5829void KHTMLPart::slotDecFontSizeFast()
5830{
5831 decFontSize(fastZoomSizes, fastZoomSizeCount);
5832}
5833
5834void KHTMLPart::incFontSize(const int stepping[], int count)
5835{
5836 int zoomFactor = d->m_fontScaleFactor;
5837
5838 if (zoomFactor < maxZoom) {
5839 // find the entry nearest to the given zoomsizes
5840 for (int i = 0; i < count; ++i)
5841 if (stepping[i] > zoomFactor) {
5842 zoomFactor = stepping[i];
5843 break;
5844 }
5845 setFontScaleFactor(zoomFactor);
5846 }
5847}
5848
5849void KHTMLPart::decFontSize(const int stepping[], int count)
5850{
5851 int zoomFactor = d->m_fontScaleFactor;
5852 if (zoomFactor > minZoom) {
5853 // find the entry nearest to the given zoomsizes
5854 for (int i = count-1; i >= 0; --i)
5855 if (stepping[i] < zoomFactor) {
5856 zoomFactor = stepping[i];
5857 break;
5858 }
5859 setFontScaleFactor(zoomFactor);
5860 }
5861}
5862
5863void KHTMLPart::setFontScaleFactor(int percent)
5864{
5865 if (percent < minZoom) percent = minZoom;
5866 if (percent > maxZoom) percent = maxZoom;
5867 if (d->m_fontScaleFactor == percent) return;
5868 d->m_fontScaleFactor = percent;
5869
5870 if (d->m_view && d->m_doc) {
5871 QApplication::setOverrideCursor( Qt::WaitCursor );
5872 if (d->m_doc->styleSelector())
5873 d->m_doc->styleSelector()->computeFontSizes(d->m_doc->logicalDpiY(), d->m_fontScaleFactor);
5874 d->m_doc->recalcStyle( NodeImpl::Force );
5875 QApplication::restoreOverrideCursor();
5876 }
5877
5878 ConstFrameIt it = d->m_frames.constBegin();
5879 const ConstFrameIt end = d->m_frames.constEnd();
5880 for (; it != end; ++it ) {
5881 if ( KHTMLPart* p = qobject_cast<KHTMLPart*>((*it)->m_part.data()) )
5882 p->setFontScaleFactor(d->m_fontScaleFactor);
5883 }
5884}
5885
5886int KHTMLPart::fontScaleFactor() const
5887{
5888 return d->m_fontScaleFactor;
5889}
5890
5891void KHTMLPart::slotZoomView( int delta )
5892{
5893 if ( delta < 0 )
5894 slotIncZoom();
5895 else
5896 slotDecZoom();
5897}
5898
5899void KHTMLPart::setStatusBarText( const QString& text, StatusBarPriority p)
5900{
5901 if (!d->m_statusMessagesEnabled)
5902 return;
5903
5904 d->m_statusBarText[p] = text;
5905
5906 // shift handling ?
5907 QString tobe = d->m_statusBarText[BarHoverText];
5908 if (tobe.isEmpty())
5909 tobe = d->m_statusBarText[BarOverrideText];
5910 if (tobe.isEmpty()) {
5911 tobe = d->m_statusBarText[BarDefaultText];
5912 if (!tobe.isEmpty() && d->m_jobspeed)
5913 tobe += " ";
5914 if (d->m_jobspeed)
5915 tobe += i18n( "(%1/s)" , KIO::convertSize( d->m_jobspeed ) );
5916 }
5917 tobe = "<qt>"+tobe;
5918
5919 emit ReadOnlyPart::setStatusBarText(tobe);
5920}
5921
5922
5923void KHTMLPart::setJSStatusBarText( const QString &text )
5924{
5925 setStatusBarText(text, BarOverrideText);
5926}
5927
5928void KHTMLPart::setJSDefaultStatusBarText( const QString &text )
5929{
5930 setStatusBarText(text, BarDefaultText);
5931}
5932
5933QString KHTMLPart::jsStatusBarText() const
5934{
5935 return d->m_statusBarText[BarOverrideText];
5936}
5937
5938QString KHTMLPart::jsDefaultStatusBarText() const
5939{
5940 return d->m_statusBarText[BarDefaultText];
5941}
5942
5943QString KHTMLPart::referrer() const
5944{
5945 return d->m_referrer;
5946}
5947
5948QString KHTMLPart::pageReferrer() const
5949{
5950 KUrl referrerURL = KUrl( d->m_pageReferrer );
5951 if (referrerURL.isValid())
5952 {
5953 QString protocol = referrerURL.protocol();
5954
5955 if ((protocol == "http") ||
5956 ((protocol == "https") && (url().protocol() == "https")))
5957 {
5958 referrerURL.setRef(QString());
5959 referrerURL.setUser(QString());
5960 referrerURL.setPass(QString());
5961 return referrerURL.url();
5962 }
5963 }
5964
5965 return QString();
5966}
5967
5968
5969QString KHTMLPart::lastModified() const
5970{
5971 if ( d->m_lastModified.isEmpty() && url().isLocalFile() ) {
5972 // Local file: set last-modified from the file's mtime.
5973 // Done on demand to save time when this isn't needed - but can lead
5974 // to slightly wrong results if updating the file on disk w/o reloading.
5975 QDateTime lastModif = QFileInfo( url().toLocalFile() ).lastModified();
5976 d->m_lastModified = lastModif.toString( Qt::LocalDate );
5977 }
5978 //kDebug(6050) << d->m_lastModified;
5979 return d->m_lastModified;
5980}
5981
5982void KHTMLPart::slotLoadImages()
5983{
5984 if (d->m_doc )
5985 d->m_doc->docLoader()->setAutoloadImages( !d->m_doc->docLoader()->autoloadImages() );
5986
5987 ConstFrameIt it = d->m_frames.constBegin();
5988 const ConstFrameIt end = d->m_frames.constEnd();
5989 for (; it != end; ++it ) {
5990 if ( KHTMLPart* p = qobject_cast<KHTMLPart*>((*it)->m_part.data()) )
5991 p->slotLoadImages();
5992 }
5993}
5994
5995void KHTMLPart::reparseConfiguration()
5996{
5997 KHTMLSettings *settings = KHTMLGlobal::defaultHTMLSettings();
5998 settings->init();
5999
6000 setAutoloadImages( settings->autoLoadImages() );
6001 if (d->m_doc)
6002 d->m_doc->docLoader()->setShowAnimations( settings->showAnimations() );
6003
6004 d->m_bOpenMiddleClick = settings->isOpenMiddleClickEnabled();
6005 d->m_bJScriptEnabled = settings->isJavaScriptEnabled(url().host());
6006 setDebugScript( settings->isJavaScriptDebugEnabled() );
6007 d->m_bJavaEnabled = settings->isJavaEnabled(url().host());
6008 d->m_bPluginsEnabled = settings->isPluginsEnabled(url().host());
6009 d->m_metaRefreshEnabled = settings->isAutoDelayedActionsEnabled ();
6010
6011 delete d->m_settings;
6012 d->m_settings = new KHTMLSettings(*KHTMLGlobal::defaultHTMLSettings());
6013
6014 QApplication::setOverrideCursor( Qt::WaitCursor );
6015 khtml::CSSStyleSelector::reparseConfiguration();
6016 if(d->m_doc) d->m_doc->updateStyleSelector();
6017 QApplication::restoreOverrideCursor();
6018
6019 if (d->m_view) {
6020 KHTMLSettings::KSmoothScrollingMode ssm = d->m_settings->smoothScrolling();
6021 if (ssm == KHTMLSettings::KSmoothScrollingDisabled)
6022 d->m_view->setSmoothScrollingModeDefault(KHTMLView::SSMDisabled);
6023 else if (ssm == KHTMLSettings::KSmoothScrollingWhenEfficient)
6024 d->m_view->setSmoothScrollingModeDefault(KHTMLView::SSMWhenEfficient);
6025 else
6026 d->m_view->setSmoothScrollingModeDefault(KHTMLView::SSMEnabled);
6027 }
6028
6029 if (KHTMLGlobal::defaultHTMLSettings()->isAdFilterEnabled())
6030 runAdFilter();
6031}
6032
6033QStringList KHTMLPart::frameNames() const
6034{
6035 QStringList res;
6036
6037 ConstFrameIt it = d->m_frames.constBegin();
6038 const ConstFrameIt end = d->m_frames.constEnd();
6039 for (; it != end; ++it )
6040 if (!(*it)->m_bPreloaded && (*it)->m_part)
6041 res += (*it)->m_name;
6042
6043 return res;
6044}
6045
6046QList<KParts::ReadOnlyPart*> KHTMLPart::frames() const
6047{
6048 QList<KParts::ReadOnlyPart*> res;
6049
6050 ConstFrameIt it = d->m_frames.constBegin();
6051 const ConstFrameIt end = d->m_frames.constEnd();
6052 for (; it != end; ++it )
6053 if (!(*it)->m_bPreloaded && (*it)->m_part) // ### TODO: make sure that we always create an empty
6054 // KHTMLPart for frames so this never happens.
6055 res.append( (*it)->m_part.data() );
6056
6057 return res;
6058}
6059
6060bool KHTMLPart::openUrlInFrame( const KUrl &url, const KParts::OpenUrlArguments& args, const KParts::BrowserArguments &browserArgs)
6061{
6062 kDebug( 6031 ) << this << url;
6063 FrameIt it = d->m_frames.find( browserArgs.frameName );
6064
6065 if ( it == d->m_frames.end() )
6066 return false;
6067
6068 // Inform someone that we are about to show something else.
6069 if ( !browserArgs.lockHistory() )
6070 emit d->m_extension->openUrlNotify();
6071
6072 requestObject( *it, url, args, browserArgs );
6073
6074 return true;
6075}
6076
6077void KHTMLPart::setDNDEnabled( bool b )
6078{
6079 d->m_bDnd = b;
6080}
6081
6082bool KHTMLPart::dndEnabled() const
6083{
6084 return d->m_bDnd;
6085}
6086
6087void KHTMLPart::customEvent( QEvent *event )
6088{
6089 if ( khtml::MousePressEvent::test( event ) )
6090 {
6091 khtmlMousePressEvent( static_cast<khtml::MousePressEvent *>( event ) );
6092 return;
6093 }
6094
6095 if ( khtml::MouseDoubleClickEvent::test( event ) )
6096 {
6097 khtmlMouseDoubleClickEvent( static_cast<khtml::MouseDoubleClickEvent *>( event ) );
6098 return;
6099 }
6100
6101 if ( khtml::MouseMoveEvent::test( event ) )
6102 {
6103 khtmlMouseMoveEvent( static_cast<khtml::MouseMoveEvent *>( event ) );
6104 return;
6105 }
6106
6107 if ( khtml::MouseReleaseEvent::test( event ) )
6108 {
6109 khtmlMouseReleaseEvent( static_cast<khtml::MouseReleaseEvent *>( event ) );
6110 return;
6111 }
6112
6113 if ( khtml::DrawContentsEvent::test( event ) )
6114 {
6115 khtmlDrawContentsEvent( static_cast<khtml::DrawContentsEvent *>( event ) );
6116 return;
6117 }
6118
6119 KParts::ReadOnlyPart::customEvent( event );
6120}
6121
6122bool KHTMLPart::isPointInsideSelection(int x, int y)
6123{
6124 // Treat a collapsed selection like no selection.
6125 if (d->editor_context.m_selection.state() == Selection::CARET)
6126 return false;
6127 if (!xmlDocImpl()->renderer())
6128 return false;
6129
6130 khtml::RenderObject::NodeInfo nodeInfo(true, true);
6131 xmlDocImpl()->renderer()->layer()->nodeAtPoint(nodeInfo, x, y);
6132 NodeImpl *innerNode = nodeInfo.innerNode();
6133 if (!innerNode || !innerNode->renderer())
6134 return false;
6135
6136 return innerNode->isPointInsideSelection(x, y, d->editor_context.m_selection);
6137}
6138
6144static bool firstRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
6145{
6146 for (khtml::RenderObject *n = renderNode; n; n = n->nextSibling()) {
6147 if (n->isText()) {
6148 khtml::RenderText* const textRenderer = static_cast<khtml::RenderText *>(n);
6149 for (khtml::InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
6150 if (box->m_y == y && textRenderer->element()) {
6151 startNode = textRenderer->element();
6152 startOffset = box->m_start;
6153 return true;
6154 }
6155 }
6156 }
6157
6158 if (firstRunAt(n->firstChild(), y, startNode, startOffset)) {
6159 return true;
6160 }
6161 }
6162
6163 return false;
6164}
6165
6171static bool lastRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset)
6172{
6173 khtml::RenderObject *n = renderNode;
6174 if (!n) {
6175 return false;
6176 }
6177 khtml::RenderObject *next;
6178 while ((next = n->nextSibling())) {
6179 n = next;
6180 }
6181
6182 while (1) {
6183 if (lastRunAt(n->firstChild(), y, endNode, endOffset)) {
6184 return true;
6185 }
6186
6187 if (n->isText()) {
6188 khtml::RenderText* const textRenderer = static_cast<khtml::RenderText *>(n);
6189 for (khtml::InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
6190 if (box->m_y == y && textRenderer->element()) {
6191 endNode = textRenderer->element();
6192 endOffset = box->m_start + box->m_len;
6193 return true;
6194 }
6195 }
6196 }
6197
6198 if (n == renderNode) {
6199 return false;
6200 }
6201
6202 n = n->previousSibling();
6203 }
6204}
6205
6206void KHTMLPart::handleMousePressEventDoubleClick(khtml::MouseDoubleClickEvent *event)
6207{
6208 QMouseEvent *mouse = event->qmouseEvent();
6209 DOM::Node innerNode = event->innerNode();
6210
6211 Selection selection;
6212
6213 if (mouse->button() == Qt::LeftButton && !innerNode.isNull() && innerNode.handle()->renderer() &&
6214 innerNode.handle()->renderer()->shouldSelect()) {
6215 Position pos(innerNode.handle()->positionForCoordinates(event->x(), event->y()).position());
6216 if (pos.node() && (pos.node()->nodeType() == Node::TEXT_NODE || pos.node()->nodeType() == Node::CDATA_SECTION_NODE)) {
6217 selection.moveTo(pos);
6218 selection.expandUsingGranularity(Selection::WORD);
6219 }
6220 }
6221
6222 if (selection.state() != Selection::CARET) {
6223 d->editor_context.beginSelectingText(Selection::WORD);
6224 }
6225
6226 setCaret(selection);
6227 startAutoScroll();
6228}
6229
6230void KHTMLPart::handleMousePressEventTripleClick(khtml::MouseDoubleClickEvent *event)
6231{
6232 QMouseEvent *mouse = event->qmouseEvent();
6233 DOM::Node innerNode = event->innerNode();
6234
6235 Selection selection;
6236
6237 if (mouse->button() == Qt::LeftButton && !innerNode.isNull() && innerNode.handle()->renderer() &&
6238 innerNode.handle()->renderer()->shouldSelect()) {
6239 Position pos(innerNode.handle()->positionForCoordinates(event->x(), event->y()).position());
6240 if (pos.node() && (pos.node()->nodeType() == Node::TEXT_NODE || pos.node()->nodeType() == Node::CDATA_SECTION_NODE)) {
6241 selection.moveTo(pos);
6242 selection.expandUsingGranularity(Selection::LINE);
6243 }
6244 }
6245
6246 if (selection.state() != Selection::CARET) {
6247 d->editor_context.beginSelectingText(Selection::LINE);
6248 }
6249
6250 setCaret(selection);
6251 startAutoScroll();
6252}
6253
6254void KHTMLPart::handleMousePressEventSingleClick(khtml::MousePressEvent *event)
6255{
6256 QMouseEvent *mouse = event->qmouseEvent();
6257 DOM::Node innerNode = event->innerNode();
6258
6259 if (mouse->button() == Qt::LeftButton) {
6260 Selection sel;
6261
6262 if (!innerNode.isNull() && innerNode.handle()->renderer() &&
6263 innerNode.handle()->renderer()->shouldSelect()) {
6264 bool extendSelection = mouse->modifiers() & Qt::ShiftModifier;
6265
6266 // Don't restart the selection when the mouse is pressed on an
6267 // existing selection so we can allow for text dragging.
6268 if (!extendSelection && isPointInsideSelection(event->x(), event->y())) {
6269 return;
6270 }
6271 Position pos(innerNode.handle()->positionForCoordinates(event->x(), event->y()).position());
6272 if (pos.isEmpty())
6273 pos = Position(innerNode.handle(), innerNode.handle()->caretMinOffset());
6274 kDebug(6050) << event->x() << event->y() << pos << endl;
6275
6276 sel = caret();
6277 if (extendSelection && sel.notEmpty()) {
6278 sel.clearModifyBias();
6279 sel.setExtent(pos);
6280 if (d->editor_context.m_selectionGranularity != Selection::CHARACTER) {
6281 sel.expandUsingGranularity(d->editor_context.m_selectionGranularity);
6282 }
6283 d->editor_context.m_beganSelectingText = true;
6284 } else {
6285 sel = pos;
6286 d->editor_context.m_selectionGranularity = Selection::CHARACTER;
6287 }
6288 }
6289
6290 setCaret(sel);
6291 startAutoScroll();
6292 }
6293}
6294
6295void KHTMLPart::khtmlMousePressEvent( khtml::MousePressEvent *event )
6296{
6297 DOM::DOMString url = event->url();
6298 QMouseEvent *_mouse = event->qmouseEvent();
6299 DOM::Node innerNode = event->innerNode();
6300 d->m_mousePressNode = innerNode;
6301
6302 d->m_dragStartPos = QPoint(event->x(), event->y());
6303
6304 if ( !event->url().isNull() ) {
6305 d->m_strSelectedURL = event->url().string();
6306 d->m_strSelectedURLTarget = event->target().string();
6307 }
6308 else {
6309 d->m_strSelectedURL.clear();
6310 d->m_strSelectedURLTarget.clear();
6311 }
6312
6313 if ( _mouse->button() == Qt::LeftButton ||
6314 _mouse->button() == Qt::MidButton )
6315 {
6316 d->m_bMousePressed = true;
6317
6318#ifdef KHTML_NO_SELECTION
6319 d->m_dragLastPos = _mouse->globalPos();
6320#else
6321 if ( _mouse->button() == Qt::LeftButton )
6322 {
6323 if ( (!d->m_strSelectedURL.isNull() && !isEditable())
6324 || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) )
6325 return;
6326
6327 d->editor_context.m_beganSelectingText = false;
6328
6329 handleMousePressEventSingleClick(event);
6330 }
6331#endif
6332 }
6333
6334 if ( _mouse->button() == Qt::RightButton )
6335 {
6336 popupMenu( d->m_strSelectedURL );
6337 // might be deleted, don't touch "this"
6338 }
6339}
6340
6341void KHTMLPart::khtmlMouseDoubleClickEvent( khtml::MouseDoubleClickEvent *event )
6342{
6343 QMouseEvent *_mouse = event->qmouseEvent();
6344 if ( _mouse->button() == Qt::LeftButton )
6345 {
6346 d->m_bMousePressed = true;
6347 d->editor_context.m_beganSelectingText = false;
6348
6349 if (event->clickCount() == 2) {
6350 handleMousePressEventDoubleClick(event);
6351 return;
6352 }
6353
6354 if (event->clickCount() >= 3) {
6355 handleMousePressEventTripleClick(event);
6356 return;
6357 }
6358 }
6359}
6360
6361#ifndef KHTML_NO_SELECTION
6362bool KHTMLPart::isExtendingSelection() const
6363 {
6364 // This is it, the whole detection. khtmlMousePressEvent only sets this
6365 // on LMB or MMB, but never on RMB. As text selection doesn't work for MMB,
6366 // it's sufficient to only rely on this flag to detect selection extension.
6367 return d->editor_context.m_beganSelectingText;
6368}
6369
6370void KHTMLPart::extendSelectionTo(int x, int y, const DOM::Node &innerNode)
6371{
6372 // handle making selection
6373 Position pos(innerNode.handle()->positionForCoordinates(x, y).position());
6374
6375 // Don't modify the selection if we're not on a node.
6376 if (pos.isEmpty())
6377 return;
6378
6379 // Restart the selection if this is the first mouse move. This work is usually
6380 // done in khtmlMousePressEvent, but not if the mouse press was on an existing selection.
6381 Selection sel = caret();
6382 sel.clearModifyBias();
6383 if (!d->editor_context.m_beganSelectingText) {
6384 // We are beginning a selection during press-drag, when the original click
6385 // wasn't appropriate for one. Make sure to set the granularity.
6386 d->editor_context.beginSelectingText(Selection::CHARACTER);
6387 sel.moveTo(pos);
6388 }
6389
6390 sel.setExtent(pos);
6391 if (d->editor_context.m_selectionGranularity != Selection::CHARACTER) {
6392 sel.expandUsingGranularity(d->editor_context.m_selectionGranularity);
6393 }
6394 setCaret(sel);
6395
6396}
6397#endif // KHTML_NO_SELECTION
6398
6399bool KHTMLPart::handleMouseMoveEventDrag(khtml::MouseMoveEvent *event)
6400{
6401#ifdef QT_NO_DRAGANDDROP
6402 return false;
6403#else
6404 if (!dndEnabled())
6405 return false;
6406
6407 if( (d->m_bMousePressed &&
6408 ( (!d->m_strSelectedURL.isEmpty() && !isEditable())
6409 || (!d->m_mousePressNode.isNull() && d->m_mousePressNode.elementId() == ID_IMG) ) )
6410 && ( d->m_dragStartPos - QPoint(event->x(), event->y()) ).manhattanLength() > KGlobalSettings::dndEventDelay() ) {
6411
6412 const DOM::DOMString url = event->url();
6413 DOM::NodeImpl* innerNodeImpl = event->innerNode().handle();
6414
6415 QPixmap pix;
6416 HTMLImageElementImpl *img = 0L;
6417 KUrl u;
6418
6419 // qDebug("****************** Event URL: %s", url.string().toLatin1().constData());
6420 // qDebug("****************** Event Target: %s", target.string().toLatin1().constData());
6421
6422 // Normal image...
6423 if (url.isEmpty() && innerNodeImpl && innerNodeImpl->id() == ID_IMG)
6424 {
6425 img = static_cast<HTMLImageElementImpl *>(innerNodeImpl);
6426 u = completeURL(img->getAttribute(ATTR_SRC).parsedUrl().string());
6427 pix = KIconLoader::global()->loadIcon("image-x-generic", KIconLoader::Desktop);
6428 }
6429 else
6430 {
6431 // Text or image link...
6432 u = completeURL( d->m_strSelectedURL );
6433 pix = KIO::pixmapForUrl(u, 0, KIconLoader::Desktop, KIconLoader::SizeMedium);
6434 }
6435
6436 u.setPass(QString());
6437
6438 QDrag *drag = new QDrag( d->m_view->viewport() );
6439 QMap<QString, QString> metaDataMap;
6440 if ( !d->m_referrer.isEmpty() )
6441 metaDataMap.insert( "referrer", d->m_referrer );
6442 QMimeData* mimeData = new QMimeData();
6443 u.populateMimeData( mimeData, metaDataMap );
6444 drag->setMimeData( mimeData );
6445
6446 if( img && img->complete() )
6447 drag->mimeData()->setImageData( img->currentImage() );
6448
6449 if ( !pix.isNull() )
6450 drag->setPixmap( pix );
6451
6452 stopAutoScroll();
6453 drag->start();
6454
6455 // when we finish our drag, we need to undo our mouse press
6456 d->m_bMousePressed = false;
6457 d->m_strSelectedURL.clear();
6458 d->m_strSelectedURLTarget.clear();
6459 return true;
6460 }
6461 return false;
6462#endif // QT_NO_DRAGANDDROP
6463}
6464
6465bool KHTMLPart::handleMouseMoveEventOver(khtml::MouseMoveEvent *event)
6466{
6467 // Mouse clicked -> do nothing
6468 if ( d->m_bMousePressed ) return false;
6469
6470 DOM::DOMString url = event->url();
6471
6472 // The mouse is over something
6473 if ( url.length() )
6474 {
6475 DOM::DOMString target = event->target();
6476 QMouseEvent *_mouse = event->qmouseEvent();
6477 DOM::Node innerNode = event->innerNode();
6478
6479 bool shiftPressed = ( _mouse->modifiers() & Qt::ShiftModifier );
6480
6481 // Image map
6482 if ( !innerNode.isNull() && innerNode.elementId() == ID_IMG )
6483 {
6484 HTMLImageElementImpl *i = static_cast<HTMLImageElementImpl *>(innerNode.handle());
6485 if ( i && i->isServerMap() )
6486 {
6487 khtml::RenderObject *r = i->renderer();
6488 if(r)
6489 {
6490 int absx, absy;
6491 r->absolutePosition(absx, absy);
6492 int x(event->x() - absx), y(event->y() - absy);
6493
6494 d->m_overURL = url.string() + QString("?%1,%2").arg(x).arg(y);
6495 d->m_overURLTarget = target.string();
6496 overURL( d->m_overURL, target.string(), shiftPressed );
6497 return true;
6498 }
6499 }
6500 }
6501
6502 // normal link
6503 if ( d->m_overURL.isEmpty() || d->m_overURL != url || d->m_overURLTarget != target )
6504 {
6505 d->m_overURL = url.string();
6506 d->m_overURLTarget = target.string();
6507 overURL( d->m_overURL, target.string(), shiftPressed );
6508 }
6509 }
6510 else // Not over a link...
6511 {
6512 if( !d->m_overURL.isEmpty() ) // and we were over a link -> reset to "default statusbar text"
6513 {
6514 // reset to "default statusbar text"
6515 resetHoverText();
6516 }
6517 }
6518 return true;
6519}
6520
6521void KHTMLPart::handleMouseMoveEventSelection(khtml::MouseMoveEvent *event)
6522{
6523 // Mouse not pressed. Do nothing.
6524 if (!d->m_bMousePressed)
6525 return;
6526
6527#ifdef KHTML_NO_SELECTION
6528 if (d->m_doc && d->m_view) {
6529 QPoint diff( mouse->globalPos() - d->m_dragLastPos );
6530
6531 if (abs(diff.x()) > 64 || abs(diff.y()) > 64) {
6532 d->m_view->scrollBy(-diff.x(), -diff.y());
6533 d->m_dragLastPos = mouse->globalPos();
6534 }
6535 }
6536#else
6537
6538 QMouseEvent *mouse = event->qmouseEvent();
6539 DOM::Node innerNode = event->innerNode();
6540
6541 if ( (mouse->buttons() & Qt::LeftButton) == 0 || !innerNode.handle() || !innerNode.handle()->renderer() ||
6542 !innerNode.handle()->renderer()->shouldSelect())
6543 return;
6544
6545 // handle making selection
6546 extendSelectionTo(event->x(), event->y(), innerNode);
6547#endif // KHTML_NO_SELECTION
6548}
6549
6550void KHTMLPart::khtmlMouseMoveEvent( khtml::MouseMoveEvent *event )
6551{
6552 if (handleMouseMoveEventDrag(event))
6553 return;
6554
6555 if (handleMouseMoveEventOver(event))
6556 return;
6557
6558 handleMouseMoveEventSelection(event);
6559}
6560
6561void KHTMLPart::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent *event )
6562{
6563 DOM::Node innerNode = event->innerNode();
6564 d->m_mousePressNode = DOM::Node();
6565
6566 if ( d->m_bMousePressed ) {
6567 setStatusBarText(QString(), BarHoverText);
6568 stopAutoScroll();
6569 }
6570
6571 // Used to prevent mouseMoveEvent from initiating a drag before
6572 // the mouse is pressed again.
6573 d->m_bMousePressed = false;
6574
6575#ifndef QT_NO_CLIPBOARD
6576 QMouseEvent *_mouse = event->qmouseEvent();
6577 if ((d->m_guiProfile == BrowserViewGUI) && (_mouse->button() == Qt::MidButton) && (event->url().isNull())) {
6578 kDebug( 6050 ) << "MMB shouldOpen=" << d->m_bOpenMiddleClick;
6579
6580 if (d->m_bOpenMiddleClick) {
6581 KHTMLPart *p = this;
6582 while (p->parentPart()) p = p->parentPart();
6583 p->d->m_extension->pasteRequest();
6584 }
6585 }
6586#endif
6587
6588#ifndef KHTML_NO_SELECTION
6589 {
6590
6591 // Clear the selection if the mouse didn't move after the last mouse press.
6592 // We do this so when clicking on the selection, the selection goes away.
6593 // However, if we are editing, place the caret.
6594 if (!d->editor_context.m_beganSelectingText
6595 && d->m_dragStartPos.x() == event->x()
6596 && d->m_dragStartPos.y() == event->y()
6597 && d->editor_context.m_selection.state() == Selection::RANGE) {
6598 Selection selection;
6599#ifdef APPLE_CHANGES
6600 if (d->editor_context.m_selection.base().node()->isContentEditable())
6601#endif
6602 selection.moveTo(d->editor_context.m_selection.base().node()->positionForCoordinates(event->x(), event->y()).position());
6603 setCaret(selection);
6604 }
6605 // get selected text and paste to the clipboard
6606#ifndef QT_NO_CLIPBOARD
6607 QString text = selectedText();
6608 text.replace(QChar(0xa0), ' ');
6609 if (!text.isEmpty()) {
6610 disconnect( qApp->clipboard(), SIGNAL(selectionChanged()), this, SLOT(slotClearSelection()));
6611 qApp->clipboard()->setText(text,QClipboard::Selection);
6612 connect( qApp->clipboard(), SIGNAL(selectionChanged()), SLOT(slotClearSelection()));
6613 }
6614#endif
6615 //kDebug( 6000 ) << "selectedText = " << text;
6616 emitSelectionChanged();
6617//kDebug(6000) << "rel2: startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << "), caretOfs " << d->caretOffset();
6618 }
6619#endif
6620}
6621
6622void KHTMLPart::khtmlDrawContentsEvent( khtml::DrawContentsEvent * )
6623{
6624}
6625
6626void KHTMLPart::guiActivateEvent( KParts::GUIActivateEvent *event )
6627{
6628 if ( event->activated() )
6629 {
6630 emitSelectionChanged();
6631 emit d->m_extension->enableAction( "print", d->m_doc != 0 );
6632
6633 if ( !d->m_settings->autoLoadImages() && d->m_paLoadImages )
6634 {
6635 QList<QAction*> lst;
6636 lst.append( d->m_paLoadImages );
6637 plugActionList( "loadImages", lst );
6638 }
6639 }
6640}
6641
6642void KHTMLPart::slotPrintFrame()
6643{
6644 if ( d->m_frames.count() == 0 )
6645 return;
6646
6647 KParts::ReadOnlyPart *frame = currentFrame();
6648 if (!frame)
6649 return;
6650
6651 KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject( frame );
6652
6653 if ( !ext )
6654 return;
6655
6656
6657 const QMetaObject *mo = ext->metaObject();
6658
6659
6660 if (mo->indexOfSlot( "print()") != -1)
6661 QMetaObject::invokeMethod(ext, "print()", Qt::DirectConnection);
6662}
6663
6664void KHTMLPart::slotSelectAll()
6665{
6666 KParts::ReadOnlyPart *part = currentFrame();
6667 if (part && part->inherits("KHTMLPart"))
6668 static_cast<KHTMLPart *>(part)->selectAll();
6669}
6670
6671void KHTMLPart::startAutoScroll()
6672{
6673 connect(&d->m_scrollTimer, SIGNAL(timeout()), this, SLOT(slotAutoScroll()));
6674 d->m_scrollTimer.setSingleShot(false);
6675 d->m_scrollTimer.start(100);
6676}
6677
6678void KHTMLPart::stopAutoScroll()
6679{
6680 disconnect(&d->m_scrollTimer, SIGNAL(timeout()), this, SLOT(slotAutoScroll()));
6681 if (d->m_scrollTimer.isActive())
6682 d->m_scrollTimer.stop();
6683}
6684
6685
6686void KHTMLPart::slotAutoScroll()
6687{
6688 if (d->m_view)
6689 d->m_view->doAutoScroll();
6690 else
6691 stopAutoScroll(); // Safety
6692}
6693
6694void KHTMLPart::runAdFilter()
6695{
6696 if ( parentPart() )
6697 parentPart()->runAdFilter();
6698
6699 if ( !d->m_doc )
6700 return;
6701
6702 QSetIterator<khtml::CachedObject*> it( d->m_doc->docLoader()->m_docObjects );
6703 while (it.hasNext())
6704 {
6705 khtml::CachedObject* obj = it.next();
6706 if ( obj->type() == khtml::CachedObject::Image ) {
6707 khtml::CachedImage *image = static_cast<khtml::CachedImage *>(obj);
6708 bool wasBlocked = image->m_wasBlocked;
6709 image->m_wasBlocked = KHTMLGlobal::defaultHTMLSettings()->isAdFiltered( d->m_doc->completeURL( image->url().string() ) );
6710 if ( image->m_wasBlocked != wasBlocked )
6711 image->do_notify(QRect(QPoint(0,0), image->pixmap_size()));
6712 }
6713 }
6714
6715 if ( KHTMLGlobal::defaultHTMLSettings()->isHideAdsEnabled() ) {
6716 for ( NodeImpl *nextNode, *node = d->m_doc; node; node = nextNode ) {
6717
6718 // We might be deleting 'node' shortly.
6719 nextNode = node->traverseNextNode();
6720
6721 if ( node->id() == ID_IMG ||
6722 node->id() == ID_IFRAME ||
6723 (node->id() == ID_INPUT && static_cast<HTMLInputElementImpl *>(node)->inputType() == HTMLInputElementImpl::IMAGE ))
6724 {
6725 if (KHTMLGlobal::defaultHTMLSettings()->isAdFiltered(d->m_doc->completeURL(static_cast<ElementImpl *>(node)->getAttribute(ATTR_SRC).parsedUrl().string())))
6726 {
6727 // Since any kids of node will be deleted, too, fastforward nextNode
6728 // until we get outside of node.
6729 while (nextNode && nextNode->isAncestor(node))
6730 nextNode = nextNode->traverseNextNode();
6731
6732 node->ref();
6733 NodeImpl *parent = node->parent();
6734 if( parent )
6735 {
6736 int exception = 0;
6737 parent->removeChild(node, exception);
6738 }
6739 node->deref();
6740 }
6741 }
6742 }
6743 }
6744}
6745
6746void KHTMLPart::selectAll()
6747{
6748 if (!d->m_doc) return;
6749
6750 NodeImpl *first;
6751 if (d->m_doc->isHTMLDocument())
6752 first = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
6753 else
6754 first = d->m_doc;
6755 NodeImpl *next;
6756
6757 // Look for first text/cdata node that has a renderer,
6758 // or first childless replaced element
6759 while ( first && !(first->renderer()
6760 && ((first->nodeType() == Node::TEXT_NODE || first->nodeType() == Node::CDATA_SECTION_NODE)
6761 || (first->renderer()->isReplaced() && !first->renderer()->firstChild()))))
6762 {
6763 next = first->firstChild();
6764 if ( !next ) next = first->nextSibling();
6765 while( first && !next )
6766 {
6767 first = first->parentNode();
6768 if ( first )
6769 next = first->nextSibling();
6770 }
6771 first = next;
6772 }
6773
6774 NodeImpl *last;
6775 if (d->m_doc->isHTMLDocument())
6776 last = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
6777 else
6778 last = d->m_doc;
6779 // Look for last text/cdata node that has a renderer,
6780 // or last childless replaced element
6781 // ### Instead of changing this loop, use findLastSelectableNode
6782 // in render_table.cpp (LS)
6783 while ( last && !(last->renderer()
6784 && ((last->nodeType() == Node::TEXT_NODE || last->nodeType() == Node::CDATA_SECTION_NODE)
6785 || (last->renderer()->isReplaced() && !last->renderer()->lastChild()))))
6786 {
6787 next = last->lastChild();
6788 if ( !next ) next = last->previousSibling();
6789 while ( last && !next )
6790 {
6791 last = last->parentNode();
6792 if ( last )
6793 next = last->previousSibling();
6794 }
6795 last = next;
6796 }
6797
6798 if ( !first || !last )
6799 return;
6800 Q_ASSERT(first->renderer());
6801 Q_ASSERT(last->renderer());
6802 d->editor_context.m_selection.moveTo(Position(first, 0), Position(last, last->nodeValue().length()));
6803 d->m_doc->updateSelection();
6804
6805 emitSelectionChanged();
6806}
6807
6808bool KHTMLPart::checkLinkSecurity(const KUrl &linkURL,const KLocalizedString &message, const QString &button)
6809{
6810 bool linkAllowed = true;
6811
6812 if ( d->m_doc )
6813 linkAllowed = KAuthorized::authorizeUrlAction("redirect", url(), linkURL);
6814
6815 if ( !linkAllowed ) {
6816 khtml::Tokenizer *tokenizer = d->m_doc->tokenizer();
6817 if (tokenizer)
6818 tokenizer->setOnHold(true);
6819
6820 int response = KMessageBox::Cancel;
6821 if (!message.isEmpty())
6822 {
6823 // Dangerous flag makes the Cancel button the default
6824 response = KMessageBox::warningContinueCancel( 0,
6825 message.subs(Qt::escape(linkURL.prettyUrl())).toString(),
6826 i18n( "Security Warning" ),
6827 KGuiItem(button),
6828 KStandardGuiItem::cancel(),
6829 QString(), // no don't ask again info
6830 KMessageBox::Notify | KMessageBox::Dangerous );
6831 }
6832 else
6833 {
6834 KMessageBox::error( 0,
6835 i18n( "<qt>Access by untrusted page to<br /><b>%1</b><br /> denied.</qt>", Qt::escape(linkURL.prettyUrl())),
6836 i18n( "Security Alert" ));
6837 }
6838
6839 if (tokenizer)
6840 tokenizer->setOnHold(false);
6841 return (response==KMessageBox::Continue);
6842 }
6843 return true;
6844}
6845
6846void KHTMLPart::slotPartRemoved( KParts::Part *part )
6847{
6848// kDebug(6050) << part;
6849 if ( part == d->m_activeFrame )
6850 {
6851 d->m_activeFrame = 0L;
6852 if ( !part->inherits( "KHTMLPart" ) )
6853 {
6854 if (factory()) {
6855 factory()->removeClient( part );
6856 }
6857 if (childClients().contains(part)) {
6858 removeChildClient( part );
6859 }
6860 }
6861 }
6862}
6863
6864void KHTMLPart::slotActiveFrameChanged( KParts::Part *part )
6865{
6866// kDebug(6050) << this << "part=" << part;
6867 if ( part == this )
6868 {
6869 kError(6050) << "strange error! we activated ourselves";
6870 assert( false );
6871 return;
6872 }
6873// kDebug(6050) << "d->m_activeFrame=" << d->m_activeFrame;
6874 if ( d->m_activeFrame && d->m_activeFrame->widget() && d->m_activeFrame->widget()->inherits( "QFrame" ) )
6875 {
6876 QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
6877 if (frame->frameStyle() != QFrame::NoFrame)
6878 {
6879 frame->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken);
6880 frame->repaint();
6881 }
6882 }
6883
6884 if( d->m_activeFrame && !d->m_activeFrame->inherits( "KHTMLPart" ) )
6885 {
6886 if (factory()) {
6887 factory()->removeClient( d->m_activeFrame );
6888 }
6889 removeChildClient( d->m_activeFrame );
6890 }
6891 if( part && !part->inherits( "KHTMLPart" ) )
6892 {
6893 if (factory()) {
6894 factory()->addClient( part );
6895 }
6896 insertChildClient( part );
6897 }
6898
6899
6900 d->m_activeFrame = part;
6901
6902 if ( d->m_activeFrame && d->m_activeFrame->widget()->inherits( "QFrame" ) )
6903 {
6904 QFrame *frame = static_cast<QFrame *>( d->m_activeFrame->widget() );
6905 if (frame->frameStyle() != QFrame::NoFrame)
6906 {
6907 frame->setFrameStyle( QFrame::StyledPanel | QFrame::Plain);
6908 frame->repaint();
6909 }
6910 kDebug(6050) << "new active frame " << d->m_activeFrame;
6911 }
6912
6913 updateActions();
6914
6915 // (note: childObject returns 0 if the argument is 0)
6916 d->m_extension->setExtensionProxy( KParts::BrowserExtension::childObject( d->m_activeFrame ) );
6917}
6918
6919void KHTMLPart::setActiveNode(const DOM::Node &node)
6920{
6921 if (!d->m_doc || !d->m_view)
6922 return;
6923
6924 // Set the document's active node
6925 d->m_doc->setFocusNode(node.handle());
6926
6927 // Scroll the view if necessary to ensure that the new focus node is visible
6928 QRect rect = node.handle()->getRect();
6929 d->m_view->ensureVisible(rect.right(), rect.bottom());
6930 d->m_view->ensureVisible(rect.left(), rect.top());
6931}
6932
6933DOM::Node KHTMLPart::activeNode() const
6934{
6935 return DOM::Node(d->m_doc?d->m_doc->focusNode():0);
6936}
6937
6938DOM::EventListener *KHTMLPart::createHTMLEventListener( QString code, QString name, NodeImpl* node, bool svg )
6939{
6940 KJSProxy *proxy = jScript();
6941
6942 if (!proxy)
6943 return 0;
6944
6945 return proxy->createHTMLEventHandler( url().url(), name, code, node, svg );
6946}
6947
6948KHTMLPart *KHTMLPart::opener()
6949{
6950 return d->m_opener;
6951}
6952
6953void KHTMLPart::setOpener(KHTMLPart *_opener)
6954{
6955 d->m_opener = _opener;
6956}
6957
6958bool KHTMLPart::openedByJS()
6959{
6960 return d->m_openedByJS;
6961}
6962
6963void KHTMLPart::setOpenedByJS(bool _openedByJS)
6964{
6965 d->m_openedByJS = _openedByJS;
6966}
6967
6968void KHTMLPart::preloadStyleSheet(const QString &url, const QString &stylesheet)
6969{
6970 khtml::Cache::preloadStyleSheet(url, stylesheet);
6971}
6972
6973void KHTMLPart::preloadScript(const QString &url, const QString &script)
6974{
6975 khtml::Cache::preloadScript(url, script);
6976}
6977
6978long KHTMLPart::cacheId() const
6979{
6980 return d->m_cacheId;
6981}
6982
6983bool KHTMLPart::restored() const
6984{
6985 return d->m_restored;
6986}
6987
6988bool KHTMLPart::pluginPageQuestionAsked(const QString& mimetype) const
6989{
6990 // parentPart() should be const!
6991 KHTMLPart* parent = const_cast<KHTMLPart *>(this)->parentPart();
6992 if ( parent )
6993 return parent->pluginPageQuestionAsked(mimetype);
6994
6995 return d->m_pluginPageQuestionAsked.contains(mimetype);
6996}
6997
6998void KHTMLPart::setPluginPageQuestionAsked(const QString& mimetype)
6999{
7000 if ( parentPart() )
7001 parentPart()->setPluginPageQuestionAsked(mimetype);
7002
7003 d->m_pluginPageQuestionAsked.append(mimetype);
7004}
7005
7006KEncodingDetector *KHTMLPart::createDecoder()
7007{
7008 KEncodingDetector *dec = new KEncodingDetector();
7009 if( !d->m_encoding.isNull() )
7010 dec->setEncoding( d->m_encoding.toLatin1().constData(),
7011 d->m_haveEncoding ? KEncodingDetector::UserChosenEncoding : KEncodingDetector::EncodingFromHTTPHeader);
7012 else {
7013 // Inherit the default encoding from the parent frame if there is one.
7014 QByteArray defaultEncoding = (parentPart() && parentPart()->d->m_decoder)
7015 ? QByteArray( parentPart()->d->m_decoder->encoding() ) : settings()->encoding().toLatin1();
7016 dec->setEncoding(defaultEncoding.constData(), KEncodingDetector::DefaultEncoding);
7017 }
7018
7019 if (d->m_doc)
7020 d->m_doc->setDecoder(dec);
7021 dec->setAutoDetectLanguage( d->m_autoDetectLanguage );
7022 return dec;
7023}
7024
7025void KHTMLPart::emitCaretPositionChanged(const DOM::Position &pos) {
7026 // pos must not be already converted to range-compliant coordinates
7027 Position rng_pos = pos.equivalentRangeCompliantPosition();
7028 Node node = rng_pos.node();
7029 emit caretPositionChanged(node, rng_pos.offset());
7030}
7031
7032void KHTMLPart::restoreScrollPosition()
7033{
7034 const KParts::OpenUrlArguments args( arguments() );
7035
7036 if ( url().hasRef() && !d->m_restoreScrollPosition && !args.reload()) {
7037 if ( !d->m_doc || !d->m_doc->parsing() )
7038 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
7039 if ( !gotoAnchor(url().encodedHtmlRef()) )
7040 gotoAnchor(url().htmlRef());
7041 return;
7042 }
7043
7044 // Check whether the viewport has become large enough to encompass the stored
7045 // offsets. If the document has been fully loaded, force the new coordinates,
7046 // even if the canvas is too short (can happen when user resizes the window
7047 // during loading).
7048 if (d->m_view->contentsHeight() - d->m_view->visibleHeight() >= args.yOffset()
7049 || d->m_bComplete) {
7050 d->m_view->setContentsPos(args.xOffset(), args.yOffset());
7051 disconnect(d->m_view, SIGNAL(finishedLayout()), this, SLOT(restoreScrollPosition()));
7052 }
7053}
7054
7055
7056void KHTMLPart::openWallet(DOM::HTMLFormElementImpl *form)
7057{
7058#ifndef KHTML_NO_WALLET
7059 KHTMLPart *p;
7060
7061 for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
7062 }
7063
7064 if (p) {
7065 p->openWallet(form);
7066 return;
7067 }
7068
7069 if (onlyLocalReferences()) { // avoid triggering on local apps, thumbnails
7070 return;
7071 }
7072
7073 if (d->m_wallet) {
7074 if (d->m_bWalletOpened) {
7075 if (d->m_wallet->isOpen()) {
7076 form->walletOpened(d->m_wallet);
7077 return;
7078 }
7079 d->m_wallet->deleteLater();
7080 d->m_wallet = 0L;
7081 d->m_bWalletOpened = false;
7082 }
7083 }
7084
7085 if (!d->m_wq) {
7086 KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
7087 d->m_wq = new KHTMLWalletQueue(this);
7088 d->m_wq->wallet = wallet;
7089 connect(wallet, SIGNAL(walletOpened(bool)), d->m_wq, SLOT(walletOpened(bool)));
7090 connect(d->m_wq, SIGNAL(walletOpened(KWallet::Wallet*)), this, SLOT(walletOpened(KWallet::Wallet*)));
7091 }
7092 assert(form);
7093 d->m_wq->callers.append(KHTMLWalletQueue::Caller(form, form->document()));
7094#endif // KHTML_NO_WALLET
7095}
7096
7097
7098void KHTMLPart::saveToWallet(const QString& key, const QMap<QString,QString>& data)
7099{
7100#ifndef KHTML_NO_WALLET
7101 KHTMLPart *p;
7102
7103 for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
7104 }
7105
7106 if (p) {
7107 p->saveToWallet(key, data);
7108 return;
7109 }
7110
7111 if (d->m_wallet) {
7112 if (d->m_bWalletOpened) {
7113 if (d->m_wallet->isOpen()) {
7114 if (!d->m_wallet->hasFolder(KWallet::Wallet::FormDataFolder())) {
7115 d->m_wallet->createFolder(KWallet::Wallet::FormDataFolder());
7116 }
7117 d->m_wallet->setFolder(KWallet::Wallet::FormDataFolder());
7118 d->m_wallet->writeMap(key, data);
7119 return;
7120 }
7121 d->m_wallet->deleteLater();
7122 d->m_wallet = 0L;
7123 d->m_bWalletOpened = false;
7124 }
7125 }
7126
7127 if (!d->m_wq) {
7128 KWallet::Wallet *wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous);
7129 d->m_wq = new KHTMLWalletQueue(this);
7130 d->m_wq->wallet = wallet;
7131 connect(wallet, SIGNAL(walletOpened(bool)), d->m_wq, SLOT(walletOpened(bool)));
7132 connect(d->m_wq, SIGNAL(walletOpened(KWallet::Wallet*)), this, SLOT(walletOpened(KWallet::Wallet*)));
7133 }
7134 d->m_wq->savers.append(qMakePair(key, data));
7135#endif // KHTML_NO_WALLET
7136}
7137
7138
7139void KHTMLPart::dequeueWallet(DOM::HTMLFormElementImpl *form) {
7140#ifndef KHTML_NO_WALLET
7141 KHTMLPart *p;
7142
7143 for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
7144 }
7145
7146 if (p) {
7147 p->dequeueWallet(form);
7148 return;
7149 }
7150
7151 if (d->m_wq) {
7152 d->m_wq->callers.removeAll(KHTMLWalletQueue::Caller(form, form->document()));
7153 }
7154#endif // KHTML_NO_WALLET
7155}
7156
7157
7158void KHTMLPart::walletOpened(KWallet::Wallet *wallet) {
7159#ifndef KHTML_NO_WALLET
7160 assert(!d->m_wallet);
7161 assert(d->m_wq);
7162
7163 d->m_wq->deleteLater(); // safe?
7164 d->m_wq = 0L;
7165
7166 if (!wallet) {
7167 d->m_bWalletOpened = false;
7168 return;
7169 }
7170
7171 d->m_wallet = wallet;
7172 d->m_bWalletOpened = true;
7173 connect(d->m_wallet, SIGNAL(walletClosed()), SLOT(slotWalletClosed()));
7174 d->m_walletForms.clear();
7175 if (!d->m_statusBarWalletLabel) {
7176 d->m_statusBarWalletLabel = new KUrlLabel(d->m_statusBarExtension->statusBar());
7177 d->m_statusBarWalletLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum));
7178 d->m_statusBarWalletLabel->setUseCursor(false);
7179 d->m_statusBarExtension->addStatusBarItem(d->m_statusBarWalletLabel, 0, false);
7180 d->m_statusBarWalletLabel->setPixmap(SmallIcon("wallet-open"));
7181 connect(d->m_statusBarWalletLabel, SIGNAL(leftClickedUrl()), SLOT(launchWalletManager()));
7182 connect(d->m_statusBarWalletLabel, SIGNAL(rightClickedUrl()), SLOT(walletMenu()));
7183 }
7184 d->m_statusBarWalletLabel->setToolTip(i18n("The wallet '%1' is open and being used for form data and passwords.", KWallet::Wallet::NetworkWallet()));
7185#endif // KHTML_NO_WALLET
7186}
7187
7188
7189KWallet::Wallet *KHTMLPart::wallet()
7190{
7191#ifndef KHTML_NO_WALLET
7192 KHTMLPart *p;
7193
7194 for (p = parentPart(); p && p->parentPart(); p = p->parentPart())
7195 ;
7196
7197 if (p)
7198 return p->wallet();
7199
7200 return d->m_wallet;
7201#else
7202 return 0;
7203#endif // !KHTML_NO_WALLET
7204}
7205
7206
7207void KHTMLPart::slotWalletClosed()
7208{
7209#ifndef KHTML_NO_WALLET
7210 if (d->m_wallet) {
7211 d->m_wallet->deleteLater();
7212 d->m_wallet = 0L;
7213 }
7214 d->m_bWalletOpened = false;
7215 if (d->m_statusBarWalletLabel) {
7216 d->m_statusBarExtension->removeStatusBarItem(d->m_statusBarWalletLabel);
7217 delete d->m_statusBarWalletLabel;
7218 d->m_statusBarWalletLabel = 0L;
7219 }
7220#endif // KHTML_NO_WALLET
7221}
7222
7223void KHTMLPart::launchWalletManager()
7224{
7225#ifndef KHTML_NO_WALLET
7226 QDBusInterface r("org.kde.kwalletmanager", "/kwalletmanager/MainWindow_1",
7227 "org.kde.KMainWindow");
7228 if (!r.isValid()) {
7229 KToolInvocation::startServiceByDesktopName("kwalletmanager_show");
7230 } else {
7231 r.call(QDBus::NoBlock, "show");
7232 r.call(QDBus::NoBlock, "raise");
7233 }
7234#endif // KHTML_NO_WALLET
7235}
7236
7237void KHTMLPart::walletMenu()
7238{
7239#ifndef KHTML_NO_WALLET
7240 KMenu *menu = new KMenu(0L);
7241 QActionGroup *menuActionGroup = new QActionGroup(menu);
7242 connect( menuActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(removeStoredPasswordForm(QAction*)) );
7243
7244 menu->addAction(i18n("&Close Wallet"), this, SLOT(slotWalletClosed()));
7245
7246 if (d->m_view && d->m_view->nonPasswordStorableSite(toplevelURL().host())) {
7247 menu->addAction(i18n("&Allow storing passwords for this site"), this, SLOT(delNonPasswordStorableSite()));
7248 }
7249
7250 // List currently removable form passwords
7251 for ( QStringList::ConstIterator it = d->m_walletForms.constBegin(); it != d->m_walletForms.constEnd(); ++it ) {
7252 QAction* action = menu->addAction( i18n("Remove password for form %1", *it) );
7253 action->setActionGroup(menuActionGroup);
7254 QVariant var(*it);
7255 action->setData(var);
7256 }
7257
7258 KAcceleratorManager::manage(menu);
7259 menu->popup(QCursor::pos());
7260#endif // KHTML_NO_WALLET
7261}
7262
7263void KHTMLPart::removeStoredPasswordForm(QAction* action)
7264{
7265#ifndef KHTML_NO_WALLET
7266 assert(action);
7267 assert(d->m_wallet);
7268 QVariant var(action->data());
7269
7270 if(var.isNull() || !var.isValid() || var.type() != QVariant::String)
7271 return;
7272
7273 QString key = var.toString();
7274 if (KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(),
7275 KWallet::Wallet::FormDataFolder(),
7276 key))
7277 return; // failed
7278
7279
7280 if (!d->m_wallet->hasFolder(KWallet::Wallet::FormDataFolder()))
7281 return; // failed
7282
7283 d->m_wallet->setFolder(KWallet::Wallet::FormDataFolder());
7284 if (d->m_wallet->removeEntry(key))
7285 return; // failed
7286
7287 d->m_walletForms.removeAll(key);
7288#endif // KHTML_NO_WALLET
7289}
7290
7291void KHTMLPart::addWalletFormKey(const QString& walletFormKey)
7292{
7293#ifndef KHTML_NO_WALLET
7294
7295 if (parentPart()) {
7296 parentPart()->addWalletFormKey(walletFormKey);
7297 return;
7298 }
7299
7300 if(!d->m_walletForms.contains(walletFormKey))
7301 d->m_walletForms.append(walletFormKey);
7302#endif // KHTML_NO_WALLET
7303}
7304
7305void KHTMLPart::delNonPasswordStorableSite()
7306{
7307#ifndef KHTML_NO_WALLET
7308 if (d->m_view)
7309 d->m_view->delNonPasswordStorableSite(toplevelURL().host());
7310#endif // KHTML_NO_WALLET
7311}
7312void KHTMLPart::saveLoginInformation(const QString& host, const QString& key, const QMap<QString, QString>& walletMap)
7313{
7314#ifndef KHTML_NO_WALLET
7315 d->m_storePass.saveLoginInformation(host, key, walletMap);
7316#endif // KHTML_NO_WALLET
7317}
7318
7319void KHTMLPart::slotToggleCaretMode()
7320{
7321 setCaretMode(d->m_paToggleCaretMode->isChecked());
7322}
7323
7324void KHTMLPart::setFormNotification(KHTMLPart::FormNotification fn) {
7325 d->m_formNotification = fn;
7326}
7327
7328KHTMLPart::FormNotification KHTMLPart::formNotification() const {
7329 return d->m_formNotification;
7330}
7331
7332KUrl KHTMLPart::toplevelURL()
7333{
7334 KHTMLPart* part = this;
7335 while (part->parentPart())
7336 part = part->parentPart();
7337
7338 if (!part)
7339 return KUrl();
7340
7341 return part->url();
7342}
7343
7344bool KHTMLPart::isModified() const
7345{
7346 if ( !d->m_doc )
7347 return false;
7348
7349 return d->m_doc->unsubmittedFormChanges();
7350}
7351
7352void KHTMLPart::setDebugScript( bool enable )
7353{
7354 unplugActionList( "debugScriptList" );
7355 if ( enable ) {
7356 if (!d->m_paDebugScript) {
7357 d->m_paDebugScript = new KAction( i18n( "JavaScript &Debugger" ), this );
7358 actionCollection()->addAction( "debugScript", d->m_paDebugScript );
7359 connect( d->m_paDebugScript, SIGNAL(triggered(bool)), this, SLOT(slotDebugScript()) );
7360 }
7361 d->m_paDebugScript->setEnabled( d->m_frame ? d->m_frame->m_jscript : 0L );
7362 QList<QAction*> lst;
7363 lst.append( d->m_paDebugScript );
7364 plugActionList( "debugScriptList", lst );
7365 }
7366 d->m_bJScriptDebugEnabled = enable;
7367}
7368
7369void KHTMLPart::setSuppressedPopupIndicator( bool enable, KHTMLPart *originPart )
7370{
7371 if ( parentPart() ) {
7372 parentPart()->setSuppressedPopupIndicator( enable, originPart );
7373 return;
7374 }
7375
7376 if ( enable && originPart ) {
7377 d->m_openableSuppressedPopups++;
7378 if ( d->m_suppressedPopupOriginParts.indexOf( originPart ) == -1 )
7379 d->m_suppressedPopupOriginParts.append( originPart );
7380 }
7381
7382 if ( enable && !d->m_statusBarPopupLabel ) {
7383 d->m_statusBarPopupLabel = new KUrlLabel( d->m_statusBarExtension->statusBar() );
7384 d->m_statusBarPopupLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ));
7385 d->m_statusBarPopupLabel->setUseCursor( false );
7386 d->m_statusBarExtension->addStatusBarItem( d->m_statusBarPopupLabel, 0, false );
7387 d->m_statusBarPopupLabel->setPixmap( SmallIcon( "window-suppressed") );
7388
7389 d->m_statusBarPopupLabel->setToolTip(i18n("This page was prevented from opening a new window via JavaScript." ) );
7390
7391 connect(d->m_statusBarPopupLabel, SIGNAL(leftClickedUrl()), SLOT(suppressedPopupMenu()));
7392 if (d->m_settings->jsPopupBlockerPassivePopup()) {
7393 QPixmap px;
7394 px = MainBarIcon( "window-suppressed" );
7395 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);
7396 }
7397 } else if ( !enable && d->m_statusBarPopupLabel ) {
7398 d->m_statusBarPopupLabel->setToolTip("" );
7399 d->m_statusBarExtension->removeStatusBarItem( d->m_statusBarPopupLabel );
7400 delete d->m_statusBarPopupLabel;
7401 d->m_statusBarPopupLabel = 0L;
7402 }
7403}
7404
7405void KHTMLPart::suppressedPopupMenu() {
7406 KMenu *m = new KMenu(0L);
7407 if ( d->m_openableSuppressedPopups )
7408 m->addAction(i18np("&Show Blocked Popup Window","&Show %1 Blocked Popup Windows", d->m_openableSuppressedPopups), this, SLOT(showSuppressedPopups()));
7409 QAction *a = m->addAction(i18n("Show Blocked Window Passive Popup &Notification"), this, SLOT(togglePopupPassivePopup()));
7410 a->setChecked(d->m_settings->jsPopupBlockerPassivePopup());
7411 m->addAction(i18n("&Configure JavaScript New Window Policies..."), this, SLOT(launchJSConfigDialog()));
7412 m->popup(QCursor::pos());
7413}
7414
7415void KHTMLPart::togglePopupPassivePopup() {
7416 // Same hack as in disableJSErrorExtension()
7417 d->m_settings->setJSPopupBlockerPassivePopup( !d->m_settings->jsPopupBlockerPassivePopup() );
7418 emit configurationChanged();
7419}
7420
7421void KHTMLPart::showSuppressedPopups() {
7422 foreach ( KHTMLPart* part, d->m_suppressedPopupOriginParts ) {
7423 if (part) {
7424 KJS::Window *w = KJS::Window::retrieveWindow( part );
7425 if (w) {
7426 w->showSuppressedWindows();
7427 w->forgetSuppressedWindows();
7428 }
7429 }
7430 }
7431 setSuppressedPopupIndicator( false );
7432 d->m_openableSuppressedPopups = 0;
7433 d->m_suppressedPopupOriginParts.clear();
7434}
7435
7436// Extension to use for "view document source", "save as" etc.
7437// Using the right extension can help the viewer get into the right mode (#40496)
7438QString KHTMLPart::defaultExtension() const
7439{
7440 if ( !d->m_doc )
7441 return ".html";
7442 if ( !d->m_doc->isHTMLDocument() )
7443 return ".xml";
7444 return d->m_doc->htmlMode() == DOM::DocumentImpl::XHtml ? ".xhtml" : ".html";
7445}
7446
7447bool KHTMLPart::inProgress() const
7448{
7449 if (!d->m_bComplete || d->m_runningScripts || (d->m_doc && d->m_doc->parsing()))
7450 return true;
7451
7452 // Any frame that hasn't completed yet ?
7453 ConstFrameIt it = d->m_frames.constBegin();
7454 const ConstFrameIt end = d->m_frames.constEnd();
7455 for (; it != end; ++it ) {
7456 if ((*it)->m_run || !(*it)->m_bCompleted)
7457 return true;
7458 }
7459
7460 return d->m_submitForm || !d->m_redirectURL.isEmpty() || d->m_redirectionTimer.isActive() || d->m_job;
7461}
7462
7463using namespace KParts;
7464#include "khtml_part.moc"
7465#include "khtmlpart_p.moc"
7466#ifndef KHTML_NO_WALLET
7467#include "khtml_wallet_p.moc"
7468#endif
7469
7470// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
SVGDocument.h
browserinterface.h
browseropenorsavequestion.h
DOM::DOMString
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
DOM::DOMString::length
uint length() const
Definition: dom_string.cpp:185
DOM::DOMString::isNull
bool isNull() const
Definition: dom_string.h:121
DOM::DOMString::string
QString string() const
Definition: dom_string.cpp:236
DOM::DOMString::isEmpty
bool isEmpty() const
Definition: dom_string.cpp:368
DOM::Document
The Document interface represents the entire HTML or XML document.
Definition: dom_doc.h:246
DOM::Editor
This class resembles the editing API when the associated khtml document is editable (in design mode),...
Definition: editor.h:61
DOM::Editor::closeTyping
void closeTyping()
Definition: editor.cpp:484
DOM::Editor::clearTypingStyle
void clearTypingStyle()
Clears the typing style for the document.
Definition: editor.cpp:479
DOM::EventListener
Introduced in DOM Level 2.
Definition: dom2_events.h:70
DOM::HTMLDocument
An HTMLDocument is the root of the HTML hierarchy and holds the entire content.
Definition: html_document.h:74
DOM::NamedNodeMap::getNamedItem
Node getNamedItem(const DOMString &name) const
Retrieves a node specified by name.
Definition: dom_node.cpp:66
DOM::Node
The Node interface is the primary datatype for the entire Document Object Model.
Definition: dom_node.h:271
DOM::Node::nextSibling
Node nextSibling() const
The node immediately following this node.
Definition: dom_node.cpp:229
DOM::Node::handle
NodeImpl * handle() const
Definition: dom_node.h:925
DOM::Node::CDATA_SECTION_NODE
@ CDATA_SECTION_NODE
Definition: dom_node.h:385
DOM::Node::TEXT_NODE
@ TEXT_NODE
Definition: dom_node.h:384
DOM::Node::isNull
bool isNull() const
tests if this Node is 0.
Definition: dom_node.h:920
DOM::Node::nodeValue
DOMString nodeValue() const
The value of this node, depending on its type; see the table above.
Definition: dom_node.cpp:176
DOM::Node::parentNode
Node parentNode() const
The parent of this node.
Definition: dom_node.cpp:199
DOM::Node::firstChild
Node firstChild() const
The first child of this node.
Definition: dom_node.cpp:211
DOM::Node::attributes
NamedNodeMap attributes() const
A NamedNodeMap containing the attributes of this node (if it is an Element ) or null otherwise.
Definition: dom_node.cpp:235
DOM::Node::elementId
quint32 elementId() const
Definition: dom_node.cpp:400
DOM::Node::nodeType
unsigned short nodeType() const
A code representing the type of the underlying object, as defined above.
Definition: dom_node.cpp:193
DOM::Node::nodeName
DOMString nodeName() const
The name of this node, depending on its type; see the table above.
Definition: dom_node.cpp:170
DOM::Range
Definition: dom2_range.h:80
DOM::Range::startContainer
Node startContainer() const
Node within which the range begins.
Definition: dom2_range.cpp:113
DOM::Range::isDetached
bool isDetached() const
not part of the DOM true if the range is detached
Definition: dom2_range.cpp:397
DOM::Range::isNull
bool isNull() const
Definition: dom2_range.cpp:410
DOM::Range::endOffset
long endOffset() const
Offset within the ending node of the range.
Definition: dom2_range.cpp:147
DOM::Range::handle
RangeImpl * handle() const
Definition: dom2_range.cpp:405
DOM::Range::endContainer
Node endContainer() const
Node within which the range ends.
Definition: dom2_range.cpp:136
DOM::Range::startOffset
long startOffset() const
Offset within the starting node of the range.
Definition: dom2_range.cpp:124
KAcceleratorManager::manage
static void manage(QWidget *widget, bool programmers_mode=false)
KActionCollection::addAction
KAction * addAction(const QString &name, const QObject *receiver=0, const char *member=0)
KActionCollection::associateWidget
void associateWidget(QWidget *widget) const
KAction
KCodecAction
KConfigGroup
KEncodingDetector
KEncodingDetector::encoding
const char * encoding() const
KEncodingDetector::AutoDetectScript
AutoDetectScript
KEncodingDetector::None
None
KEncodingDetector::CentralEuropean
CentralEuropean
KEncodingDetector::Japanese
Japanese
KEncodingDetector::SemiautomaticDetection
SemiautomaticDetection
KEncodingDetector::Hebrew
Hebrew
KEncodingDetector::Greek
Greek
KEncodingDetector::Cyrillic
Cyrillic
KEncodingDetector::WesternEuropean
WesternEuropean
KEncodingDetector::Turkish
Turkish
KEncodingDetector::Arabic
Arabic
KEncodingDetector::Baltic
Baltic
KEncodingDetector::EncodingFromHTTPHeader
EncodingFromHTTPHeader
KEncodingDetector::DefaultEncoding
DefaultEncoding
KEncodingDetector::UserChosenEncoding
UserChosenEncoding
KEncodingDetector::setAutoDetectLanguage
void setAutoDetectLanguage(AutoDetectScript)
KEncodingDetector::setEncoding
bool setEncoding(const char *encoding, EncodingChoiceSource type)
KFileItemList
KFileItem
KFileItem::Unknown
Unknown
KFindDialog
KGlobalSettings::dndEventDelay
static int dndEventDelay()
KGlobalSettings::showIconsOnPushButtons
static bool showIconsOnPushButtons()
KGuiItem
KHTMLFindBar
Definition: khtmlfindbar.h:30
KHTMLFindBar::options
long options() const
Returns the state of the options.
Definition: khtmlfindbar.cpp:87
KHTMLFindBar::setOptions
void setOptions(long options)
Set the options which are checked.
Definition: khtmlfindbar.cpp:190
KHTMLFind::findBar
KHTMLFindBar * findBar() const
Definition: khtmlfind_p.h:56
KHTMLGlobal::vLinks
static KParts::HistoryProvider * vLinks()
Definition: khtml_global.h:69
KHTMLGlobal::componentData
static const KComponentData & componentData()
Definition: khtml_global.cpp:202
KHTMLGlobal::deregisterPart
static void deregisterPart(KHTMLPart *part)
Definition: khtml_global.cpp:162
KHTMLGlobal::defaultHTMLSettings
static KHTMLSettings * defaultHTMLSettings()
Definition: khtml_global.cpp:237
KHTMLGlobal::registerPart
static void registerPart(KHTMLPart *part)
Definition: khtml_global.cpp:150
KHTMLHtmlExtension
Definition: khtml_ext.h:201
KHTMLPageCache::saveData
void saveData(long id, QDataStream *str)
Save the data of cache entry id to the datastream str.
Definition: khtml_pagecache.cpp:267
KHTMLPageCache::fetchData
void fetchData(long id, QObject *recvObj, const char *recvSlot)
Fetch data for cache entry id and send it to slot recvSlot in the object recvObj.
Definition: khtml_pagecache.cpp:206
KHTMLPageCache::endData
void endData(long id)
Signal end of data for the cache entry with id id.
Definition: khtml_pagecache.cpp:172
KHTMLPageCache::addData
void addData(long id, const QByteArray &data)
Add data to the cache entry with id id.
Definition: khtml_pagecache.cpp:163
KHTMLPageCache::self
static KHTMLPageCache * self()
static "constructor".
Definition: khtml_pagecache.cpp:130
KHTMLPageCache::createCacheEntry
long createCacheEntry()
Create a new cache entry.
Definition: khtml_pagecache.cpp:151
KHTMLPageCache::cancelEntry
void cancelEntry(long id)
Cancel the entry.
Definition: khtml_pagecache.cpp:180
KHTMLPageCache::isComplete
bool isComplete(long id)
Definition: khtml_pagecache.cpp:197
KHTMLPageCache::cancelFetch
void cancelFetch(QObject *recvObj)
Cancel sending data to recvObj.
Definition: khtml_pagecache.cpp:224
KHTMLPartBrowserExtension
This is the BrowserExtension for a KHTMLPart document.
Definition: khtml_ext.h:44
KHTMLPartBrowserHostExtension
Definition: khtml_ext.h:95
KHTMLPartIface
D-BUS interface for KHTML.
Definition: khtml_iface.h:33
KHTMLPartPrivate
Definition: khtmlpart_p.h:94
KHTMLPartPrivate::m_designMode
bool m_designMode
Definition: khtmlpart_p.h:390
KHTMLPartPrivate::top
KHTMLPart * top()
Definition: khtml_part.cpp:5242
KHTMLPartPrivate::isLocalAnchorJump
bool isLocalAnchorJump(const KUrl &url)
Definition: khtml_part.cpp:620
KHTMLPartPrivate::isFullyLoaded
bool isFullyLoaded(bool *pendingRedirections) const
Definition: khtml_part.cpp:2359
KHTMLPartPrivate::executeAnchorJump
void executeAnchorJump(const KUrl &url, bool lockHistory)
Definition: khtml_part.cpp:631
KHTMLPartPrivate::canNavigate
bool canNavigate(KParts::ReadOnlyPart *b)
Definition: khtml_part.cpp:5250
KHTMLPartPrivate::renameFrameForContainer
void renameFrameForContainer(DOM::HTMLPartContainerElementImpl *cont, const QString &newName)
Definition: khtml_part.cpp:5326
KHTMLPartPrivate::m_loadedObjects
unsigned long m_loadedObjects
Definition: khtmlpart_p.h:396
KHTMLPartPrivate::q
KHTMLPart * q
Definition: khtmlpart_p.h:221
KHTMLPartPrivate::m_jobPercent
unsigned int m_jobPercent
Definition: khtmlpart_p.h:398
KHTMLPartPrivate::m_totalObjectCount
unsigned long m_totalObjectCount
Definition: khtmlpart_p.h:397
KHTMLPartPrivate::propagateInitialDomainAndBaseTo
void propagateInitialDomainAndBaseTo(KHTMLPart *kid)
Definition: khtml_part.cpp:5061
KHTMLPartPrivate::executeJavascriptURL
void executeJavascriptURL(const QString &u)
Definition: khtml_part.cpp:2539
KHTMLPartPrivate::classifyMimeType
MimeType classifyMimeType(const QString &mime)
Definition: khtml_part.cpp:1962
KHTMLPartPrivate::s_dnsInitialised
static bool s_dnsInitialised
Definition: khtmlpart_p.h:421
KHTMLPartPrivate::setFlagRecursively
void setFlagRecursively(bool KHTMLPartPrivate::*flag, bool value)
Definition: khtml_part.cpp:2813
KHTMLPartPrivate::m_find
KHTMLFind m_find
Definition: khtmlpart_p.h:405
KHTMLPartPrivate::isJavaScriptURL
static bool isJavaScriptURL(const QString &url)
Definition: khtml_part.cpp:2553
KHTMLPartPrivate::m_redirectURL
QString m_redirectURL
Definition: khtmlpart_p.h:315
KHTMLPartPrivate::m_objects
KHTMLFrameList m_objects
Definition: khtmlpart_p.h:225
KHTMLPartPrivate::findFrameParent
KHTMLPart * findFrameParent(KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame, bool checkForNavigation)
Definition: khtml_part.cpp:5195
KHTMLPartPrivate::m_ssl_in_use
bool m_ssl_in_use
Definition: khtmlpart_p.h:300
KHTMLPartPrivate::m_redirectionTimer
QTimer m_redirectionTimer
Definition: khtmlpart_p.h:312
KHTMLPartPrivate::m_extension
KHTMLPartBrowserExtension * m_extension
Definition: khtmlpart_p.h:230
KHTMLPartPrivate::m_frame
QPointer< khtml::ChildFrame > m_frame
Definition: khtmlpart_p.h:223
KHTMLPartPrivate::m_decoder
KEncodingDetector * m_decoder
Definition: khtmlpart_p.h:244
KHTMLPartPrivate::m_progressUpdateTimer
QTimer m_progressUpdateTimer
Definition: khtmlpart_p.h:401
KHTMLPartPrivate::codeForJavaScriptURL
static QString codeForJavaScriptURL(const QString &url)
Definition: khtml_part.cpp:2534
KHTMLPartPrivate::m_doc
DOM::DocumentImpl * m_doc
Definition: khtmlpart_p.h:242
KHTMLPartPrivate::m_frames
KHTMLFrameList m_frames
Definition: khtmlpart_p.h:224
KHTMLPartPrivate::m_caretMode
bool m_caretMode
Definition: khtmlpart_p.h:391
KHTMLPartPrivate::m_delayRedirect
int m_delayRedirect
Definition: khtmlpart_p.h:314
KHTMLPartPrivate::clearRedirection
void clearRedirection()
Definition: khtml_part.cpp:2588
KHTMLPart
This class is khtml's main class.
Definition: khtml_part.h:207
KHTMLPart::setAlwaysHonourDoctype
void setAlwaysHonourDoctype(bool b=true)
Sets whether the document's Doctype should always be used to determine the parsing mode for the docum...
Definition: khtml_part.cpp:2114
KHTMLPart::khtmlDrawContentsEvent
virtual void khtmlDrawContentsEvent(khtml::DrawContentsEvent *)
Eventhandler for the khtml::DrawContentsEvent.
Definition: khtml_part.cpp:6622
KHTMLPart::setPageSecurity
void setPageSecurity(PageSecurity sec)
Definition: khtml_part.cpp:1657
KHTMLPart::khtmlMouseReleaseEvent
virtual void khtmlMouseReleaseEvent(khtml::MouseReleaseEvent *event)
Eventhandler for the khtml::MouseMouseReleaseEvent.
Definition: khtml_part.cpp:6561
KHTMLPart::jScriptEnabled
bool jScriptEnabled() const
Returns true if Javascript support is enabled or false otherwise.
Definition: khtml_part.cpp:1106
KHTMLPart::pluginsEnabled
bool pluginsEnabled
Definition: khtml_part.h:258
KHTMLPart::show
void show()
Convenience method to show the document's view.
Definition: khtml_part.cpp:5680
KHTMLPart::popupMenu
void popupMenu(const QString &url, const QPoint &point)
Emitted when the user clicks the right mouse button on the document.
KHTMLPart::document
DOM::Document document() const
Returns a reference to the DOM document.
Definition: khtml_part.cpp:1012
KHTMLPart::slotFinished
virtual void slotFinished(KJob *)
Called when the job downloading the page is finished.
Definition: khtml_part.cpp:1907
KHTMLPart::autoloadImages
bool autoloadImages() const
Returns whether images contained in the document are loaded automatically or not.
Definition: khtml_part.cpp:1478
KHTMLPart::khtmlMouseMoveEvent
virtual void khtmlMouseMoveEvent(khtml::MouseMoveEvent *event)
Eventhandler for the khtml::MouseMouseMoveEvent.
Definition: khtml_part.cpp:6550
KHTMLPart::setURLCursor
void setURLCursor(const QCursor &c)
Sets the cursor to use when the cursor is on a link.
Definition: khtml_part.cpp:2783
KHTMLPart::urlSelected
virtual bool urlSelected(const QString &url, int button, int state, const QString &_target, const KParts::OpenUrlArguments &args=KParts::OpenUrlArguments(), const KParts::BrowserArguments &browserArgs=KParts::BrowserArguments())
Definition: khtml_part.cpp:3690
KHTMLPart::findFrame
KHTMLPart * findFrame(const QString &f)
Finds a frame by name.
Definition: khtml_part.cpp:5283
KHTMLPart::jsStatusBarText
QString jsStatusBarText() const
Called by KJS.
Definition: khtml_part.cpp:5933
KHTMLPart::view
KHTMLView * view() const
Returns a pointer to the HTML document's view.
Definition: khtml_part.cpp:1059
KHTMLPart::CaretDisplayPolicy
CaretDisplayPolicy
Enumeration for displaying the caret.
Definition: khtml_part.h:586
KHTMLPart::CaretInvisible
@ CaretInvisible
caret is not displayed
Definition: khtml_part.h:588
KHTMLPart::metaRefreshEnabled
bool metaRefreshEnabled
Definition: khtml_part.h:269
KHTMLPart::setMetaRefreshEnabled
void setMetaRefreshEnabled(bool enable)
Enable/disable automatic forwarding by <meta http-equiv="refresh" ....
Definition: khtml_part.cpp:1128
KHTMLPart::setDNSPrefetch
void setDNSPrefetch(DNSPrefetch pmode)
Sets whether DNS Names found in loaded documents'anchors should be pre-fetched (pre-resolved).
Definition: khtml_part.cpp:1115
KHTMLPart::statusMessagesEnabled
bool statusMessagesEnabled() const
Returns true if status messages are enabled.
Definition: khtml_part.cpp:1092
KHTMLPart::formNotification
FormNotification formNotification() const
Determine if signal should be emitted before, instead or never when a submitForm() happens.
Definition: khtml_part.cpp:7328
KHTMLPart::browserHostExtension
KParts::BrowserHostExtension * browserHostExtension() const
Definition: khtml_part.cpp:1054
KHTMLPart::prevAnchor
bool prevAnchor()
Go to previous anchor.
Definition: khtml_part.cpp:2764
KHTMLPart::partManager
KParts::PartManager * partManager()
Returns a reference to the partmanager instance which manages html frame objects.
Definition: khtml_part.cpp:4661
KHTMLPart::updateZoomFactor
void updateZoomFactor()
Definition: khtml_part.cpp:5793
KHTMLPart::formSubmitNotification
void formSubmitNotification(const char *action, const QString &url, const QByteArray &formData, const QString &target, const QString &contentType, const QString &boundary)
If form notification is on, this will be emitted either for a form submit or before the form submit a...
KHTMLPart::toplevelURL
KUrl toplevelURL()
Returns the toplevel (origin) URL of this document, even if this part is a frame or an iframe.
Definition: khtml_part.cpp:7332
KHTMLPart::isEditable
bool isEditable() const
Returns true if the document is editable, false otherwise.
Definition: khtml_part.cpp:2904
KHTMLPart::setEncoding
bool setEncoding(const QString &name, bool override=false)
Sets the encoding the page uses.
Definition: khtml_part.cpp:2654
KHTMLPart::setDNDEnabled
void setDNDEnabled(bool b)
Enables or disables Drag'n'Drop support.
Definition: khtml_part.cpp:6077
KHTMLPart::showError
virtual void showError(KJob *job)
Called when a certain error situation (i.e.
Definition: khtml_part.cpp:1790
KHTMLPart::findFramePart
KParts::ReadOnlyPart * findFramePart(const QString &f)
Finds a frame by name.
Definition: khtml_part.cpp:5293
KHTMLPart::completeURL
KUrl completeURL(const QString &url)
returns a KUrl object for the given url.
Definition: khtml_part.cpp:2522
KHTMLPart::openFile
virtual bool openFile()
Internal empty reimplementation of KParts::ReadOnlyPart::openFile .
Definition: khtml_part.cpp:1628
KHTMLPart::encoding
QString encoding
Definition: khtml_part.h:267
KHTMLPart::parentPart
KHTMLPart * parentPart()
Returns a pointer to the parent KHTMLPart if the part is a frame in an HTML frameset.
Definition: khtml_part.cpp:5356
KHTMLPart::write
virtual void write(const char *str, int len=-1)
Writes another part of the HTML code to the widget.
Definition: khtml_part.cpp:2089
KHTMLPart::doCloseStream
virtual bool doCloseStream()
Implements the streaming API of KParts::ReadOnlyPart.
Definition: khtml_part.cpp:2187
KHTMLPart::zoomFactor
int zoomFactor() const
Returns the current zoom factor.
Definition: khtml_part.cpp:5714
KHTMLPart::dndEnabled
bool dndEnabled
Definition: khtml_part.h:257
KHTMLPart::forcePermitLocalImages
bool forcePermitLocalImages() const
If true, local image files will be loaded even when forbidden by the Kiosk/KAuthorized policies ( def...
Definition: khtml_part.cpp:2803
KHTMLPart::setFixedFont
void setFixedFont(const QString &name)
Sets the fixed font style.
Definition: khtml_part.cpp:2778
KHTMLPart::FormNotification
FormNotification
Definition: khtml_part.h:1106
KHTMLPart::Before
@ Before
Definition: khtml_part.h:1106
KHTMLPart::Only
@ Only
Definition: khtml_part.h:1106
KHTMLPart::mayPrefetchHostname
bool mayPrefetchHostname(const QString &name)
Will pre-resolve name according to dnsPrefetch current settings Returns true if the name will be pre-...
Definition: khtml_part.cpp:3460
KHTMLPart::inProgress
bool inProgress() const
Definition: khtml_part.cpp:7447
KHTMLPart::browserExtension
KParts::BrowserExtension * browserExtension() const
Returns a pointer to the KParts::BrowserExtension.
Definition: khtml_part.cpp:1049
KHTMLPart::findText
void findText()
Starts a new search by popping up a dialog asking the user what he wants to search for.
Definition: khtml_part.cpp:3053
KHTMLPart::nodeActivated
void nodeActivated(const DOM::Node &)
This signal is emitted when an element retrieves the keyboard focus.
KHTMLPart::doWriteStream
virtual bool doWriteStream(const QByteArray &data)
Implements the streaming API of KParts::ReadOnlyPart.
Definition: khtml_part.cpp:2181
KHTMLPart::setCaretPosition
void setCaretPosition(DOM::Node node, long offset, bool extendSelection=false)
Sets the caret to the given position.
Definition: khtml_part.cpp:2913
KHTMLPart::onURL
void onURL(const QString &url)
Emitted if the cursor is moved over an URL.
KHTMLPart::frameNames
QStringList frameNames() const
Returns a list of names of all frame (including iframe) objects of the current document.
Definition: khtml_part.cpp:6033
KHTMLPart::paint
void paint(QPainter *, const QRect &, int=0, bool *=0)
Paints the HTML page to a QPainter.
Definition: khtml_part.cpp:2194
KHTMLPart::khtmlMousePressEvent
virtual void khtmlMousePressEvent(khtml::MousePressEvent *event)
Eventhandler of the khtml::MousePressEvent.
Definition: khtml_part.cpp:6295
KHTMLPart::currentFrame
KParts::ReadOnlyPart * currentFrame() const
Return the current frame (the one that has focus) Not necessarily a direct child of ours,...
Definition: khtml_part.cpp:5299
KHTMLPart::customEvent
virtual void customEvent(QEvent *event)
Definition: khtml_part.cpp:6087
KHTMLPart::setPluginPageQuestionAsked
void setPluginPageQuestionAsked(const QString &mimetype)
Definition: khtml_part.cpp:6998
KHTMLPart::DNSPrefetch
DNSPrefetch
DNS Prefetching Mode enumeration.
Definition: khtml_part.h:281
KHTMLPart::DNSPrefetchOnlyWWWAndSLD
@ DNSPrefetchOnlyWWWAndSLD
Definition: khtml_part.h:284
KHTMLPart::DNSPrefetchDisabled
@ DNSPrefetchDisabled
Definition: khtml_part.h:282
KHTMLPart::DNSPrefetchEnabled
@ DNSPrefetchEnabled
Definition: khtml_part.h:283
KHTMLPart::dnsPrefetch
DNSPrefetch dnsPrefetch
Definition: khtml_part.h:259
KHTMLPart::setStatusMessagesEnabled
void setStatusMessagesEnabled(bool enable)
Enable/disable statusbar messages.
Definition: khtml_part.cpp:1078
KHTMLPart::setActiveNode
void setActiveNode(const DOM::Node &node)
Sets the focused node of the document to the specified node.
Definition: khtml_part.cpp:6919
KHTMLPart::pageReferrer
QString pageReferrer() const
Referrer used to obtain this page.
Definition: khtml_part.cpp:5948
KHTMLPart::nonSharedNodeUnderMouse
DOM::Node nonSharedNodeUnderMouse() const
Returns the Node currently under the mouse that is not shared.
Definition: khtml_part.cpp:5697
KHTMLPart::restored
bool restored() const
Definition: khtml_part.cpp:6983
KHTMLPart::findFrameParent
KHTMLPart * findFrameParent(KParts::ReadOnlyPart *callingPart, const QString &f, khtml::ChildFrame **childFrame=0)
Recursively finds the part containing the frame with name f and checks if it is accessible by calling...
Definition: khtml_part.cpp:5190
KHTMLPart::backgroundURL
KUrl backgroundURL() const
Returns the URL for the background Image (used by save background)
Definition: khtml_part.cpp:3931
KHTMLPart::setCaretVisible
void setCaretVisible(bool show)
Sets the visibility of the caret.
Definition: khtml_part.cpp:2952
KHTMLPart::startingJob
virtual void startingJob(KIO::Job *)
Hook for adding code before a job is started.
Definition: khtml_part.h:1404
KHTMLPart::selectedTextAsHTML
QString selectedTextAsHTML() const
Return the text the user has marked.
Definition: khtml_part.cpp:3080
KHTMLPart::javaEnabled
bool javaEnabled
Definition: khtml_part.h:256
KHTMLPart::end
virtual void end()
Call this after your last call to write().
Definition: khtml_part.cpp:2138
KHTMLPart::setEditable
void setEditable(bool enable)
Makes the document editable.
Definition: khtml_part.cpp:2889
KHTMLPart::htmlDocument
DOM::HTMLDocument htmlDocument() const
Returns a reference to the DOM HTML document (for non-HTML documents, returns null)
Definition: khtml_part.cpp:1004
KHTMLPart::begin
virtual void begin(const KUrl &url=KUrl(), int xOffset=0, int yOffset=0)
Clears the widget and prepares it for new content.
Definition: khtml_part.cpp:1993
KHTMLPart::guiActivateEvent
virtual void guiActivateEvent(KParts::GUIActivateEvent *event)
Internal reimplementation of KParts::Part::guiActivateEvent .
Definition: khtml_part.cpp:6626
KHTMLPart::onlyLocalReferences
bool onlyLocalReferences() const
Returns whether only file:/ or data:/ references are allowed to be loaded ( default false ).
Definition: khtml_part.cpp:2793
KHTMLPart::setFormNotification
void setFormNotification(FormNotification fn)
Determine if signal should be emitted before, instead or never when a submitForm() happens.
Definition: khtml_part.cpp:7324
KHTMLPart::hasSelection
bool hasSelection() const
Has the user selected anything?
Definition: khtml_part.cpp:3256
KHTMLPart::setOnlyLocalReferences
void setOnlyLocalReferences(bool enable)
Security option.
Definition: khtml_part.cpp:2798
KHTMLPart::setFontScaleFactor
void setFontScaleFactor(int percent)
Sets the scale factor to be applied to fonts.
Definition: khtml_part.cpp:5863
KHTMLPart::closeUrl
virtual bool closeUrl()
Stops loading the document and kills all data requests (for images, etc.)
Definition: khtml_part.cpp:922
KHTMLPart::selection
DOM::Range selection() const
Returns the selected part of the HTML.
Definition: khtml_part.cpp:3261
KHTMLPart::settings
const KHTMLSettings * settings() const
Definition: khtml_part.cpp:2508
KHTMLPart::~KHTMLPart
virtual ~KHTMLPart()
Destructor.
Definition: khtml_part.cpp:532
KHTMLPart::findTextBegin
void findTextBegin()
Initiates a text search.
Definition: khtml_part.cpp:2969
KHTMLPart::frames
QList< KParts::ReadOnlyPart * > frames() const
Definition: khtml_part.cpp:6046
KHTMLPart::isPointInsideSelection
bool isPointInsideSelection(int x, int y)
Returns whether the given point is inside the current selection.
Definition: khtml_part.cpp:6122
KHTMLPart::referrer
QString referrer() const
Referrer used for links in this page.
Definition: khtml_part.cpp:5943
KHTMLPart::docCreated
void docCreated()
KHTMLPart::activeNode
DOM::Node activeNode() const
Returns the node that has the keyboard focus.
Definition: khtml_part.cpp:6933
KHTMLPart::nodeUnderMouse
DOM::Node nodeUnderMouse() const
Returns the Node currently under the mouse.
Definition: khtml_part.cpp:5692
KHTMLPart::executeScript
QVariant executeScript(const QString &script)
Execute the specified snippet of JavaScript code.
Definition: khtml_part.cpp:1321
KHTMLPart::scheduleRedirection
void scheduleRedirection(int delay, const QString &url, bool lockHistory=true)
Schedules a redirection after delay seconds.
Definition: khtml_part.cpp:2560
KHTMLPart::setJScriptEnabled
void setJScriptEnabled(bool enable)
Enable/disable Javascript support.
Definition: khtml_part.cpp:1097
KHTMLPart::fontScaleFactor
int fontScaleFactor() const
Returns the current font scale factor.
Definition: khtml_part.cpp:5886
KHTMLPart::isCaretMode
bool isCaretMode() const
Returns whether caret mode is on/off.
Definition: khtml_part.cpp:2884
KHTMLPart::gotoAnchor
bool gotoAnchor(const QString &name)
Finds the anchor named name.
Definition: khtml_part.cpp:2708
KHTMLPart::isModified
bool isModified() const
Checks whether the page contains unsubmitted form changes.
Definition: khtml_part.cpp:7344
KHTMLPart::framejScript
KJSProxy * framejScript(KParts::ReadOnlyPart *framePart)
Returns child frame framePart its script interpreter.
Definition: khtml_part.cpp:5336
KHTMLPart::preloadStyleSheet
void preloadStyleSheet(const QString &url, const QString &stylesheet)
Loads a style sheet into the stylesheet cache.
Definition: khtml_part.cpp:6968
KHTMLPart::editor
DOM::Editor * editor() const
Returns the instance of the attached html editor interface.
Definition: khtml_part.cpp:3500
KHTMLPart::timerEvent
virtual void timerEvent(QTimerEvent *)
Definition: khtml_part.cpp:3437
KHTMLPart::GUIProfile
GUIProfile
Definition: khtml_part.h:272
KHTMLPart::BrowserViewGUI
@ BrowserViewGUI
Definition: khtml_part.h:272
KHTMLPart::executeScript
QVariant executeScript(const DOM::Node &n, const QString &script)
Same as executeScript( const QString & ) except with the Node parameter specifying the 'this' value.
Definition: khtml_part.cpp:1326
KHTMLPart::selectedText
virtual QString selectedText() const
Returns the text the user has marked.
Definition: khtml_part.cpp:3098
KHTMLPart::caretPositionChanged
void caretPositionChanged(const DOM::Node &node, long offset)
This signal is emitted whenever the caret position has been changed.
KHTMLPart::jScriptInterpreter
KJS::Interpreter * jScriptInterpreter()
Returns the JavaScript interpreter the part is using.
Definition: khtml_part.cpp:1083
KHTMLPart::setCaretDisplayPolicyNonFocused
void setCaretDisplayPolicyNonFocused(CaretDisplayPolicy policy)
Sets the caret display policy when the view is not focused.
Definition: khtml_part.cpp:2942
KHTMLPart::configurationChanged
void configurationChanged()
Emitted whenever the configuration has changed.
KHTMLPart::htmlError
void htmlError(int errorCode, const QString &text, const KUrl &reqUrl)
presents a detailed error message to the user.
Definition: khtml_part.cpp:1807
KHTMLPart::lastModified
QString lastModified
Definition: khtml_part.h:268
KHTMLPart::createPart
virtual KParts::ReadOnlyPart * createPart(QWidget *parentWidget, QObject *parent, const QString &mimetype, QString &serviceName, QStringList &serviceTypes, const QStringList &params)
This method is called when a new embedded object (include html frames) is to be created.
Definition: khtml_part.cpp:4608
KHTMLPart::hide
void hide()
Convenience method to hide the document's view.
Definition: khtml_part.cpp:5686
KHTMLPart::setCaretMode
void setCaretMode(bool enable)
Enables/disables caret mode.
Definition: khtml_part.cpp:2867
KHTMLPart::submitFormProxy
void submitFormProxy(const char *action, const QString &url, const QByteArray &formData, const QString &target, const QString &contentType=QString(), const QString &boundary=QString())
Definition: khtml_part.cpp:4687
KHTMLPart::setStandardFont
void setStandardFont(const QString &name)
Sets the standard font style.
Definition: khtml_part.cpp:2773
KHTMLPart::caretDisplayPolicyNonFocused
CaretDisplayPolicy caretDisplayPolicyNonFocused() const
Returns the current caret policy when the view is not focused.
Definition: khtml_part.cpp:2930
KHTMLPart::documentSource
QString documentSource() const
Returns the content of the source document.
Definition: khtml_part.cpp:1017
KHTMLPart::findTextNext
bool findTextNext(bool reverse=false)
Finds the next occurrence of a string set by findText()
Definition: khtml_part.cpp:3068
KHTMLPart::KHTMLPart
KHTMLPart(QWidget *parentWidget=0, QObject *parent=0, GUIProfile prof=DefaultGUI)
Constructs a new KHTMLPart.
Definition: khtml_part.cpp:181
KHTMLPart::restoreState
virtual void restoreState(QDataStream &stream)
Restores the KHTMLPart's previously saved state (including child frame objects) from the provided QDa...
Definition: khtml_part.cpp:5482
KHTMLPart::stopAnimations
void stopAnimations()
Stops all animated images on the current and child pages.
Definition: khtml_part.cpp:2200
KHTMLPart::jsDefaultStatusBarText
QString jsDefaultStatusBarText() const
Called by KJS.
Definition: khtml_part.cpp:5938
KHTMLPart::saveState
virtual void saveState(QDataStream &stream)
Saves the KHTMLPart's complete state (including child frame objects) to the provided QDataStream.
Definition: khtml_part.cpp:5394
KHTMLPart::setAutoloadImages
void setAutoloadImages(bool enable)
Specifies whether images contained in the document should be loaded automatically or not.
Definition: khtml_part.cpp:1450
KHTMLPart::baseURL
KUrl baseURL() const
Definition: khtml_part.cpp:2514
KHTMLPart::openUrl
virtual bool openUrl(const KUrl &url)
Opens the specified URL url.
Definition: khtml_part.cpp:665
KHTMLPart::khtmlMouseDoubleClickEvent
virtual void khtmlMouseDoubleClickEvent(khtml::MouseDoubleClickEvent *)
Eventhandler for the khtml::MouseDoubleClickEvent.
Definition: khtml_part.cpp:6341
KHTMLPart::setJavaEnabled
void setJavaEnabled(bool enable)
Enables/disables Java applet support.
Definition: khtml_part.cpp:1363
KHTMLPart::PageSecurity
PageSecurity
Definition: khtml_part.h:1277
KHTMLPart::NotCrypted
@ NotCrypted
Definition: khtml_part.h:1277
KHTMLPart::Encrypted
@ Encrypted
Definition: khtml_part.h:1277
KHTMLPart::setUserStyleSheet
void setUserStyleSheet(const KUrl &url)
Sets a user defined style sheet to be used on top of the HTML 4 default style sheet.
Definition: khtml_part.cpp:2696
KHTMLPart::setJSDefaultStatusBarText
void setJSDefaultStatusBarText(const QString &text)
Called by KJS.
Definition: khtml_part.cpp:5928
KHTMLPart::doOpenStream
virtual bool doOpenStream(const QString &mimeType)
Implements the streaming API of KParts::ReadOnlyPart.
Definition: khtml_part.cpp:2170
KHTMLPart::pluginPageQuestionAsked
bool pluginPageQuestionAsked(const QString &mimetype) const
Definition: khtml_part.cpp:6988
KHTMLPart::setForcePermitLocalImages
void setForcePermitLocalImages(bool enable)
Security option.
Definition: khtml_part.cpp:2808
KHTMLPart::selectionChanged
void selectionChanged()
This signal is emitted when the selection changes.
KHTMLPart::urlCursor
QCursor urlCursor() const
Returns the cursor which is used when the cursor is on a link.
Definition: khtml_part.cpp:2788
KHTMLPart::preloadScript
void preloadScript(const QString &url, const QString &script)
Loads a script into the script cache.
Definition: khtml_part.cpp:6973
KHTMLPart::setJSStatusBarText
void setJSStatusBarText(const QString &text)
Called by KJS.
Definition: khtml_part.cpp:5923
KHTMLPart::setSuppressedPopupIndicator
void setSuppressedPopupIndicator(bool enable, KHTMLPart *originPart=0)
Shows or hides the suppressed popup indicator.
Definition: khtml_part.cpp:7369
KHTMLPart::frameExists
bool frameExists(const QString &frameName)
Returns whether a frame with the specified name is exists or not.
Definition: khtml_part.cpp:5314
KHTMLPart::selectAll
void selectAll()
Marks all text in the document as selected.
Definition: khtml_part.cpp:6746
KHTMLPart::setPluginsEnabled
void setPluginsEnabled(bool enable)
Enables or disables plugins, default is enabled.
Definition: khtml_part.cpp:1382
KHTMLPart::setZoomFactor
void setZoomFactor(int percent)
Sets the Zoom factor.
Definition: khtml_part.cpp:5778
KHTMLPart::setSelection
void setSelection(const DOM::Range &)
Sets the current selection.
Definition: khtml_part.cpp:3275
KHTMLPart::nextAnchor
bool nextAnchor()
Go to the next anchor.
Definition: khtml_part.cpp:2755
KHTMLPopupGUIClient
Definition: khtml_ext.h:117
KHTMLPopupGUIClient::actionGroups
KParts::BrowserExtension::ActionGroupMap actionGroups() const
Definition: khtml_ext.cpp:688
KHTMLPopupGUIClient::saveURL
static void saveURL(QWidget *parent, const QString &caption, const KUrl &url, const QMap< QString, QString > &metaData=KIO::MetaData(), const QString &filter=QString(), long cacheId=0, const QString &suggestedFilename=QString())
Definition: khtml_ext.cpp:859
KHTMLRun
Definition: khtml_run.h:39
KHTMLSettings
Settings for the HTML view.
Definition: khtml_settings.h:42
KHTMLSettings::KAnimationDisabled
@ KAnimationDisabled
Definition: khtml_settings.h:55
KHTMLSettings::isOpenMiddleClickEnabled
bool isOpenMiddleClickEnabled()
Definition: khtml_settings.cpp:808
KHTMLSettings::showAnimations
KAnimationAdvice showAnimations() const
Definition: khtml_settings.cpp:1134
KHTMLSettings::isJavaScriptDebugEnabled
bool isJavaScriptDebugEnabled(const QString &hostname=QString()) const
Definition: khtml_settings.cpp:916
KHTMLSettings::init
void init()
Called by constructor and reparseConfiguration.
Definition: khtml_settings.cpp:342
KHTMLSettings::isJavaEnabled
bool isJavaEnabled(const QString &hostname=QString()) const
Definition: khtml_settings.cpp:906
KHTMLSettings::KSmoothScrollingMode
KSmoothScrollingMode
Definition: khtml_settings.h:60
KHTMLSettings::KSmoothScrollingWhenEfficient
@ KSmoothScrollingWhenEfficient
Definition: khtml_settings.h:62
KHTMLSettings::KSmoothScrollingDisabled
@ KSmoothScrollingDisabled
Definition: khtml_settings.h:61
KHTMLSettings::encoding
const QString & encoding() const
Definition: khtml_settings.cpp:1094
KHTMLSettings::KDNSPrefetch
KDNSPrefetch
Definition: khtml_settings.h:66
KHTMLSettings::KDNSPrefetchOnlyWWWAndSLD
@ KDNSPrefetchOnlyWWWAndSLD
Definition: khtml_settings.h:68
KHTMLSettings::KDNSPrefetchDisabled
@ KDNSPrefetchDisabled
Definition: khtml_settings.h:67
KHTMLSettings::isJavaScriptEnabled
bool isJavaScriptEnabled(const QString &hostname=QString()) const
Definition: khtml_settings.cpp:911
KHTMLSettings::isAutoDelayedActionsEnabled
bool isAutoDelayedActionsEnabled() const
Definition: khtml_settings.cpp:1149
KHTMLSettings::isPluginsEnabled
bool isPluginsEnabled(const QString &hostname=QString()) const
Definition: khtml_settings.cpp:928
KHTMLSettings::autoLoadImages
bool autoLoadImages() const
Definition: khtml_settings.cpp:1124
KHTMLSettings::userStyleSheet
QString userStyleSheet() const
Definition: khtml_settings.cpp:1079
KHTMLSettings::isAdFiltered
bool isAdFiltered(const QString &url) const
tests whether url is filtered.
Definition: khtml_settings.cpp:833
KHTMLTextExtension
Definition: khtml_ext.h:182
KHTMLViewBar
Definition: khtmlviewbar.h:29
KHTMLViewBar::Bottom
@ Bottom
Definition: khtmlviewbar.h:34
KHTMLViewBar::Top
@ Top
Definition: khtmlviewbar.h:33
KHTMLView
Renders and displays HTML in a QScrollArea.
Definition: khtmlview.h:93
KHTMLView::part
KHTMLPart * part() const
Returns a pointer to the KHTMLPart that is rendering the page.
Definition: khtmlview.h:135
KHTMLView::SSMDisabled
@ SSMDisabled
Definition: khtmlview.h:305
KHTMLView::SSMEnabled
@ SSMEnabled
Definition: khtmlview.h:305
KHTMLView::SSMWhenEfficient
@ SSMWhenEfficient
Definition: khtmlview.h:305
KHTMLWalletQueue
Definition: khtml_wallet_p.h:42
KHTMLZoomFactorAction
Definition: khtml_ext.h:162
KIO::Job
KIO::MetaData
KIO::NetAccess::removeTempFile
static void removeTempFile(const QString &name)
KIO::NetAccess::download
static bool download(const KUrl &src, QString &target, QWidget *window)
KIO::StatJob
KIO::TransferJob
KIO::TransferJob::isErrorPage
bool isErrorPage() const
KIO::UDSEntry
KIO::UDSEntry::numberValue
long long numberValue(uint field, long long defaultValue=0) const
KIO::UDSEntry::UDS_MODIFICATION_TIME
UDS_MODIFICATION_TIME
KIconLoader::Desktop
Desktop
KIconLoader::global
static KIconLoader * global()
KIconLoader::SizeHuge
SizeHuge
KIconLoader::SizeMedium
SizeMedium
KIconLoader::loadIcon
QPixmap loadIcon(const QString &name, KIconLoader::Group group, int size=0, int state=KIconLoader::DefaultState, const QStringList &overlays=QStringList(), QString *path_store=0L, bool canReturnNull=false) const
KIcon
KJSErrorDlg
Definition: kjserrordlg.h:9
KJSErrorDlg::addError
void addError(const QString &error)
Definition: kjserrordlg.cpp:13
KJobUiDelegate::showErrorMessage
virtual void showErrorMessage()
KJob
KJob::errorString
virtual QString errorString() const
KJob::error
int error() const
KJob::uiDelegate
KJobUiDelegate * uiDelegate() const
KJob::errorText
QString errorText() const
KLocale::encoding
const QByteArray encoding() const
KLocale::formatNumber
QString formatNumber(const QString &numStr, bool round=true, int precision=-1) const
KLocale::removeCatalog
void removeCatalog(const QString &catalog)
KLocale::formatDateTime
QString formatDateTime(const KDateTime &dateTime, DateFormat format=ShortDate, DateTimeFormatOptions options=0) const
KLocale::LongDate
LongDate
KLocalizedString
KMenu
KMessageBox::error
static void error(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
KMessageBox::warningContinueCancel
static int warningContinueCancel(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
KMessageBox::Continue
Continue
KMessageBox::Cancel
Cancel
KMessageBox::information
static void information(QWidget *parent, const QString &text, const QString &caption=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
KMessageBox::Notify
Notify
KMessageBox::Dangerous
Dangerous
KMimeTypeTrader::query
KService::List query(const QString &mimeType, const QString &genericServiceType=QString::fromLatin1("Application"), const QString &constraint=QString()) const
KMimeTypeTrader::self
static KMimeTypeTrader * self()
KMimeType::ResolveAliases
ResolveAliases
KMimeType::defaultMimeType
static QString defaultMimeType()
KMimeType::mimeType
static Ptr mimeType(const QString &name, FindByNameOption options=ResolveAliases)
KMimeType::findByPath
static Ptr findByPath(const QString &path, mode_t mode=0, bool fast_mode=false, int *accuracy=0)
KMimeType::findByUrl
static Ptr findByUrl(const KUrl &url, mode_t mode=0, bool is_local_file=false, bool fast_mode=false, int *accuracy=0)
KParts::BrowserExtension
KParts::BrowserExtension::openUrlNotify
void openUrlNotify()
KParts::BrowserExtension::pasteRequest
void pasteRequest()
KParts::BrowserExtension::setLocationBarUrl
void setLocationBarUrl(const QString &url)
KParts::BrowserExtension::childObject
static BrowserExtension * childObject(QObject *obj)
KParts::BrowserExtension::IsLink
IsLink
KParts::BrowserExtension::ShowNavigationItems
ShowNavigationItems
KParts::BrowserExtension::ShowTextSelectionItems
ShowTextSelectionItems
KParts::BrowserExtension::ShowReload
ShowReload
KParts::BrowserExtension::ShowBookmark
ShowBookmark
KParts::BrowserHostExtension
KParts::BrowserOpenOrSaveQuestion
KParts::BrowserOpenOrSaveQuestion::Result
Result
KParts::BrowserOpenOrSaveQuestion::Cancel
Cancel
KParts::BrowserOpenOrSaveQuestion::Save
Save
KParts::BrowserRun::AttachmentDisposition
AttachmentDisposition
KParts::BrowserRun::InlineDisposition
InlineDisposition
KParts::GUIActivateEvent
KParts::GUIActivateEvent::activated
bool activated() const
KParts::HistoryProvider::insert
virtual void insert(const QString &item)
KParts::LiveConnectExtension
KParts::LiveConnectExtension::childObject
static LiveConnectExtension * childObject(QObject *obj)
KParts::OpenUrlArguments
KParts::OpenUrlArguments::setYOffset
void setYOffset(int y)
KParts::OpenUrlArguments::setXOffset
void setXOffset(int x)
KParts::OpenUrlArguments::setReload
void setReload(bool b)
KParts::OpenUrlArguments::xOffset
int xOffset() const
KParts::OpenUrlArguments::mimeType
QString mimeType() const
KParts::OpenUrlArguments::metaData
QMap< QString, QString > & metaData()
KParts::OpenUrlArguments::yOffset
int yOffset() const
KParts::OpenUrlArguments::setMimeType
void setMimeType(const QString &mime)
KParts::OpenUrlArguments::reload
bool reload() const
KParts::PartBase::setComponentData
virtual void setComponentData(const KComponentData &componentData)
KParts::PartManager
KParts::PartManager::removePart
virtual void removePart(Part *part)
KParts::PartManager::activePart
virtual Part * activePart() const
KParts::PartManager::addPart
virtual void addPart(Part *part, bool setActive=true)
KParts::Part
KParts::Part::widget
virtual QWidget * widget()
KParts::Part::setWidget
virtual void setWidget(QWidget *widget)
KParts::Part::setStatusBarText
void setStatusBarText(const QString &text)
KParts::Part::loadPlugins
void loadPlugins()
KParts::Part::customEvent
virtual void customEvent(QEvent *event)
KParts::ReadOnlyPart
KParts::ReadOnlyPart::started
void started(KIO::Job *)
KParts::ReadOnlyPart::arguments
OpenUrlArguments arguments() const
KParts::ReadOnlyPart::url
KUrl url
KParts::ReadOnlyPart::completed
void completed()
KParts::ReadOnlyPart::setArguments
void setArguments(const OpenUrlArguments &arguments)
KParts::ReadOnlyPart::canceled
void canceled(const QString &errMsg)
KParts::ReadOnlyPart::openUrl
virtual bool openUrl(const KUrl &url)
KParts::ReadOnlyPart::setUrl
void setUrl(const KUrl &url)
KParts::StatusBarExtension
KParts::StatusBarExtension::setStatusBar
void setStatusBar(KStatusBar *status)
KParts::StatusBarExtension::childObject
static StatusBarExtension * childObject(QObject *obj)
KParts::WindowArgs
KParts::WindowArgs::setLowerWindow
void setLowerWindow(bool lower)
KPassivePopup::message
static KPassivePopup * message(const QString &caption, const QString &text, const QPixmap &icon, QSystemTrayIcon *parent, int timeout=-1)
KPluginFactory::create
T * create(const QString &keyword, QObject *parent=0, const QVariantList &args=QVariantList())
KPluginLoader
KPluginLoader::errorString
QString errorString() const
KPluginLoader::factory
KPluginFactory * factory()
KProtocolManager::cacheControl
static KIO::CacheControl cacheControl()
KProtocolManager::userAgentForHost
static QString userAgentForHost(const QString &hostname)
KRun::runUrl
static bool runUrl(const KUrl &url, const QString &mimetype, QWidget *window, bool tempFile=false, bool runExecutables=true, const QString &suggestedFileName=QString(), const QByteArray &asn=QByteArray())
KSSLCertificate::KSSLValidation
KSSLValidation
KSSLSettings
KSelectAction
KSharedPtr
KShortcut
KSslInfoDialog
KSslInfoDialog::errorsFromString
static QList< QList< KSslError::Error > > errorsFromString(const QString &s)
KSslInfoDialog::setSslInfo
void setSslInfo(const QList< QSslCertificate > &certificateChain, const QString &ip, const QString &host, const QString &sslProtocol, const QString &cipher, int usedBits, int bits, const QList< QList< KSslError::Error > > &validationErrors)
KStandardDirs::locate
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
KTemporaryFile
KTemporaryFile::setSuffix
void setSuffix(const QString &suffix)
KToggleAction
KToolInvocation::kdeinitExec
static int kdeinitExec(const QString &name, const QStringList &args=QStringList(), QString *error=0, int *pid=0, const QByteArray &startup_id=QByteArray())
KToolInvocation::startServiceByDesktopName
static int startServiceByDesktopName(const QString &_name, const QString &URL, QString *error=0, QString *serviceName=0, int *pid=0, const QByteArray &startup_id=QByteArray(), bool noWait=false)
KUrlLabel
KUrl::List
KUrl
KUrl::populateMimeData
void populateMimeData(QMimeData *mimeData, const MetaDataMap &metaData=MetaDataMap(), MimeDataFlags flags=DefaultMimeDataFlags) const
KUrl::encodedHtmlRef
QString encodedHtmlRef() const
KUrl::prettyUrl
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::ObeyTrailingSlash
ObeyTrailingSlash
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::ref
QString ref() const
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::setFileName
void setFileName(const QString &_txt)
KUrl::equals
bool equals(const KUrl &u, const EqualsOptions &options=0) const
KUrl::query
QString query() const
KUrl::isLocalFile
bool isLocalFile() const
KUrl::htmlRef
QString htmlRef() const
KUrl::split
static List split(const KUrl &_url)
KUrl::CompareWithoutTrailingSlash
CompareWithoutTrailingSlash
KUrl::CompareWithoutFragment
CompareWithoutFragment
KUrl::AllowEmptyPath
AllowEmptyPath
KUrl::setPath
void setPath(const QString &path)
KUrl::setQuery
void setQuery(const QString &query)
KUrl::setRef
void setRef(const QString &fragment)
KUrl::setPass
void setPass(const QString &pass)
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
KUrl::protocol
QString protocol() const
KUrl::queryItem
QString queryItem(const QString &item) const
KUrl::hasRef
bool hasRef() const
KUrl::join
static KUrl join(const List &_list)
KUrl::toLocalFile
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::setUser
void setUser(const QString &user)
KWallet::Wallet
KWallet::Wallet::Asynchronous
Asynchronous
KWallet::Wallet::NetworkWallet
static const QString NetworkWallet()
KWallet::Wallet::openWallet
static Wallet * openWallet(const QString &name, WId w, OpenType ot=Synchronous)
KWallet::Wallet::keyDoesNotExist
static bool keyDoesNotExist(const QString &wallet, const QString &folder, const QString &key)
KWallet::Wallet::FormDataFolder
static const QString FormDataFolder()
KXMLGUIClient::removeChildClient
void removeChildClient(KXMLGUIClient *child)
KXMLGUIClient::actionCollection
virtual KActionCollection * actionCollection() const
KXMLGUIClient::unplugActionList
void unplugActionList(const QString &name)
KXMLGUIClient::plugActionList
void plugActionList(const QString &name, const QList< QAction * > &actionList)
KXMLGUIClient::childClients
QList< KXMLGUIClient * > childClients()
KXMLGUIClient::factory
KXMLGUIFactory * factory() const
KXMLGUIClient::insertChildClient
void insertChildClient(KXMLGUIClient *child)
KXMLGUIFactory::removeClient
void removeClient(KXMLGUIClient *client)
KXMLGUIFactory::addClient
void addClient(KXMLGUIClient *client)
QAction
QCursor
QDialog
QEvent
QFrame
QList
QMap
QObject
QPair
QWidget
khtml::ChildFrame
Definition: khtml_childframe_p.h:41
khtml::ChildFrame::m_bCompleted
bool m_bCompleted
Definition: khtml_childframe_p.h:61
khtml::ChildFrame::m_args
KParts::OpenUrlArguments m_args
Definition: khtml_childframe_p.h:63
khtml::ChildFrame::m_jscript
KJSProxy * m_jscript
Definition: khtml_childframe_p.h:60
khtml::ChildFrame::m_serviceType
QString m_serviceType
Definition: khtml_childframe_p.h:59
khtml::ChildFrame::m_part
QPointer< KParts::ReadOnlyPart > m_part
Definition: khtml_childframe_p.h:56
khtml::ChildFrame::m_partContainerElement
QWeakPointer< DOM::HTMLPartContainerElementImpl > m_partContainerElement
Definition: khtml_childframe_p.h:49
khtml::ChildFrame::m_run
QWeakPointer< KHTMLRun > m_run
Definition: khtml_childframe_p.h:65
khtml::ChildFrame::m_bPendingRedirection
bool m_bPendingRedirection
Definition: khtml_childframe_p.h:71
khtml::ChildFrame::dumpFrameTree
static void dumpFrameTree(KHTMLPart *part)
Definition: khtml_childframe.cpp:83
khtml::ChildFrame::m_extension
QWeakPointer< KParts::BrowserExtension > m_extension
Definition: khtml_childframe_p.h:50
khtml::ChildFrame::m_bPreloaded
bool m_bPreloaded
Definition: khtml_childframe_p.h:69
khtml::ChildFrame::m_serviceName
QString m_serviceName
Definition: khtml_childframe_p.h:58
khtml::ChildFrame::m_scriptable
QWeakPointer< KParts::ScriptableExtension > m_scriptable
Definition: khtml_childframe_p.h:51
khtml::ChildFrame::m_params
QStringList m_params
Definition: khtml_childframe_p.h:68
khtml::ChildFrame::Type
Type
Definition: khtml_childframe_p.h:44
khtml::ChildFrame::IFrame
@ IFrame
Definition: khtml_childframe_p.h:44
khtml::ChildFrame::Frame
@ Frame
Definition: khtml_childframe_p.h:44
khtml::ChildFrame::Object
@ Object
Definition: khtml_childframe_p.h:44
khtml::ChildFrame::m_type
Type m_type
Definition: khtml_childframe_p.h:67
khtml::ChildFrame::m_browserArgs
KParts::BrowserArguments m_browserArgs
Definition: khtml_childframe_p.h:64
khtml::ChildFrame::m_name
QString m_name
Definition: khtml_childframe_p.h:62
khtml::ChildFrame::m_bNotify
bool m_bNotify
Definition: khtml_childframe_p.h:70
khtml::DrawContentsEvent
Definition: khtml_events.h:131
khtml::DrawContentsEvent::test
static bool test(const QEvent *event)
Definition: khtml_events.h:142
khtml::MouseDoubleClickEvent
Definition: khtml_events.h:80
khtml::MouseDoubleClickEvent::test
static bool test(const QEvent *event)
Definition: khtml_events.h:90
khtml::MouseDoubleClickEvent::clickCount
int clickCount() const
Definition: khtml_events.h:93
khtml::MouseEvent::x
int x() const
Definition: khtml_events.h:39
khtml::MouseEvent::y
int y() const
Definition: khtml_events.h:40
khtml::MouseEvent::url
DOM::DOMString url() const
Definition: khtml_events.h:44
khtml::MouseMoveEvent
Definition: khtml_events.h:101
khtml::MouseMoveEvent::test
static bool test(const QEvent *event)
Definition: khtml_events.h:109
khtml::MousePressEvent
Definition: khtml_events.h:64
khtml::MousePressEvent::test
static bool test(const QEvent *event)
Definition: khtml_events.h:72
khtml::MouseReleaseEvent
Definition: khtml_events.h:116
khtml::MouseReleaseEvent::test
static bool test(const QEvent *event)
Definition: khtml_events.h:124
dom2_range.h
dom_element.h
dom_exception.h
dom_string.h
assert
#define assert(x)
Definition: editor.cpp:43
editor.h
header
const char header[]
global.h
KParts::ScriptableExtension::childObject
static ScriptableExtension * childObject(QObject *obj)
KParts::ScriptableExtension::host
ScriptableExtension * host() const
KParts::ScriptableExtension::adapterFromLiveConnect
static ScriptableExtension * adapterFromLiveConnect(QObject *parentObj, LiveConnectExtension *oldApi)
KParts::ScriptableExtension::setHost
void setHost(ScriptableExtension *host)
kDebug
#define kDebug
kWarning
#define kWarning
hostinfo_p.h
html_document.h
job.h
jobuidelegate.h
kacceleratormanager.h
kactioncollection.h
kactionmenu.h
kauthorized.h
kcodecaction.h
indent
QString indent(QString text, int spaces)
kconfiggroup.h
kdebug.h
kfiledialog.h
kfileitem.h
kglobalsettings.h
ConstFrameIt
KHTMLFrameList::ConstIterator ConstFrameIt
Definition: khtml_childframe_p.h:86
FrameIt
KHTMLFrameList::Iterator FrameIt
Definition: khtml_childframe_p.h:87
fastZoomSizeCount
const int KDE_NO_EXPORT fastZoomSizeCount
fastZoomSizes
const int KDE_NO_EXPORT fastZoomSizes[]
khtml_iface.h
khtml_pagecache.h
firstRunAt
static bool firstRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset)
returns the position of the first inline text box of the line at coordinate y in renderNode
Definition: khtml_part.cpp:6144
isAncestorOrSamePart
static bool isAncestorOrSamePart(KHTMLPart *p1, KHTMLPart *p2)
Definition: khtml_part.cpp:2255
zoomSizeCount
static const int zoomSizeCount
Definition: khtml_part.cpp:5721
sMaxDNSPrefetchPerPage
static const int sMaxDNSPrefetchPerPage
Definition: khtml_part.cpp:143
sDNSPrefetchTimerDelay
static const int sDNSPrefetchTimerDelay
Definition: khtml_part.cpp:144
setCaretInvisibleIfNeeded
static void setCaretInvisibleIfNeeded(KHTMLPart *part)
Definition: khtml_part.cpp:2860
zoomSizes
static const int zoomSizes[]
Definition: khtml_part.cpp:5720
maxZoom
static const int maxZoom
Definition: khtml_part.cpp:5723
sDNSCacheSize
static const int sDNSCacheSize
Definition: khtml_part.cpp:146
s_DOMTreeIndentLevel
static int s_DOMTreeIndentLevel
Definition: khtml_part.cpp:1397
fastZoomSizeCount
const int KDE_NO_EXPORT fastZoomSizeCount
lastRunAt
static bool lastRunAt(khtml::RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset)
returns the position of the last inline text box of the line at coordinate y in renderNode
Definition: khtml_part.cpp:6171
minZoom
static const int minZoom
Definition: khtml_part.cpp:5722
fastZoomSizes
const int KDE_NO_EXPORT fastZoomSizes[]
sDNSTTLSeconds
static const int sDNSTTLSeconds
Definition: khtml_part.cpp:145
khtml_part.h
khtml_settings.h
d
#define d
Definition: khtmlfind.cpp:42
khtmlpart_p.h
MimeType
MimeType
Definition: khtmlpart_p.h:82
MimeHTML
@ MimeHTML
Definition: khtmlpart_p.h:83
MimeImage
@ MimeImage
Definition: khtmlpart_p.h:87
MimeXHTML
@ MimeXHTML
Definition: khtmlpart_p.h:85
MimeText
@ MimeText
Definition: khtmlpart_p.h:88
MimeOther
@ MimeOther
Definition: khtmlpart_p.h:89
MimeSVG
@ MimeSVG
Definition: khtmlpart_p.h:84
MimeXML
@ MimeXML
Definition: khtmlpart_p.h:86
khtmlview.h
khtmlviewbar.h
kicon.h
SmallIcon
QPixmap SmallIcon(const QString &name, int force_size, int state, const QStringList &overlays)
MainBarIcon
QPixmap MainBarIcon(const QString &name, int force_size, int state, const QStringList &overlays)
kiconloader.h
kjserrordlg.h
timeout
int timeout
klocale.h
ki18n
KLocalizedString ki18n(const char *msg)
i18n
QString i18n(const char *text)
i18np
QString i18np(const char *sing, const char *plur, const A1 &a1)
i18nc
QString i18nc(const char *ctxt, const char *text)
kmenu.h
kmessagebox.h
kmimetypetrader.h
kpassivepopup.h
kprotocolmanager.h
kselectaction.h
ksslinfodialog.h
ksslsettings.h
kstandardaction.h
kstandarddirs.h
kstandardguiitem.h
kstatusbar.h
kstringhandler.h
ktemporaryfile.h
ktoggleaction.h
ktoolinvocation.h
kurifilter.h
kurllabel.h
kwindowsystem.h
DOM
This library provides a full-featured HTML parser and widget.
Definition: design.h:55
DOM::strcmp
bool strcmp(const DOMString &a, const DOMString &b)
Definition: dom_string.h:169
KAuthorized::authorizeUrlAction
bool authorizeUrlAction(const QString &action, const KUrl &baseUrl, const KUrl &destUrl)
KDE::lstat
int lstat(const QString &path, KDE_struct_stat *buf)
KDE::stat
int stat(const QString &path, KDE_struct_stat *buf)
run
bool run(const KUrl &_url, bool _is_local)
KGlobal::locale
KLocale * locale()
KGlobal::config
KSharedConfigPtr config()
KIO::HostInfo::setCacheSize
void setCacheSize(int s)
KIO::HostInfo::prefetchHost
void prefetchHost(const QString &hostName)
KIO::HostInfo::setTTL
void setTTL(int ttl)
KIO
KIO::pixmapForUrl
QPixmap pixmapForUrl(const KUrl &_url, mode_t _mode=0, KIconLoader::Group _group=KIconLoader::Desktop, int _force_size=0, int _state=0, QString *_path=0)
KIO::http_post
TransferJob * http_post(const KUrl &url, const QByteArray &postData, JobFlags flags=DefaultFlags)
KIO::convertSize
QString convertSize(KIO::filesize_t size)
KIO::getCacheControlString
QString getCacheControlString(KIO::CacheControl cacheControl)
KIO::get
TransferJob * get(const KUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
KIO::NoReload
NoReload
mimetype
MimetypeJob * mimetype(const KUrl &url, JobFlags flags=DefaultFlags)
KIO::stat
StatJob * stat(const KUrl &url, bool sideIsSource, short int details, JobFlags flags=DefaultFlags)
KIO::CC_Cache
CC_Cache
KIO::CC_Verify
CC_Verify
KIO::CC_Reload
CC_Reload
KIO::CC_Refresh
CC_Refresh
KIO::rawErrorDetail
QByteArray rawErrorDetail(int errorCode, const QString &errorText, const KUrl *reqUrl=0L, int method=-1)
KIO::HideProgressInfo
HideProgressInfo
KIO::ERR_NO_CONTENT
ERR_NO_CONTENT
KIO::ERR_UNKNOWN
ERR_UNKNOWN
KIO::ERR_IS_DIRECTORY
ERR_IS_DIRECTORY
KIO::http_update_cache
SimpleJob * http_update_cache(const KUrl &url, bool no_cache, time_t expireDate)
message
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
KParts
next
KAction * next(const QObject *recvr, const char *slot, QObject *parent)
name
const char * name(StandardAction id)
KStandardAction::SelectAll
SelectAll
KStandardAction::Find
Find
KStandardAction::FindNext
FindNext
KStandardAction::FindPrev
FindPrev
KStandardAction::SaveAs
SaveAs
cont
KGuiItem cont()
KStandardGuiItem::cancel
KGuiItem cancel()
ok
KGuiItem ok()
KStandardGuiItem::close
KGuiItem close()
end
const KShortcut & end()
reload
const KShortcut & reload()
KStringHandler::rsqueeze
QString rsqueeze(const QString &str, int maxlen=40)
KStringHandler::csqueeze
QString csqueeze(const QString &str, int maxlen=40)
khtml
netaccess.h
if
if(!yymsg) yymsg
partmanager.h
scriptableextension.h
KHTMLFrameList
Definition: khtml_childframe_p.h:82
KHTMLFrameList::find
Iterator find(const QString &name) KDE_NO_EXPORT
Definition: khtml_childframe.cpp:126
KHTMLPartPrivate::SubmitForm
Definition: khtmlpart_p.h:356
KParts::BrowserArguments
KParts::BrowserArguments::setLockHistory
void setLockHistory(bool lock)
KParts::BrowserArguments::redirectedRequest
bool redirectedRequest() const
KParts::BrowserArguments::setDoPost
void setDoPost(bool enable)
KParts::BrowserArguments::contentType
QString contentType() const
KParts::BrowserArguments::docState
QStringList docState
KParts::BrowserArguments::setForcesNewWindow
void setForcesNewWindow(bool forcesNewWindow)
KParts::BrowserArguments::postData
QByteArray postData
KParts::BrowserArguments::setContentType
void setContentType(const QString &contentType)
KParts::BrowserArguments::lockHistory
bool lockHistory() const
KParts::BrowserArguments::frameName
QString frameName
KParts::BrowserArguments::softReload
bool softReload
KParts::BrowserArguments::doPost
bool doPost() const
KParts::ScriptableExtension
KPluginFactory
khtml::EditorContext
Contextual information about the caret and the built-in editor.
Definition: editing_p.h:38
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal