2015-11-08 10:22:01 +02:00
/* This file is part of the KDE project
*
* Copyright ( C ) 1998 , 1999 Torben Weis < weis @ kde . org >
* 1999 Lars Knoll < knoll @ kde . org >
* 1999 Antti Koivisto < koivisto @ kde . org >
* 2000 Simon Hausmann < hausmann @ kde . org >
* 2000 Stefan Schimanski < 1 Stein @ gmx . de >
* 2001 - 2005 George Staikos < staikos @ kde . org >
* 2001 - 2003 Dirk Mueller < mueller @ kde . org >
* 2000 - 2005 David Faure < faure @ kde . org >
* 2002 Apple Computer , Inc .
* 2010 Maksim Orlovich ( maksim @ kde . org )
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation ; either
* version 2 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public License
* along with this library ; see the file COPYING . LIB . If not , write to
* the Free Software Foundation , Inc . , 51 Franklin Street , Fifth Floor ,
* Boston , MA 02110 - 1301 , USA .
*/
//#define SPEED_DEBUG
# include "khtml_part.h"
# include "ui_htmlpageinfo.h"
# include "khtmlviewbar.h"
# include "khtml_pagecache.h"
# include "dom/dom_string.h"
# include "dom/dom_element.h"
# include "dom/dom_exception.h"
# include "dom/html_document.h"
# include "dom/dom2_range.h"
# include "editing/editor.h"
# include "html/html_documentimpl.h"
# include "html/html_baseimpl.h"
# include "html/html_objectimpl.h"
# include "html/html_miscimpl.h"
# include "html/html_imageimpl.h"
# include "imload/imagemanager.h"
# include "rendering/render_text.h"
# include "rendering/render_frames.h"
# include "rendering/render_layer.h"
# include "rendering/render_position.h"
# include "misc/loader.h"
# include "misc/khtml_partaccessor.h"
# include "xml/dom2_eventsimpl.h"
# include "xml/dom2_rangeimpl.h"
# include "xml/xml_tokenizer.h"
# include "css/cssstyleselector.h"
using namespace DOM ;
# include "khtmlview.h"
# include <kparts/partmanager.h>
# include <kparts/browseropenorsavequestion.h>
# include <kacceleratormanager.h>
# include "ecma/kjs_proxy.h"
# include "ecma/kjs_window.h"
# include "ecma/kjs_events.h"
# include "khtml_settings.h"
# include "kjserrordlg.h"
# include <kjs/function.h>
# include <kjs/interpreter.h>
# include <sys/types.h>
# include <assert.h>
# include <unistd.h>
# include <config.h>
# include <kstandarddirs.h>
# include <kstringhandler.h>
# include <kio/job.h>
# include <kio/jobuidelegate.h>
# include <kio/global.h>
# include <kio/netaccess.h>
# include <kio/hostinfo_p.h>
# include <kprotocolmanager.h>
# include <kdebug.h>
# include <kicon.h>
# include <kiconloader.h>
# include <klocale.h>
# include <kmessagebox.h>
# include <kstandardaction.h>
# include <kstandardguiitem.h>
# include <kactioncollection.h>
# include <kfiledialog.h>
# include <kmimetypetrader.h>
# include <ktemporaryfile.h>
# include <kglobalsettings.h>
# include <ktoolinvocation.h>
# include <kauthorized.h>
# include <kparts/browserinterface.h>
# include <kparts/scriptableextension.h>
# include <kde_file.h>
# include <kactionmenu.h>
# include <ktoggleaction.h>
# include <kcodecaction.h>
# include <kselectaction.h>
# include <ksslinfodialog.h>
# include <ksslsettings.h>
# include <kfileitem.h>
# include <kurifilter.h>
# include <kstatusbar.h>
# include <kurllabel.h>
# include <QtGui/QClipboard>
# include <QtGui/QToolTip>
# include <QtCore/QFile>
# include <QtCore/qmetaobject.h>
# include <QtGui/QTextDocument>
# include <QtCore/qdatetime.h>
# include <QtNetwork/QSslCertificate>
# include "khtmlpart_p.h"
# include "khtml_iface.h"
# include "kpassivepopup.h"
# include "kmenu.h"
# include "rendering/render_form.h"
# include <kwindowsystem.h>
# include <kconfiggroup.h>
# include "ecma/debugger/debugwindow.h"
// SVG
# include <svg/SVGDocument.h>
bool KHTMLPartPrivate : : s_dnsInitialised = false ;
// DNS prefetch settings
static const int sMaxDNSPrefetchPerPage = 42 ;
static const int sDNSPrefetchTimerDelay = 200 ;
static const int sDNSTTLSeconds = 400 ;
static const int sDNSCacheSize = 500 ;
namespace khtml {
class PartStyleSheetLoader : public CachedObjectClient
{
public :
PartStyleSheetLoader ( KHTMLPart * part , DOM : : DOMString url , DocLoader * dl )
{
m_part = part ;
m_cachedSheet = dl - > requestStyleSheet ( url , QString ( ) , " text/css " ,
true /* "user sheet" */ ) ;
if ( m_cachedSheet )
m_cachedSheet - > ref ( this ) ;
}
virtual ~ PartStyleSheetLoader ( )
{
if ( m_cachedSheet ) m_cachedSheet - > deref ( this ) ;
}
virtual void setStyleSheet ( const DOM : : DOMString & , const DOM : : DOMString & sheet , const DOM : : DOMString & , const DOM : : DOMString & /*mimetype*/ )
{
if ( m_part )
m_part - > setUserStyleSheet ( sheet . string ( ) ) ;
delete this ;
}
virtual void error ( int , const QString & ) {
delete this ;
}
QPointer < KHTMLPart > m_part ;
khtml : : CachedCSSStyleSheet * m_cachedSheet ;
} ;
}
KHTMLPart : : KHTMLPart ( QWidget * parentWidget , QObject * parent , GUIProfile prof )
: KParts : : ReadOnlyPart ( parent )
{
d = 0 ;
KHTMLGlobal : : registerPart ( this ) ;
setComponentData ( KHTMLGlobal : : componentData ( ) , false ) ;
init ( new KHTMLView ( this , parentWidget ) , prof ) ;
}
KHTMLPart : : KHTMLPart ( KHTMLView * view , QObject * parent , GUIProfile prof )
: KParts : : ReadOnlyPart ( parent )
{
d = 0 ;
KHTMLGlobal : : registerPart ( this ) ;
setComponentData ( KHTMLGlobal : : componentData ( ) , false ) ;
assert ( view ) ;
if ( ! view - > part ( ) )
view - > setPart ( this ) ;
init ( view , prof ) ;
}
void KHTMLPart : : init ( KHTMLView * view , GUIProfile prof )
{
if ( prof = = DefaultGUI )
setXMLFile ( " khtml.rc " ) ;
else if ( prof = = BrowserViewGUI )
setXMLFile ( " khtml_browser.rc " ) ;
d = new KHTMLPartPrivate ( this , parent ( ) ) ;
d - > m_view = view ;
if ( ! parentPart ( ) ) {
QWidget * widget = new QWidget ( view - > parentWidget ( ) ) ;
widget - > setObjectName ( " khtml_part_widget " ) ;
QVBoxLayout * layout = new QVBoxLayout ( widget ) ;
layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
layout - > setSpacing ( 0 ) ;
widget - > setLayout ( layout ) ;
d - > m_topViewBar = new KHTMLViewBar ( KHTMLViewBar : : Top , d - > m_view , widget ) ;
d - > m_bottomViewBar = new KHTMLViewBar ( KHTMLViewBar : : Bottom , d - > m_view , widget ) ;
layout - > addWidget ( d - > m_topViewBar ) ;
layout - > addWidget ( d - > m_view ) ;
layout - > addWidget ( d - > m_bottomViewBar ) ;
setWidget ( widget ) ;
widget - > setFocusProxy ( d - > m_view ) ;
} else {
setWidget ( view ) ;
}
d - > m_guiProfile = prof ;
d - > m_extension = new KHTMLPartBrowserExtension ( this ) ;
d - > m_extension - > setObjectName ( " KHTMLBrowserExtension " ) ;
d - > m_hostExtension = new KHTMLPartBrowserHostExtension ( this ) ;
d - > m_statusBarExtension = new KParts : : StatusBarExtension ( this ) ;
d - > m_scriptableExtension = new KJS : : KHTMLPartScriptable ( this ) ;
new KHTMLTextExtension ( this ) ;
new KHTMLHtmlExtension ( this ) ;
d - > m_statusBarPopupLabel = 0L ;
d - > m_openableSuppressedPopups = 0 ;
d - > m_paLoadImages = 0 ;
d - > m_paDebugScript = 0 ;
d - > m_bMousePressed = false ;
d - > m_bRightMousePressed = false ;
d - > m_bCleared = false ;
if ( prof = = BrowserViewGUI ) {
d - > m_paViewDocument = new KAction ( i18n ( " View Do&cument Source " ) , this ) ;
actionCollection ( ) - > addAction ( " viewDocumentSource " , d - > m_paViewDocument ) ;
connect ( d - > m_paViewDocument , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotViewDocumentSource ( ) ) ) ;
if ( ! parentPart ( ) ) {
d - > m_paViewDocument - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : Key_U ) ) ;
}
d - > m_paViewFrame = new KAction ( i18n ( " View Frame Source " ) , this ) ;
actionCollection ( ) - > addAction ( " viewFrameSource " , d - > m_paViewFrame ) ;
connect ( d - > m_paViewFrame , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotViewFrameSource ( ) ) ) ;
if ( ! parentPart ( ) ) {
d - > m_paViewFrame - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : SHIFT + Qt : : Key_U ) ) ;
}
d - > m_paViewInfo = new KAction ( i18n ( " View Document Information " ) , this ) ;
actionCollection ( ) - > addAction ( " viewPageInfo " , d - > m_paViewInfo ) ;
if ( ! parentPart ( ) ) {
d - > m_paViewInfo - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : Key_I ) ) ;
}
connect ( d - > m_paViewInfo , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotViewPageInfo ( ) ) ) ;
d - > m_paSaveBackground = new KAction ( i18n ( " Save &Background Image As... " ) , this ) ;
actionCollection ( ) - > addAction ( " saveBackground " , d - > m_paSaveBackground ) ;
connect ( d - > m_paSaveBackground , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotSaveBackground ( ) ) ) ;
d - > m_paSaveDocument = actionCollection ( ) - > addAction ( KStandardAction : : SaveAs , " saveDocument " ,
this , SLOT ( slotSaveDocument ( ) ) ) ;
if ( parentPart ( ) )
d - > m_paSaveDocument - > setShortcuts ( KShortcut ( ) ) ; // avoid clashes
d - > m_paSaveFrame = new KAction ( i18n ( " Save &Frame As... " ) , this ) ;
actionCollection ( ) - > addAction ( " saveFrame " , d - > m_paSaveFrame ) ;
connect ( d - > m_paSaveFrame , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotSaveFrame ( ) ) ) ;
} else {
d - > m_paViewDocument = 0 ;
d - > m_paViewFrame = 0 ;
d - > m_paViewInfo = 0 ;
d - > m_paSaveBackground = 0 ;
d - > m_paSaveDocument = 0 ;
d - > m_paSaveFrame = 0 ;
}
d - > m_paSecurity = new KAction ( i18n ( " SSL " ) , this ) ;
actionCollection ( ) - > addAction ( " security " , d - > m_paSecurity ) ;
connect ( d - > m_paSecurity , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotSecurity ( ) ) ) ;
d - > m_paDebugRenderTree = new KAction ( i18n ( " Print Rendering Tree to STDOUT " ) , this ) ;
actionCollection ( ) - > addAction ( " debugRenderTree " , d - > m_paDebugRenderTree ) ;
connect ( d - > m_paDebugRenderTree , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotDebugRenderTree ( ) ) ) ;
d - > m_paDebugDOMTree = new KAction ( i18n ( " Print DOM Tree to STDOUT " ) , this ) ;
actionCollection ( ) - > addAction ( " debugDOMTree " , d - > m_paDebugDOMTree ) ;
connect ( d - > m_paDebugDOMTree , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotDebugDOMTree ( ) ) ) ;
KAction * paDebugFrameTree = new KAction ( i18n ( " Print frame tree to STDOUT " ) , this ) ;
actionCollection ( ) - > addAction ( " debugFrameTree " , paDebugFrameTree ) ;
connect ( paDebugFrameTree , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotDebugFrameTree ( ) ) ) ;
d - > m_paStopAnimations = new KAction ( i18n ( " Stop Animated Images " ) , this ) ;
actionCollection ( ) - > addAction ( " stopAnimations " , d - > m_paStopAnimations ) ;
connect ( d - > m_paStopAnimations , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotStopAnimations ( ) ) ) ;
d - > m_paSetEncoding = new KCodecAction ( KIcon ( " character-set " ) , i18n ( " Set &Encoding " ) , this , true ) ;
actionCollection ( ) - > addAction ( " setEncoding " , d - > m_paSetEncoding ) ;
// d->m_paSetEncoding->setDelayed( false );
connect ( d - > m_paSetEncoding , SIGNAL ( triggered ( QString ) ) , this , SLOT ( slotSetEncoding ( QString ) ) ) ;
connect ( d - > m_paSetEncoding , SIGNAL ( triggered ( KEncodingDetector : : AutoDetectScript ) ) , this , SLOT ( slotAutomaticDetectionLanguage ( KEncodingDetector : : AutoDetectScript ) ) ) ;
if ( KGlobal : : config ( ) - > hasGroup ( " HTML Settings " ) ) {
KConfigGroup config ( KGlobal : : config ( ) , " HTML Settings " ) ;
d - > m_autoDetectLanguage = static_cast < KEncodingDetector : : AutoDetectScript > ( config . readEntry ( " AutomaticDetectionLanguage " , /*static_cast<int>(language) */ 0 ) ) ;
if ( d - > m_autoDetectLanguage = = KEncodingDetector : : None ) {
const QByteArray name = KGlobal : : locale ( ) - > encoding ( ) . toLower ( ) ;
// kWarning() << "00000000 ";
if ( name . endsWith ( " 1251 " ) | | name . startsWith ( " koi " ) | | name = = " iso-8859-5 " )
d - > m_autoDetectLanguage = KEncodingDetector : : Cyrillic ;
else if ( name . endsWith ( " 1256 " ) | | name = = " iso-8859-6 " )
d - > m_autoDetectLanguage = KEncodingDetector : : Arabic ;
else if ( name . endsWith ( " 1257 " ) | | name = = " iso-8859-13 " | | name = = " iso-8859-4 " )
d - > m_autoDetectLanguage = KEncodingDetector : : Baltic ;
else if ( name . endsWith ( " 1250 " ) | | name = = " ibm852 " | | name = = " iso-8859-2 " | | name = = " iso-8859-3 " )
d - > m_autoDetectLanguage = KEncodingDetector : : CentralEuropean ;
else if ( name . endsWith ( " 1253 " ) | | name = = " iso-8859-7 " )
d - > m_autoDetectLanguage = KEncodingDetector : : Greek ;
else if ( name . endsWith ( " 1255 " ) | | name = = " iso-8859-8 " | | name = = " iso-8859-8-i " )
d - > m_autoDetectLanguage = KEncodingDetector : : Hebrew ;
else if ( name = = " jis7 " | | name = = " eucjp " | | name = = " sjis " )
d - > m_autoDetectLanguage = KEncodingDetector : : Japanese ;
else if ( name . endsWith ( " 1254 " ) | | name = = " iso-8859-9 " )
d - > m_autoDetectLanguage = KEncodingDetector : : Turkish ;
else if ( name . endsWith ( " 1252 " ) | | name = = " iso-8859-1 " | | name = = " iso-8859-15 " )
d - > m_autoDetectLanguage = KEncodingDetector : : WesternEuropean ;
else
d - > m_autoDetectLanguage = KEncodingDetector : : SemiautomaticDetection ;
// kWarning() << "0000000end " << d->m_autoDetectLanguage << " " << KGlobal::locale()->encodingMib();
}
d - > m_paSetEncoding - > setCurrentAutoDetectScript ( d - > m_autoDetectLanguage ) ;
}
d - > m_paUseStylesheet = new KSelectAction ( i18n ( " Use S&tylesheet " ) , this ) ;
actionCollection ( ) - > addAction ( " useStylesheet " , d - > m_paUseStylesheet ) ;
connect ( d - > m_paUseStylesheet , SIGNAL ( triggered ( int ) ) , this , SLOT ( slotUseStylesheet ( ) ) ) ;
if ( prof = = BrowserViewGUI ) {
d - > m_paIncZoomFactor = new KHTMLZoomFactorAction ( this , true , " format-font-size-more " , i18n ( " Enlarge Font " ) , this ) ;
actionCollection ( ) - > addAction ( " incFontSizes " , d - > m_paIncZoomFactor ) ;
connect ( d - > m_paIncZoomFactor , SIGNAL ( triggered ( bool ) ) , SLOT ( slotIncFontSizeFast ( ) ) ) ;
d - > m_paIncZoomFactor - > setWhatsThis ( i18n ( " <qt>Enlarge Font<br /><br /> "
" Make the font in this window bigger. "
" Click and hold down the mouse button for a menu with all available font sizes.</qt> " ) ) ;
d - > m_paDecZoomFactor = new KHTMLZoomFactorAction ( this , false , " format-font-size-less " , i18n ( " Shrink Font " ) , this ) ;
actionCollection ( ) - > addAction ( " decFontSizes " , d - > m_paDecZoomFactor ) ;
connect ( d - > m_paDecZoomFactor , SIGNAL ( triggered ( bool ) ) , SLOT ( slotDecFontSizeFast ( ) ) ) ;
d - > m_paDecZoomFactor - > setWhatsThis ( i18n ( " <qt>Shrink Font<br /><br /> "
" Make the font in this window smaller. "
" Click and hold down the mouse button for a menu with all available font sizes.</qt> " ) ) ;
if ( ! parentPart ( ) ) {
// For framesets, this action also affects frames, so only
// the frameset needs to define a shortcut for the action.
// TODO: Why also CTRL+=? Because of http://trolltech.com/developer/knowledgebase/524/?
// Nobody else does it...
d - > m_paIncZoomFactor - > setShortcut ( KShortcut ( " CTRL++; CTRL+= " ) ) ;
d - > m_paDecZoomFactor - > setShortcut ( QKeySequence ( Qt : : CTRL + Qt : : Key_Minus ) ) ;
}
}
d - > m_paFind = actionCollection ( ) - > addAction ( KStandardAction : : Find , " find " , this , SLOT ( slotFind ( ) ) ) ;
d - > m_paFind - > setWhatsThis ( i18n ( " <qt>Find text<br /><br /> "
" Shows a dialog that allows you to find text on the displayed page.</qt> " ) ) ;
d - > m_paFindNext = actionCollection ( ) - > addAction ( KStandardAction : : FindNext , " findNext " , this , SLOT ( slotFindNext ( ) ) ) ;
d - > m_paFindNext - > setWhatsThis ( i18n ( " <qt>Find next<br /><br /> "
" Find the next occurrence of the text that you "
" have found using the <b>Find Text</b> function.</qt> " ) ) ;
d - > m_paFindPrev = actionCollection ( ) - > addAction ( KStandardAction : : FindPrev , " findPrevious " ,
this , SLOT ( slotFindPrev ( ) ) ) ;
d - > m_paFindPrev - > setWhatsThis ( i18n ( " <qt>Find previous<br /><br /> "
" Find the previous occurrence of the text that you "
" have found using the <b>Find Text</b> function.</qt> " ) ) ;
// These two actions aren't visible in the menus, but exist for the (configurable) shortcut
d - > m_paFindAheadText = new KAction ( i18n ( " Find Text as You Type " ) , this ) ;
actionCollection ( ) - > addAction ( " findAheadText " , d - > m_paFindAheadText ) ;
d - > m_paFindAheadText - > setShortcuts ( KShortcut ( ' / ' ) ) ;
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. " ) ) ;
connect ( d - > m_paFindAheadText , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotFindAheadText ( ) ) ) ;
d - > m_paFindAheadLinks = new KAction ( i18n ( " Find Links as You Type " ) , this ) ;
actionCollection ( ) - > addAction ( " findAheadLink " , d - > m_paFindAheadLinks ) ;
// The issue is that it sets the (sticky) option FindLinksOnly, so
// if you trigger this shortcut once by mistake, Esc and Ctrl+F will still have the option set.
// Better let advanced users configure a shortcut for this advanced option
//d->m_paFindAheadLinks->setShortcuts( KShortcut( '\'' ) );
d - > m_paFindAheadLinks - > setHelpText ( i18n ( " This shortcut shows the find bar, and sets the option \" Find links only \" . " ) ) ;
connect ( d - > m_paFindAheadLinks , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotFindAheadLink ( ) ) ) ;
if ( parentPart ( ) )
{
d - > m_paFind - > setShortcuts ( KShortcut ( ) ) ; // avoid clashes
d - > m_paFindNext - > setShortcuts ( KShortcut ( ) ) ; // avoid clashes
d - > m_paFindPrev - > setShortcuts ( KShortcut ( ) ) ; // avoid clashes
d - > m_paFindAheadText - > setShortcuts ( KShortcut ( ) ) ;
d - > m_paFindAheadLinks - > setShortcuts ( KShortcut ( ) ) ;
}
d - > m_paPrintFrame = new KAction ( i18n ( " Print Frame... " ) , this ) ;
actionCollection ( ) - > addAction ( " printFrame " , d - > m_paPrintFrame ) ;
d - > m_paPrintFrame - > setIcon ( KIcon ( " document-print-frame " ) ) ;
connect ( d - > m_paPrintFrame , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotPrintFrame ( ) ) ) ;
d - > m_paPrintFrame - > setWhatsThis ( i18n ( " <qt>Print Frame<br /><br /> "
" Some pages have several frames. To print only a single frame, click "
" on it and then use this function.</qt> " ) ) ;
// Warning: The name selectAll is used hardcoded by some 3rd parties to remove the
// shortcut for selectAll so they do not get ambigous shortcuts. Renaming it
// will either crash or render useless that workaround. It would be better
// to use the name KStandardAction::name(KStandardAction::SelectAll) but we
// can't for the same reason.
d - > m_paSelectAll = actionCollection ( ) - > addAction ( KStandardAction : : SelectAll , " selectAll " ,
this , SLOT ( slotSelectAll ( ) ) ) ;
if ( parentPart ( ) ) // Only the frameset has the shortcut, but the slot uses the current frame.
d - > m_paSelectAll - > setShortcuts ( KShortcut ( ) ) ; // avoid clashes
d - > m_paToggleCaretMode = new KToggleAction ( i18n ( " Toggle Caret Mode " ) , this ) ;
actionCollection ( ) - > addAction ( " caretMode " , d - > m_paToggleCaretMode ) ;
d - > m_paToggleCaretMode - > setShortcut ( QKeySequence ( Qt : : Key_F7 ) ) ;
connect ( d - > m_paToggleCaretMode , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotToggleCaretMode ( ) ) ) ;
d - > m_paToggleCaretMode - > setChecked ( isCaretMode ( ) ) ;
if ( parentPart ( ) )
d - > m_paToggleCaretMode - > setShortcut ( KShortcut ( ) ) ; // avoid clashes
// set the default java(script) flags according to the current host.
d - > m_bOpenMiddleClick = d - > m_settings - > isOpenMiddleClickEnabled ( ) ;
d - > m_bJScriptEnabled = d - > m_settings - > isJavaScriptEnabled ( ) ;
setDebugScript ( d - > m_settings - > isJavaScriptDebugEnabled ( ) ) ;
d - > m_bJavaEnabled = d - > m_settings - > isJavaEnabled ( ) ;
d - > m_bPluginsEnabled = d - > m_settings - > isPluginsEnabled ( ) ;
// Set the meta-refresh flag...
d - > m_metaRefreshEnabled = d - > m_settings - > isAutoDelayedActionsEnabled ( ) ;
KHTMLSettings : : KSmoothScrollingMode ssm = d - > m_settings - > smoothScrolling ( ) ;
if ( ssm = = KHTMLSettings : : KSmoothScrollingDisabled )
d - > m_view - > setSmoothScrollingModeDefault ( KHTMLView : : SSMDisabled ) ;
else if ( ssm = = KHTMLSettings : : KSmoothScrollingWhenEfficient )
d - > m_view - > setSmoothScrollingModeDefault ( KHTMLView : : SSMWhenEfficient ) ;
else
d - > m_view - > setSmoothScrollingModeDefault ( KHTMLView : : SSMEnabled ) ;
if ( d - > m_bDNSPrefetchIsDefault & & ! onlyLocalReferences ( ) ) {
KHTMLSettings : : KDNSPrefetch dpm = d - > m_settings - > dnsPrefetch ( ) ;
if ( dpm = = KHTMLSettings : : KDNSPrefetchDisabled )
d - > m_bDNSPrefetch = DNSPrefetchDisabled ;
else if ( dpm = = KHTMLSettings : : KDNSPrefetchOnlyWWWAndSLD )
d - > m_bDNSPrefetch = DNSPrefetchOnlyWWWAndSLD ;
else
d - > m_bDNSPrefetch = DNSPrefetchEnabled ;
}
if ( ! KHTMLPartPrivate : : s_dnsInitialised & & d - > m_bDNSPrefetch ! = DNSPrefetchDisabled ) {
KIO : : HostInfo : : setCacheSize ( sDNSCacheSize ) ;
KIO : : HostInfo : : setTTL ( sDNSTTLSeconds ) ;
KHTMLPartPrivate : : s_dnsInitialised = true ;
}
// all shortcuts should only be active, when this part has focus
foreach ( QAction * action , actionCollection ( ) - > actions ( ) ) {
action - > setShortcutContext ( Qt : : WidgetWithChildrenShortcut ) ;
}
actionCollection ( ) - > associateWidget ( view ) ;
connect ( view , SIGNAL ( zoomView ( int ) ) , SLOT ( slotZoomView ( int ) ) ) ;
connect ( this , SIGNAL ( completed ( ) ) ,
this , SLOT ( updateActions ( ) ) ) ;
connect ( this , SIGNAL ( completed ( bool ) ) ,
this , SLOT ( updateActions ( ) ) ) ;
connect ( this , SIGNAL ( started ( KIO : : Job * ) ) ,
this , SLOT ( updateActions ( ) ) ) ;
// #### FIXME: the process wide loader is going to signal every part about every loaded object.
// That's quite inefficient. Should be per-document-tree somehow. Even signaling to
// child parts that a request from an ancestor has loaded is inefficent..
connect ( khtml : : Cache : : loader ( ) , SIGNAL ( requestStarted ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ,
this , SLOT ( slotLoaderRequestStarted ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ) ;
connect ( khtml : : Cache : : loader ( ) , SIGNAL ( requestDone ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ,
this , SLOT ( slotLoaderRequestDone ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ) ;
connect ( khtml : : Cache : : loader ( ) , SIGNAL ( requestFailed ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ,
this , SLOT ( slotLoaderRequestDone ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ) ;
connect ( & d - > m_progressUpdateTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( slotProgressUpdate ( ) ) ) ;
findTextBegin ( ) ; //reset find variables
connect ( & d - > m_redirectionTimer , SIGNAL ( timeout ( ) ) ,
this , SLOT ( slotRedirect ( ) ) ) ;
if ( QDBusConnection : : sessionBus ( ) . isConnected ( ) ) {
new KHTMLPartIface ( this ) ; // our "adaptor"
for ( int i = 1 ; ; + + i )
if ( QDBusConnection : : sessionBus ( ) . registerObject ( QString ( " /KHTML/%1/widget " ) . arg ( i ) , this ) )
break ;
else if ( i = = 0xffff )
kFatal ( ) < < " Something is very wrong in KHTMLPart! " ;
}
if ( prof = = BrowserViewGUI & & ! parentPart ( ) )
loadPlugins ( ) ;
// "khtml" catalog does not exist, our translations are in kdelibs.
// removing this catalog from KGlobal::locale() prevents problems
// with changing the language in applications at runtime -Thomas Reitelbach
// DF: a better fix would be to set the right catalog name in the KComponentData!
KGlobal : : locale ( ) - > removeCatalog ( " khtml " ) ;
}
KHTMLPart : : ~ KHTMLPart ( )
{
kDebug ( 6050 ) < < this ;
KConfigGroup config ( KGlobal : : config ( ) , " HTML Settings " ) ;
config . writeEntry ( " AutomaticDetectionLanguage " , int ( d - > m_autoDetectLanguage ) ) ;
if ( d - > m_manager ) { // the PartManager for this part's children
d - > m_manager - > removePart ( this ) ;
}
slotWalletClosed ( ) ;
if ( ! parentPart ( ) ) { // only delete it if the top khtml_part closes
removeJSErrorExtension ( ) ;
}
stopAutoScroll ( ) ;
d - > m_redirectionTimer . stop ( ) ;
if ( ! d - > m_bComplete )
closeUrl ( ) ;
disconnect ( khtml : : Cache : : loader ( ) , SIGNAL ( requestStarted ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ,
this , SLOT ( slotLoaderRequestStarted ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ) ;
disconnect ( khtml : : Cache : : loader ( ) , SIGNAL ( requestDone ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ,
this , SLOT ( slotLoaderRequestDone ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ) ;
disconnect ( khtml : : Cache : : loader ( ) , SIGNAL ( requestFailed ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ,
this , SLOT ( slotLoaderRequestDone ( khtml : : DocLoader * , khtml : : CachedObject * ) ) ) ;
clear ( ) ;
hide ( ) ;
if ( d - > m_view )
{
d - > m_view - > m_part = 0 ;
}
// Have to delete this here since we forward declare it in khtmlpart_p and
// at least some compilers won't call the destructor in this case.
delete d - > m_jsedlg ;
d - > m_jsedlg = 0 ;
if ( ! parentPart ( ) ) // only delete d->m_frame if the top khtml_part closes
delete d - > m_frame ;
else if ( d - > m_frame & & d - > m_frame - > m_run ) // for kids, they may get detached while
d - > m_frame - > m_run . data ( ) - > abort ( ) ; // resolving mimetype; cancel that if needed
delete d ; d = 0 ;
KHTMLGlobal : : deregisterPart ( this ) ;
}
bool KHTMLPart : : restoreURL ( const KUrl & url )
{
kDebug ( 6050 ) < < url ;
d - > m_redirectionTimer . stop ( ) ;
/*
* That ' s not a good idea as it will call closeUrl ( ) on all
* child frames , preventing them from further loading . This
* method gets called from restoreState ( ) in case of a full frameset
* restoral , and restoreState ( ) calls closeUrl ( ) before restoring
* anyway .
kDebug ( 6050 ) < < " closing old URL " ;
closeUrl ( ) ;
*/
d - > m_bComplete = false ;
d - > m_bLoadEventEmitted = false ;
d - > m_workingURL = url ;
// set the java(script) flags according to the current host.
d - > m_bJScriptEnabled = KHTMLGlobal : : defaultHTMLSettings ( ) - > isJavaScriptEnabled ( url . host ( ) ) ;
setDebugScript ( KHTMLGlobal : : defaultHTMLSettings ( ) - > isJavaScriptDebugEnabled ( ) ) ;
d - > m_bJavaEnabled = KHTMLGlobal : : defaultHTMLSettings ( ) - > isJavaEnabled ( url . host ( ) ) ;
d - > m_bPluginsEnabled = KHTMLGlobal : : defaultHTMLSettings ( ) - > isPluginsEnabled ( url . host ( ) ) ;
setUrl ( url ) ;
d - > m_restoreScrollPosition = true ;
disconnect ( d - > m_view , SIGNAL ( finishedLayout ( ) ) , this , SLOT ( restoreScrollPosition ( ) ) ) ;
connect ( d - > m_view , SIGNAL ( finishedLayout ( ) ) , this , SLOT ( restoreScrollPosition ( ) ) ) ;
KHTMLPageCache : : self ( ) - > fetchData ( d - > m_cacheId , this , SLOT ( slotRestoreData ( QByteArray ) ) ) ;
emit started ( 0L ) ;
return true ;
}
bool KHTMLPartPrivate : : isLocalAnchorJump ( const KUrl & url )
{
// kio_help actually uses fragments to identify different pages, so
// always reload with it.
if ( url . protocol ( ) = = QLatin1String ( " help " ) )
return false ;
return url . hasRef ( ) & & url . equals ( q - > url ( ) ,
KUrl : : CompareWithoutTrailingSlash | KUrl : : CompareWithoutFragment | KUrl : : AllowEmptyPath ) ;
}
void KHTMLPartPrivate : : executeAnchorJump ( const KUrl & url , bool lockHistory )
{
DOM : : HashChangeEventImpl * hashChangeEvImpl = 0 ;
const QString & oldRef = q - > url ( ) . ref ( ) ;
const QString & newRef = url . ref ( ) ;
const bool hashChanged = ( oldRef ! = newRef ) | | ( oldRef . isNull ( ) & & newRef . isEmpty ( ) ) ;
if ( hashChanged ) {
// Note: we want to emit openUrlNotify first thing to make the history capture the old state,
// however do not update history if a lock was explicitly requested, e.g. Location.replace()
if ( ! lockHistory ) {
emit m_extension - > openUrlNotify ( ) ;
}
// Create hashchange event
hashChangeEvImpl = new DOM : : HashChangeEventImpl ( ) ;
hashChangeEvImpl - > initHashChangeEvent ( " hashchange " ,
true , //bubble
false , //cancelable
q - > url ( ) . url ( ) , //oldURL
url . url ( ) //newURL
) ;
}
if ( ! q - > gotoAnchor ( newRef ) ) // encoded fragment
q - > gotoAnchor ( url . htmlRef ( ) ) ; // not encoded fragment
q - > setUrl ( url ) ;
emit m_extension - > setLocationBarUrl ( url . prettyUrl ( ) ) ;
if ( hashChangeEvImpl ) {
m_doc - > dispatchWindowEvent ( hashChangeEvImpl ) ;
}
}
bool KHTMLPart : : openUrl ( const KUrl & url )
{
kDebug ( 6050 ) < < this < < " opening " < < url ;
# ifndef KHTML_NO_WALLET
// Wallet forms are per page, so clear it when loading a different page if we
// are not an iframe (because we store walletforms only on the topmost part).
if ( ! parentPart ( ) )
d - > m_walletForms . clear ( ) ;
# endif
d - > m_redirectionTimer . stop ( ) ;
// check to see if this is an "error://" URL. This is caused when an error
// occurs before this part was loaded (e.g. KonqRun), and is passed to
// khtmlpart so that it can display the error.
if ( url . protocol ( ) = = " error " ) {
closeUrl ( ) ;
if ( d - > m_bJScriptEnabled ) {
d - > m_statusBarText [ BarOverrideText ] . clear ( ) ;
d - > m_statusBarText [ BarDefaultText ] . clear ( ) ;
}
/**
* The format of the error url is that two variables are passed in the query :
* error = int kio error code , errText = QString error text from kio
* and the URL where the error happened is passed as a sub URL .
*/
KUrl : : List urls = KUrl : : split ( url ) ;
//kDebug(6050) << "Handling error URL. URL count:" << urls.count();
if ( ! urls . isEmpty ( ) ) {
const KUrl mainURL = urls . first ( ) ;
int error = mainURL . queryItem ( " error " ) . toInt ( ) ;
// error=0 isn't a valid error code, so 0 means it's missing from the URL
if ( error = = 0 ) error = KIO : : ERR_UNKNOWN ;
const QString errorText = mainURL . queryItem ( " errText " ) ;
urls . pop_front ( ) ;
d - > m_workingURL = KUrl : : join ( urls ) ;
//kDebug(6050) << "Emitting fixed URL " << d->m_workingURL.prettyUrl();
emit d - > m_extension - > setLocationBarUrl ( d - > m_workingURL . prettyUrl ( ) ) ;
htmlError ( error , errorText , d - > m_workingURL ) ;
return true ;
}
}
if ( ! parentPart ( ) ) { // only do it for toplevel part
QString host = url . isLocalFile ( ) ? " localhost " : url . host ( ) ;
QString userAgent = KProtocolManager : : userAgentForHost ( host ) ;
if ( userAgent ! = KProtocolManager : : userAgentForHost ( QString ( ) ) ) {
if ( ! d - > m_statusBarUALabel ) {
d - > m_statusBarUALabel = new KUrlLabel ( d - > m_statusBarExtension - > statusBar ( ) ) ;
d - > m_statusBarUALabel - > setSizePolicy ( QSizePolicy ( QSizePolicy : : Fixed , QSizePolicy : : Minimum ) ) ;
d - > m_statusBarUALabel - > setUseCursor ( false ) ;
d - > m_statusBarExtension - > addStatusBarItem ( d - > m_statusBarUALabel , 0 , false ) ;
d - > m_statusBarUALabel - > setPixmap ( SmallIcon ( " preferences-web-browser-identification " ) ) ;
}
d - > m_statusBarUALabel - > setToolTip ( i18n ( " The fake user-agent '%1' is in use. " , userAgent ) ) ;
} else if ( d - > m_statusBarUALabel ) {
d - > m_statusBarExtension - > removeStatusBarItem ( d - > m_statusBarUALabel ) ;
delete d - > m_statusBarUALabel ;
d - > m_statusBarUALabel = 0L ;
}
}
KParts : : BrowserArguments browserArgs ( d - > m_extension - > browserArguments ( ) ) ;
KParts : : OpenUrlArguments args ( arguments ( ) ) ;
// in case
// a) we have no frameset (don't test m_frames.count(), iframes get in there)
// b) the url is identical with the currently displayed one (except for the htmlref!)
// c) the url request is not a POST operation and
// d) the caller did not request to reload the page
// e) there was no HTTP redirection meanwhile (testcase: webmin's software/tree.cgi)
// => we don't reload the whole document and
// we just jump to the requested html anchor
bool isFrameSet = false ;
if ( d - > m_doc & & d - > m_doc - > isHTMLDocument ( ) ) {
HTMLDocumentImpl * htmlDoc = static_cast < HTMLDocumentImpl * > ( d - > m_doc ) ;
isFrameSet = htmlDoc - > body ( ) & & ( htmlDoc - > body ( ) - > id ( ) = = ID_FRAMESET ) ;
}
if ( isFrameSet & & d - > isLocalAnchorJump ( url ) & & browserArgs . softReload )
{
QList < khtml : : ChildFrame * > : : Iterator it = d - > m_frames . begin ( ) ;
const QList < khtml : : ChildFrame * > : : Iterator end = d - > m_frames . end ( ) ;
for ( ; it ! = end ; + + it ) {
KHTMLPart * const part = qobject_cast < KHTMLPart * > ( ( * it ) - > m_part . data ( ) ) ;
if ( part )
{
// We are reloading frames to make them jump into offsets.
KParts : : OpenUrlArguments partargs ( part - > arguments ( ) ) ;
partargs . setReload ( true ) ;
part - > setArguments ( partargs ) ;
part - > openUrl ( part - > url ( ) ) ;
}
} /*next it*/
return true ;
}
if ( url . hasRef ( ) & & ! isFrameSet )
{
bool noReloadForced = ! args . reload ( ) & & ! browserArgs . redirectedRequest ( ) & & ! browserArgs . doPost ( ) ;
if ( noReloadForced & & d - > isLocalAnchorJump ( url ) )
{
kDebug ( 6050 ) < < " jumping to anchor. m_url = " < < url ;
setUrl ( url ) ;
emit started ( 0 ) ;
if ( ! gotoAnchor ( url . encodedHtmlRef ( ) ) )
gotoAnchor ( url . htmlRef ( ) ) ;
d - > m_bComplete = true ;
if ( d - > m_doc )
d - > m_doc - > setParsing ( false ) ;
kDebug ( 6050 ) < < " completed... " ;
emit completed ( ) ;
return true ;
}
}
// Save offset of viewport when page is reloaded to be compliant
// to every other capable browser out there.
if ( args . reload ( ) ) {
args . setXOffset ( d - > m_view - > contentsX ( ) ) ;
args . setYOffset ( d - > m_view - > contentsY ( ) ) ;
setArguments ( args ) ;
}
if ( ! d - > m_restored )
closeUrl ( ) ;
d - > m_restoreScrollPosition = d - > m_restored ;
disconnect ( d - > m_view , SIGNAL ( finishedLayout ( ) ) , this , SLOT ( restoreScrollPosition ( ) ) ) ;
connect ( d - > m_view , SIGNAL ( finishedLayout ( ) ) , this , SLOT ( restoreScrollPosition ( ) ) ) ;
// Classify the mimetype. Some, like images and plugins are handled
// by wrapping things up in tags, so we want to plain output the HTML,
// and not start the job and all that (since we would want the
// KPart or whatever to load it).
// This is also the only place we need to do this, as it's for
// internal iframe use, not any other clients.
MimeType type = d - > classifyMimeType ( args . mimeType ( ) ) ;
if ( type = = MimeImage | | type = = MimeOther ) {
begin ( url , args . xOffset ( ) , args . yOffset ( ) ) ;
write ( QString : : fromLatin1 ( " <html><head></head><body> " ) ) ;
if ( type = = MimeImage )
write ( QString : : fromLatin1 ( " <img " ) ) ;
else
write ( QString : : fromLatin1 ( " <embed " ) ) ;
write ( QString : : fromLatin1 ( " src= \" " ) ) ;
assert ( url . url ( ) . indexOf ( ' " ' ) = = - 1 ) ;
write ( url . url ( ) ) ;
write ( QString : : fromLatin1 ( " \" > " ) ) ;
end ( ) ;
return true ;
}
// 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
// data arrives) (Simon)
d - > m_workingURL = url ;
if ( url . protocol ( ) . startsWith ( " http " ) & & ! url . host ( ) . isEmpty ( ) & &
url . path ( ) . isEmpty ( ) ) {
d - > m_workingURL . setPath ( " / " ) ;
emit d - > m_extension - > setLocationBarUrl ( d - > m_workingURL . prettyUrl ( ) ) ;
}
setUrl ( d - > m_workingURL ) ;
QMap < QString , QString > & metaData = args . metaData ( ) ;
metaData . insert ( " main_frame_request " , parentPart ( ) = = 0 ? " TRUE " : " FALSE " ) ;
metaData . insert ( " ssl_parent_ip " , d - > m_ssl_parent_ip ) ;
metaData . insert ( " ssl_parent_cert " , d - > m_ssl_parent_cert ) ;
metaData . insert ( " PropagateHttpHeader " , " true " ) ;
metaData . insert ( " ssl_was_in_use " , d - > m_ssl_in_use ? " TRUE " : " FALSE " ) ;
metaData . insert ( " ssl_activate_warnings " , " TRUE " ) ;
metaData . insert ( " cross-domain " , toplevelURL ( ) . url ( ) ) ;
if ( d - > m_restored )
{
metaData . insert ( " referrer " , d - > m_pageReferrer ) ;
d - > m_cachePolicy = KIO : : CC_Cache ;
}
else if ( args . reload ( ) & & ! browserArgs . softReload )
d - > m_cachePolicy = KIO : : CC_Reload ;
else
d - > m_cachePolicy = KProtocolManager : : cacheControl ( ) ;
if ( browserArgs . doPost ( ) & & ( url . protocol ( ) . startsWith ( " http " ) ) )
{
d - > m_job = KIO : : http_post ( url , browserArgs . postData , KIO : : HideProgressInfo ) ;
d - > m_job - > addMetaData ( " content-type " , browserArgs . contentType ( ) ) ;
}
else
{
d - > m_job = KIO : : get ( url , KIO : : NoReload , KIO : : HideProgressInfo ) ;
d - > m_job - > addMetaData ( " cache " , KIO : : getCacheControlString ( d - > m_cachePolicy ) ) ;
}
if ( widget ( ) )
d - > m_job - > ui ( ) - > setWindow ( widget ( ) - > topLevelWidget ( ) ) ;
d - > m_job - > addMetaData ( metaData ) ;
connect ( d - > m_job , SIGNAL ( result ( KJob * ) ) ,
SLOT ( slotFinished ( KJob * ) ) ) ;
connect ( d - > m_job , SIGNAL ( data ( KIO : : Job * , QByteArray ) ) ,
SLOT ( slotData ( KIO : : Job * , QByteArray ) ) ) ;
connect ( d - > m_job , SIGNAL ( infoMessage ( KJob * , QString , QString ) ) ,
SLOT ( slotInfoMessage ( KJob * , QString ) ) ) ;
connect ( d - > m_job , SIGNAL ( redirection ( KIO : : Job * , KUrl ) ) ,
SLOT ( slotRedirection ( KIO : : Job * , KUrl ) ) ) ;
d - > m_bComplete = false ;
d - > m_bLoadEventEmitted = false ;
// delete old status bar msg's from kjs (if it _was_ activated on last URL)
if ( d - > m_bJScriptEnabled ) {
d - > m_statusBarText [ BarOverrideText ] . clear ( ) ;
d - > m_statusBarText [ BarDefaultText ] . clear ( ) ;
}
// set the javascript flags according to the current url
d - > m_bJScriptEnabled = KHTMLGlobal : : defaultHTMLSettings ( ) - > isJavaScriptEnabled ( url . host ( ) ) ;
setDebugScript ( KHTMLGlobal : : defaultHTMLSettings ( ) - > isJavaScriptDebugEnabled ( ) ) ;
d - > m_bJavaEnabled = KHTMLGlobal : : defaultHTMLSettings ( ) - > isJavaEnabled ( url . host ( ) ) ;
d - > m_bPluginsEnabled = KHTMLGlobal : : defaultHTMLSettings ( ) - > isPluginsEnabled ( url . host ( ) ) ;
connect ( d - > m_job , SIGNAL ( speed ( KJob * , ulong ) ) ,
this , SLOT ( slotJobSpeed ( KJob * , ulong ) ) ) ;
connect ( d - > m_job , SIGNAL ( percent ( KJob * , ulong ) ) ,
this , SLOT ( slotJobPercent ( KJob * , ulong ) ) ) ;
connect ( d - > m_job , SIGNAL ( result ( KJob * ) ) ,
this , SLOT ( slotJobDone ( KJob * ) ) ) ;
d - > m_jobspeed = 0 ;
// If this was an explicit reload and the user style sheet should be used,
// do a stat to see whether the stylesheet was changed in the meanwhile.
if ( args . reload ( ) & & ! settings ( ) - > userStyleSheet ( ) . isEmpty ( ) ) {
KUrl url ( settings ( ) - > userStyleSheet ( ) ) ;
KIO : : StatJob * job = KIO : : stat ( url , KIO : : HideProgressInfo ) ;
connect ( job , SIGNAL ( result ( KJob * ) ) ,
this , SLOT ( slotUserSheetStatDone ( KJob * ) ) ) ;
}
startingJob ( d - > m_job ) ;
emit started ( 0L ) ;
return true ;
}
bool KHTMLPart : : closeUrl ( )
{
if ( d - > m_job )
{
KHTMLPageCache : : self ( ) - > cancelEntry ( d - > m_cacheId ) ;
d - > m_job - > kill ( ) ;
d - > m_job = 0 ;
}
if ( d - > m_doc & & d - > m_doc - > isHTMLDocument ( ) ) {
HTMLDocumentImpl * hdoc = static_cast < HTMLDocumentImpl * > ( d - > m_doc ) ;
if ( hdoc - > body ( ) & & d - > m_bLoadEventEmitted ) {
hdoc - > body ( ) - > dispatchWindowEvent ( EventImpl : : UNLOAD_EVENT , false , false ) ;
if ( d - > m_doc )
d - > m_doc - > updateRendering ( ) ;
d - > m_bLoadEventEmitted = false ;
}
}
d - > m_bComplete = true ; // to avoid emitting completed() in slotFinishedParsing() (David)
d - > m_bLoadEventEmitted = true ; // don't want that one either
d - > m_cachePolicy = KProtocolManager : : cacheControl ( ) ; // reset cache policy
disconnect ( d - > m_view , SIGNAL ( finishedLayout ( ) ) , this , SLOT ( restoreScrollPosition ( ) ) ) ;
KHTMLPageCache : : self ( ) - > cancelFetch ( this ) ;
if ( d - > m_doc & & d - > m_doc - > parsing ( ) )
{
kDebug ( 6050 ) < < " was still parsing... calling end " ;
slotFinishedParsing ( ) ;
d - > m_doc - > setParsing ( false ) ;
}
if ( ! d - > m_workingURL . isEmpty ( ) )
{
// Aborted before starting to render
kDebug ( 6050 ) < < " Aborted before starting to render, reverting location bar to " < < url ( ) . prettyUrl ( ) ;
emit d - > m_extension - > setLocationBarUrl ( url ( ) . prettyUrl ( ) ) ;
}
d - > m_workingURL = KUrl ( ) ;
if ( d - > m_doc & & d - > m_doc - > docLoader ( ) )
khtml : : Cache : : loader ( ) - > cancelRequests ( d - > m_doc - > docLoader ( ) ) ;
// tell all subframes to stop as well
{
ConstFrameIt it = d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it )
{
if ( ( * it ) - > m_run )
( * it ) - > m_run . data ( ) - > abort ( ) ;
if ( ! ( * it ) - > m_part . isNull ( ) )
( * it ) - > m_part . data ( ) - > closeUrl ( ) ;
}
}
// tell all objects to stop as well
{
ConstFrameIt it = d - > m_objects . constBegin ( ) ;
const ConstFrameIt end = d - > m_objects . constEnd ( ) ;
for ( ; it ! = end ; + + it )
{
if ( ! ( * it ) - > m_part . isNull ( ) )
( * it ) - > m_part . data ( ) - > closeUrl ( ) ;
}
}
// Stop any started redirections as well!! (DA)
if ( d & & d - > m_redirectionTimer . isActive ( ) )
d - > m_redirectionTimer . stop ( ) ;
// null node activated.
emit nodeActivated ( Node ( ) ) ;
// make sure before clear() runs, we pop out of a dialog's message loop
if ( d - > m_view )
d - > m_view - > closeChildDialogs ( ) ;
return true ;
}
DOM : : HTMLDocument KHTMLPart : : htmlDocument ( ) const
{
if ( d - > m_doc & & d - > m_doc - > isHTMLDocument ( ) )
return static_cast < HTMLDocumentImpl * > ( d - > m_doc ) ;
else
return static_cast < HTMLDocumentImpl * > ( 0 ) ;
}
DOM : : Document KHTMLPart : : document ( ) const
{
return d - > m_doc ;
}
QString KHTMLPart : : documentSource ( ) const
{
QString sourceStr ;
if ( ! ( url ( ) . isLocalFile ( ) ) & & KHTMLPageCache : : self ( ) - > isComplete ( d - > m_cacheId ) )
{
QByteArray sourceArray ;
QDataStream dataStream ( & sourceArray , QIODevice : : WriteOnly ) ;
KHTMLPageCache : : self ( ) - > saveData ( d - > m_cacheId , & dataStream ) ;
QTextStream stream ( sourceArray , QIODevice : : ReadOnly ) ;
stream . setCodec ( QTextCodec : : codecForName ( encoding ( ) . toLatin1 ( ) . constData ( ) ) ) ;
sourceStr = stream . readAll ( ) ;
} else
{
QString tmpFile ;
if ( KIO : : NetAccess : : download ( url ( ) , tmpFile , NULL ) )
{
QFile f ( tmpFile ) ;
if ( f . open ( QIODevice : : ReadOnly ) )
{
QTextStream stream ( & f ) ;
stream . setCodec ( QTextCodec : : codecForName ( encoding ( ) . toLatin1 ( ) . constData ( ) ) ) ;
sourceStr = stream . readAll ( ) ;
f . close ( ) ;
}
KIO : : NetAccess : : removeTempFile ( tmpFile ) ;
}
}
return sourceStr ;
}
KParts : : BrowserExtension * KHTMLPart : : browserExtension ( ) const
{
return d - > m_extension ;
}
KParts : : BrowserHostExtension * KHTMLPart : : browserHostExtension ( ) const
{
return d - > m_hostExtension ;
}
KHTMLView * KHTMLPart : : view ( ) const
{
return d - > m_view ;
}
KHTMLViewBar * KHTMLPart : : pTopViewBar ( ) const
{
if ( const_cast < KHTMLPart * > ( this ) - > parentPart ( ) )
return const_cast < KHTMLPart * > ( this ) - > parentPart ( ) - > pTopViewBar ( ) ;
return d - > m_topViewBar ;
}
KHTMLViewBar * KHTMLPart : : pBottomViewBar ( ) const
{
if ( const_cast < KHTMLPart * > ( this ) - > parentPart ( ) )
return const_cast < KHTMLPart * > ( this ) - > parentPart ( ) - > pBottomViewBar ( ) ;
return d - > m_bottomViewBar ;
}
void KHTMLPart : : setStatusMessagesEnabled ( bool enable )
{
d - > m_statusMessagesEnabled = enable ;
}
KJS : : Interpreter * KHTMLPart : : jScriptInterpreter ( )
{
KJSProxy * proxy = jScript ( ) ;
if ( ! proxy | | proxy - > paused ( ) )
return 0 ;
return proxy - > interpreter ( ) ;
}
bool KHTMLPart : : statusMessagesEnabled ( ) const
{
return d - > m_statusMessagesEnabled ;
}
void KHTMLPart : : setJScriptEnabled ( bool enable )
{
if ( ! enable & & jScriptEnabled ( ) & & d - > m_frame & & d - > m_frame - > m_jscript ) {
d - > m_frame - > m_jscript - > clear ( ) ;
}
d - > m_bJScriptForce = enable ;
d - > m_bJScriptOverride = true ;
}
bool KHTMLPart : : jScriptEnabled ( ) const
{
if ( onlyLocalReferences ( ) ) return false ;
if ( d - > m_bJScriptOverride )
return d - > m_bJScriptForce ;
return d - > m_bJScriptEnabled ;
}
void KHTMLPart : : setDNSPrefetch ( DNSPrefetch pmode )
{
d - > m_bDNSPrefetch = pmode ;
d - > m_bDNSPrefetchIsDefault = false ;
}
KHTMLPart : : DNSPrefetch KHTMLPart : : dnsPrefetch ( ) const
{
if ( onlyLocalReferences ( ) )
return DNSPrefetchDisabled ;
return d - > m_bDNSPrefetch ;
}
void KHTMLPart : : setMetaRefreshEnabled ( bool enable )
{
d - > m_metaRefreshEnabled = enable ;
}
bool KHTMLPart : : metaRefreshEnabled ( ) const
{
return d - > m_metaRefreshEnabled ;
}
KJSProxy * KHTMLPart : : jScript ( )
{
if ( ! jScriptEnabled ( ) ) return 0 ;
if ( ! d - > m_frame ) {
KHTMLPart * p = parentPart ( ) ;
if ( ! p ) {
d - > m_frame = new khtml : : ChildFrame ;
d - > m_frame - > m_part = this ;
} else {
ConstFrameIt it = p - > d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = p - > d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it )
if ( ( * it ) - > m_part . data ( ) = = this ) {
d - > m_frame = * it ;
break ;
}
}
if ( ! d - > m_frame )
return 0 ;
}
if ( ! d - > m_frame - > m_jscript )
d - > m_frame - > m_jscript = new KJSProxy ( d - > m_frame ) ;
d - > m_frame - > m_jscript - > setDebugEnabled ( d - > m_bJScriptDebugEnabled ) ;
return d - > m_frame - > m_jscript ;
}
QVariant KHTMLPart : : crossFrameExecuteScript ( const QString & target , const QString & script )
{
KHTMLPart * destpart = this ;
QString trg = target . toLower ( ) ;
if ( target = = " _top " ) {
while ( destpart - > parentPart ( ) )
destpart = destpart - > parentPart ( ) ;
}
else if ( target = = " _parent " ) {
if ( parentPart ( ) )
destpart = parentPart ( ) ;
}
else if ( target = = " _self " | | target = = " _blank " ) {
// we always allow these
}
else {
destpart = findFrame ( target ) ;
if ( ! destpart )
destpart = this ;
}
// easy way out?
if ( destpart = = this )
return executeScript ( DOM : : Node ( ) , script ) ;
// now compare the domains
if ( destpart - > checkFrameAccess ( this ) )
return destpart - > executeScript ( DOM : : Node ( ) , script ) ;
// eww, something went wrong. better execute it in our frame
return executeScript ( DOM : : Node ( ) , script ) ;
}
//Enable this to see all JS scripts being executed
//#define KJS_VERBOSE
KJSErrorDlg * KHTMLPart : : jsErrorExtension ( ) {
if ( ! d - > m_settings - > jsErrorsEnabled ( ) ) {
return 0L ;
}
if ( parentPart ( ) ) {
return parentPart ( ) - > jsErrorExtension ( ) ;
}
if ( ! d - > m_statusBarJSErrorLabel ) {
d - > m_statusBarJSErrorLabel = new KUrlLabel ( d - > m_statusBarExtension - > statusBar ( ) ) ;
d - > m_statusBarJSErrorLabel - > setSizePolicy ( QSizePolicy ( QSizePolicy : : Fixed , QSizePolicy : : Minimum ) ) ;
d - > m_statusBarJSErrorLabel - > setUseCursor ( false ) ;
d - > m_statusBarExtension - > addStatusBarItem ( d - > m_statusBarJSErrorLabel , 0 , false ) ;
d - > m_statusBarJSErrorLabel - > setToolTip ( i18n ( " This web page contains coding errors. " ) ) ;
d - > m_statusBarJSErrorLabel - > setPixmap ( SmallIcon ( " script-error " ) ) ;
connect ( d - > m_statusBarJSErrorLabel , SIGNAL ( leftClickedUrl ( ) ) , SLOT ( launchJSErrorDialog ( ) ) ) ;
connect ( d - > m_statusBarJSErrorLabel , SIGNAL ( rightClickedUrl ( ) ) , SLOT ( jsErrorDialogContextMenu ( ) ) ) ;
}
if ( ! d - > m_jsedlg ) {
d - > m_jsedlg = new KJSErrorDlg ;
d - > m_jsedlg - > setURL ( url ( ) . prettyUrl ( ) ) ;
if ( KGlobalSettings : : showIconsOnPushButtons ( ) ) {
d - > m_jsedlg - > _clear - > setIcon ( KIcon ( " edit-clear-locationbar-ltr " ) ) ;
d - > m_jsedlg - > _close - > setIcon ( KIcon ( " window-close " ) ) ;
}
}
return d - > m_jsedlg ;
}
void KHTMLPart : : removeJSErrorExtension ( ) {
if ( parentPart ( ) ) {
parentPart ( ) - > removeJSErrorExtension ( ) ;
return ;
}
if ( d - > m_statusBarJSErrorLabel ! = 0 ) {
d - > m_statusBarExtension - > removeStatusBarItem ( d - > m_statusBarJSErrorLabel ) ;
delete d - > m_statusBarJSErrorLabel ;
d - > m_statusBarJSErrorLabel = 0 ;
}
delete d - > m_jsedlg ;
d - > m_jsedlg = 0 ;
}
void KHTMLPart : : disableJSErrorExtension ( ) {
removeJSErrorExtension ( ) ;
// These two lines are really kind of hacky, and it sucks to do this inside
// KHTML but I don't know of anything that's reasonably easy as an alternative
// right now. It makes me wonder if there should be a more clean way to
// contact all running "KHTML" instance as opposed to Konqueror instances too.
d - > m_settings - > setJSErrorsEnabled ( false ) ;
emit configurationChanged ( ) ;
}
void KHTMLPart : : jsErrorDialogContextMenu ( ) {
KMenu * m = new KMenu ( 0L ) ;
m - > addAction ( i18n ( " &Hide Errors " ) , this , SLOT ( removeJSErrorExtension ( ) ) ) ;
m - > addAction ( i18n ( " &Disable Error Reporting " ) , this , SLOT ( disableJSErrorExtension ( ) ) ) ;
m - > popup ( QCursor : : pos ( ) ) ;
}
void KHTMLPart : : launchJSErrorDialog ( ) {
KJSErrorDlg * dlg = jsErrorExtension ( ) ;
if ( dlg ) {
dlg - > show ( ) ;
dlg - > raise ( ) ;
}
}
void KHTMLPart : : launchJSConfigDialog ( ) {
QStringList args ;
args < < " khtml_java_js " ;
KToolInvocation : : kdeinitExec ( " kcmshell4 " , args ) ;
}
QVariant KHTMLPart : : executeScript ( const QString & filename , int baseLine , const DOM : : Node & n , const QString & script )
{
# ifdef KJS_VERBOSE
// The script is now printed by KJS's Parser::parse
kDebug ( 6070 ) < < " executeScript: caller=' " < < objectName ( ) < < " ' filename= " < < filename < < " baseLine= " < < baseLine /*<< " script=" << script*/ ;
# endif
KJSProxy * proxy = jScript ( ) ;
if ( ! proxy | | proxy - > paused ( ) )
return QVariant ( ) ;
KJS : : Completion comp ;
QVariant ret = proxy - > evaluate ( filename , baseLine , script , n , & comp ) ;
2015-11-10 01:11:59 +02:00
# ifdef KJS_DEBUGGER
2015-11-08 10:22:01 +02:00
/*
* Error handling
*/
if ( comp . complType ( ) = = KJS : : Throw & & comp . value ( ) ) {
KJSErrorDlg * dlg = jsErrorExtension ( ) ;
if ( dlg ) {
QString msg = KJSDebugger : : DebugWindow : : exceptionToString (
proxy - > interpreter ( ) - > globalExec ( ) , comp . value ( ) ) ;
dlg - > addError ( i18n ( " <qt><b>Error</b>: %1: %2</qt> " ,
Qt : : escape ( filename ) , Qt : : escape ( msg ) ) ) ;
}
}
2015-11-10 01:11:59 +02:00
# endif
2015-11-08 10:22:01 +02:00
// Handle immediate redirects now (e.g. location='foo')
if ( ! d - > m_redirectURL . isEmpty ( ) & & d - > m_delayRedirect = = - 1 )
{
kDebug ( 6070 ) < < " executeScript done, handling immediate redirection NOW " ;
// Must abort tokenizer, no further script must execute.
khtml : : Tokenizer * t = d - > m_doc - > tokenizer ( ) ;
if ( t )
t - > abort ( ) ;
d - > m_redirectionTimer . setSingleShot ( true ) ;
d - > m_redirectionTimer . start ( 0 ) ;
}
return ret ;
}
QVariant KHTMLPart : : executeScript ( const QString & script )
{
return executeScript ( DOM : : Node ( ) , script ) ;
}
QVariant KHTMLPart : : executeScript ( const DOM : : Node & n , const QString & script )
{
# ifdef KJS_VERBOSE
kDebug ( 6070 ) < < " caller= " < < objectName ( ) < < " node= " < < n . nodeName ( ) . string ( ) . toLatin1 ( ) . constData ( ) < < " ( " < < ( n . isNull ( ) ? 0 : n . nodeType ( ) ) < < " ) " /* << script */ ;
# endif
KJSProxy * proxy = jScript ( ) ;
if ( ! proxy | | proxy - > paused ( ) )
return QVariant ( ) ;
+ + ( d - > m_runningScripts ) ;
KJS : : Completion comp ;
const QVariant ret = proxy - > evaluate ( QString ( ) , 1 , script , n , & comp ) ;
- - ( d - > m_runningScripts ) ;
2015-11-10 01:11:59 +02:00
# ifdef KJS_DEBUGGER
2015-11-08 10:22:01 +02:00
/*
* Error handling
*/
if ( comp . complType ( ) = = KJS : : Throw & & comp . value ( ) ) {
KJSErrorDlg * dlg = jsErrorExtension ( ) ;
if ( dlg ) {
QString msg = KJSDebugger : : DebugWindow : : exceptionToString (
proxy - > interpreter ( ) - > globalExec ( ) , comp . value ( ) ) ;
dlg - > addError ( i18n ( " <qt><b>Error</b>: node %1: %2</qt> " ,
n . nodeName ( ) . string ( ) , Qt : : escape ( msg ) ) ) ;
}
}
2015-11-10 01:11:59 +02:00
# endif
2015-11-08 10:22:01 +02:00
if ( ! d - > m_runningScripts & & d - > m_doc & & ! d - > m_doc - > parsing ( ) & & d - > m_submitForm )
submitFormAgain ( ) ;
# ifdef KJS_VERBOSE
kDebug ( 6070 ) < < " done " ;
# endif
return ret ;
}
void KHTMLPart : : setJavaEnabled ( bool enable )
{
d - > m_bJavaForce = enable ;
d - > m_bJavaOverride = true ;
}
bool KHTMLPart : : javaEnabled ( ) const
{
if ( onlyLocalReferences ( ) ) return false ;
# ifndef Q_WS_QWS
if ( d - > m_bJavaOverride )
return d - > m_bJavaForce ;
return d - > m_bJavaEnabled ;
# else
return false ;
# endif
}
void KHTMLPart : : setPluginsEnabled ( bool enable )
{
d - > m_bPluginsForce = enable ;
d - > m_bPluginsOverride = true ;
}
bool KHTMLPart : : pluginsEnabled ( ) const
{
if ( onlyLocalReferences ( ) ) return false ;
if ( d - > m_bPluginsOverride )
return d - > m_bPluginsForce ;
return d - > m_bPluginsEnabled ;
}
static int s_DOMTreeIndentLevel = 0 ;
void KHTMLPart : : slotDebugDOMTree ( )
{
if ( d - > m_doc )
qDebug ( " %s " , d - > m_doc - > toString ( ) . string ( ) . toLatin1 ( ) . constData ( ) ) ;
// Now print the contents of the frames that contain HTML
const int indentLevel = s_DOMTreeIndentLevel + + ;
ConstFrameIt it = d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it )
if ( ! ( * it ) - > m_part . isNull ( ) & & ( * it ) - > m_part . data ( ) - > inherits ( " KHTMLPart " ) ) {
KParts : : ReadOnlyPart * const p = ( * it ) - > m_part . data ( ) ;
kDebug ( 6050 ) < < QString ( ) . leftJustified ( s_DOMTreeIndentLevel * 4 , ' ' ) < < " FRAME " < < p - > objectName ( ) < < " " ;
static_cast < KHTMLPart * > ( p ) - > slotDebugDOMTree ( ) ;
}
s_DOMTreeIndentLevel = indentLevel ;
}
void KHTMLPart : : slotDebugScript ( )
{
if ( jScript ( ) )
jScript ( ) - > showDebugWindow ( ) ;
}
void KHTMLPart : : slotDebugRenderTree ( )
{
# ifndef NDEBUG
if ( d - > m_doc ) {
d - > m_doc - > renderer ( ) - > printTree ( ) ;
// dump out the contents of the rendering & DOM trees
// QString dumps;
// QTextStream outputStream(&dumps,QIODevice::WriteOnly);
// d->m_doc->renderer()->layer()->dump( outputStream );
// kDebug() << "dump output:" << "\n" + dumps;
// d->m_doc->renderer()->printLineBoxTree();
}
# endif
}
void KHTMLPart : : slotDebugFrameTree ( )
{
khtml : : ChildFrame : : dumpFrameTree ( this ) ;
}
void KHTMLPart : : slotStopAnimations ( )
{
stopAnimations ( ) ;
}
void KHTMLPart : : setAutoloadImages ( bool enable )
{
if ( d - > m_doc & & d - > m_doc - > docLoader ( ) - > autoloadImages ( ) = = enable )
return ;
if ( d - > m_doc )
d - > m_doc - > docLoader ( ) - > setAutoloadImages ( enable ) ;
unplugActionList ( " loadImages " ) ;
if ( enable ) {
delete d - > m_paLoadImages ;
d - > m_paLoadImages = 0 ;
}
else if ( ! d - > m_paLoadImages ) {
d - > m_paLoadImages = new KAction ( i18n ( " Display Images on Page " ) , this ) ;
actionCollection ( ) - > addAction ( " loadImages " , d - > m_paLoadImages ) ;
d - > m_paLoadImages - > setIcon ( KIcon ( " image-loading " ) ) ;
connect ( d - > m_paLoadImages , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotLoadImages ( ) ) ) ;
}
if ( d - > m_paLoadImages ) {
QList < QAction * > lst ;
lst . append ( d - > m_paLoadImages ) ;
plugActionList ( " loadImages " , lst ) ;
}
}
bool KHTMLPart : : autoloadImages ( ) const
{
if ( d - > m_doc )
return d - > m_doc - > docLoader ( ) - > autoloadImages ( ) ;
return true ;
}
void KHTMLPart : : clear ( )
{
if ( d - > m_bCleared )
return ;
d - > m_bCleared = true ;
d - > m_bClearing = true ;
{
ConstFrameIt it = d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it )
{
// Stop HTMLRun jobs for frames
if ( ( * it ) - > m_run )
( * it ) - > m_run . data ( ) - > abort ( ) ;
}
}
{
ConstFrameIt it = d - > m_objects . constBegin ( ) ;
const ConstFrameIt end = d - > m_objects . constEnd ( ) ;
for ( ; it ! = end ; + + it )
{
// Stop HTMLRun jobs for objects
if ( ( * it ) - > m_run )
( * it ) - > m_run . data ( ) - > abort ( ) ;
}
}
findTextBegin ( ) ; // resets d->m_findNode and d->m_findPos
d - > m_mousePressNode = DOM : : Node ( ) ;
if ( d - > m_doc )
{
if ( d - > m_doc - > attached ( ) ) //the view may have detached it already
d - > m_doc - > detach ( ) ;
}
// Moving past doc so that onUnload works.
if ( d - > m_frame & & d - > m_frame - > m_jscript )
d - > m_frame - > m_jscript - > clear ( ) ;
// stopping marquees
if ( d - > m_doc & & d - > m_doc - > renderer ( ) & & d - > m_doc - > renderer ( ) - > layer ( ) )
d - > m_doc - > renderer ( ) - > layer ( ) - > suspendMarquees ( ) ;
if ( d - > m_view )
d - > m_view - > clear ( ) ;
// do not dereference the document before the jscript and view are cleared, as some destructors
// might still try to access the document.
if ( d - > m_doc ) {
d - > m_doc - > deref ( ) ;
}
d - > m_doc = 0 ;
delete d - > m_decoder ;
d - > m_decoder = 0 ;
// We don't want to change between parts if we are going to delete all of them anyway
if ( partManager ( ) ) {
disconnect ( partManager ( ) , SIGNAL ( activePartChanged ( KParts : : Part * ) ) ,
this , SLOT ( slotActiveFrameChanged ( KParts : : Part * ) ) ) ;
}
if ( d - > m_frames . count ( ) )
{
const KHTMLFrameList frames = d - > m_frames ;
d - > m_frames . clear ( ) ;
ConstFrameIt it = frames . begin ( ) ;
const ConstFrameIt end = frames . end ( ) ;
for ( ; it ! = end ; + + it )
{
if ( ( * it ) - > m_part )
{
partManager ( ) - > removePart ( ( * it ) - > m_part . data ( ) ) ;
delete ( * it ) - > m_part . data ( ) ;
}
delete * it ;
}
}
d - > m_suppressedPopupOriginParts . clear ( ) ;
if ( d - > m_objects . count ( ) )
{
KHTMLFrameList objects = d - > m_objects ;
d - > m_objects . clear ( ) ;
ConstFrameIt oi = objects . constBegin ( ) ;
const ConstFrameIt oiEnd = objects . constEnd ( ) ;
for ( ; oi ! = oiEnd ; + + oi )
{
delete ( * oi ) - > m_part . data ( ) ;
delete * oi ;
}
}
// Listen to part changes again
if ( partManager ( ) ) {
connect ( partManager ( ) , SIGNAL ( activePartChanged ( KParts : : Part * ) ) ,
this , SLOT ( slotActiveFrameChanged ( KParts : : Part * ) ) ) ;
}
d - > clearRedirection ( ) ;
d - > m_redirectLockHistory = true ;
d - > m_bClearing = false ;
d - > m_frameNameId = 1 ;
d - > m_bFirstData = true ;
d - > m_bMousePressed = false ;
if ( d - > editor_context . m_caretBlinkTimer > = 0 )
killTimer ( d - > editor_context . m_caretBlinkTimer ) ;
d - > editor_context . reset ( ) ;
# ifndef QT_NO_CLIPBOARD
connect ( qApp - > clipboard ( ) , SIGNAL ( selectionChanged ( ) ) , SLOT ( slotClearSelection ( ) ) ) ;
# endif
d - > m_jobPercent = 0 ;
if ( ! d - > m_haveEncoding )
d - > m_encoding . clear ( ) ;
d - > m_DNSPrefetchQueue . clear ( ) ;
if ( d - > m_DNSPrefetchTimer > 0 )
killTimer ( d - > m_DNSPrefetchTimer ) ;
d - > m_DNSPrefetchTimer = - 1 ;
d - > m_lookedupHosts . clear ( ) ;
if ( d - > m_DNSTTLTimer > 0 )
killTimer ( d - > m_DNSTTLTimer ) ;
d - > m_DNSTTLTimer = - 1 ;
d - > m_numDNSPrefetchedNames = 0 ;
# ifdef SPEED_DEBUG
d - > m_parsetime . restart ( ) ;
# endif
}
bool KHTMLPart : : openFile ( )
{
return true ;
}
DOM : : HTMLDocumentImpl * KHTMLPart : : docImpl ( ) const
{
if ( d & & d - > m_doc & & d - > m_doc - > isHTMLDocument ( ) )
return static_cast < HTMLDocumentImpl * > ( d - > m_doc ) ;
return 0 ;
}
DOM : : DocumentImpl * KHTMLPart : : xmlDocImpl ( ) const
{
if ( d )
return d - > m_doc ;
return 0 ;
}
void KHTMLPart : : slotInfoMessage ( KJob * kio_job , const QString & msg )
{
assert ( d - > m_job = = kio_job ) ;
Q_ASSERT ( kio_job ) ;
Q_UNUSED ( kio_job ) ;
if ( ! parentPart ( ) )
setStatusBarText ( msg , BarDefaultText ) ;
}
void KHTMLPart : : setPageSecurity ( PageSecurity sec )
{
emit d - > m_extension - > setPageSecurity ( sec ) ;
}
void KHTMLPart : : slotData ( KIO : : Job * kio_job , const QByteArray & data )
{
assert ( d - > m_job = = kio_job ) ;
Q_ASSERT ( kio_job ) ;
Q_UNUSED ( kio_job ) ;
//kDebug( 6050 ) << "slotData: " << data.size();
// The first data ?
if ( ! d - > m_workingURL . isEmpty ( ) )
{
//kDebug( 6050 ) << "begin!";
// We must suspend KIO while we're inside begin() because it can cause
// crashes if a window (such as kjsdebugger) goes back into the event loop,
// more data arrives, and begin() gets called again (re-entered).
d - > m_job - > suspend ( ) ;
begin ( d - > m_workingURL , arguments ( ) . xOffset ( ) , arguments ( ) . yOffset ( ) ) ;
d - > m_job - > resume ( ) ;
// CC_Refresh means : always send the server an If-Modified-Since conditional request.
// This is the default cache setting and correspond to the KCM's "Keep cache in sync".
// CC_Verify means : only send a conditional request if the cache expiry date is passed.
// It doesn't have a KCM setter.
// We override the first to the second, except when doing a soft-reload.
if ( d - > m_cachePolicy = = KIO : : CC_Refresh & & ! d - > m_extension - > browserArguments ( ) . softReload )
d - > m_doc - > docLoader ( ) - > setCachePolicy ( KIO : : CC_Verify ) ;
else
d - > m_doc - > docLoader ( ) - > setCachePolicy ( d - > m_cachePolicy ) ;
d - > m_workingURL = KUrl ( ) ;
d - > m_cacheId = KHTMLPageCache : : self ( ) - > createCacheEntry ( ) ;
// When the first data arrives, the metadata has just been made available
d - > m_httpHeaders = d - > m_job - > queryMetaData ( " HTTP-Headers " ) ;
time_t cacheCreationDate = d - > m_job - > queryMetaData ( " cache-creation-date " ) . toLong ( ) ;
d - > m_doc - > docLoader ( ) - > setCacheCreationDate ( cacheCreationDate ) ;
d - > m_pageServices = d - > m_job - > queryMetaData ( " PageServices " ) ;
d - > m_pageReferrer = d - > m_job - > queryMetaData ( " referrer " ) ;
d - > m_ssl_in_use = ( d - > m_job - > queryMetaData ( " ssl_in_use " ) = = " TRUE " ) ;
{
KHTMLPart * p = parentPart ( ) ;
if ( p & & p - > d - > m_ssl_in_use ! = d - > m_ssl_in_use ) {
while ( p - > parentPart ( ) ) p = p - > parentPart ( ) ;
p - > setPageSecurity ( NotCrypted ) ;
}
}
setPageSecurity ( d - > m_ssl_in_use ? Encrypted : NotCrypted ) ;
// Shouldn't all of this be done only if ssl_in_use == true ? (DF)
d - > m_ssl_parent_ip = d - > m_job - > queryMetaData ( " ssl_parent_ip " ) ;
d - > m_ssl_parent_cert = d - > m_job - > queryMetaData ( " ssl_parent_cert " ) ;
d - > m_ssl_peer_chain = d - > m_job - > queryMetaData ( " ssl_peer_chain " ) ;
d - > m_ssl_peer_ip = d - > m_job - > queryMetaData ( " ssl_peer_ip " ) ;
d - > m_ssl_cipher = d - > m_job - > queryMetaData ( " ssl_cipher " ) ;
d - > m_ssl_protocol_version = d - > m_job - > queryMetaData ( " ssl_protocol_version " ) ;
d - > m_ssl_cipher_used_bits = d - > m_job - > queryMetaData ( " ssl_cipher_used_bits " ) ;
d - > m_ssl_cipher_bits = d - > m_job - > queryMetaData ( " ssl_cipher_bits " ) ;
d - > m_ssl_cert_errors = d - > m_job - > queryMetaData ( " ssl_cert_errors " ) ;
// Check for charset meta-data
QString qData = d - > m_job - > queryMetaData ( " charset " ) ;
if ( ! qData . isEmpty ( ) & & ! d - > m_haveEncoding ) // only use information if the user didn't override the settings
d - > m_encoding = qData ;
// Support for http-refresh
qData = d - > m_job - > queryMetaData ( " http-refresh " ) ;
if ( ! qData . isEmpty ( ) )
d - > m_doc - > processHttpEquiv ( " refresh " , qData ) ;
// DISABLED: Support Content-Location per section 14.14 of RFC 2616.
// See BR# 51185,BR# 82747
/*
QString baseURL = d - > m_job - > queryMetaData ( " content-location " ) ;
if ( ! baseURL . isEmpty ( ) )
d - > m_doc - > setBaseURL ( KUrl ( d - > m_doc - > completeURL ( baseURL ) ) ) ;
*/
// Support for Content-Language
QString language = d - > m_job - > queryMetaData ( " content-language " ) ;
if ( ! language . isEmpty ( ) )
d - > m_doc - > setContentLanguage ( language ) ;
if ( ! url ( ) . isLocalFile ( ) )
{
// Support for http last-modified
d - > m_lastModified = d - > m_job - > queryMetaData ( " modified " ) ;
}
else
d - > m_lastModified . clear ( ) ; // done on-demand by lastModified()
}
KHTMLPageCache : : self ( ) - > addData ( d - > m_cacheId , data ) ;
write ( data . data ( ) , data . size ( ) ) ;
}
void KHTMLPart : : slotRestoreData ( const QByteArray & data )
{
// The first data ?
if ( ! d - > m_workingURL . isEmpty ( ) )
{
long saveCacheId = d - > m_cacheId ;
QString savePageReferrer = d - > m_pageReferrer ;
QString saveEncoding = d - > m_encoding ;
begin ( d - > m_workingURL , arguments ( ) . xOffset ( ) , arguments ( ) . yOffset ( ) ) ;
d - > m_encoding = saveEncoding ;
d - > m_pageReferrer = savePageReferrer ;
d - > m_cacheId = saveCacheId ;
d - > m_workingURL = KUrl ( ) ;
}
//kDebug( 6050 ) << data.size();
write ( data . data ( ) , data . size ( ) ) ;
if ( data . size ( ) = = 0 )
{
//kDebug( 6050 ) << "<<end of data>>";
// End of data.
if ( d - > m_doc & & d - > m_doc - > parsing ( ) )
end ( ) ; //will emit completed()
}
}
void KHTMLPart : : showError ( KJob * job )
{
kDebug ( 6050 ) < < " d->m_bParsing= " < < ( d - > m_doc & & d - > m_doc - > parsing ( ) ) < < " d->m_bComplete= " < < d - > m_bComplete
< < " d->m_bCleared= " < < d - > m_bCleared ;
if ( job - > error ( ) = = KIO : : ERR_NO_CONTENT )
return ;
if ( ( d - > m_doc & & d - > m_doc - > parsing ( ) ) | | d - > m_workingURL . isEmpty ( ) ) // if we got any data already
job - > uiDelegate ( ) - > showErrorMessage ( ) ;
else
{
htmlError ( job - > error ( ) , job - > errorText ( ) , d - > m_workingURL ) ;
}
}
// This is a protected method, placed here because of it's relevance to showError
void KHTMLPart : : htmlError ( int errorCode , const QString & text , const KUrl & reqUrl )
{
kDebug ( 6050 ) < < " errorCode " < < errorCode < < " text " < < text ;
// make sure we're not executing any embedded JS
bool bJSFO = d - > m_bJScriptForce ;
bool bJSOO = d - > m_bJScriptOverride ;
d - > m_bJScriptForce = false ;
d - > m_bJScriptOverride = true ;
begin ( ) ;
QString errorName , techName , description ;
QStringList causes , solutions ;
QByteArray raw = KIO : : rawErrorDetail ( errorCode , text , & reqUrl ) ;
QDataStream stream ( raw ) ;
stream > > errorName > > techName > > description > > causes > > solutions ;
QString url , protocol , datetime ;
// This is somewhat confusing, but we have to escape the externally-
// controlled URL twice: once for i18n, and once for HTML.
url = Qt : : escape ( Qt : : escape ( reqUrl . prettyUrl ( ) ) ) ;
protocol = reqUrl . protocol ( ) ;
datetime = KGlobal : : locale ( ) - > formatDateTime ( QDateTime : : currentDateTime ( ) ,
KLocale : : LongDate ) ;
QString filename ( KStandardDirs : : locate ( " data " , " khtml/error.html " ) ) ;
QFile file ( filename ) ;
bool isOpened = file . open ( QIODevice : : ReadOnly ) ;
if ( ! isOpened )
kWarning ( 6050 ) < < " Could not open error html template: " < < filename ;
QString html = QString ( QLatin1String ( file . readAll ( ) ) ) ;
html . replace ( QLatin1String ( " TITLE " ) , i18n ( " Error: %1 - %2 " , errorName , url ) ) ;
html . replace ( QLatin1String ( " DIRECTION " ) , QApplication : : isRightToLeft ( ) ? " rtl " : " ltr " ) ;
html . replace ( QLatin1String ( " ICON_PATH " ) , KIconLoader : : global ( ) - > iconPath ( " dialog-warning " , - KIconLoader : : SizeHuge ) ) ;
QString doc = QLatin1String ( " <h1> " ) ;
doc + = i18n ( " The requested operation could not be completed " ) ;
doc + = QLatin1String ( " </h1><h2> " ) ;
doc + = errorName ;
doc + = QLatin1String ( " </h2> " ) ;
if ( ! techName . isNull ( ) ) {
doc + = QLatin1String ( " <h2> " ) ;
doc + = i18n ( " Technical Reason: " ) ;
doc + = techName ;
doc + = QLatin1String ( " </h2> " ) ;
}
doc + = QLatin1String ( " <br clear= \" all \" > " ) ;
doc + = QLatin1String ( " <h3> " ) ;
doc + = i18n ( " Details of the Request: " ) ;
doc + = QLatin1String ( " </h3><ul><li> " ) ;
doc + = i18n ( " URL: %1 " , url ) ;
doc + = QLatin1String ( " </li><li> " ) ;
if ( ! protocol . isNull ( ) ) {
doc + = i18n ( " Protocol: %1 " , protocol ) ;
doc + = QLatin1String ( " </li><li> " ) ;
}
doc + = i18n ( " Date and Time: %1 " , datetime ) ;
doc + = QLatin1String ( " </li><li> " ) ;
doc + = i18n ( " Additional Information: %1 " , text ) ;
doc + = QLatin1String ( " </li></ul><h3> " ) ;
doc + = i18n ( " Description: " ) ;
doc + = QLatin1String ( " </h3><p> " ) ;
doc + = description ;
doc + = QLatin1String ( " </p> " ) ;
if ( causes . count ( ) ) {
doc + = QLatin1String ( " <h3> " ) ;
doc + = i18n ( " Possible Causes: " ) ;
doc + = QLatin1String ( " </h3><ul><li> " ) ;
doc + = causes . join ( " </li><li> " ) ;
doc + = QLatin1String ( " </li></ul> " ) ;
}
if ( solutions . count ( ) ) {
doc + = QLatin1String ( " <h3> " ) ;
doc + = i18n ( " Possible Solutions: " ) ;
doc + = QLatin1String ( " </h3><ul><li> " ) ;
doc + = solutions . join ( " </li><li> " ) ;
doc + = QLatin1String ( " </li></ul> " ) ;
}
html . replace ( QLatin1String ( " TEXT " ) , doc ) ;
write ( html ) ;
end ( ) ;
d - > m_bJScriptForce = bJSFO ;
d - > m_bJScriptOverride = bJSOO ;
// make the working url the current url, so that reload works and
// emit the progress signals to advance one step in the history
// (so that 'back' works)
setUrl ( reqUrl ) ; // same as d->m_workingURL
d - > m_workingURL = KUrl ( ) ;
emit started ( 0 ) ;
emit completed ( ) ;
}
void KHTMLPart : : slotFinished ( KJob * job )
{
d - > m_job = 0L ;
d - > m_jobspeed = 0L ;
if ( job - > error ( ) )
{
KHTMLPageCache : : self ( ) - > cancelEntry ( d - > m_cacheId ) ;
// The following catches errors that occur as a result of HTTP
// to FTP redirections where the FTP URL is a directory. Since
// KIO cannot change a redirection request from GET to LISTDIR,
// we have to take care of it here once we know for sure it is
// a directory...
if ( job - > error ( ) = = KIO : : ERR_IS_DIRECTORY )
{
emit canceled ( job - > errorString ( ) ) ;
emit d - > m_extension - > openUrlRequest ( d - > m_workingURL ) ;
}
else
{
emit canceled ( job - > errorString ( ) ) ;
// TODO: what else ?
checkCompleted ( ) ;
showError ( job ) ;
}
return ;
}
KIO : : TransferJob * tjob = : : qobject_cast < KIO : : TransferJob * > ( job ) ;
if ( tjob & & tjob - > isErrorPage ( ) ) {
HTMLPartContainerElementImpl * elt = d - > m_frame ?
d - > m_frame - > m_partContainerElement . data ( ) : 0 ;
if ( ! elt )
return ;
elt - > partLoadingErrorNotify ( ) ;
checkCompleted ( ) ;
if ( d - > m_bComplete ) return ;
}
//kDebug( 6050 ) << "slotFinished";
KHTMLPageCache : : self ( ) - > endData ( d - > m_cacheId ) ;
if ( d - > m_doc & & d - > m_doc - > docLoader ( ) - > expireDate ( ) & & url ( ) . protocol ( ) . startsWith ( " http " ) )
KIO : : http_update_cache ( url ( ) , false , d - > m_doc - > docLoader ( ) - > expireDate ( ) ) ;
d - > m_workingURL = KUrl ( ) ;
if ( d - > m_doc & & d - > m_doc - > parsing ( ) )
end ( ) ; //will emit completed()
}
MimeType KHTMLPartPrivate : : classifyMimeType ( const QString & mimeStr )
{
// See HTML5's "5.5.1 Navigating across documents" section.
if ( mimeStr = = " application/xhtml+xml " )
return MimeXHTML ;
if ( mimeStr = = " image/svg+xml " )
return MimeSVG ;
if ( mimeStr = = " text/html " | | mimeStr . isEmpty ( ) )
return MimeHTML ;
KMimeType : : Ptr mime = KMimeType : : mimeType ( mimeStr , KMimeType : : ResolveAliases ) ;
if ( ( mime & & mime - > is ( " text/xml " ) ) | | mimeStr . endsWith ( " +xml " ) )
return MimeXML ;
if ( mime & & mime - > is ( " text/plain " ) )
return MimeText ;
2016-02-20 06:16:31 +02:00
if ( khtmlImLoad : : ImageManager : : supportedMimeTypes ( ) . contains ( mimeStr ) )
2015-11-08 10:22:01 +02:00
return MimeImage ;
// Sometimes our subclasses like to handle custom mimetypes. In that case,
// we want to handle them as HTML. We do that in the following cases:
// 1) We're at top-level, so we were forced to open something
// 2) We're an object --- this again means we were forced to open something,
// as an iframe-generating-an-embed case would have us as an iframe
if ( ! q - > parentPart ( ) | | ( m_frame & & m_frame - > m_type = = khtml : : ChildFrame : : Object ) )
return MimeHTML ;
return MimeOther ;
}
void KHTMLPart : : begin ( const KUrl & url , int xOffset , int yOffset )
{
if ( d - > m_view - > underMouse ( ) )
QToolTip : : hideText ( ) ; // in case a previous tooltip is still shown
// No need to show this for a new page until an error is triggered
if ( ! parentPart ( ) ) {
removeJSErrorExtension ( ) ;
setSuppressedPopupIndicator ( false ) ;
d - > m_openableSuppressedPopups = 0 ;
foreach ( KHTMLPart * part , d - > m_suppressedPopupOriginParts ) {
if ( part ) {
KJS : : Window * w = KJS : : Window : : retrieveWindow ( part ) ;
if ( w )
w - > forgetSuppressedWindows ( ) ;
}
}
}
d - > m_bCleared = false ;
d - > m_cacheId = 0 ;
d - > m_bComplete = false ;
d - > m_bLoadEventEmitted = false ;
clear ( ) ;
d - > m_bCleared = false ;
if ( url . isValid ( ) ) {
QString urlString = url . url ( ) ;
KHTMLGlobal : : vLinks ( ) - > insert ( urlString ) ;
QString urlString2 = url . prettyUrl ( ) ;
if ( urlString ! = urlString2 ) {
KHTMLGlobal : : vLinks ( ) - > insert ( urlString2 ) ;
}
}
// ###
//stopParser();
KParts : : OpenUrlArguments args = arguments ( ) ;
args . setXOffset ( xOffset ) ;
args . setYOffset ( yOffset ) ;
setArguments ( args ) ;
d - > m_pageReferrer . clear ( ) ;
d - > m_referrer = url . protocol ( ) . startsWith ( " http " ) ? url . url ( ) : " " ;
setUrl ( url ) ;
// Note: by now, any special mimetype besides plaintext would have been
// handled specially inside openURL, so we handle their cases the same
// as HTML.
MimeType type = d - > classifyMimeType ( args . mimeType ( ) ) ;
switch ( type ) {
case MimeSVG :
d - > m_doc = DOMImplementationImpl : : createSVGDocument ( d - > m_view ) ;
break ;
case MimeXML : // any XML derivative, except XHTML or SVG
// ### not sure if XHTML documents served as text/xml should use DocumentImpl or HTMLDocumentImpl
d - > m_doc = DOMImplementationImpl : : createXMLDocument ( d - > m_view ) ;
break ;
case MimeText :
d - > m_doc = new HTMLTextDocumentImpl ( d - > m_view ) ;
break ;
case MimeXHTML :
case MimeHTML :
default :
d - > m_doc = DOMImplementationImpl : : createHTMLDocument ( d - > m_view ) ;
// HTML or XHTML? (#86446)
static_cast < HTMLDocumentImpl * > ( d - > m_doc ) - > setHTMLRequested ( type ! = MimeXHTML ) ;
}
d - > m_doc - > ref ( ) ;
d - > m_doc - > setURL ( url . url ( ) ) ;
d - > m_doc - > open ( ) ;
if ( ! d - > m_doc - > attached ( ) )
d - > m_doc - > attach ( ) ;
d - > m_doc - > setBaseURL ( KUrl ( ) ) ;
d - > m_doc - > docLoader ( ) - > setShowAnimations ( KHTMLGlobal : : defaultHTMLSettings ( ) - > showAnimations ( ) ) ;
emit docCreated ( ) ;
d - > m_paUseStylesheet - > setItems ( QStringList ( ) ) ;
d - > m_paUseStylesheet - > setEnabled ( false ) ;
setAutoloadImages ( KHTMLGlobal : : defaultHTMLSettings ( ) - > autoLoadImages ( ) ) ;
QString userStyleSheet = KHTMLGlobal : : defaultHTMLSettings ( ) - > userStyleSheet ( ) ;
if ( ! userStyleSheet . isEmpty ( ) )
setUserStyleSheet ( KUrl ( userStyleSheet ) ) ;
d - > m_doc - > setRestoreState ( d - > m_extension - > browserArguments ( ) . docState ) ;
connect ( d - > m_doc , SIGNAL ( finishedParsing ( ) ) , this , SLOT ( slotFinishedParsing ( ) ) ) ;
emit d - > m_extension - > enableAction ( " print " , true ) ;
d - > m_doc - > setParsing ( true ) ;
}
void KHTMLPart : : write ( const char * data , int len )
{
if ( ! d - > m_decoder )
d - > m_decoder = createDecoder ( ) ;
if ( len = = - 1 )
len = strlen ( data ) ;
if ( len = = 0 )
return ;
QString decoded = d - > m_decoder - > decodeWithBuffering ( data , len ) ;
if ( decoded . isEmpty ( ) )
return ;
if ( d - > m_bFirstData )
onFirstData ( ) ;
khtml : : Tokenizer * t = d - > m_doc - > tokenizer ( ) ;
if ( t )
t - > write ( decoded , true ) ;
}
// ### KDE5: remove
void KHTMLPart : : setAlwaysHonourDoctype ( bool b )
{
d - > m_bStrictModeQuirk = ! b ;
}
void KHTMLPart : : write ( const QString & str )
{
if ( str . isNull ( ) )
return ;
if ( d - > m_bFirstData ) {
// determine the parse mode
if ( d - > m_bStrictModeQuirk ) {
d - > m_doc - > setParseMode ( DocumentImpl : : Strict ) ;
d - > m_bFirstData = false ;
} else {
onFirstData ( ) ;
}
}
khtml : : Tokenizer * t = d - > m_doc - > tokenizer ( ) ;
if ( t )
t - > write ( str , true ) ;
}
void KHTMLPart : : end ( )
{
if ( d - > m_doc ) {
if ( d - > m_decoder )
{
QString decoded = d - > m_decoder - > flush ( ) ;
if ( d - > m_bFirstData )
onFirstData ( ) ;
if ( ! decoded . isEmpty ( ) )
write ( decoded ) ;
}
d - > m_doc - > finishParsing ( ) ;
}
}
void KHTMLPart : : onFirstData ( )
{
assert ( d - > m_bFirstData ) ;
// determine the parse mode
d - > m_doc - > determineParseMode ( ) ;
d - > m_bFirstData = false ;
// ### this is still quite hacky, but should work a lot better than the old solution
// Note: decoder may be null if only write(QString) is used.
if ( d - > m_decoder & & d - > m_decoder - > visuallyOrdered ( ) )
d - > m_doc - > setVisuallyOrdered ( ) ;
// ensure part and view shares zoom-level before styling
updateZoomFactor ( ) ;
d - > m_doc - > recalcStyle ( NodeImpl : : Force ) ;
}
bool KHTMLPart : : doOpenStream ( const QString & mimeType )
{
KMimeType : : Ptr mime = KMimeType : : mimeType ( mimeType , KMimeType : : ResolveAliases ) ;
if ( mime & & ( mime - > is ( " text/html " ) | | mime - > is ( " text/xml " ) ) )
{
begin ( url ( ) ) ;
return true ;
}
return false ;
}
bool KHTMLPart : : doWriteStream ( const QByteArray & data )
{
write ( data . data ( ) , data . size ( ) ) ;
return true ;
}
bool KHTMLPart : : doCloseStream ( )
{
end ( ) ;
return true ;
}
void KHTMLPart : : paint ( QPainter * p , const QRect & rc , int yOff , bool * more )
{
if ( ! d - > m_view ) return ;
d - > m_view - > paint ( p , rc , yOff , more ) ;
}
void KHTMLPart : : stopAnimations ( )
{
if ( d - > m_doc )
d - > m_doc - > docLoader ( ) - > setShowAnimations ( KHTMLSettings : : KAnimationDisabled ) ;
ConstFrameIt it = d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it ) {
if ( KHTMLPart * p = qobject_cast < KHTMLPart * > ( ( * it ) - > m_part . data ( ) ) )
p - > stopAnimations ( ) ;
}
}
void KHTMLPart : : resetFromScript ( )
{
closeUrl ( ) ;
d - > m_bComplete = false ;
d - > m_bLoadEventEmitted = false ;
disconnect ( d - > m_doc , SIGNAL ( finishedParsing ( ) ) , this , SLOT ( slotFinishedParsing ( ) ) ) ;
connect ( d - > m_doc , SIGNAL ( finishedParsing ( ) ) , this , SLOT ( slotFinishedParsing ( ) ) ) ;
d - > m_doc - > setParsing ( true ) ;
emit started ( 0L ) ;
}
void KHTMLPart : : slotFinishedParsing ( )
{
d - > m_doc - > setParsing ( false ) ;
d - > m_doc - > dispatchHTMLEvent ( EventImpl : : KHTML_CONTENTLOADED_EVENT , true , false ) ;
checkEmitLoadEvent ( ) ;
disconnect ( d - > m_doc , SIGNAL ( finishedParsing ( ) ) , this , SLOT ( slotFinishedParsing ( ) ) ) ;
if ( ! d - > m_view )
return ; // We are probably being destructed.
checkCompleted ( ) ;
}
void KHTMLPart : : slotLoaderRequestStarted ( khtml : : DocLoader * dl , khtml : : CachedObject * obj )
{
if ( obj & & obj - > type ( ) = = khtml : : CachedObject : : Image & & d - > m_doc & & d - > m_doc - > docLoader ( ) = = dl ) {
KHTMLPart * p = this ;
while ( p ) {
KHTMLPart * const op = p ;
+ + ( p - > d - > m_totalObjectCount ) ;
p = p - > parentPart ( ) ;
if ( ! p & & op - > d - > m_loadedObjects < = op - > d - > m_totalObjectCount
& & ! op - > d - > m_progressUpdateTimer . isActive ( ) ) {
op - > d - > m_progressUpdateTimer . setSingleShot ( true ) ;
op - > d - > m_progressUpdateTimer . start ( 200 ) ;
}
}
}
}
static bool isAncestorOrSamePart ( KHTMLPart * p1 , KHTMLPart * p2 )
{
KHTMLPart * p = p2 ;
do {
if ( p = = p1 )
return true ;
} while ( ( p = p - > parentPart ( ) ) ) ;
return false ;
}
void KHTMLPart : : slotLoaderRequestDone ( khtml : : DocLoader * dl , khtml : : CachedObject * obj )
{
if ( obj & & obj - > type ( ) = = khtml : : CachedObject : : Image & & d - > m_doc & & d - > m_doc - > docLoader ( ) = = dl ) {
KHTMLPart * p = this ;
while ( p ) {
KHTMLPart * const op = p ;
+ + ( p - > d - > m_loadedObjects ) ;
p = p - > parentPart ( ) ;
if ( ! p & & op - > d - > m_loadedObjects < = op - > d - > m_totalObjectCount & & op - > d - > m_jobPercent < = 100
& & ! op - > d - > m_progressUpdateTimer . isActive ( ) ) {
op - > d - > m_progressUpdateTimer . setSingleShot ( true ) ;
op - > d - > m_progressUpdateTimer . start ( 200 ) ;
}
}
}
/// if we have no document, or the object is not a request of one of our children,
// then our loading state can't possibly be affected : don't waste time checking for completion.
if ( ! d - > m_doc | | ! dl - > doc ( ) - > part ( ) | | ! isAncestorOrSamePart ( this , dl - > doc ( ) - > part ( ) ) )
return ;
checkCompleted ( ) ;
}
void KHTMLPart : : slotProgressUpdate ( )
{
int percent ;
if ( d - > m_loadedObjects < d - > m_totalObjectCount )
percent = d - > m_jobPercent / 4 + ( d - > m_loadedObjects * 300 ) / ( 4 * d - > m_totalObjectCount ) ;
else
percent = d - > m_jobPercent ;
if ( d - > m_bComplete )
percent = 100 ;
if ( d - > m_statusMessagesEnabled ) {
if ( d - > m_bComplete )
emit d - > m_extension - > infoMessage ( i18n ( " Page loaded. " ) ) ;
else if ( d - > m_loadedObjects < d - > m_totalObjectCount & & percent > = 75 )
emit d - > m_extension - > infoMessage ( i18np ( " %1 Image of %2 loaded. " , " %1 Images of %2 loaded. " , d - > m_loadedObjects , d - > m_totalObjectCount ) ) ;
}
emit d - > m_extension - > loadingProgress ( percent ) ;
}
void KHTMLPart : : slotJobSpeed ( KJob * /*job*/ , unsigned long speed )
{
d - > m_jobspeed = speed ;
if ( ! parentPart ( ) )
setStatusBarText ( jsStatusBarText ( ) , BarOverrideText ) ;
}
void KHTMLPart : : slotJobPercent ( KJob * /*job*/ , unsigned long percent )
{
d - > m_jobPercent = percent ;
if ( ! parentPart ( ) ) {
d - > m_progressUpdateTimer . setSingleShot ( true ) ;
d - > m_progressUpdateTimer . start ( 0 ) ;
}
}
void KHTMLPart : : slotJobDone ( KJob * /*job*/ )
{
d - > m_jobPercent = 100 ;
if ( ! parentPart ( ) ) {
d - > m_progressUpdateTimer . setSingleShot ( true ) ;
d - > m_progressUpdateTimer . start ( 0 ) ;
}
}
void KHTMLPart : : slotUserSheetStatDone ( KJob * _job )
{
using namespace KIO ;
if ( _job - > error ( ) ) {
showError ( _job ) ;
return ;
}
const UDSEntry entry = dynamic_cast < KIO : : StatJob * > ( _job ) - > statResult ( ) ;
const time_t lastModified = entry . numberValue ( KIO : : UDSEntry : : UDS_MODIFICATION_TIME , - 1 ) ;
// If the filesystem supports modification times, only reload the
// user-defined stylesheet if necessary - otherwise always reload.
if ( lastModified ! = static_cast < time_t > ( - 1 ) ) {
if ( d - > m_userStyleSheetLastModified > = lastModified ) {
return ;
}
d - > m_userStyleSheetLastModified = lastModified ;
}
setUserStyleSheet ( KUrl ( settings ( ) - > userStyleSheet ( ) ) ) ;
}
bool KHTMLPartPrivate : : isFullyLoaded ( bool * pendingRedirections ) const
{
* pendingRedirections = false ;
// Any frame that hasn't completed yet ?
ConstFrameIt it = m_frames . constBegin ( ) ;
const ConstFrameIt end = m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it ) {
if ( ! ( * it ) - > m_bCompleted | | ( * it ) - > m_run )
{
//kDebug( 6050 ) << this << " is waiting for " << (*it)->m_part;
return false ;
}
// Check for frames with pending redirections
if ( ( * it ) - > m_bPendingRedirection )
* pendingRedirections = true ;
}
// Any object that hasn't completed yet ?
{
ConstFrameIt oi = m_objects . constBegin ( ) ;
const ConstFrameIt oiEnd = m_objects . constEnd ( ) ;
for ( ; oi ! = oiEnd ; + + oi )
if ( ! ( * oi ) - > m_bCompleted )
return false ;
}
// Are we still parsing
if ( m_doc & & m_doc - > parsing ( ) )
return false ;
// Still waiting for images/scripts from the loader ?
int requests = 0 ;
if ( m_doc & & m_doc - > docLoader ( ) )
requests = khtml : : Cache : : loader ( ) - > numRequests ( m_doc - > docLoader ( ) ) ;
if ( requests > 0 )
{
//kDebug(6050) << "still waiting for images/scripts from the loader - requests:" << requests;
return false ;
}
return true ;
}
void KHTMLPart : : checkCompleted ( )
{
// kDebug( 6050 ) << this;
// kDebug( 6050 ) << " parsing: " << (d->m_doc && d->m_doc->parsing());
// kDebug( 6050 ) << " complete: " << d->m_bComplete;
// restore the cursor position
if ( d - > m_doc & & ! d - > m_doc - > parsing ( ) & & ! d - > m_focusNodeRestored )
{
if ( d - > m_focusNodeNumber > = 0 )
d - > m_doc - > setFocusNode ( d - > m_doc - > nodeWithAbsIndex ( d - > m_focusNodeNumber ) ) ;
d - > m_focusNodeRestored = true ;
}
bool fullyLoaded , pendingChildRedirections ;
fullyLoaded = d - > isFullyLoaded ( & pendingChildRedirections ) ;
// Are we still loading, or already have done the relevant work?
if ( ! fullyLoaded | | d - > m_bComplete )
return ;
// OK, completed.
// Now do what should be done when we are really completed.
d - > m_bComplete = true ;
d - > m_cachePolicy = KProtocolManager : : cacheControl ( ) ; // reset cache policy
d - > m_totalObjectCount = 0 ;
d - > m_loadedObjects = 0 ;
KHTMLPart * p = this ;
while ( p ) {
KHTMLPart * op = p ;
p = p - > parentPart ( ) ;
if ( ! p & & ! op - > d - > m_progressUpdateTimer . isActive ( ) ) {
op - > d - > m_progressUpdateTimer . setSingleShot ( true ) ;
op - > d - > m_progressUpdateTimer . start ( 0 ) ;
}
}
checkEmitLoadEvent ( ) ; // if we didn't do it before
bool pendingAction = false ;
if ( ! d - > m_redirectURL . isEmpty ( ) )
{
// DA: Do not start redirection for frames here! That action is
// deferred until the parent emits a completed signal.
if ( parentPart ( ) = = 0 ) {
//kDebug(6050) << this << " starting redirection timer";
d - > m_redirectionTimer . setSingleShot ( true ) ;
d - > m_redirectionTimer . start ( qMax ( 0 , 1000 * d - > m_delayRedirect ) ) ;
} else {
//kDebug(6050) << this << " not toplevel -> not starting redirection timer. Waiting for slotParentCompleted.";
}
pendingAction = true ;
}
else if ( pendingChildRedirections )
{
pendingAction = true ;
}
// the view will emit completed on our behalf,
// either now or at next repaint if one is pending
//kDebug(6050) << this << " asks the view to emit completed. pendingAction=" << pendingAction;
d - > m_view - > complete ( pendingAction ) ;
// find the alternate stylesheets
QStringList sheets ;
if ( d - > m_doc )
sheets = d - > m_doc - > availableStyleSheets ( ) ;
sheets . prepend ( i18n ( " Automatic Detection " ) ) ;
d - > m_paUseStylesheet - > setItems ( sheets ) ;
d - > m_paUseStylesheet - > setEnabled ( sheets . count ( ) > 2 ) ;
if ( sheets . count ( ) > 2 )
{
d - > m_paUseStylesheet - > setCurrentItem ( qMax ( sheets . indexOf ( d - > m_sheetUsed ) , 0 ) ) ;
slotUseStylesheet ( ) ;
}
setJSDefaultStatusBarText ( QString ( ) ) ;
# ifdef SPEED_DEBUG
if ( ! parentPart ( ) )
kDebug ( 6080 ) < < " DONE: " < < d - > m_parsetime . elapsed ( ) ;
# endif
}
void KHTMLPart : : checkEmitLoadEvent ( )
{
bool fullyLoaded , pendingChildRedirections ;
fullyLoaded = d - > isFullyLoaded ( & pendingChildRedirections ) ;
// ### might want to wait on pendingChildRedirections here, too
if ( d - > m_bLoadEventEmitted | | ! d - > m_doc | | ! fullyLoaded ) return ;
d - > m_bLoadEventEmitted = true ;
if ( d - > m_doc )
d - > m_doc - > close ( ) ;
}
const KHTMLSettings * KHTMLPart : : settings ( ) const
{
return d - > m_settings ;
}
# ifndef KDE_NO_COMPAT // KDE5: remove this ifndef, keep the method (renamed to baseUrl)
KUrl KHTMLPart : : baseURL ( ) const
{
if ( ! d - > m_doc ) return KUrl ( ) ;
return d - > m_doc - > baseURL ( ) ;
}
# endif
KUrl KHTMLPart : : completeURL ( const QString & url )
{
if ( ! d - > m_doc ) return KUrl ( url ) ;
#if 0
if ( d - > m_decoder )
return KUrl ( d - > m_doc - > completeURL ( url ) , d - > m_decoder - > codec ( ) - > mibEnum ( ) ) ;
# endif
return KUrl ( d - > m_doc - > completeURL ( url ) ) ;
}
QString KHTMLPartPrivate : : codeForJavaScriptURL ( const QString & u )
{
return KUrl : : fromPercentEncoding ( u . right ( u . length ( ) - 11 ) . toUtf8 ( ) ) ;
}
void KHTMLPartPrivate : : executeJavascriptURL ( const QString & u )
{
QString script = codeForJavaScriptURL ( u ) ;
kDebug ( 6050 ) < < " script= " < < script ;
QVariant res = q - > executeScript ( DOM : : Node ( ) , script ) ;
if ( res . type ( ) = = QVariant : : String ) {
q - > begin ( q - > url ( ) ) ;
q - > setAlwaysHonourDoctype ( ) ; // Disable public API compat; it messes with doctype
q - > write ( res . toString ( ) ) ;
q - > end ( ) ;
}
emit q - > completed ( ) ;
}
bool KHTMLPartPrivate : : isJavaScriptURL ( const QString & url )
{
return url . indexOf ( QLatin1String ( " javascript: " ) , 0 , Qt : : CaseInsensitive ) = = 0 ;
}
// Called by ecma/kjs_window in case of redirections from Javascript,
// and by xml/dom_docimpl.cpp in case of http-equiv meta refresh.
void KHTMLPart : : scheduleRedirection ( int delay , const QString & url , bool doLockHistory )
{
kDebug ( 6050 ) < < " delay= " < < delay < < " url= " < < url < < " from= " < < this - > url ( ) < < " parent= " < < parentPart ( ) ;
kDebug ( 6050 ) < < " current redirectURL= " < < d - > m_redirectURL < < " with delay " < < d - > m_delayRedirect ;
// In case of JS redirections, some, such as jump to anchors, and javascript:
// evaluation should actually be handled immediately, and not waiting until
// the end of the script. (Besides, we don't want to abort the tokenizer for those)
if ( delay = = - 1 & & d - > isInPageURL ( url ) ) {
d - > executeInPageURL ( url , doLockHistory ) ;
return ;
}
if ( delay < 24 * 60 * 60 & &
( d - > m_redirectURL . isEmpty ( ) | | delay < = d - > m_delayRedirect ) ) {
d - > m_delayRedirect = delay ;
d - > m_redirectURL = url ;
d - > m_redirectLockHistory = doLockHistory ;
kDebug ( 6050 ) < < " d->m_bComplete= " < < d - > m_bComplete ;
if ( d - > m_bComplete ) {
d - > m_redirectionTimer . stop ( ) ;
d - > m_redirectionTimer . setSingleShot ( true ) ;
d - > m_redirectionTimer . start ( qMax ( 0 , 1000 * d - > m_delayRedirect ) ) ;
}
}
}
void KHTMLPartPrivate : : clearRedirection ( )
{
m_delayRedirect = 0 ;
m_redirectURL . clear ( ) ;
m_redirectionTimer . stop ( ) ;
}
void KHTMLPart : : slotRedirect ( )
{
kDebug ( 6050 ) < < this ;
QString u = d - > m_redirectURL ;
KUrl url ( u ) ;
d - > clearRedirection ( ) ;
if ( d - > isInPageURL ( u ) )
{
d - > executeInPageURL ( u , d - > m_redirectLockHistory ) ;
return ;
}
KParts : : OpenUrlArguments args ;
KUrl cUrl ( this - > url ( ) ) ;
// handle windows opened by JS
if ( openedByJS ( ) & & d - > m_opener )
cUrl = d - > m_opener - > url ( ) ;
if ( ! KAuthorized : : authorizeUrlAction ( " redirect " , cUrl , url ) )
{
kWarning ( 6050 ) < < " KHTMLPart::scheduleRedirection: Redirection from " < < cUrl < < " to " < < url < < " REJECTED! " ;
emit completed ( ) ;
return ;
}
if ( url . equals ( this - > url ( ) ,
KUrl : : CompareWithoutTrailingSlash | KUrl : : CompareWithoutFragment | KUrl : : AllowEmptyPath ) )
{
args . metaData ( ) . insert ( " referrer " , d - > m_pageReferrer ) ;
}
// For javascript and META-tag based redirections:
// - We don't take cross-domain-ness in consideration if we are the
// toplevel frame because the new URL may be in a different domain as the current URL
// but that's ok.
// - If we are not the toplevel frame then we check against the toplevelURL()
if ( parentPart ( ) )
args . metaData ( ) . insert ( " cross-domain " , toplevelURL ( ) . url ( ) ) ;
KParts : : BrowserArguments browserArgs ;
browserArgs . setLockHistory ( d - > m_redirectLockHistory ) ;
// _self: make sure we don't use any <base target=>'s
if ( ! urlSelected ( u , 0 , 0 , " _self " , args , browserArgs ) ) {
// urlSelected didn't open a url, so emit completed ourselves
emit completed ( ) ;
}
}
void KHTMLPart : : slotRedirection ( KIO : : Job * , const KUrl & url )
{
// the slave told us that we got redirected
//kDebug( 6050 ) << "redirection by KIO to" << url;
emit d - > m_extension - > setLocationBarUrl ( url . prettyUrl ( ) ) ;
d - > m_workingURL = url ;
}
bool KHTMLPart : : setEncoding ( const QString & name , bool override )
{
d - > m_encoding = name ;
d - > m_haveEncoding = override ;
if ( ! url ( ) . isEmpty ( ) ) {
// reload document
closeUrl ( ) ;
KUrl oldUrl = url ( ) ;
setUrl ( KUrl ( ) ) ;
d - > m_restored = true ;
openUrl ( oldUrl ) ;
d - > m_restored = false ;
}
return true ;
}
QString KHTMLPart : : encoding ( ) const
{
if ( d - > m_haveEncoding & & ! d - > m_encoding . isEmpty ( ) )
return d - > m_encoding ;
if ( d - > m_decoder & & d - > m_decoder - > encoding ( ) )
return QString ( d - > m_decoder - > encoding ( ) ) ;
return defaultEncoding ( ) ;
}
QString KHTMLPart : : defaultEncoding ( ) const
{
QString encoding = settings ( ) - > encoding ( ) ;
if ( ! encoding . isEmpty ( ) )
return encoding ;
// HTTP requires the default encoding to be latin1, when neither
// the user nor the page requested a particular encoding.
if ( url ( ) . protocol ( ) . startsWith ( " http " ) )
return " iso-8859-1 " ;
else
return KGlobal : : locale ( ) - > encoding ( ) ;
}
void KHTMLPart : : setUserStyleSheet ( const KUrl & url )
{
if ( d - > m_doc & & d - > m_doc - > docLoader ( ) )
( void ) new khtml : : PartStyleSheetLoader ( this , url . url ( ) , d - > m_doc - > docLoader ( ) ) ;
}
void KHTMLPart : : setUserStyleSheet ( const QString & styleSheet )
{
if ( d - > m_doc )
d - > m_doc - > setUserStyleSheet ( styleSheet ) ;
}
bool KHTMLPart : : gotoAnchor ( const QString & name )
{
if ( ! d - > m_doc )
return false ;
HTMLCollectionImpl * anchors = new HTMLCollectionImpl ( d - > m_doc , HTMLCollectionImpl : : DOC_ANCHORS ) ;
anchors - > ref ( ) ;
NodeImpl * n = anchors - > namedItem ( name ) ;
anchors - > deref ( ) ;
if ( ! n ) {
n = d - > m_doc - > getElementById ( name ) ;
}
d - > m_doc - > setCSSTarget ( n ) ; // Setting to null will clear the current target.
// Implement the rule that "" and "top" both mean top of page.
bool top = ! n & & ( name . isEmpty ( ) | | name . toLower ( ) = = " top " ) ;
if ( top ) {
d - > m_view - > setContentsPos ( d - > m_view - > contentsX ( ) , 0 ) ;
return true ;
} else if ( ! n ) {
kDebug ( 6050 ) < < name < < " not found " ;
return false ;
}
int x = 0 , y = 0 ;
int gox , dummy ;
HTMLElementImpl * a = static_cast < HTMLElementImpl * > ( n ) ;
a - > getUpperLeftCorner ( x , y ) ;
if ( x < = d - > m_view - > contentsX ( ) )
gox = x - 10 ;
else {
gox = d - > m_view - > contentsX ( ) ;
if ( x + 10 > d - > m_view - > contentsX ( ) + d - > m_view - > visibleWidth ( ) ) {
a - > getLowerRightCorner ( x , dummy ) ;
gox = x - d - > m_view - > visibleWidth ( ) + 10 ;
}
}
d - > m_view - > setContentsPos ( gox , y ) ;
return true ;
}
bool KHTMLPart : : nextAnchor ( )
{
if ( ! d - > m_doc )
return false ;
d - > m_view - > focusNextPrevNode ( true ) ;
return true ;
}
bool KHTMLPart : : prevAnchor ( )
{
if ( ! d - > m_doc )
return false ;
d - > m_view - > focusNextPrevNode ( false ) ;
return true ;
}
void KHTMLPart : : setStandardFont ( const QString & name )
{
d - > m_settings - > setStdFontName ( name ) ;
}
void KHTMLPart : : setFixedFont ( const QString & name )
{
d - > m_settings - > setFixedFontName ( name ) ;
}
void KHTMLPart : : setURLCursor ( const QCursor & c )
{
d - > m_linkCursor = c ;
}
QCursor KHTMLPart : : urlCursor ( ) const
{
return d - > m_linkCursor ;
}
bool KHTMLPart : : onlyLocalReferences ( ) const
{
return d - > m_onlyLocalReferences ;
}
void KHTMLPart : : setOnlyLocalReferences ( bool enable )
{
d - > m_onlyLocalReferences = enable ;
}
bool KHTMLPart : : forcePermitLocalImages ( ) const
{
return d - > m_forcePermitLocalImages ;
}
void KHTMLPart : : setForcePermitLocalImages ( bool enable )
{
d - > m_forcePermitLocalImages = enable ;
}
void KHTMLPartPrivate : : setFlagRecursively (
bool KHTMLPartPrivate : : * flag , bool value )
{
// first set it on the current one
this - > * flag = value ;
// descend into child frames recursively
{
QList < khtml : : ChildFrame * > : : Iterator it = m_frames . begin ( ) ;
const QList < khtml : : ChildFrame * > : : Iterator itEnd = m_frames . end ( ) ;
for ( ; it ! = itEnd ; + + it ) {
KHTMLPart * const part = qobject_cast < KHTMLPart * > ( ( * it ) - > m_part . data ( ) ) ;
if ( part )
part - > d - > setFlagRecursively ( flag , value ) ;
} /*next it*/
}
// do the same again for objects
{
QList < khtml : : ChildFrame * > : : Iterator it = m_objects . begin ( ) ;
const QList < khtml : : ChildFrame * > : : Iterator itEnd = m_objects . end ( ) ;
for ( ; it ! = itEnd ; + + it ) {
KHTMLPart * const part = qobject_cast < KHTMLPart * > ( ( * it ) - > m_part . data ( ) ) ;
if ( part )
part - > d - > setFlagRecursively ( flag , value ) ;
} /*next it*/
}
}
void KHTMLPart : : initCaret ( )
{
// initialize caret if not used yet
if ( d - > editor_context . m_selection . state ( ) = = Selection : : NONE ) {
if ( d - > m_doc ) {
NodeImpl * node ;
if ( d - > m_doc - > isHTMLDocument ( ) ) {
HTMLDocumentImpl * htmlDoc = static_cast < HTMLDocumentImpl * > ( d - > m_doc ) ;
node = htmlDoc - > body ( ) ;
} else
node = d - > m_doc ;
if ( ! node ) return ;
d - > editor_context . m_selection . moveTo ( Position ( node , 0 ) ) ;
d - > editor_context . m_selection . setNeedsLayout ( ) ;
d - > editor_context . m_selection . needsCaretRepaint ( ) ;
}
}
}
static void setCaretInvisibleIfNeeded ( KHTMLPart * part )
{
// On contenteditable nodes, don't hide the caret
if ( ! khtml : : KHTMLPartAccessor : : caret ( part ) . caretPos ( ) . node ( ) - > isContentEditable ( ) )
part - > setCaretVisible ( false ) ;
}
void KHTMLPart : : setCaretMode ( bool enable )
{
kDebug ( 6200 ) < < enable ;
if ( isCaretMode ( ) = = enable ) return ;
d - > setFlagRecursively ( & KHTMLPartPrivate : : m_caretMode , enable ) ;
// FIXME: this won't work on frames as expected
if ( ! isEditable ( ) ) {
if ( enable ) {
initCaret ( ) ;
setCaretVisible ( true ) ;
// view()->ensureCaretVisible();
} else {
setCaretInvisibleIfNeeded ( this ) ;
}
}
}
bool KHTMLPart : : isCaretMode ( ) const
{
return d - > m_caretMode ;
}
void KHTMLPart : : setEditable ( bool enable )
{
if ( isEditable ( ) = = enable ) return ;
d - > setFlagRecursively ( & KHTMLPartPrivate : : m_designMode , enable ) ;
// FIXME: this won't work on frames as expected
if ( ! isCaretMode ( ) ) {
if ( enable ) {
initCaret ( ) ;
setCaretVisible ( true ) ;
// view()->ensureCaretVisible();
} else
setCaretInvisibleIfNeeded ( this ) ;
}
}
bool KHTMLPart : : isEditable ( ) const
{
return d - > m_designMode ;
}
khtml : : EditorContext * KHTMLPart : : editorContext ( ) const {
return & d - > editor_context ;
}
void KHTMLPart : : setCaretPosition ( DOM : : Node node , long offset , bool extendSelection )
{
Q_UNUSED ( node ) ;
Q_UNUSED ( offset ) ;
Q_UNUSED ( extendSelection ) ;
# ifndef KHTML_NO_CARET
#if 0
kDebug ( 6200 ) < < " node: " < < node . handle ( ) < < " nodeName: "
< < node . nodeName ( ) . string ( ) < < " offset: " < < offset
< < " extendSelection " < < extendSelection ;
if ( view ( ) - > moveCaretTo ( node . handle ( ) , offset , ! extendSelection ) )
emitSelectionChanged ( ) ;
view ( ) - > ensureCaretVisible ( ) ;
# endif
# endif // KHTML_NO_CARET
}
KHTMLPart : : CaretDisplayPolicy KHTMLPart : : caretDisplayPolicyNonFocused ( ) const
{
#if 0
# ifndef KHTML_NO_CARET
return ( CaretDisplayPolicy ) view ( ) - > caretDisplayPolicyNonFocused ( ) ;
# else // KHTML_NO_CARET
return CaretInvisible ;
# endif // KHTML_NO_CARET
# endif
return CaretInvisible ;
}
void KHTMLPart : : setCaretDisplayPolicyNonFocused ( CaretDisplayPolicy policy )
{
Q_UNUSED ( policy ) ;
#if 0
# ifndef KHTML_NO_CARET
view ( ) - > setCaretDisplayPolicyNonFocused ( policy ) ;
# endif // KHTML_NO_CARET
# endif
}
void KHTMLPart : : setCaretVisible ( bool show )
{
if ( show ) {
NodeImpl * caretNode = d - > editor_context . m_selection . caretPos ( ) . node ( ) ;
if ( isCaretMode ( ) | | ( caretNode & & caretNode - > isContentEditable ( ) ) ) {
invalidateSelection ( ) ;
enableFindAheadActions ( false ) ;
}
} else {
if ( d - > editor_context . m_caretBlinkTimer > = 0 )
killTimer ( d - > editor_context . m_caretBlinkTimer ) ;
clearCaretRectIfNeeded ( ) ;
}
}
void KHTMLPart : : findTextBegin ( )
{
d - > m_find . findTextBegin ( ) ;
}
bool KHTMLPart : : initFindNode ( bool selection , bool reverse , bool fromCursor )
{
return d - > m_find . initFindNode ( selection , reverse , fromCursor ) ;
}
void KHTMLPart : : slotFind ( )
{
KParts : : ReadOnlyPart * part = currentFrame ( ) ;
if ( ! part )
return ;
if ( ! part - > inherits ( " KHTMLPart " ) )
{
kError ( 6000 ) < < " part is a " < < part - > metaObject ( ) - > className ( ) < < " , can't do a search into it " ;
return ;
}
static_cast < KHTMLPart * > ( part ) - > findText ( ) ;
}
void KHTMLPart : : slotFindNext ( )
{
KParts : : ReadOnlyPart * part = currentFrame ( ) ;
if ( ! part )
return ;
if ( ! part - > inherits ( " KHTMLPart " ) )
{
kError ( 6000 ) < < " part is a " < < part - > metaObject ( ) - > className ( ) < < " , can't do a search into it " ;
return ;
}
static_cast < KHTMLPart * > ( part ) - > findTextNext ( ) ;
}
void KHTMLPart : : slotFindPrev ( )
{
KParts : : ReadOnlyPart * part = currentFrame ( ) ;
if ( ! part )
return ;
if ( ! part - > inherits ( " KHTMLPart " ) )
{
kError ( 6000 ) < < " part is a " < < part - > metaObject ( ) - > className ( ) < < " , can't do a search into it " ;
return ;
}
static_cast < KHTMLPart * > ( part ) - > findTextNext ( true ) ; // reverse
}
void KHTMLPart : : slotFindDone ( )
{
// ### remove me
}
void KHTMLPart : : slotFindAheadText ( )
{
KHTMLPart * part = qobject_cast < KHTMLPart * > ( currentFrame ( ) ) ;
if ( ! part )
return ;
part - > findText ( ) ;
KHTMLFindBar * findBar = part - > d - > m_find . findBar ( ) ;
findBar - > setOptions ( findBar - > options ( ) & ~ FindLinksOnly ) ;
}
void KHTMLPart : : slotFindAheadLink ( )
{
KHTMLPart * part = qobject_cast < KHTMLPart * > ( currentFrame ( ) ) ;
if ( ! part )
return ;
part - > findText ( ) ;
KHTMLFindBar * findBar = part - > d - > m_find . findBar ( ) ;
findBar - > setOptions ( findBar - > options ( ) | FindLinksOnly ) ;
}
void KHTMLPart : : enableFindAheadActions ( bool )
{
// ### remove me
}
void KHTMLPart : : slotFindDialogDestroyed ( )
{
// ### remove me
}
void KHTMLPart : : findText ( )
{
if ( parentPart ( ) )
return parentPart ( ) - > findText ( ) ;
d - > m_find . activate ( ) ;
}
void KHTMLPart : : findText ( const QString & str , long options , QWidget * parent , KFindDialog * findDialog )
{
if ( parentPart ( ) )
return parentPart ( ) - > findText ( str , options , parent , findDialog ) ;
d - > m_find . createNewKFind ( str , options , parent , findDialog ) ;
}
// New method
bool KHTMLPart : : findTextNext ( bool reverse )
{
if ( parentPart ( ) )
return parentPart ( ) - > findTextNext ( reverse ) ;
return d - > m_find . findTextNext ( reverse ) ;
}
bool KHTMLPart : : pFindTextNextInThisFrame ( bool reverse )
{
return d - > m_find . findTextNext ( reverse ) ;
}
QString KHTMLPart : : selectedTextAsHTML ( ) const
{
const Selection & sel = d - > editor_context . m_selection ;
if ( ! hasSelection ( ) ) {
kDebug ( ) < < " Selection is not valid. Returning empty selection " ;
return QString ( ) ;
}
if ( sel . start ( ) . offset ( ) < 0 | | sel . end ( ) . offset ( ) < 0 ) {
kDebug ( ) < < " invalid values for end/startOffset " < < sel . start ( ) . offset ( ) < < " " < < sel . end ( ) . offset ( ) ;
return QString ( ) ;
}
DOM : : Range r = selection ( ) ;
if ( r . isNull ( ) | | r . isDetached ( ) )
return QString ( ) ;
int exceptioncode = 0 ; //ignore the result
return r . handle ( ) - > toHTML ( exceptioncode ) . string ( ) ;
}
QString KHTMLPart : : selectedText ( ) const
{
bool hasNewLine = true ;
bool seenTDTag = false ;
QString text ;
const Selection & sel = d - > editor_context . m_selection ;
DOM : : Node n = sel . start ( ) . node ( ) ;
while ( ! n . isNull ( ) ) {
if ( n . nodeType ( ) = = DOM : : Node : : TEXT_NODE & & n . handle ( ) - > renderer ( ) ) {
DOM : : DOMStringImpl * dstr = static_cast < DOM : : TextImpl * > ( n . handle ( ) ) - > renderString ( ) ;
QString str ( dstr - > s , dstr - > l ) ;
if ( ! str . isEmpty ( ) ) {
if ( seenTDTag ) {
text + = " " ;
seenTDTag = false ;
}
hasNewLine = false ;
if ( n = = sel . start ( ) . node ( ) & & n = = sel . end ( ) . node ( ) ) {
int s = khtml : : RenderPosition : : fromDOMPosition ( sel . start ( ) ) . renderedOffset ( ) ;
int e = khtml : : RenderPosition : : fromDOMPosition ( sel . end ( ) ) . renderedOffset ( ) ;
text = str . mid ( s , e - s ) ;
} else if ( n = = sel . start ( ) . node ( ) ) {
text = str . mid ( khtml : : RenderPosition : : fromDOMPosition ( sel . start ( ) ) . renderedOffset ( ) ) ;
} else if ( n = = sel . end ( ) . node ( ) ) {
text + = str . left ( khtml : : RenderPosition : : fromDOMPosition ( sel . end ( ) ) . renderedOffset ( ) ) ;
} else
text + = str ;
}
}
else {
// This is our simple HTML -> ASCII transformation:
unsigned short id = n . elementId ( ) ;
switch ( id ) {
case ID_TEXTAREA :
text + = static_cast < HTMLTextAreaElementImpl * > ( n . handle ( ) ) - > value ( ) . string ( ) ;
break ;
case ID_INPUT :
if ( static_cast < HTMLInputElementImpl * > ( n . handle ( ) ) - > inputType ( ) ! = HTMLInputElementImpl : : PASSWORD )
text + = static_cast < HTMLInputElementImpl * > ( n . handle ( ) ) - > value ( ) . string ( ) ;
break ;
case ID_SELECT :
text + = static_cast < HTMLSelectElementImpl * > ( n . handle ( ) ) - > value ( ) . string ( ) ;
break ;
case ID_BR :
text + = " \n " ;
hasNewLine = true ;
break ;
case ID_IMG :
text + = static_cast < HTMLImageElementImpl * > ( n . handle ( ) ) - > altText ( ) . string ( ) ;
break ;
case ID_TD :
break ;
case ID_TH :
case ID_HR :
case ID_OL :
case ID_UL :
case ID_LI :
case ID_DD :
case ID_DL :
case ID_DT :
case ID_PRE :
case ID_LISTING :
case ID_BLOCKQUOTE :
case ID_DIV :
if ( ! hasNewLine )
text + = " \n " ;
hasNewLine = true ;
break ;
case ID_P :
case ID_TR :
case ID_H1 :
case ID_H2 :
case ID_H3 :
case ID_H4 :
case ID_H5 :
case ID_H6 :
if ( ! hasNewLine )
text + = " \n " ;
hasNewLine = true ;
break ;
}
}
if ( n = = sel . end ( ) . node ( ) ) break ;
DOM : : Node next = n . firstChild ( ) ;
if ( next . isNull ( ) ) next = n . nextSibling ( ) ;
while ( next . isNull ( ) & & ! n . parentNode ( ) . isNull ( ) ) {
n = n . parentNode ( ) ;
next = n . nextSibling ( ) ;
unsigned short id = n . elementId ( ) ;
switch ( id ) {
case ID_TD :
seenTDTag = true ; //Add two spaces after a td if then followed by text.
break ;
case ID_TH :
case ID_HR :
case ID_OL :
case ID_UL :
case ID_LI :
case ID_DD :
case ID_DL :
case ID_DT :
case ID_PRE :
case ID_LISTING :
case ID_BLOCKQUOTE :
case ID_DIV :
seenTDTag = false ;
if ( ! hasNewLine )
text + = " \n " ;
hasNewLine = true ;
break ;
case ID_P :
case ID_TR :
case ID_H1 :
case ID_H2 :
case ID_H3 :
case ID_H4 :
case ID_H5 :
case ID_H6 :
if ( ! hasNewLine )
text + = " \n " ;
// text += "\n";
hasNewLine = true ;
break ;
}
}
n = next ;
}
if ( text . isEmpty ( ) )
return QString ( ) ;
int start = 0 ;
int end = text . length ( ) ;
// Strip leading LFs
while ( ( start < end ) & & ( text [ start ] = = ' \n ' ) )
+ + start ;
// Strip excessive trailing LFs
while ( ( start < ( end - 1 ) ) & & ( text [ end - 1 ] = = ' \n ' ) & & ( text [ end - 2 ] = = ' \n ' ) )
- - end ;
return text . mid ( start , end - start ) ;
}
QString KHTMLPart : : simplifiedSelectedText ( ) const
{
QString text = selectedText ( ) ;
text . replace ( QChar ( 0xa0 ) , ' ' ) ;
// remove leading and trailing whitespace
while ( ! text . isEmpty ( ) & & text [ 0 ] . isSpace ( ) )
text = text . mid ( 1 ) ;
while ( ! text . isEmpty ( ) & & text [ text . length ( ) - 1 ] . isSpace ( ) )
text . truncate ( text . length ( ) - 1 ) ;
return text ;
}
bool KHTMLPart : : hasSelection ( ) const
{
return ! d - > editor_context . m_selection . isEmpty ( ) & & ! d - > editor_context . m_selection . isCollapsed ( ) ;
}
DOM : : Range KHTMLPart : : selection ( ) const
{
return d - > editor_context . m_selection . toRange ( ) ;
}
void KHTMLPart : : selection ( DOM : : Node & s , long & so , DOM : : Node & e , long & eo ) const
{
DOM : : Range r = d - > editor_context . m_selection . toRange ( ) ;
s = r . startContainer ( ) ;
so = r . startOffset ( ) ;
e = r . endContainer ( ) ;
eo = r . endOffset ( ) ;
}
void KHTMLPart : : setSelection ( const DOM : : Range & r )
{
setCaret ( r ) ;
}
const Selection & KHTMLPart : : caret ( ) const
{
return d - > editor_context . m_selection ;
}
const Selection & KHTMLPart : : dragCaret ( ) const
{
return d - > editor_context . m_dragCaret ;
}
void KHTMLPart : : setCaret ( const Selection & s , bool closeTyping )
{
if ( d - > editor_context . m_selection ! = s ) {
clearCaretRectIfNeeded ( ) ;
setFocusNodeIfNeeded ( s ) ;
d - > editor_context . m_selection = s ;
notifySelectionChanged ( closeTyping ) ;
}
}
void KHTMLPart : : setDragCaret ( const DOM : : Selection & dragCaret )
{
if ( d - > editor_context . m_dragCaret ! = dragCaret ) {
d - > editor_context . m_dragCaret . needsCaretRepaint ( ) ;
d - > editor_context . m_dragCaret = dragCaret ;
d - > editor_context . m_dragCaret . needsCaretRepaint ( ) ;
}
}
void KHTMLPart : : clearSelection ( )
{
clearCaretRectIfNeeded ( ) ;
setFocusNodeIfNeeded ( d - > editor_context . m_selection ) ;
d - > editor_context . m_selection . collapse ( ) ;
notifySelectionChanged ( ) ;
}
void KHTMLPart : : invalidateSelection ( )
{
clearCaretRectIfNeeded ( ) ;
d - > editor_context . m_selection . setNeedsLayout ( ) ;
selectionLayoutChanged ( ) ;
}
void KHTMLPart : : setSelectionVisible ( bool flag )
{
if ( d - > editor_context . m_caretVisible = = flag )
return ;
clearCaretRectIfNeeded ( ) ;
setFocusNodeIfNeeded ( d - > editor_context . m_selection ) ;
d - > editor_context . m_caretVisible = flag ;
// notifySelectionChanged();
}
# if 1
void KHTMLPart : : slotClearSelection ( )
{
if ( ! isCaretMode ( )
& & d - > editor_context . m_selection . state ( ) ! = Selection : : NONE
& & ! d - > editor_context . m_selection . caretPos ( ) . node ( ) - > isContentEditable ( ) )
clearCaretRectIfNeeded ( ) ;
bool hadSelection = hasSelection ( ) ;
d - > editor_context . m_selection . collapse ( ) ;
if ( hadSelection )
notifySelectionChanged ( ) ;
}
# endif
void KHTMLPart : : clearCaretRectIfNeeded ( )
{
if ( d - > editor_context . m_caretPaint ) {
d - > editor_context . m_caretPaint = false ;
d - > editor_context . m_selection . needsCaretRepaint ( ) ;
}
}
void KHTMLPart : : setFocusNodeIfNeeded ( const Selection & s )
{
if ( ! xmlDocImpl ( ) | | s . state ( ) = = Selection : : NONE )
return ;
NodeImpl * n = s . start ( ) . node ( ) ;
NodeImpl * target = ( n & & n - > isContentEditable ( ) ) ? n : 0 ;
if ( ! target ) {
while ( n & & n ! = s . end ( ) . node ( ) ) {
if ( n - > isContentEditable ( ) ) {
target = n ;
break ;
}
n = n - > traverseNextNode ( ) ;
}
}
assert ( target = = 0 | | target - > isContentEditable ( ) ) ;
if ( target ) {
for ( ; target & & ! target - > isFocusable ( ) ; target = target - > parentNode ( ) )
{ }
if ( target & & target - > isMouseFocusable ( ) )
xmlDocImpl ( ) - > setFocusNode ( target ) ;
else if ( ! target | | ! target - > focused ( ) )
xmlDocImpl ( ) - > setFocusNode ( 0 ) ;
}
}
void KHTMLPart : : selectionLayoutChanged ( )
{
// kill any caret blink timer now running
if ( d - > editor_context . m_caretBlinkTimer > = 0 ) {
killTimer ( d - > editor_context . m_caretBlinkTimer ) ;
d - > editor_context . m_caretBlinkTimer = - 1 ;
}
// see if a new caret blink timer needs to be started
if ( d - > editor_context . m_caretVisible
& & d - > editor_context . m_selection . state ( ) ! = Selection : : NONE ) {
d - > editor_context . m_caretPaint = isCaretMode ( )
| | d - > editor_context . m_selection . caretPos ( ) . node ( ) - > isContentEditable ( ) ;
if ( d - > editor_context . m_caretBlinks & & d - > editor_context . m_caretPaint )
d - > editor_context . m_caretBlinkTimer = startTimer ( qApp - > cursorFlashTime ( ) / 2 ) ;
d - > editor_context . m_selection . needsCaretRepaint ( ) ;
// make sure that caret is visible
QRect r ( d - > editor_context . m_selection . getRepaintRect ( ) ) ;
if ( d - > editor_context . m_caretPaint )
d - > m_view - > ensureVisible ( r . x ( ) , r . y ( ) ) ;
}
if ( d - > m_doc )
d - > m_doc - > updateSelection ( ) ;
// Always clear the x position used for vertical arrow navigation.
// It will be restored by the vertical arrow navigation code if necessary.
d - > editor_context . m_xPosForVerticalArrowNavigation = d - > editor_context . NoXPosForVerticalArrowNavigation ;
}
void KHTMLPart : : notifySelectionChanged ( bool closeTyping )
{
Editor * ed = d - > editor_context . m_editor ;
selectionLayoutChanged ( ) ;
if ( ed ) {
ed - > clearTypingStyle ( ) ;
if ( closeTyping )
ed - > closeTyping ( ) ;
}
emitSelectionChanged ( ) ;
}
void KHTMLPart : : timerEvent ( QTimerEvent * e )
{
if ( e - > timerId ( ) = = d - > editor_context . m_caretBlinkTimer ) {
if ( d - > editor_context . m_caretBlinks & &
d - > editor_context . m_selection . state ( ) ! = Selection : : NONE ) {
d - > editor_context . m_caretPaint = ! d - > editor_context . m_caretPaint ;
d - > editor_context . m_selection . needsCaretRepaint ( ) ;
}
} else if ( e - > timerId ( ) = = d - > m_DNSPrefetchTimer ) {
// kDebug( 6050 ) << "will lookup " << d->m_DNSPrefetchQueue.head() << d->m_numDNSPrefetchedNames;
KIO : : HostInfo : : prefetchHost ( d - > m_DNSPrefetchQueue . dequeue ( ) ) ;
if ( d - > m_DNSPrefetchQueue . isEmpty ( ) ) {
killTimer ( d - > m_DNSPrefetchTimer ) ;
d - > m_DNSPrefetchTimer = - 1 ;
}
} else if ( e - > timerId ( ) = = d - > m_DNSTTLTimer ) {
foreach ( const QString & name , d - > m_lookedupHosts )
d - > m_DNSPrefetchQueue . enqueue ( name ) ;
if ( d - > m_DNSPrefetchTimer < = 0 )
d - > m_DNSPrefetchTimer = startTimer ( sDNSPrefetchTimerDelay ) ;
}
}
bool KHTMLPart : : mayPrefetchHostname ( const QString & name )
{
if ( d - > m_bDNSPrefetch = = DNSPrefetchDisabled )
return false ;
if ( d - > m_numDNSPrefetchedNames > = sMaxDNSPrefetchPerPage )
return false ;
if ( d - > m_bDNSPrefetch = = DNSPrefetchOnlyWWWAndSLD ) {
int dots = name . count ( ' . ' ) ;
if ( dots > 2 | | ( dots = = 2 & & ! name . startsWith ( " www. " ) ) )
return false ;
}
if ( d - > m_lookedupHosts . contains ( name ) )
return false ;
d - > m_DNSPrefetchQueue . enqueue ( name ) ;
d - > m_lookedupHosts . insert ( name ) ;
d - > m_numDNSPrefetchedNames + + ;
if ( d - > m_DNSPrefetchTimer < 1 )
d - > m_DNSPrefetchTimer = startTimer ( sDNSPrefetchTimerDelay ) ;
if ( d - > m_DNSTTLTimer < 1 )
d - > m_DNSTTLTimer = startTimer ( sDNSTTLSeconds * 1000 + 1 ) ;
return true ;
}
void KHTMLPart : : paintCaret ( QPainter * p , const QRect & rect ) const
{
if ( d - > editor_context . m_caretPaint )
d - > editor_context . m_selection . paintCaret ( p , rect ) ;
}
void KHTMLPart : : paintDragCaret ( QPainter * p , const QRect & rect ) const
{
d - > editor_context . m_dragCaret . paintCaret ( p , rect ) ;
}
DOM : : Editor * KHTMLPart : : editor ( ) const {
if ( ! d - > editor_context . m_editor )
const_cast < KHTMLPart * > ( this ) - > d - > editor_context . m_editor = new DOM : : Editor ( const_cast < KHTMLPart * > ( this ) ) ;
return d - > editor_context . m_editor ;
}
void KHTMLPart : : resetHoverText ( )
{
if ( ! d - > m_overURL . isEmpty ( ) ) // Only if we were showing a link
{
d - > m_overURL . clear ( ) ;
d - > m_overURLTarget . clear ( ) ;
emit onURL ( QString ( ) ) ;
// revert to default statusbar text
setStatusBarText ( QString ( ) , BarHoverText ) ;
emit d - > m_extension - > mouseOverInfo ( KFileItem ( ) ) ;
}
}
void KHTMLPart : : overURL ( const QString & url , const QString & target , bool /*shiftPressed*/ )
{
KUrl u = completeURL ( url ) ;
// special case for <a href="">
if ( url . isEmpty ( ) )
u . setFileName ( url ) ;
emit onURL ( url ) ;
if ( url . isEmpty ( ) ) {
setStatusBarText ( Qt : : escape ( u . prettyUrl ( ) ) , BarHoverText ) ;
return ;
}
if ( d - > isJavaScriptURL ( url ) ) {
QString jscode = d - > codeForJavaScriptURL ( url ) ;
jscode = KStringHandler : : rsqueeze ( jscode , 80 ) ; // truncate if too long
if ( url . startsWith ( " javascript:window.open " ) )
jscode + = i18n ( " (In new window) " ) ;
setStatusBarText ( Qt : : escape ( jscode ) , BarHoverText ) ;
return ;
}
KFileItem item ( u , QString ( ) , KFileItem : : Unknown ) ;
emit d - > m_extension - > mouseOverInfo ( item ) ;
QString com ;
KMimeType : : Ptr typ = KMimeType : : findByUrl ( u ) ;
if ( typ )
com = typ - > comment ( u ) ;
if ( ! u . isValid ( ) ) {
setStatusBarText ( Qt : : escape ( u . prettyUrl ( ) ) , BarHoverText ) ;
return ;
}
if ( u . isLocalFile ( ) )
{
// TODO : use KIO::stat() and create a KFileItem out of its result,
// to use KFileItem::statusBarText()
const QString path = QFile : : encodeName ( u . toLocalFile ( ) ) ;
KDE_struct_stat buff ;
bool ok = ! KDE : : stat ( path , & buff ) ;
KDE_struct_stat lbuff ;
if ( ok ) ok = ! KDE : : lstat ( path , & lbuff ) ;
QString text = Qt : : escape ( u . prettyUrl ( ) ) ;
QString text2 = text ;
if ( ok & & S_ISLNK ( lbuff . st_mode ) )
{
QString tmp ;
if ( com . isNull ( ) )
tmp = i18n ( " Symbolic Link " ) ;
else
tmp = i18n ( " %1 (Link) " , com ) ;
char buff_two [ 1024 ] ;
text + = " -> " ;
int n = readlink ( path . toLocal8Bit ( ) . data ( ) , buff_two , 1022 ) ;
if ( n = = - 1 )
{
text2 + = " " ;
text2 + = tmp ;
setStatusBarText ( text2 , BarHoverText ) ;
return ;
}
buff_two [ n ] = 0 ;
text + = buff_two ;
text + = " " ;
text + = tmp ;
}
else if ( ok & & S_ISREG ( buff . st_mode ) )
{
if ( buff . st_size < 1024 )
text = i18np ( " %2 (%1 byte) " , " %2 (%1 bytes) " , ( long ) buff . st_size , text2 ) ; // always put the URL last, in case it contains '%'
else
{
float d = ( float ) buff . st_size / 1024.0 ;
text = i18n ( " %2 (%1 K) " , KGlobal : : locale ( ) - > formatNumber ( d , 2 ) , text2 ) ; // was %.2f
}
text + = " " ;
text + = com ;
}
else if ( ok & & S_ISDIR ( buff . st_mode ) )
{
text + = " " ;
text + = com ;
}
else
{
text + = " " ;
text + = com ;
}
setStatusBarText ( text , BarHoverText ) ;
}
else
{
QString extra ;
if ( target . toLower ( ) = = " _blank " )
{
extra = i18n ( " (In new window) " ) ;
}
else if ( ! target . isEmpty ( ) & &
( target . toLower ( ) ! = " _top " ) & &
( target . toLower ( ) ! = " _self " ) & &
( target . toLower ( ) ! = " _parent " ) )
{
KHTMLPart * p = this ;
while ( p - > parentPart ( ) )
p = p - > parentPart ( ) ;
if ( ! p - > frameExists ( target ) )
extra = i18n ( " (In new window) " ) ;
else
extra = i18n ( " (In other frame) " ) ;
}
if ( u . protocol ( ) = = QLatin1String ( " mailto " ) ) {
QString mailtoMsg /* = QString::fromLatin1("<img src=%1>").arg(locate("icon", QString::fromLatin1("locolor/16x16/actions/mail_send.png")))*/ ;
mailtoMsg + = i18n ( " Email to: " ) + KUrl : : fromPercentEncoding ( u . path ( ) . toLatin1 ( ) ) ;
const QStringList queries = u . query ( ) . mid ( 1 ) . split ( ' & ' ) ;
QStringList : : ConstIterator it = queries . begin ( ) ;
const QStringList : : ConstIterator itEnd = queries . end ( ) ;
for ( ; it ! = itEnd ; + + it )
if ( ( * it ) . startsWith ( QLatin1String ( " subject= " ) ) )
mailtoMsg + = i18n ( " - Subject: " ) + KUrl : : fromPercentEncoding ( ( * it ) . mid ( 8 ) . toLatin1 ( ) ) ;
else if ( ( * it ) . startsWith ( QLatin1String ( " cc= " ) ) )
mailtoMsg + = i18n ( " - CC: " ) + KUrl : : fromPercentEncoding ( ( * it ) . mid ( 3 ) . toLatin1 ( ) ) ;
else if ( ( * it ) . startsWith ( QLatin1String ( " bcc= " ) ) )
mailtoMsg + = i18n ( " - BCC: " ) + KUrl : : fromPercentEncoding ( ( * it ) . mid ( 4 ) . toLatin1 ( ) ) ;
mailtoMsg = Qt : : escape ( mailtoMsg ) ;
mailtoMsg . replace ( QRegExp ( " ([ \n \r \t ]|[ ]{10}) " ) , QString ( ) ) ;
setStatusBarText ( " <qt> " + mailtoMsg , BarHoverText ) ;
return ;
}
// Is this check necessary at all? (Frerich)
#if 0
else if ( u . protocol ( ) = = QLatin1String ( " http " ) ) {
DOM : : Node hrefNode = nodeUnderMouse ( ) . parentNode ( ) ;
while ( hrefNode . nodeName ( ) . string ( ) ! = QLatin1String ( " A " ) & & ! hrefNode . isNull ( ) )
hrefNode = hrefNode . parentNode ( ) ;
if ( ! hrefNode . isNull ( ) ) {
DOM : : Node hreflangNode = hrefNode . attributes ( ) . getNamedItem ( " HREFLANG " ) ;
if ( ! hreflangNode . isNull ( ) ) {
QString countryCode = hreflangNode . nodeValue ( ) . string ( ) . toLower ( ) ;
// Map the language code to an appropriate country code.
if ( countryCode = = QLatin1String ( " en " ) )
countryCode = QLatin1String ( " gb " ) ;
QString flagImg = QLatin1String ( " <img src=%1> " ) . arg (
locate ( " locale " , QLatin1String ( " l10n/ " )
+ countryCode
+ QLatin1String ( " /flag.png " ) ) ) ;
emit setStatusBarText ( flagImg + u . prettyUrl ( ) + extra ) ;
}
}
}
# endif
setStatusBarText ( Qt : : escape ( u . prettyUrl ( ) ) + extra , BarHoverText ) ;
}
}
//
// This executes in the active part on a click or other url selection action in
// that active part.
//
bool KHTMLPart : : urlSelected ( const QString & url , int button , int state , const QString & _target , const KParts : : OpenUrlArguments & _args , const KParts : : BrowserArguments & _browserArgs )
{
KParts : : OpenUrlArguments args = _args ;
KParts : : BrowserArguments browserArgs = _browserArgs ;
bool hasTarget = false ;
QString target = _target ;
if ( target . isEmpty ( ) & & d - > m_doc )
target = d - > m_doc - > baseTarget ( ) ;
if ( ! target . isEmpty ( ) )
hasTarget = true ;
if ( d - > isJavaScriptURL ( url ) )
{
crossFrameExecuteScript ( target , d - > codeForJavaScriptURL ( url ) ) ;
return false ;
}
KUrl cURL = completeURL ( url ) ;
// special case for <a href=""> (IE removes filename, mozilla doesn't)
if ( url . isEmpty ( ) )
cURL . setFileName ( url ) ; // removes filename
if ( ! cURL . isValid ( ) )
// ### ERROR HANDLING
return false ;
kDebug ( 6050 ) < < this < < " complete URL: " < < cURL . url ( ) < < " target= " < < target ;
if ( state & Qt : : ControlModifier )
{
emit d - > m_extension - > createNewWindow ( cURL , args , browserArgs ) ;
return true ;
}
if ( button = = Qt : : LeftButton & & ( state & Qt : : ShiftModifier ) )
{
KIO : : MetaData metaData ;
metaData . insert ( " referrer " , d - > m_referrer ) ;
KHTMLPopupGUIClient : : saveURL ( d - > m_view , i18n ( " Save As " ) , cURL , metaData ) ;
return false ;
}
if ( ! checkLinkSecurity ( cURL ,
ki18n ( " <qt>This untrusted page links to<br /><b>%1</b>.<br />Do you want to follow the link?</qt> " ) ,
i18n ( " Follow " ) ) )
return false ;
browserArgs . frameName = target ;
args . metaData ( ) . insert ( " main_frame_request " ,
parentPart ( ) = = 0 ? " TRUE " : " FALSE " ) ;
args . metaData ( ) . insert ( " ssl_parent_ip " , d - > m_ssl_parent_ip ) ;
args . metaData ( ) . insert ( " ssl_parent_cert " , d - > m_ssl_parent_cert ) ;
args . metaData ( ) . insert ( " PropagateHttpHeader " , " true " ) ;
args . metaData ( ) . insert ( " ssl_was_in_use " , d - > m_ssl_in_use ? " TRUE " : " FALSE " ) ;
args . metaData ( ) . insert ( " ssl_activate_warnings " , " TRUE " ) ;
if ( hasTarget & & target ! = " _self " & & target ! = " _top " & & target ! = " _blank " & & target ! = " _parent " )
{
// unknown frame names should open in a new window.
khtml : : ChildFrame * frame = recursiveFrameRequest ( this , cURL , args , browserArgs , false ) ;
if ( frame )
{
args . metaData ( ) [ " referrer " ] = d - > m_referrer ;
requestObject ( frame , cURL , args , browserArgs ) ;
return true ;
}
}
if ( ! d - > m_referrer . isEmpty ( ) & & ! args . metaData ( ) . contains ( " referrer " ) )
args . metaData ( ) [ " referrer " ] = d - > m_referrer ;
if ( button = = Qt : : NoButton & & ( state & Qt : : ShiftModifier ) & & ( state & Qt : : ControlModifier ) )
{
emit d - > m_extension - > createNewWindow ( cURL , args , browserArgs ) ;
return true ;
}
if ( state & Qt : : ShiftModifier )
{
KParts : : WindowArgs winArgs ;
winArgs . setLowerWindow ( true ) ;
emit d - > m_extension - > createNewWindow ( cURL , args , browserArgs , winArgs ) ;
return true ;
}
//If we're asked to open up an anchor in the current URL, in current window,
//merely gotoanchor, and do not reload the new page. Note that this does
//not apply if the URL is the same page, but without a ref
if ( cURL . hasRef ( ) & & ( ! hasTarget | | target = = " _self " ) )
{
if ( d - > isLocalAnchorJump ( cURL ) )
{
d - > executeAnchorJump ( cURL , browserArgs . lockHistory ( ) ) ;
return false ; // we jumped, but we didn't open a URL
}
}
if ( ! d - > m_bComplete & & ! hasTarget )
closeUrl ( ) ;
view ( ) - > viewport ( ) - > unsetCursor ( ) ;
emit d - > m_extension - > openUrlRequest ( cURL , args , browserArgs ) ;
return true ;
}
void KHTMLPart : : slotViewDocumentSource ( )
{
KUrl currentUrl ( this - > url ( ) ) ;
bool isTempFile = false ;
if ( ! ( currentUrl . isLocalFile ( ) ) & & KHTMLPageCache : : self ( ) - > isComplete ( d - > m_cacheId ) )
{
KTemporaryFile sourceFile ;
sourceFile . setSuffix ( defaultExtension ( ) ) ;
sourceFile . setAutoRemove ( false ) ;
if ( sourceFile . open ( ) )
{
QDataStream stream ( & sourceFile ) ;
KHTMLPageCache : : self ( ) - > saveData ( d - > m_cacheId , & stream ) ;
currentUrl = KUrl ( ) ;
currentUrl . setPath ( sourceFile . fileName ( ) ) ;
isTempFile = true ;
}
}
( void ) KRun : : runUrl ( currentUrl , QLatin1String ( " text/plain " ) , view ( ) , isTempFile ) ;
}
void KHTMLPart : : slotViewPageInfo ( )
{
Ui_KHTMLInfoDlg ui ;
QDialog * dlg = new QDialog ( 0 ) ;
dlg - > setAttribute ( Qt : : WA_DeleteOnClose ) ;
dlg - > setObjectName ( " KHTML Page Info Dialog " ) ;
ui . setupUi ( dlg ) ;
ui . _close - > setGuiItem ( KStandardGuiItem : : close ( ) ) ;
connect ( ui . _close , SIGNAL ( clicked ( ) ) , dlg , SLOT ( accept ( ) ) ) ;
if ( d - > m_doc )
ui . _title - > setText ( d - > m_doc - > title ( ) . string ( ) . trimmed ( ) ) ;
// If it's a frame, set the caption to "Frame Information"
if ( parentPart ( ) & & d - > m_doc & & d - > m_doc - > isHTMLDocument ( ) ) {
dlg - > setWindowTitle ( i18n ( " Frame Information " ) ) ;
}
QString editStr ;
if ( ! d - > m_pageServices . isEmpty ( ) )
editStr = i18n ( " <a href= \" %1 \" >[Properties]</a> " , d - > m_pageServices ) ;
QString squeezedURL = KStringHandler : : csqueeze ( url ( ) . prettyUrl ( ) , 80 ) ;
ui . _url - > setText ( " <a href= \" " + url ( ) . url ( ) + " \" > " + squeezedURL + " </a> " + editStr ) ;
if ( lastModified ( ) . isEmpty ( ) )
{
ui . _lastModified - > hide ( ) ;
ui . _lmLabel - > hide ( ) ;
}
else
ui . _lastModified - > setText ( lastModified ( ) ) ;
const QString & enc = encoding ( ) ;
if ( enc . isEmpty ( ) ) {
ui . _eLabel - > hide ( ) ;
ui . _encoding - > hide ( ) ;
} else {
ui . _encoding - > setText ( enc ) ;
}
if ( ! xmlDocImpl ( ) | | xmlDocImpl ( ) - > parseMode ( ) = = DOM : : DocumentImpl : : Unknown ) {
ui . _mode - > hide ( ) ;
ui . _modeLabel - > hide ( ) ;
} else {
switch ( xmlDocImpl ( ) - > parseMode ( ) ) {
case DOM : : DocumentImpl : : Compat :
ui . _mode - > setText ( i18nc ( " HTML rendering mode (see http://en.wikipedia.org/wiki/Quirks_mode) " , " Quirks " ) ) ;
break ;
case DOM : : DocumentImpl : : Transitional :
ui . _mode - > setText ( i18nc ( " HTML rendering mode (see http://en.wikipedia.org/wiki/Quirks_mode) " , " Almost standards " ) ) ;
break ;
case DOM : : DocumentImpl : : Strict :
default : // others handled above
ui . _mode - > setText ( i18nc ( " HTML rendering mode (see http://en.wikipedia.org/wiki/Quirks_mode) " , " Strict " ) ) ;
break ;
}
}
/* populate the list view now */
const QStringList headers = d - > m_httpHeaders . split ( " \n " ) ;
QStringList : : ConstIterator it = headers . begin ( ) ;
const QStringList : : ConstIterator itEnd = headers . end ( ) ;
for ( ; it ! = itEnd ; + + it ) {
const QStringList header = ( * it ) . split ( QRegExp ( " :[ ]+ " ) ) ;
if ( header . count ( ) ! = 2 )
continue ;
QTreeWidgetItem * item = new QTreeWidgetItem ( ui . _headers ) ;
item - > setText ( 0 , header [ 0 ] ) ;
item - > setText ( 1 , header [ 1 ] ) ;
}
dlg - > show ( ) ;
/* put no code here */
}
void KHTMLPart : : slotViewFrameSource ( )
{
KParts : : ReadOnlyPart * frame = currentFrame ( ) ;
if ( ! frame )
return ;
KUrl url = frame - > url ( ) ;
bool isTempFile = false ;
if ( ! ( url . isLocalFile ( ) ) & & frame - > inherits ( " KHTMLPart " ) )
{
long cacheId = static_cast < KHTMLPart * > ( frame ) - > d - > m_cacheId ;
if ( KHTMLPageCache : : self ( ) - > isComplete ( cacheId ) )
{
KTemporaryFile sourceFile ;
sourceFile . setSuffix ( defaultExtension ( ) ) ;
sourceFile . setAutoRemove ( false ) ;
if ( sourceFile . open ( ) )
{
QDataStream stream ( & sourceFile ) ;
KHTMLPageCache : : self ( ) - > saveData ( cacheId , & stream ) ;
url = KUrl ( ) ;
url . setPath ( sourceFile . fileName ( ) ) ;
isTempFile = true ;
}
}
}
( void ) KRun : : runUrl ( url , QLatin1String ( " text/plain " ) , view ( ) , isTempFile ) ;
}
KUrl KHTMLPart : : backgroundURL ( ) const
{
// ### what about XML documents? get from CSS?
if ( ! d - > m_doc | | ! d - > m_doc - > isHTMLDocument ( ) )
return KUrl ( ) ;
QString relURL = static_cast < HTMLDocumentImpl * > ( d - > m_doc ) - > body ( ) - > getAttribute ( ATTR_BACKGROUND ) . string ( ) ;
return KUrl ( url ( ) , relURL ) ;
}
void KHTMLPart : : slotSaveBackground ( )
{
KIO : : MetaData metaData ;
metaData [ " referrer " ] = d - > m_referrer ;
KHTMLPopupGUIClient : : saveURL ( d - > m_view , i18n ( " Save Background Image As " ) , backgroundURL ( ) , metaData ) ;
}
void KHTMLPart : : slotSaveDocument ( )
{
KUrl srcURL ( url ( ) ) ;
if ( srcURL . fileName ( KUrl : : ObeyTrailingSlash ) . isEmpty ( ) )
srcURL . setFileName ( " index " + defaultExtension ( ) ) ;
KIO : : MetaData metaData ;
// Referre unknown?
KHTMLPopupGUIClient : : saveURL ( d - > m_view , i18n ( " Save As " ) , srcURL , metaData , " text/html " , d - > m_cacheId ) ;
}
void KHTMLPart : : slotSecurity ( )
{
// kDebug( 6050 ) << "Meta Data:" << endl
// << d->m_ssl_peer_cert_subject
// << endl
// << d->m_ssl_peer_cert_issuer
// << endl
// << d->m_ssl_cipher
// << endl
// << d->m_ssl_cipher_desc
// << endl
// << d->m_ssl_cipher_version
// << endl
// << d->m_ssl_good_from
// << endl
// << d->m_ssl_good_until
// << endl
// << d->m_ssl_cert_state
// << endl;
//### reenable with new signature
#if 0
KSslInfoDialog * kid = new KSslInfoDialog ( d - > m_ssl_in_use , widget ( ) , " kssl_info_dlg " , true ) ;
const QStringList sl = d - > m_ssl_peer_chain . split ( ' \n ' , QString : : SkipEmptyParts ) ;
QList < QSslCertificate > certChain ;
bool certChainOk = d - > m_ssl_in_use ;
if ( certChainOk ) {
foreach ( const QString & s , sl ) {
certChain . append ( QSslCertificate ( s . toLatin1 ( ) ) ) ; //or is it toLocal8Bit or whatever?
if ( certChain . last ( ) . isNull ( ) ) {
certChainOk = false ;
break ;
}
}
}
if ( certChainOk ) {
kid - > setup ( certChain ,
d - > m_ssl_peer_ip ,
url ( ) . url ( ) ,
d - > m_ssl_cipher ,
d - > m_ssl_cipher_desc ,
d - > m_ssl_cipher_version ,
d - > m_ssl_cipher_used_bits . toInt ( ) ,
d - > m_ssl_cipher_bits . toInt ( ) ,
( KSSLCertificate : : KSSLValidation ) d - > m_ssl_cert_state . toInt ( ) ) ;
}
kid - > exec ( ) ;
//the dialog deletes itself on close
# endif
KSslInfoDialog * kid = new KSslInfoDialog ( 0 ) ;
//### This is boilerplate code and it's copied from SlaveInterface.
QStringList sl = d - > m_ssl_peer_chain . split ( ' \x01 ' , QString : : SkipEmptyParts ) ;
QList < QSslCertificate > certChain ;
bool decodedOk = true ;
foreach ( const QString & s , sl ) {
certChain . append ( QSslCertificate ( s . toLatin1 ( ) ) ) ; //or is it toLocal8Bit or whatever?
if ( certChain . last ( ) . isNull ( ) ) {
decodedOk = false ;
break ;
}
}
if ( decodedOk | | true /*H4X*/ ) {
kid - > setSslInfo ( certChain ,
d - > m_ssl_peer_ip ,
url ( ) . host ( ) ,
d - > m_ssl_protocol_version ,
d - > m_ssl_cipher ,
d - > m_ssl_cipher_used_bits . toInt ( ) ,
d - > m_ssl_cipher_bits . toInt ( ) ,
KSslInfoDialog : : errorsFromString ( d - > m_ssl_cert_errors ) ) ;
kDebug ( 7024 ) < < " Showing SSL Info dialog " ;
kid - > exec ( ) ;
kDebug ( 7024 ) < < " SSL Info dialog closed " ;
} else {
KMessageBox : : information ( 0 , i18n ( " The peer SSL certificate chain "
" appears to be corrupt. " ) ,
i18n ( " SSL " ) ) ;
}
}
void KHTMLPart : : slotSaveFrame ( )
{
KParts : : ReadOnlyPart * frame = currentFrame ( ) ;
if ( ! frame )
return ;
KUrl srcURL ( frame - > url ( ) ) ;
if ( srcURL . fileName ( KUrl : : ObeyTrailingSlash ) . isEmpty ( ) )
srcURL . setFileName ( " index " + defaultExtension ( ) ) ;
KIO : : MetaData metaData ;
// Referrer unknown?
KHTMLPopupGUIClient : : saveURL ( d - > m_view , i18n ( " Save Frame As " ) , srcURL , metaData , " text/html " ) ;
}
void KHTMLPart : : slotSetEncoding ( const QString & enc )
{
d - > m_autoDetectLanguage = KEncodingDetector : : None ;
setEncoding ( enc , true ) ;
}
void KHTMLPart : : slotAutomaticDetectionLanguage ( KEncodingDetector : : AutoDetectScript scri )
{
d - > m_autoDetectLanguage = scri ;
setEncoding ( QString ( ) , false ) ;
}
void KHTMLPart : : slotUseStylesheet ( )
{
if ( d - > m_doc )
{
bool autoselect = ( d - > m_paUseStylesheet - > currentItem ( ) = = 0 ) ;
d - > m_sheetUsed = autoselect ? QString ( ) : d - > m_paUseStylesheet - > currentText ( ) ;
d - > m_doc - > updateStyleSelector ( ) ;
}
}
void KHTMLPart : : updateActions ( )
{
bool frames = false ;
QList < khtml : : ChildFrame * > : : ConstIterator it = d - > m_frames . constBegin ( ) ;
const QList < khtml : : ChildFrame * > : : ConstIterator end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it )
if ( ( * it ) - > m_type = = khtml : : ChildFrame : : Frame )
{
frames = true ;
break ;
}
if ( d - > m_paViewFrame )
d - > m_paViewFrame - > setEnabled ( frames ) ;
if ( d - > m_paSaveFrame )
d - > m_paSaveFrame - > setEnabled ( frames ) ;
if ( frames )
d - > m_paFind - > setText ( i18n ( " &Find in Frame... " ) ) ;
else
d - > m_paFind - > setText ( i18n ( " &Find... " ) ) ;
KParts : : Part * frame = 0 ;
if ( frames )
frame = currentFrame ( ) ;
bool enableFindAndSelectAll = true ;
if ( frame )
enableFindAndSelectAll = frame - > inherits ( " KHTMLPart " ) ;
d - > m_paFind - > setEnabled ( enableFindAndSelectAll ) ;
d - > m_paSelectAll - > setEnabled ( enableFindAndSelectAll ) ;
bool enablePrintFrame = false ;
if ( frame )
{
QObject * ext = KParts : : BrowserExtension : : childObject ( frame ) ;
if ( ext )
enablePrintFrame = ext - > metaObject ( ) - > indexOfSlot ( " print() " ) ! = - 1 ;
}
d - > m_paPrintFrame - > setEnabled ( enablePrintFrame ) ;
QString bgURL ;
// ### frames
if ( d - > m_doc & & d - > m_doc - > isHTMLDocument ( ) & & static_cast < HTMLDocumentImpl * > ( d - > m_doc ) - > body ( ) & & ! d - > m_bClearing )
bgURL = static_cast < HTMLDocumentImpl * > ( d - > m_doc ) - > body ( ) - > getAttribute ( ATTR_BACKGROUND ) . string ( ) ;
if ( d - > m_paSaveBackground )
d - > m_paSaveBackground - > setEnabled ( ! bgURL . isEmpty ( ) ) ;
if ( d - > m_paDebugScript )
d - > m_paDebugScript - > setEnabled ( d - > m_frame ? d - > m_frame - > m_jscript : 0L ) ;
}
KParts : : ScriptableExtension * KHTMLPart : : scriptableExtension ( const DOM : : NodeImpl * frame ) {
const ConstFrameIt end = d - > m_objects . constEnd ( ) ;
for ( ConstFrameIt it = d - > m_objects . constBegin ( ) ; it ! = end ; + + it )
if ( ( * it ) - > m_partContainerElement . data ( ) = = frame )
return ( * it ) - > m_scriptable . data ( ) ;
return 0L ;
}
void KHTMLPart : : loadFrameElement ( DOM : : HTMLPartContainerElementImpl * frame , const QString & url ,
const QString & frameName , const QStringList & params , bool isIFrame )
{
//kDebug( 6050 ) << this << " requestFrame( ..., " << url << ", " << frameName << " )";
khtml : : ChildFrame * child ;
FrameIt it = d - > m_frames . find ( frameName ) ;
if ( it = = d - > m_frames . end ( ) ) {
child = new khtml : : ChildFrame ;
//kDebug( 6050 ) << "inserting new frame into frame map " << frameName;
child - > m_name = frameName ;
d - > m_frames . insert ( d - > m_frames . end ( ) , child ) ;
} else {
child = * it ;
}
child - > m_type = isIFrame ? khtml : : ChildFrame : : IFrame : khtml : : ChildFrame : : Frame ;
child - > m_partContainerElement = frame ;
child - > m_params = params ;
// If we do not have a part, make sure we create one.
if ( ! child - > m_part ) {
QStringList dummy ; // the list of servicetypes handled by the part is now unused.
QString khtml = QString : : fromLatin1 ( " khtml " ) ;
KParts : : ReadOnlyPart * part = createPart ( d - > m_view - > viewport ( ) , this ,
QString : : fromLatin1 ( " text/html " ) ,
khtml , dummy , QStringList ( ) ) ;
// We navigate it to about:blank to setup an empty one, but we do it
// before hooking up the signals and extensions, so that any sync emit
// of completed by the kid doesn't cause us to be marked as completed.
// (async ones are discovered by the presence of the KHTMLRun)
// ### load event on the kid?
navigateLocalProtocol ( child , part , KUrl ( " about:blank " ) ) ;
connectToChildPart ( child , part , " text/html " /* mimetype of the part, not what's being loaded */ ) ;
}
KUrl u = url . isEmpty ( ) ? KUrl ( ) : completeURL ( url ) ;
// Since we don't specify args here a KHTMLRun will be used to determine the
// mimetype, which will then be passed down at the bottom of processObjectRequest
// inside URLArgs to the part. In our particular case, this means that we can
// use that inside KHTMLPart::openUrl to route things appropriately.
child - > m_bCompleted = false ;
if ( ! requestObject ( child , u ) & & ! child - > m_run ) {
child - > m_bCompleted = true ;
}
}
QString KHTMLPart : : requestFrameName ( )
{
return QString : : fromLatin1 ( " <!--frame %1--> " ) . arg ( d - > m_frameNameId + + ) ;
}
bool KHTMLPart : : loadObjectElement ( DOM : : HTMLPartContainerElementImpl * frame , const QString & url ,
const QString & serviceType , const QStringList & params )
{
//kDebug( 6031 ) << this << "frame=" << frame;
khtml : : ChildFrame * child = new khtml : : ChildFrame ;
FrameIt it = d - > m_objects . insert ( d - > m_objects . end ( ) , child ) ;
( * it ) - > m_partContainerElement = frame ;
( * it ) - > m_type = khtml : : ChildFrame : : Object ;
( * it ) - > m_params = params ;
KParts : : OpenUrlArguments args ;
args . setMimeType ( serviceType ) ;
if ( ! requestObject ( * it , completeURL ( url ) , args ) & & ! ( * it ) - > m_run ) {
( * it ) - > m_bCompleted = true ;
return false ;
}
return true ;
}
bool KHTMLPart : : requestObject ( khtml : : ChildFrame * child , const KUrl & url , const KParts : : OpenUrlArguments & _args ,
const KParts : : BrowserArguments & browserArgs )
{
// we always permit javascript: URLs here since they're basically just
// empty pages (and checkLinkSecurity/KAuthorized doesn't know what to do with them)
if ( ! d - > isJavaScriptURL ( url . url ( ) ) & & ! checkLinkSecurity ( url ) )
{
kDebug ( 6031 ) < < this < < " checkLinkSecurity refused " ;
return false ;
}
if ( d - > m_bClearing )
{
return false ;
}
if ( child - > m_bPreloaded )
{
if ( child - > m_partContainerElement & & child - > m_part )
child - > m_partContainerElement . data ( ) - > setWidget ( child - > m_part . data ( ) - > widget ( ) ) ;
child - > m_bPreloaded = false ;
return true ;
}
//kDebug(6031) << "child=" << child << "child->m_part=" << child->m_part;
KParts : : OpenUrlArguments args ( _args ) ;
if ( child - > m_run ) {
kDebug ( 6031 ) < < " navigating ChildFrame while mimetype resolution was in progress... " ;
child - > m_run . data ( ) - > abort ( ) ;
}
// ### Dubious -- the whole dir/ vs. img thing
if ( child - > m_part & & ! args . reload ( ) & & child - > m_part . data ( ) - > url ( ) . equals ( url ,
KUrl : : CompareWithoutTrailingSlash | KUrl : : CompareWithoutFragment | KUrl : : AllowEmptyPath ) )
args . setMimeType ( child - > m_serviceType ) ;
child - > m_browserArgs = browserArgs ;
child - > m_args = args ;
// reload/soft-reload arguments are always inherited from parent
child - > m_args . setReload ( arguments ( ) . reload ( ) ) ;
child - > m_browserArgs . softReload = d - > m_extension - > browserArguments ( ) . softReload ;
child - > m_serviceName . clear ( ) ;
if ( ! d - > m_referrer . isEmpty ( ) & & ! child - > m_args . metaData ( ) . contains ( " referrer " ) )
child - > m_args . metaData ( ) [ " referrer " ] = d - > m_referrer ;
child - > m_args . metaData ( ) . insert ( " PropagateHttpHeader " , " true " ) ;
child - > m_args . metaData ( ) . insert ( " ssl_parent_ip " , d - > m_ssl_parent_ip ) ;
child - > m_args . metaData ( ) . insert ( " ssl_parent_cert " , d - > m_ssl_parent_cert ) ;
child - > m_args . metaData ( ) . insert ( " main_frame_request " ,
parentPart ( ) = = 0 ? " TRUE " : " FALSE " ) ;
child - > m_args . metaData ( ) . insert ( " ssl_was_in_use " ,
d - > m_ssl_in_use ? " TRUE " : " FALSE " ) ;
child - > m_args . metaData ( ) . insert ( " ssl_activate_warnings " , " TRUE " ) ;
child - > m_args . metaData ( ) . insert ( " cross-domain " , toplevelURL ( ) . url ( ) ) ;
// We know the frame will be text/html if the HTML says <frame src=""> or <frame src="about:blank">,
// no need to KHTMLRun to figure out the mimetype"
// ### What if we're inside an XML document?
if ( ( url . isEmpty ( ) | | url . url ( ) = = " about:blank " | | url . protocol ( ) = = " javascript " ) & & args . mimeType ( ) . isEmpty ( ) )
args . setMimeType ( QLatin1String ( " text/html " ) ) ;
if ( args . mimeType ( ) . isEmpty ( ) ) {
kDebug ( 6031 ) < < " Running new KHTMLRun for " < < this < < " and child= " < < child ;
child - > m_run = new KHTMLRun ( this , child , url , child - > m_args , child - > m_browserArgs , true ) ;
d - > m_bComplete = false ; // ensures we stop it in checkCompleted...
return false ;
} else {
return processObjectRequest ( child , url , args . mimeType ( ) ) ;
}
}
void KHTMLPart : : childLoadFailure ( khtml : : ChildFrame * child )
{
child - > m_bCompleted = true ;
if ( child - > m_partContainerElement )
child - > m_partContainerElement . data ( ) - > partLoadingErrorNotify ( ) ;
checkCompleted ( ) ;
}
bool KHTMLPart : : processObjectRequest ( khtml : : ChildFrame * child , const KUrl & _url , const QString & mimetype )
{
kDebug ( 6031 ) < < " trying to create part for " < < mimetype < < _url ;
// IMPORTANT: create a copy of the url here, because it is just a reference, which was likely to be given
// by an emitting frame part (emit openUrlRequest( blahurl, ... ) . A few lines below we delete the part
// though -> the reference becomes invalid -> crash is likely
KUrl url ( _url ) ;
// khtmlrun called us with empty url + mimetype to indicate a loading error,
// we obviosuly failed; but we can return true here since we don't want it
// doing anything more, while childLoadFailure is enough to notify our kid.
if ( d - > m_onlyLocalReferences | | ( url . isEmpty ( ) & & mimetype . isEmpty ( ) ) ) {
childLoadFailure ( child ) ;
return true ;
}
// we also want to ignore any spurious requests due to closing when parser is being cleared. These should be
// ignored entirely --- the tail end of ::clear will clean things up.
if ( d - > m_bClearing )
return false ;
if ( child - > m_bNotify ) {
child - > m_bNotify = false ;
if ( ! child - > m_browserArgs . lockHistory ( ) )
emit d - > m_extension - > openUrlNotify ( ) ;
}
// Now, depending on mimetype and current state of the world, we may have
// to create a new part or ask the user to save things, etc.
//
// We need a new part if there isn't one at all (doh) or the one that's there
// is not for the mimetype we're loading.
//
// For these new types, we may have to ask the user to save it or not
// (we don't if it's navigating the same type).
// Further, we will want to ask if content-disposition suggests we ask for
// saving, even if we're re-navigating.
if ( ! child - > m_part | | child - > m_serviceType ! = mimetype | |
( child - > m_run & & child - > m_run . data ( ) - > serverSuggestsSave ( ) ) ) {
// We often get here if we didn't know the mimetype in advance, and had to rely
// on KRun to figure it out. In this case, we let the element check if it wants to
// handle this mimetype itself, for e.g. objects containing images.
if ( child - > m_partContainerElement & &
child - > m_partContainerElement . data ( ) - > mimetypeHandledInternally ( mimetype ) ) {
child - > m_bCompleted = true ;
checkCompleted ( ) ;
return true ;
}
// Before attempting to load a part, check if the user wants that.
// Many don't like getting ZIP files embedded.
// However we don't want to ask for flash and other plugin things.
//
// Note: this is fine for frames, since we will merely effectively ignore
// the navigation if this happens
if ( child - > m_type ! = khtml : : ChildFrame : : Object & & child - > m_type ! = khtml : : ChildFrame : : IFrame ) {
QString suggestedFileName ;
int disposition = 0 ;
if ( KHTMLRun * run = child - > m_run . data ( ) ) {
suggestedFileName = run - > suggestedFileName ( ) ;
disposition = run - > serverSuggestsSave ( ) ?
KParts : : BrowserRun : : AttachmentDisposition :
KParts : : BrowserRun : : InlineDisposition ;
}
KParts : : BrowserOpenOrSaveQuestion dlg ( widget ( ) , url , mimetype ) ;
dlg . setSuggestedFileName ( suggestedFileName ) ;
const KParts : : BrowserOpenOrSaveQuestion : : Result res = dlg . askEmbedOrSave ( disposition ) ;
switch ( res ) {
case KParts : : BrowserOpenOrSaveQuestion : : Save :
KHTMLPopupGUIClient : : saveURL ( widget ( ) , i18n ( " Save As " ) , url , child - > m_args . metaData ( ) , QString ( ) , 0 , suggestedFileName ) ;
// fall-through
case KParts : : BrowserOpenOrSaveQuestion : : Cancel :
child - > m_bCompleted = true ;
checkCompleted ( ) ;
return true ; // done
default : // Embed
break ;
}
}
// Now, for frames and iframes, we always create a KHTMLPart anyway,
// doing it in advance when registering the frame. So we want the
// actual creation only for objects here.
if ( child - > m_type = = khtml : : ChildFrame : : Object ) {
KMimeType : : Ptr mime = KMimeType : : mimeType ( mimetype ) ;
if ( mime ) {
// Even for objects, however, we want to force a KHTMLPart for
// html & xml, even if the normally preferred part is another one,
// so that we can script the target natively via contentDocument method.
if ( mime - > is ( " text/html " )
| | mime - > is ( " application/xml " ) ) { // this includes xhtml and svg
child - > m_serviceName = " khtml " ;
} else {
if ( ! pluginsEnabled ( ) ) {
childLoadFailure ( child ) ;
return false ;
}
}
}
QStringList dummy ; // the list of servicetypes handled by the part is now unused.
KParts : : ReadOnlyPart * part = createPart ( d - > m_view - > viewport ( ) , this , mimetype , child - > m_serviceName , dummy , child - > m_params ) ;
if ( ! part ) {
childLoadFailure ( child ) ;
return false ;
}
connectToChildPart ( child , part , mimetype ) ;
}
}
checkEmitLoadEvent ( ) ;
// Some JS code in the load event may have destroyed the part
// In that case, abort
if ( ! child - > m_part )
return false ;
if ( child - > m_bPreloaded ) {
if ( child - > m_partContainerElement & & child - > m_part )
child - > m_partContainerElement . data ( ) - > setWidget ( child - > m_part . data ( ) - > widget ( ) ) ;
child - > m_bPreloaded = false ;
return true ;
}
// reload/soft-reload arguments are always inherited from parent
child - > m_args . setReload ( arguments ( ) . reload ( ) ) ;
child - > m_browserArgs . softReload = d - > m_extension - > browserArguments ( ) . softReload ;
// make sure the part has a way to find out about the mimetype.
// we actually set it in child->m_args in requestObject already,
// but it's useless if we had to use a KHTMLRun instance, as the
// point the run object is to find out exactly the mimetype.
child - > m_args . setMimeType ( mimetype ) ;
child - > m_part . data ( ) - > setArguments ( child - > m_args ) ;
// if not a frame set child as completed
// ### dubious.
child - > m_bCompleted = child - > m_type = = khtml : : ChildFrame : : Object ;
if ( child - > m_extension )
child - > m_extension . data ( ) - > setBrowserArguments ( child - > m_browserArgs ) ;
return navigateChild ( child , url ) ;
}
bool KHTMLPart : : navigateLocalProtocol ( khtml : : ChildFrame * /*child*/ , KParts : : ReadOnlyPart * inPart ,
const KUrl & url )
{
if ( ! qobject_cast < KHTMLPart * > ( inPart ) )
return false ;
KHTMLPart * p = static_cast < KHTMLPart * > ( static_cast < KParts : : ReadOnlyPart * > ( inPart ) ) ;
p - > begin ( ) ;
// We may have to re-propagate the domain here if we go here due to navigation
d - > propagateInitialDomainAndBaseTo ( p ) ;
// Support for javascript: sources
if ( d - > isJavaScriptURL ( url . url ( ) ) ) {
// See if we want to replace content with javascript: output..
QVariant res = p - > executeScript ( DOM : : Node ( ) ,
d - > codeForJavaScriptURL ( url . url ( ) ) ) ;
if ( res . type ( ) = = QVariant : : String & & p - > d - > m_redirectURL . isEmpty ( ) ) {
p - > begin ( ) ;
p - > setAlwaysHonourDoctype ( ) ; // Disable public API compat; it messes with doctype
// We recreated the document, so propagate domain again.
d - > propagateInitialDomainAndBaseTo ( p ) ;
p - > write ( res . toString ( ) ) ;
p - > end ( ) ;
}
} else {
p - > setUrl ( url ) ;
// we need a body element. testcase: <iframe id="a"></iframe><script>alert(a.document.body);</script>
p - > write ( " <HTML><TITLE></TITLE><BODY></BODY></HTML> " ) ;
}
p - > end ( ) ;
// we don't need to worry about child completion explicitly for KHTMLPart...
// or do we?
return true ;
}
bool KHTMLPart : : navigateChild ( khtml : : ChildFrame * child , const KUrl & url )
{
if ( url . protocol ( ) = = " javascript " | | url . url ( ) = = " about:blank " ) {
return navigateLocalProtocol ( child , child - > m_part . data ( ) , url ) ;
} else if ( ! url . isEmpty ( ) ) {
kDebug ( 6031 ) < < " opening " < < url < < " in frame " < < child - > m_part ;
bool b = child - > m_part . data ( ) - > openUrl ( url ) ;
if ( child - > m_bCompleted )
checkCompleted ( ) ;
return b ;
} else {
// empty URL -> no need to navigate
child - > m_bCompleted = true ;
checkCompleted ( ) ;
return true ;
}
}
void KHTMLPart : : connectToChildPart ( khtml : : ChildFrame * child , KParts : : ReadOnlyPart * part ,
const QString & mimetype )
{
kDebug ( 6031 ) < < " we: " < < this < < " kid: " < < child < < part < < mimetype ;
part - > setObjectName ( child - > m_name ) ;
// Cleanup any previous part for this childframe and its connections
if ( KParts : : ReadOnlyPart * p = child - > m_part . data ( ) ) {
if ( ! qobject_cast < KHTMLPart * > ( p ) & & child - > m_jscript )
child - > m_jscript - > clear ( ) ;
partManager ( ) - > removePart ( p ) ;
delete p ;
child - > m_scriptable . clear ( ) ;
}
child - > m_part = part ;
child - > m_serviceType = mimetype ;
if ( child - > m_partContainerElement & & part - > widget ( ) )
child - > m_partContainerElement . data ( ) - > setWidget ( part - > widget ( ) ) ;
if ( child - > m_type ! = khtml : : ChildFrame : : Object )
partManager ( ) - > addPart ( part , false ) ;
// else
// kDebug(6031) << "AH! NO FRAME!!!!!";
if ( qobject_cast < KHTMLPart * > ( part ) ) {
static_cast < KHTMLPart * > ( part ) - > d - > m_frame = child ;
} else if ( child - > m_partContainerElement ) {
// See if this can be scripted..
KParts : : ScriptableExtension * scriptExt = KParts : : ScriptableExtension : : childObject ( part ) ;
if ( ! scriptExt ) {
// Try to fall back to LiveConnectExtension compat
KParts : : LiveConnectExtension * lc = KParts : : LiveConnectExtension : : childObject ( part ) ;
if ( lc )
scriptExt = KParts : : ScriptableExtension : : adapterFromLiveConnect ( part , lc ) ;
}
if ( scriptExt )
scriptExt - > setHost ( d - > m_scriptableExtension ) ;
child - > m_scriptable = scriptExt ;
}
KParts : : StatusBarExtension * sb = KParts : : StatusBarExtension : : childObject ( part ) ;
if ( sb )
sb - > setStatusBar ( d - > m_statusBarExtension - > statusBar ( ) ) ;
connect ( part , SIGNAL ( started ( KIO : : Job * ) ) ,
this , SLOT ( slotChildStarted ( KIO : : Job * ) ) ) ;
connect ( part , SIGNAL ( completed ( ) ) ,
this , SLOT ( slotChildCompleted ( ) ) ) ;
connect ( part , SIGNAL ( completed ( bool ) ) ,
this , SLOT ( slotChildCompleted ( bool ) ) ) ;
connect ( part , SIGNAL ( setStatusBarText ( QString ) ) ,
this , SIGNAL ( setStatusBarText ( QString ) ) ) ;
if ( part - > inherits ( " KHTMLPart " ) )
{
connect ( this , SIGNAL ( completed ( ) ) ,
part , SLOT ( slotParentCompleted ( ) ) ) ;
connect ( this , SIGNAL ( completed ( bool ) ) ,
part , SLOT ( slotParentCompleted ( ) ) ) ;
// As soon as the child's document is created, we need to set its domain
// (but we do so only once, so it can't be simply done in the child)
connect ( part , SIGNAL ( docCreated ( ) ) ,
this , SLOT ( slotChildDocCreated ( ) ) ) ;
}
child - > m_extension = KParts : : BrowserExtension : : childObject ( part ) ;
if ( KParts : : BrowserExtension * kidBrowserExt = child - > m_extension . data ( ) )
{
connect ( kidBrowserExt , SIGNAL ( openUrlNotify ( ) ) ,
d - > m_extension , SIGNAL ( openUrlNotify ( ) ) ) ;
connect ( kidBrowserExt , SIGNAL ( openUrlRequestDelayed ( KUrl , KParts : : OpenUrlArguments , KParts : : BrowserArguments ) ) ,
this , SLOT ( slotChildURLRequest ( KUrl , KParts : : OpenUrlArguments , KParts : : BrowserArguments ) ) ) ;
connect ( kidBrowserExt , SIGNAL ( createNewWindow ( KUrl , KParts : : OpenUrlArguments , KParts : : BrowserArguments , KParts : : WindowArgs , KParts : : ReadOnlyPart * * ) ) ,
d - > m_extension , SIGNAL ( createNewWindow ( KUrl , KParts : : OpenUrlArguments , KParts : : BrowserArguments , KParts : : WindowArgs , KParts : : ReadOnlyPart * * ) ) ) ;
connect ( kidBrowserExt , SIGNAL ( popupMenu ( QPoint , KFileItemList , KParts : : OpenUrlArguments , KParts : : BrowserArguments , KParts : : BrowserExtension : : PopupFlags , KParts : : BrowserExtension : : ActionGroupMap ) ) ,
d - > m_extension , SIGNAL ( popupMenu ( QPoint , KFileItemList , KParts : : OpenUrlArguments , KParts : : BrowserArguments , KParts : : BrowserExtension : : PopupFlags , KParts : : BrowserExtension : : ActionGroupMap ) ) ) ;
connect ( kidBrowserExt , SIGNAL ( popupMenu ( QPoint , KUrl , mode_t , KParts : : OpenUrlArguments , KParts : : BrowserArguments , KParts : : BrowserExtension : : PopupFlags , KParts : : BrowserExtension : : ActionGroupMap ) ) ,
d - > m_extension , SIGNAL ( popupMenu ( QPoint , KUrl , mode_t , KParts : : OpenUrlArguments , KParts : : BrowserArguments , KParts : : BrowserExtension : : PopupFlags , KParts : : BrowserExtension : : ActionGroupMap ) ) ) ;
connect ( kidBrowserExt , SIGNAL ( infoMessage ( QString ) ) ,
d - > m_extension , SIGNAL ( infoMessage ( QString ) ) ) ;
connect ( kidBrowserExt , SIGNAL ( requestFocus ( KParts : : ReadOnlyPart * ) ) ,
this , SLOT ( slotRequestFocus ( KParts : : ReadOnlyPart * ) ) ) ;
kidBrowserExt - > setBrowserInterface ( d - > m_extension - > browserInterface ( ) ) ;
}
}
KParts : : ReadOnlyPart * KHTMLPart : : createPart ( QWidget * parentWidget ,
QObject * parent , const QString & mimetype ,
QString & serviceName , QStringList & serviceTypes ,
const QStringList & params )
{
QString constr ;
if ( ! serviceName . isEmpty ( ) )
constr . append ( QString : : fromLatin1 ( " DesktopEntryName == '%1' " ) . arg ( serviceName ) ) ;
KService : : List offers = KMimeTypeTrader : : self ( ) - > query ( mimetype , " KParts/ReadOnlyPart " , constr ) ;
if ( offers . isEmpty ( ) ) {
int pos = mimetype . indexOf ( " -plugin " ) ;
if ( pos < 0 )
return 0L ;
QString stripped_mime = mimetype . left ( pos ) ;
offers = KMimeTypeTrader : : self ( ) - > query ( stripped_mime , " KParts/ReadOnlyPart " , constr ) ;
if ( offers . isEmpty ( ) )
return 0L ;
}
KService : : List : : ConstIterator it = offers . constBegin ( ) ;
const KService : : List : : ConstIterator itEnd = offers . constEnd ( ) ;
for ( ; it ! = itEnd ; + + it )
{
KService : : Ptr service = ( * it ) ;
KPluginLoader loader ( * service , KHTMLGlobal : : componentData ( ) ) ;
KPluginFactory * const factory = loader . factory ( ) ;
if ( factory ) {
// Turn params into a QVariantList as expected by KPluginFactory
QVariantList variantlist ;
Q_FOREACH ( const QString & str , params )
variantlist < < QVariant ( str ) ;
if ( service - > serviceTypes ( ) . contains ( " Browser/View " ) )
variantlist < < QString ( " Browser/View " ) ;
KParts : : ReadOnlyPart * part = factory - > create < KParts : : ReadOnlyPart > ( parentWidget , parent , QString ( ) , variantlist ) ;
if ( part ) {
serviceTypes = service - > serviceTypes ( ) ;
serviceName = service - > name ( ) ;
return part ;
}
} else {
// TODO KMessageBox::error and i18n, like in KonqFactory::createView?
kWarning ( ) < < QString ( " There was an error loading the module %1. \n The diagnostics is: \n %2 " )
. arg ( service - > name ( ) ) . arg ( loader . errorString ( ) ) ;
}
}
return 0 ;
}
KParts : : PartManager * KHTMLPart : : partManager ( )
{
if ( ! d - > m_manager & & d - > m_view )
{
d - > m_manager = new KParts : : PartManager ( d - > m_view - > topLevelWidget ( ) , this ) ;
d - > m_manager - > setObjectName ( " khtml part manager " ) ;
d - > m_manager - > setAllowNestedParts ( true ) ;
connect ( d - > m_manager , SIGNAL ( activePartChanged ( KParts : : Part * ) ) ,
this , SLOT ( slotActiveFrameChanged ( KParts : : Part * ) ) ) ;
connect ( d - > m_manager , SIGNAL ( partRemoved ( KParts : : Part * ) ) ,
this , SLOT ( slotPartRemoved ( KParts : : Part * ) ) ) ;
}
return d - > m_manager ;
}
void KHTMLPart : : submitFormAgain ( )
{
disconnect ( this , SIGNAL ( completed ( ) ) , this , SLOT ( submitFormAgain ( ) ) ) ;
if ( d - > m_doc & & ! d - > m_doc - > parsing ( ) & & d - > m_submitForm )
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 ) ;
delete d - > m_submitForm ;
d - > m_submitForm = 0 ;
}
void KHTMLPart : : submitFormProxy ( const char * action , const QString & url , const QByteArray & formData , const QString & _target , const QString & contentType , const QString & boundary )
{
submitForm ( action , url , formData , _target , contentType , boundary ) ;
}
void KHTMLPart : : submitForm ( const char * action , const QString & url , const QByteArray & formData , const QString & _target , const QString & contentType , const QString & boundary )
{
kDebug ( 6000 ) < < this < < " target= " < < _target < < " url= " < < url ;
if ( d - > m_formNotification = = KHTMLPart : : Only ) {
emit formSubmitNotification ( action , url , formData , _target , contentType , boundary ) ;
return ;
} else if ( d - > m_formNotification = = KHTMLPart : : Before ) {
emit formSubmitNotification ( action , url , formData , _target , contentType , boundary ) ;
}
KUrl u = completeURL ( url ) ;
if ( ! u . isValid ( ) )
{
// ### ERROR HANDLING!
return ;
}
// Form security checks
//
/*
* If these form security checks are still in this place in a month or two
* I ' m going to simply delete them .
*/
/* This is separate for a reason. It has to be _before_ all script, etc,
* AND I don ' t want to break anything that uses checkLinkSecurity ( ) in
* other places .
*/
if ( ! d - > m_submitForm ) {
if ( u . protocol ( ) ! = " https " & & u . protocol ( ) ! = " mailto " ) {
if ( d - > m_ssl_in_use ) { // Going from SSL -> nonSSL
int rc = KMessageBox : : warningContinueCancel ( NULL , i18n ( " Warning: This is a secure form but it is attempting to send your data back unencrypted. "
" \n A third party may be able to intercept and view this information. "
" \n Are you sure you wish to continue? " ) ,
i18n ( " Network Transmission " ) , KGuiItem ( i18n ( " &Send Unencrypted " ) ) ) ;
if ( rc = = KMessageBox : : Cancel )
return ;
} else { // Going from nonSSL -> nonSSL
KSSLSettings kss ( true ) ;
if ( kss . warnOnUnencrypted ( ) ) {
int rc = KMessageBox : : warningContinueCancel ( NULL ,
i18n ( " Warning: Your data is about to be transmitted across the network unencrypted. "
" \n Are you sure you wish to continue? " ) ,
i18n ( " Network Transmission " ) ,
KGuiItem ( i18n ( " &Send Unencrypted " ) ) ,
KStandardGuiItem : : cancel ( ) ,
" WarnOnUnencryptedForm " ) ;
// Move this setting into KSSL instead
QString grpNotifMsgs = QLatin1String ( " Notification Messages " ) ;
KConfigGroup cg ( KGlobal : : config ( ) , grpNotifMsgs ) ;
if ( ! cg . readEntry ( " WarnOnUnencryptedForm " , true ) ) {
cg . deleteEntry ( " WarnOnUnencryptedForm " ) ;
cg . sync ( ) ;
kss . setWarnOnUnencrypted ( false ) ;
kss . save ( ) ;
}
if ( rc = = KMessageBox : : Cancel )
return ;
}
}
}
if ( u . protocol ( ) = = " mailto " ) {
int rc = KMessageBox : : warningContinueCancel ( NULL ,
i18n ( " This site is attempting to submit form data via email. \n "
" Do you want to continue? " ) ,
i18n ( " Network Transmission " ) ,
KGuiItem ( i18n ( " &Send Email " ) ) ,
KStandardGuiItem : : cancel ( ) ,
" WarnTriedEmailSubmit " ) ;
if ( rc = = KMessageBox : : Cancel ) {
return ;
}
}
}
// End form security checks
//
QString urlstring = u . url ( ) ;
if ( d - > isJavaScriptURL ( urlstring ) ) {
crossFrameExecuteScript ( _target , d - > codeForJavaScriptURL ( urlstring ) ) ;
return ;
}
if ( ! checkLinkSecurity ( u ,
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> " ) ,
i18n ( " Submit " ) ) )
return ;
// OK. We're actually going to submit stuff. Clear any redirections,
// we should win over them
d - > clearRedirection ( ) ;
KParts : : OpenUrlArguments args ;
if ( ! d - > m_referrer . isEmpty ( ) )
args . metaData ( ) [ " referrer " ] = d - > m_referrer ;
args . metaData ( ) . insert ( " PropagateHttpHeader " , " true " ) ;
args . metaData ( ) . insert ( " ssl_parent_ip " , d - > m_ssl_parent_ip ) ;
args . metaData ( ) . insert ( " ssl_parent_cert " , d - > m_ssl_parent_cert ) ;
args . metaData ( ) . insert ( " main_frame_request " ,
parentPart ( ) = = 0 ? " TRUE " : " FALSE " ) ;
args . metaData ( ) . insert ( " ssl_was_in_use " , d - > m_ssl_in_use ? " TRUE " : " FALSE " ) ;
args . metaData ( ) . insert ( " ssl_activate_warnings " , " TRUE " ) ;
//WABA: When we post a form we should treat it as the main url
//the request should never be considered cross-domain
//args.metaData().insert("cross-domain", toplevelURL().url());
KParts : : BrowserArguments browserArgs ;
browserArgs . frameName = _target . isEmpty ( ) ? d - > m_doc - > baseTarget ( ) : _target ;
// Handle mailto: forms
if ( u . protocol ( ) = = " mailto " ) {
// 1) Check for attach= and strip it
QString q = u . query ( ) . mid ( 1 ) ;
QStringList nvps = q . split ( " & " ) ;
bool triedToAttach = false ;
QStringList : : Iterator nvp = nvps . begin ( ) ;
const QStringList : : Iterator nvpEnd = nvps . end ( ) ;
// cannot be a for loop as if something is removed we don't want to do ++nvp, as
// remove returns an iterator pointing to the next item
while ( nvp ! = nvpEnd ) {
const QStringList pair = ( * nvp ) . split ( " = " ) ;
if ( pair . count ( ) > = 2 ) {
if ( pair . first ( ) . toLower ( ) = = " attach " ) {
nvp = nvps . erase ( nvp ) ;
triedToAttach = true ;
} else {
+ + nvp ;
}
} else {
+ + nvp ;
}
}
if ( triedToAttach )
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 " ) ;
// 2) Append body=
QString bodyEnc ;
if ( contentType . toLower ( ) = = " multipart/form-data " ) {
// FIXME: is this correct? I suspect not
bodyEnc = QLatin1String ( KUrl : : toPercentEncoding ( QString : : fromLatin1 ( formData . data ( ) ,
formData . size ( ) ) ) ) ;
} else if ( contentType . toLower ( ) = = " text/plain " ) {
// Convention seems to be to decode, and s/&/\n/
QString tmpbody = QString : : fromLatin1 ( formData . data ( ) ,
formData . size ( ) ) ;
tmpbody . replace ( QRegExp ( " [&] " ) , " \n " ) ;
tmpbody . replace ( QRegExp ( " [+] " ) , " " ) ;
tmpbody = KUrl : : fromPercentEncoding ( tmpbody . toLatin1 ( ) ) ; // Decode the rest of it
bodyEnc = QLatin1String ( KUrl : : toPercentEncoding ( tmpbody ) ) ; // Recode for the URL
} else {
bodyEnc = QLatin1String ( KUrl : : toPercentEncoding ( QString : : fromLatin1 ( formData . data ( ) ,
formData . size ( ) ) ) ) ;
}
nvps . append ( QString ( " body=%1 " ) . arg ( bodyEnc ) ) ;
q = nvps . join ( " & " ) ;
u . setQuery ( q ) ;
}
if ( strcmp ( action , " get " ) = = 0 ) {
if ( u . protocol ( ) ! = " mailto " )
u . setQuery ( QString : : fromLatin1 ( formData . data ( ) , formData . size ( ) ) ) ;
browserArgs . setDoPost ( false ) ;
}
else {
browserArgs . postData = formData ;
browserArgs . setDoPost ( true ) ;
// construct some user headers if necessary
if ( contentType . isNull ( ) | | contentType = = " application/x-www-form-urlencoded " )
browserArgs . setContentType ( " Content-Type: application/x-www-form-urlencoded " ) ;
else // contentType must be "multipart/form-data"
browserArgs . setContentType ( " Content-Type: " + contentType + " ; boundary= " + boundary ) ;
}
if ( d - > m_doc - > parsing ( ) | | d - > m_runningScripts > 0 ) {
if ( d - > m_submitForm ) {
kDebug ( 6000 ) < < " ABORTING! " ;
return ;
}
d - > m_submitForm = new KHTMLPartPrivate : : SubmitForm ;
d - > m_submitForm - > submitAction = action ;
d - > m_submitForm - > submitUrl = url ;
d - > m_submitForm - > submitFormData = formData ;
d - > m_submitForm - > target = _target ;
d - > m_submitForm - > submitContentType = contentType ;
d - > m_submitForm - > submitBoundary = boundary ;
connect ( this , SIGNAL ( completed ( ) ) , this , SLOT ( submitFormAgain ( ) ) ) ;
}
else
{
emit d - > m_extension - > openUrlRequest ( u , args , browserArgs ) ;
}
}
void KHTMLPart : : popupMenu ( const QString & linkUrl )
{
KUrl popupURL ;
KUrl linkKUrl ;
KParts : : OpenUrlArguments args ;
KParts : : BrowserArguments browserArgs ;
QString referrer ;
KParts : : BrowserExtension : : PopupFlags itemflags = KParts : : BrowserExtension : : ShowBookmark | KParts : : BrowserExtension : : ShowReload ;
if ( linkUrl . isEmpty ( ) ) { // click on background
KHTMLPart * khtmlPart = this ;
while ( khtmlPart - > parentPart ( ) )
{
khtmlPart = khtmlPart - > parentPart ( ) ;
}
popupURL = khtmlPart - > url ( ) ;
referrer = khtmlPart - > pageReferrer ( ) ;
if ( hasSelection ( ) )
itemflags = KParts : : BrowserExtension : : ShowTextSelectionItems ;
else
itemflags | = KParts : : BrowserExtension : : ShowNavigationItems ;
} else { // click on link
popupURL = completeURL ( linkUrl ) ;
linkKUrl = popupURL ;
referrer = this - > referrer ( ) ;
itemflags | = KParts : : BrowserExtension : : IsLink ;
if ( ! ( d - > m_strSelectedURLTarget ) . isEmpty ( ) & &
( d - > m_strSelectedURLTarget . toLower ( ) ! = " _top " ) & &
( d - > m_strSelectedURLTarget . toLower ( ) ! = " _self " ) & &
( d - > m_strSelectedURLTarget . toLower ( ) ! = " _parent " ) ) {
if ( d - > m_strSelectedURLTarget . toLower ( ) = = " _blank " )
browserArgs . setForcesNewWindow ( true ) ;
else {
KHTMLPart * p = this ;
while ( p - > parentPart ( ) )
p = p - > parentPart ( ) ;
if ( ! p - > frameExists ( d - > m_strSelectedURLTarget ) )
browserArgs . setForcesNewWindow ( true ) ;
}
}
}
// Danger, Will Robinson. The Popup might stay around for a much
// longer time than KHTMLPart. Deal with it.
KHTMLPopupGUIClient * client = new KHTMLPopupGUIClient ( this , linkKUrl ) ;
QPointer < QObject > guard ( client ) ;
QString mimetype = QLatin1String ( " text/html " ) ;
args . metaData ( ) [ " referrer " ] = referrer ;
if ( ! linkUrl . isEmpty ( ) ) // over a link
{
if ( popupURL . isLocalFile ( ) ) // safe to do this
{
mimetype = KMimeType : : findByUrl ( popupURL , 0 , true , false ) - > name ( ) ;
}
else // look at "extension" of link
{
const QString fname ( popupURL . fileName ( KUrl : : ObeyTrailingSlash ) ) ;
if ( ! fname . isEmpty ( ) & & ! popupURL . hasRef ( ) & & popupURL . query ( ) . isEmpty ( ) )
{
KMimeType : : Ptr pmt = KMimeType : : findByPath ( fname , 0 , true ) ;
// Further check for mime types guessed from the extension which,
// on a web page, are more likely to be a script delivering content
// of undecidable type. If the mime type from the extension is one
// of these, don't use it. Retain the original type 'text/html'.
if ( pmt - > name ( ) ! = KMimeType : : defaultMimeType ( ) & &
! pmt - > is ( " application/x-perl " ) & &
! pmt - > is ( " application/x-perl-module " ) & &
! pmt - > is ( " application/x-php " ) & &
! pmt - > is ( " application/x-python-bytecode " ) & &
! pmt - > is ( " application/x-python " ) & &
! pmt - > is ( " application/x-shellscript " ) )
mimetype = pmt - > name ( ) ;
}
}
}
args . setMimeType ( mimetype ) ;
emit d - > m_extension - > popupMenu ( QCursor : : pos ( ) , popupURL , S_IFREG /*always a file*/ ,
args , browserArgs , itemflags ,
client - > actionGroups ( ) ) ;
if ( ! guard . isNull ( ) ) {
delete client ;
emit popupMenu ( linkUrl , QCursor : : pos ( ) ) ;
d - > m_strSelectedURL . clear ( ) ;
d - > m_strSelectedURLTarget . clear ( ) ;
}
}
void KHTMLPart : : slotParentCompleted ( )
{
//kDebug(6050) << this;
if ( ! d - > m_redirectURL . isEmpty ( ) & & ! d - > m_redirectionTimer . isActive ( ) )
{
//kDebug(6050) << this << ": starting timer for child redirection -> " << d->m_redirectURL;
d - > m_redirectionTimer . setSingleShot ( true ) ;
d - > m_redirectionTimer . start ( qMax ( 0 , 1000 * d - > m_delayRedirect ) ) ;
}
}
void KHTMLPart : : slotChildStarted ( KIO : : Job * job )
{
khtml : : ChildFrame * child = frame ( sender ( ) ) ;
assert ( child ) ;
child - > m_bCompleted = false ;
if ( d - > m_bComplete )
{
#if 0
// WABA: Looks like this belongs somewhere else
if ( ! parentPart ( ) ) // "toplevel" html document? if yes, then notify the hosting browser about the document (url) changes
{
emit d - > m_extension - > openURLNotify ( ) ;
}
# endif
d - > m_bComplete = false ;
emit started ( job ) ;
}
}
void KHTMLPart : : slotChildCompleted ( )
{
slotChildCompleted ( false ) ;
}
void KHTMLPart : : slotChildCompleted ( bool pendingAction )
{
khtml : : ChildFrame * child = frame ( sender ( ) ) ;
if ( child ) {
kDebug ( 6031 ) < < this < < " child= " < < child < < " m_partContainerElement= " < < child - > m_partContainerElement ;
child - > m_bCompleted = true ;
child - > m_bPendingRedirection = pendingAction ;
child - > m_args = KParts : : OpenUrlArguments ( ) ;
child - > m_browserArgs = KParts : : BrowserArguments ( ) ;
// dispatch load event. We don't do that for KHTMLPart's since their internal
// load will be forwarded inside NodeImpl::dispatchWindowEvent
if ( ! qobject_cast < KHTMLPart * > ( child - > m_part ) )
QTimer : : singleShot ( 0 , child - > m_partContainerElement . data ( ) , SLOT ( slotEmitLoadEvent ( ) ) ) ;
}
checkCompleted ( ) ;
}
void KHTMLPart : : slotChildDocCreated ( )
{
// Set domain to the frameset's domain
// This must only be done when loading the frameset initially (#22039),
// not when following a link in a frame (#44162).
if ( KHTMLPart * htmlFrame = qobject_cast < KHTMLPart * > ( sender ( ) ) )
d - > propagateInitialDomainAndBaseTo ( htmlFrame ) ;
// So it only happens once
disconnect ( sender ( ) , SIGNAL ( docCreated ( ) ) , this , SLOT ( slotChildDocCreated ( ) ) ) ;
}
void KHTMLPartPrivate : : propagateInitialDomainAndBaseTo ( KHTMLPart * kid )
{
// This method is used to propagate our domain and base information for
// child frames, to provide them for about: or JavaScript: URLs
if ( m_doc & & kid - > d - > m_doc ) {
DocumentImpl * kidDoc = kid - > d - > m_doc ;
if ( kidDoc - > origin ( ) - > isEmpty ( ) ) {
kidDoc - > setOrigin ( m_doc - > origin ( ) ) ;
kidDoc - > setBaseURL ( m_doc - > baseURL ( ) ) ;
}
}
}
void KHTMLPart : : slotChildURLRequest ( const KUrl & url , const KParts : : OpenUrlArguments & args , const KParts : : BrowserArguments & browserArgs )
{
khtml : : ChildFrame * child = frame ( sender ( ) - > parent ( ) ) ;
KHTMLPart * callingHtmlPart = const_cast < KHTMLPart * > ( dynamic_cast < const KHTMLPart * > ( sender ( ) - > parent ( ) ) ) ;
// TODO: handle child target correctly! currently the script are always executed for the parent
QString urlStr = url . url ( ) ;
if ( d - > isJavaScriptURL ( urlStr ) ) {
executeScript ( DOM : : Node ( ) , d - > codeForJavaScriptURL ( urlStr ) ) ;
return ;
}
QString frameName = browserArgs . frameName . toLower ( ) ;
if ( ! frameName . isEmpty ( ) ) {
if ( frameName = = QLatin1String ( " _top " ) )
{
emit d - > m_extension - > openUrlRequest ( url , args , browserArgs ) ;
return ;
}
else if ( frameName = = QLatin1String ( " _blank " ) )
{
emit d - > m_extension - > createNewWindow ( url , args , browserArgs ) ;
return ;
}
else if ( frameName = = QLatin1String ( " _parent " ) )
{
KParts : : BrowserArguments newBrowserArgs ( browserArgs ) ;
newBrowserArgs . frameName . clear ( ) ;
emit d - > m_extension - > openUrlRequest ( url , args , newBrowserArgs ) ;
return ;
}
else if ( frameName ! = QLatin1String ( " _self " ) )
{
khtml : : ChildFrame * _frame = recursiveFrameRequest ( callingHtmlPart , url , args , browserArgs ) ;
if ( ! _frame )
{
emit d - > m_extension - > openUrlRequest ( url , args , browserArgs ) ;
return ;
}
child = _frame ;
}
}
if ( child & & child - > m_type ! = khtml : : ChildFrame : : Object ) {
// Inform someone that we are about to show something else.
child - > m_bNotify = true ;
requestObject ( child , url , args , browserArgs ) ;
} else if ( frameName = = " _self " ) // this is for embedded objects (via <object>) which want to replace the current document
{
KParts : : BrowserArguments newBrowserArgs ( browserArgs ) ;
newBrowserArgs . frameName . clear ( ) ;
emit d - > m_extension - > openUrlRequest ( url , args , newBrowserArgs ) ;
}
}
void KHTMLPart : : slotRequestFocus ( KParts : : ReadOnlyPart * )
{
emit d - > m_extension - > requestFocus ( this ) ;
}
khtml : : ChildFrame * KHTMLPart : : frame ( const QObject * obj )
{
assert ( obj - > inherits ( " KParts::ReadOnlyPart " ) ) ;
const KParts : : ReadOnlyPart * const part = static_cast < const KParts : : ReadOnlyPart * > ( obj ) ;
FrameIt it = d - > m_frames . begin ( ) ;
const FrameIt end = d - > m_frames . end ( ) ;
for ( ; it ! = end ; + + it ) {
if ( ( * it ) - > m_part . data ( ) = = part )
return * it ;
}
FrameIt oi = d - > m_objects . begin ( ) ;
const FrameIt oiEnd = d - > m_objects . end ( ) ;
for ( ; oi ! = oiEnd ; + + oi ) {
if ( ( * oi ) - > m_part . data ( ) = = part )
return * oi ;
}
return 0L ;
}
//#define DEBUG_FINDFRAME
bool KHTMLPart : : checkFrameAccess ( KHTMLPart * callingHtmlPart )
{
if ( callingHtmlPart = = this )
return true ; // trivial
if ( ! xmlDocImpl ( ) ) {
# ifdef DEBUG_FINDFRAME
kDebug ( 6050 ) < < " Empty part " < < this < < " URL = " < < url ( ) ;
# endif
return false ; // we are empty?
}
// now compare the domains
if ( callingHtmlPart & & callingHtmlPart - > xmlDocImpl ( ) & & xmlDocImpl ( ) ) {
khtml : : SecurityOrigin * actDomain = callingHtmlPart - > xmlDocImpl ( ) - > origin ( ) ;
khtml : : SecurityOrigin * destDomain = xmlDocImpl ( ) - > origin ( ) ;
if ( actDomain - > canAccess ( destDomain ) )
return true ;
}
# ifdef DEBUG_FINDFRAME
else
{
kDebug ( 6050 ) < < " Unknown part/domain " < < callingHtmlPart < < " tries to access part " < < this ;
}
# endif
return false ;
}
KHTMLPart *
KHTMLPart : : findFrameParent ( KParts : : ReadOnlyPart * callingPart , const QString & f , khtml : : ChildFrame * * childFrame )
{
return d - > findFrameParent ( callingPart , f , childFrame , false ) ;
}
KHTMLPart * KHTMLPartPrivate : : findFrameParent ( KParts : : ReadOnlyPart * callingPart ,
const QString & f , khtml : : ChildFrame * * childFrame , bool checkForNavigation )
{
# ifdef DEBUG_FINDFRAME
kDebug ( 6050 ) < < q < < " URL = " < < q - > url ( ) < < " name = " < < q - > objectName ( ) < < " findFrameParent( " < < f < < " ) " ;
# endif
// Check access
KHTMLPart * const callingHtmlPart = qobject_cast < KHTMLPart * > ( callingPart ) ;
if ( ! callingHtmlPart )
return 0 ;
if ( ! checkForNavigation & & ! q - > checkFrameAccess ( callingHtmlPart ) )
return 0 ;
if ( ! childFrame & & ! q - > parentPart ( ) & & ( q - > objectName ( ) = = f ) ) {
if ( ! checkForNavigation | | callingHtmlPart - > d - > canNavigate ( q ) )
return q ;
}
FrameIt it = m_frames . find ( f ) ;
const FrameIt end = m_frames . end ( ) ;
if ( it ! = end )
{
# ifdef DEBUG_FINDFRAME
kDebug ( 6050 ) < < " FOUND! " ;
# endif
if ( ! checkForNavigation | | callingHtmlPart - > d - > canNavigate ( ( * it ) - > m_part . data ( ) ) ) {
if ( childFrame )
* childFrame = * it ;
return q ;
}
}
it = m_frames . begin ( ) ;
for ( ; it ! = end ; + + it )
{
if ( KHTMLPart * p = qobject_cast < KHTMLPart * > ( ( * it ) - > m_part . data ( ) ) )
{
KHTMLPart * const frameParent = p - > d - > findFrameParent ( callingPart , f , childFrame , checkForNavigation ) ;
if ( frameParent )
return frameParent ;
}
}
return 0 ;
}
KHTMLPart * KHTMLPartPrivate : : top ( )
{
KHTMLPart * t = q ;
while ( t - > parentPart ( ) )
t = t - > parentPart ( ) ;
return t ;
}
bool KHTMLPartPrivate : : canNavigate ( KParts : : ReadOnlyPart * bCand )
{
if ( ! bCand ) // No part here (e.g. invalid url), reuse that frame
return true ;
KHTMLPart * b = qobject_cast < KHTMLPart * > ( bCand ) ;
if ( ! b ) // Another kind of part? Not sure what to do...
return false ;
// HTML5 gives conditions for this (a) being able to navigate b
// 1) Same domain
if ( q - > checkFrameAccess ( b ) )
return true ;
// 2) A is nested, with B its top
if ( q - > parentPart ( ) & & top ( ) = = b )
return true ;
// 3) B is 'auxilary' -- window.open with opener,
// and A can navigate B's opener
if ( b - > opener ( ) & & canNavigate ( b - > opener ( ) ) )
return true ;
// 4) B is not top-level, but an ancestor of it has same origin as A
for ( KHTMLPart * anc = b - > parentPart ( ) ; anc ; anc = anc - > parentPart ( ) ) {
if ( anc - > checkFrameAccess ( q ) )
return true ;
}
return false ;
}
KHTMLPart * KHTMLPart : : findFrame ( const QString & f )
{
khtml : : ChildFrame * childFrame ;
KHTMLPart * parentFrame = findFrameParent ( this , f , & childFrame ) ;
if ( parentFrame )
return qobject_cast < KHTMLPart * > ( childFrame - > m_part . data ( ) ) ;
return 0 ;
}
KParts : : ReadOnlyPart * KHTMLPart : : findFramePart ( const QString & f )
{
khtml : : ChildFrame * childFrame ;
return findFrameParent ( this , f , & childFrame ) ? childFrame - > m_part . data ( ) : 0L ;
}
KParts : : ReadOnlyPart * KHTMLPart : : currentFrame ( ) const
{
KParts : : ReadOnlyPart * part = ( KParts : : ReadOnlyPart * ) ( this ) ;
// Find active part in our frame manager, in case we are a frameset
// and keep doing that (in case of nested framesets).
// Just realized we could also do this recursively, calling part->currentFrame()...
while ( part & & part - > inherits ( " KHTMLPart " ) & &
static_cast < KHTMLPart * > ( part ) - > d - > m_frames . count ( ) > 0 ) {
KHTMLPart * frameset = static_cast < KHTMLPart * > ( part ) ;
part = static_cast < KParts : : ReadOnlyPart * > ( frameset - > partManager ( ) - > activePart ( ) ) ;
if ( ! part ) return frameset ;
}
return part ;
}
bool KHTMLPart : : frameExists ( const QString & frameName )
{
FrameIt it = d - > m_frames . find ( frameName ) ;
if ( it = = d - > m_frames . end ( ) )
return false ;
// WABA: We only return true if the child actually has a frame
// set. Otherwise we might find our preloaded-selve.
// This happens when we restore the frameset.
return ( ! ( * it ) - > m_partContainerElement . isNull ( ) ) ;
}
void KHTMLPartPrivate : : renameFrameForContainer ( DOM : : HTMLPartContainerElementImpl * cont ,
const QString & newName )
{
for ( int i = 0 ; i < m_frames . size ( ) ; + + i ) {
khtml : : ChildFrame * f = m_frames [ i ] ;
if ( f - > m_partContainerElement . data ( ) = = cont )
f - > m_name = newName ;
}
}
KJSProxy * KHTMLPart : : framejScript ( KParts : : ReadOnlyPart * framePart )
{
KHTMLPart * const kp = qobject_cast < KHTMLPart * > ( framePart ) ;
if ( kp )
return kp - > jScript ( ) ;
FrameIt it = d - > m_frames . begin ( ) ;
const FrameIt itEnd = d - > m_frames . end ( ) ;
for ( ; it ! = itEnd ; + + it ) {
khtml : : ChildFrame * frame = * it ;
if ( framePart = = frame - > m_part . data ( ) ) {
if ( ! frame - > m_jscript )
frame - > m_jscript = new KJSProxy ( frame ) ;
return frame - > m_jscript ;
}
}
return 0L ;
}
KHTMLPart * KHTMLPart : : parentPart ( )
{
return qobject_cast < KHTMLPart * > ( parent ( ) ) ;
}
khtml : : ChildFrame * KHTMLPart : : recursiveFrameRequest ( KHTMLPart * callingHtmlPart , const KUrl & url ,
const KParts : : OpenUrlArguments & args ,
const KParts : : BrowserArguments & browserArgs , bool callParent )
{
# ifdef DEBUG_FINDFRAME
kDebug ( 6050 ) < < this < < " frame = " < < browserArgs . frameName < < " url = " < < url ;
# endif
khtml : : ChildFrame * childFrame ;
KHTMLPart * childPart = findFrameParent ( callingHtmlPart , browserArgs . frameName , & childFrame ) ;
if ( childPart )
{
if ( childPart = = this )
return childFrame ;
childPart - > requestObject ( childFrame , url , args , browserArgs ) ;
return 0 ;
}
if ( parentPart ( ) & & callParent )
{
khtml : : ChildFrame * res = parentPart ( ) - > recursiveFrameRequest ( callingHtmlPart , url , args , browserArgs , callParent ) ;
if ( res )
parentPart ( ) - > requestObject ( res , url , args , browserArgs ) ;
}
return 0L ;
}
# ifdef DEBUG_SAVESTATE
static int s_saveStateIndentLevel = 0 ;
# endif
void KHTMLPart : : saveState ( QDataStream & stream )
{
# ifdef DEBUG_SAVESTATE
QString indent = QString ( ) . leftJustified ( s_saveStateIndentLevel * 4 , ' ' ) ;
const int indentLevel = s_saveStateIndentLevel + + ;
kDebug ( 6050 ) < < indent < < " saveState this= " < < this < < " ' " < < objectName ( ) < < " ' saving URL " < < url ( ) . url ( ) ;
# endif
stream < < url ( ) < < ( qint32 ) d - > m_view - > contentsX ( ) < < ( qint32 ) d - > m_view - > contentsY ( )
< < ( qint32 ) d - > m_view - > contentsWidth ( ) < < ( qint32 ) d - > m_view - > contentsHeight ( ) < < ( qint32 ) d - > m_view - > marginWidth ( ) < < ( qint32 ) d - > m_view - > marginHeight ( ) ;
// save link cursor position
int focusNodeNumber ;
if ( ! d - > m_focusNodeRestored )
focusNodeNumber = d - > m_focusNodeNumber ;
else if ( d - > m_doc & & d - > m_doc - > focusNode ( ) )
focusNodeNumber = d - > m_doc - > nodeAbsIndex ( d - > m_doc - > focusNode ( ) ) ;
else
focusNodeNumber = - 1 ;
stream < < focusNodeNumber ;
// Save the doc's cache id.
stream < < d - > m_cacheId ;
// Save the state of the document (Most notably the state of any forms)
QStringList docState ;
if ( d - > m_doc )
{
docState = d - > m_doc - > docState ( ) ;
}
stream < < d - > m_encoding < < d - > m_sheetUsed < < docState ;
stream < < d - > m_zoomFactor ;
stream < < d - > m_fontScaleFactor ;
stream < < d - > m_httpHeaders ;
stream < < d - > m_pageServices ;
stream < < d - > m_pageReferrer ;
// Save ssl data
stream < < d - > m_ssl_in_use
< < d - > m_ssl_peer_chain
< < d - > m_ssl_peer_ip
< < d - > m_ssl_cipher
< < d - > m_ssl_protocol_version
< < d - > m_ssl_cipher_used_bits
< < d - > m_ssl_cipher_bits
< < d - > m_ssl_cert_errors
< < d - > m_ssl_parent_ip
< < d - > m_ssl_parent_cert ;
QStringList frameNameLst , frameServiceTypeLst , frameServiceNameLst ;
KUrl : : List frameURLLst ;
QList < QByteArray > frameStateBufferLst ;
QList < int > frameTypeLst ;
ConstFrameIt it = d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it )
{
if ( ! ( * it ) - > m_part )
continue ;
frameNameLst < < ( * it ) - > m_name ;
frameServiceTypeLst < < ( * it ) - > m_serviceType ;
frameServiceNameLst < < ( * it ) - > m_serviceName ;
frameURLLst < < ( * it ) - > m_part . data ( ) - > url ( ) ;
QByteArray state ;
QDataStream frameStream ( & state , QIODevice : : WriteOnly ) ;
if ( ( * it ) - > m_extension )
( * it ) - > m_extension . data ( ) - > saveState ( frameStream ) ;
frameStateBufferLst < < state ;
frameTypeLst < < int ( ( * it ) - > m_type ) ;
}
// Save frame data
stream < < ( quint32 ) frameNameLst . count ( ) ;
stream < < frameNameLst < < frameServiceTypeLst < < frameServiceNameLst < < frameURLLst < < frameStateBufferLst < < frameTypeLst ;
# ifdef DEBUG_SAVESTATE
s_saveStateIndentLevel = indentLevel ;
# endif
}
void KHTMLPart : : restoreState ( QDataStream & stream )
{
KUrl u ;
qint32 xOffset , yOffset , wContents , hContents , mWidth , mHeight ;
quint32 frameCount ;
QStringList frameNames , frameServiceTypes , docState , frameServiceNames ;
QList < int > frameTypes ;
KUrl : : List frameURLs ;
QList < QByteArray > frameStateBuffers ;
QList < int > fSizes ;
QString encoding , sheetUsed ;
long old_cacheId = d - > m_cacheId ;
stream > > u > > xOffset > > yOffset > > wContents > > hContents > > mWidth > > mHeight ;
d - > m_view - > setMarginWidth ( mWidth ) ;
d - > m_view - > setMarginHeight ( mHeight ) ;
// restore link cursor position
// nth node is active. value is set in checkCompleted()
stream > > d - > m_focusNodeNumber ;
d - > m_focusNodeRestored = false ;
stream > > d - > m_cacheId ;
stream > > encoding > > sheetUsed > > docState ;
d - > m_encoding = encoding ;
d - > m_sheetUsed = sheetUsed ;
int zoomFactor ;
stream > > zoomFactor ;
setZoomFactor ( zoomFactor ) ;
int fontScaleFactor ;
stream > > fontScaleFactor ;
setFontScaleFactor ( fontScaleFactor ) ;
stream > > d - > m_httpHeaders ;
stream > > d - > m_pageServices ;
stream > > d - > m_pageReferrer ;
// Restore ssl data
stream > > d - > m_ssl_in_use
> > d - > m_ssl_peer_chain
> > d - > m_ssl_peer_ip
> > d - > m_ssl_cipher
> > d - > m_ssl_protocol_version
> > d - > m_ssl_cipher_used_bits
> > d - > m_ssl_cipher_bits
> > d - > m_ssl_cert_errors
> > d - > m_ssl_parent_ip
> > d - > m_ssl_parent_cert ;
setPageSecurity ( d - > m_ssl_in_use ? Encrypted : NotCrypted ) ;
stream > > frameCount > > frameNames > > frameServiceTypes > > frameServiceNames
> > frameURLs > > frameStateBuffers > > frameTypes ;
d - > m_bComplete = false ;
d - > m_bLoadEventEmitted = false ;
// kDebug( 6050 ) << "docState.count() = " << docState.count();
// kDebug( 6050 ) << "m_url " << url().url() << " <-> " << u.url();
// kDebug( 6050 ) << "m_frames.count() " << d->m_frames.count() << " <-> " << frameCount;
if ( d - > m_cacheId = = old_cacheId & & signed ( frameCount ) = = d - > m_frames . count ( ) )
{
// Partial restore
d - > m_redirectionTimer . stop ( ) ;
FrameIt fIt = d - > m_frames . begin ( ) ;
const FrameIt fEnd = d - > m_frames . end ( ) ;
for ( ; fIt ! = fEnd ; + + fIt )
( * fIt ) - > m_bCompleted = false ;
fIt = d - > m_frames . begin ( ) ;
QStringList : : ConstIterator fNameIt = frameNames . constBegin ( ) ;
QStringList : : ConstIterator fServiceTypeIt = frameServiceTypes . constBegin ( ) ;
QStringList : : ConstIterator fServiceNameIt = frameServiceNames . constBegin ( ) ;
KUrl : : List : : ConstIterator fURLIt = frameURLs . constBegin ( ) ;
QList < QByteArray > : : ConstIterator fBufferIt = frameStateBuffers . constBegin ( ) ;
QList < int > : : ConstIterator fFrameTypeIt = frameTypes . constBegin ( ) ;
for ( ; fIt ! = fEnd ; + + fIt , + + fNameIt , + + fServiceTypeIt , + + fServiceNameIt , + + fURLIt , + + fBufferIt , + + fFrameTypeIt )
{
khtml : : ChildFrame * const child = * fIt ;
// kDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt;
if ( child - > m_name ! = * fNameIt | | child - > m_serviceType ! = * fServiceTypeIt )
{
child - > m_bPreloaded = true ;
child - > m_name = * fNameIt ;
child - > m_serviceName = * fServiceNameIt ;
child - > m_type = static_cast < khtml : : ChildFrame : : Type > ( * fFrameTypeIt ) ;
processObjectRequest ( child , * fURLIt , * fServiceTypeIt ) ;
}
if ( child - > m_part )
{
child - > m_bCompleted = false ;
if ( child - > m_extension & & ! ( * fBufferIt ) . isEmpty ( ) )
{
QDataStream frameStream ( * fBufferIt ) ;
child - > m_extension . data ( ) - > restoreState ( frameStream ) ;
}
else
child - > m_part . data ( ) - > openUrl ( * fURLIt ) ;
}
}
KParts : : OpenUrlArguments args ( arguments ( ) ) ;
args . setXOffset ( xOffset ) ;
args . setYOffset ( yOffset ) ;
setArguments ( args ) ;
KParts : : BrowserArguments browserArgs ( d - > m_extension - > browserArguments ( ) ) ;
browserArgs . docState = docState ;
d - > m_extension - > setBrowserArguments ( browserArgs ) ;
d - > m_view - > resizeContents ( wContents , hContents ) ;
d - > m_view - > setContentsPos ( xOffset , yOffset ) ;
setUrl ( u ) ;
}
else
{
// Full restore.
closeUrl ( ) ;
// We must force a clear because we want to be sure to delete all
// frames.
d - > m_bCleared = false ;
clear ( ) ;
d - > m_encoding = encoding ;
d - > m_sheetUsed = sheetUsed ;
QStringList : : ConstIterator fNameIt = frameNames . constBegin ( ) ;
const QStringList : : ConstIterator fNameEnd = frameNames . constEnd ( ) ;
QStringList : : ConstIterator fServiceTypeIt = frameServiceTypes . constBegin ( ) ;
QStringList : : ConstIterator fServiceNameIt = frameServiceNames . constBegin ( ) ;
KUrl : : List : : ConstIterator fURLIt = frameURLs . constBegin ( ) ;
QList < QByteArray > : : ConstIterator fBufferIt = frameStateBuffers . constBegin ( ) ;
QList < int > : : ConstIterator fFrameTypeIt = frameTypes . constBegin ( ) ;
for ( ; fNameIt ! = fNameEnd ; + + fNameIt , + + fServiceTypeIt , + + fServiceNameIt , + + fURLIt , + + fBufferIt , + + fFrameTypeIt )
{
khtml : : ChildFrame * const newChild = new khtml : : ChildFrame ;
newChild - > m_bPreloaded = true ;
newChild - > m_name = * fNameIt ;
newChild - > m_serviceName = * fServiceNameIt ;
newChild - > m_type = static_cast < khtml : : ChildFrame : : Type > ( * fFrameTypeIt ) ;
// kDebug( 6050 ) << *fNameIt << " ---- " << *fServiceTypeIt;
const FrameIt childFrame = d - > m_frames . insert ( d - > m_frames . end ( ) , newChild ) ;
processObjectRequest ( * childFrame , * fURLIt , * fServiceTypeIt ) ;
( * childFrame ) - > m_bPreloaded = true ;
if ( ( * childFrame ) - > m_part )
{
if ( ( * childFrame ) - > m_extension & & ! ( * fBufferIt ) . isEmpty ( ) )
{
QDataStream frameStream ( * fBufferIt ) ;
( * childFrame ) - > m_extension . data ( ) - > restoreState ( frameStream ) ;
}
else
( * childFrame ) - > m_part . data ( ) - > openUrl ( * fURLIt ) ;
}
}
KParts : : OpenUrlArguments args ( arguments ( ) ) ;
args . setXOffset ( xOffset ) ;
args . setYOffset ( yOffset ) ;
setArguments ( args ) ;
KParts : : BrowserArguments browserArgs ( d - > m_extension - > browserArguments ( ) ) ;
browserArgs . docState = docState ;
d - > m_extension - > setBrowserArguments ( browserArgs ) ;
if ( ! KHTMLPageCache : : self ( ) - > isComplete ( d - > m_cacheId ) )
{
d - > m_restored = true ;
openUrl ( u ) ;
d - > m_restored = false ;
}
else
{
restoreURL ( u ) ;
}
}
}
void KHTMLPart : : show ( )
{
if ( widget ( ) )
widget ( ) - > show ( ) ;
}
void KHTMLPart : : hide ( )
{
if ( widget ( ) )
widget ( ) - > hide ( ) ;
}
DOM : : Node KHTMLPart : : nodeUnderMouse ( ) const
{
return d - > m_view - > nodeUnderMouse ( ) ;
}
DOM : : Node KHTMLPart : : nonSharedNodeUnderMouse ( ) const
{
return d - > m_view - > nonSharedNodeUnderMouse ( ) ;
}
void KHTMLPart : : emitSelectionChanged ( )
{
// Don't emit signals about our selection if this is a frameset;
// the active frame has the selection (#187403)
if ( ! d - > m_activeFrame )
{
emit d - > m_extension - > enableAction ( " copy " , hasSelection ( ) ) ;
emit d - > m_extension - > selectionInfo ( selectedText ( ) ) ;
emit selectionChanged ( ) ;
}
}
int KHTMLPart : : zoomFactor ( ) const
{
return d - > m_zoomFactor ;
}
// ### make the list configurable ?
static const int zoomSizes [ ] = { 20 , 40 , 60 , 80 , 90 , 95 , 100 , 105 , 110 , 120 , 140 , 160 , 180 , 200 , 250 , 300 } ;
static const int zoomSizeCount = ( sizeof ( zoomSizes ) / sizeof ( int ) ) ;
static const int minZoom = 20 ;
static const int maxZoom = 300 ;
// My idea of useful stepping ;-) (LS)
extern const int KDE_NO_EXPORT fastZoomSizes [ ] = { 20 , 50 , 75 , 90 , 100 , 120 , 150 , 200 , 300 } ;
extern const int KDE_NO_EXPORT fastZoomSizeCount = sizeof fastZoomSizes / sizeof fastZoomSizes [ 0 ] ;
void KHTMLPart : : slotIncZoom ( )
{
zoomIn ( zoomSizes , zoomSizeCount ) ;
}
void KHTMLPart : : slotDecZoom ( )
{
zoomOut ( zoomSizes , zoomSizeCount ) ;
}
void KHTMLPart : : slotIncZoomFast ( )
{
zoomIn ( fastZoomSizes , fastZoomSizeCount ) ;
}
void KHTMLPart : : slotDecZoomFast ( )
{
zoomOut ( fastZoomSizes , fastZoomSizeCount ) ;
}
void KHTMLPart : : zoomIn ( const int stepping [ ] , int count )
{
int zoomFactor = d - > m_zoomFactor ;
if ( zoomFactor < maxZoom ) {
// find the entry nearest to the given zoomsizes
for ( int i = 0 ; i < count ; + + i )
if ( stepping [ i ] > zoomFactor ) {
zoomFactor = stepping [ i ] ;
break ;
}
setZoomFactor ( zoomFactor ) ;
}
}
void KHTMLPart : : zoomOut ( const int stepping [ ] , int count )
{
int zoomFactor = d - > m_zoomFactor ;
if ( zoomFactor > minZoom ) {
// find the entry nearest to the given zoomsizes
for ( int i = count - 1 ; i > = 0 ; - - i )
if ( stepping [ i ] < zoomFactor ) {
zoomFactor = stepping [ i ] ;
break ;
}
setZoomFactor ( zoomFactor ) ;
}
}
void KHTMLPart : : setZoomFactor ( int percent )
{
// ### zooming under 100% is majorly botched,
// so disable that for now.
if ( percent < 100 ) percent = 100 ;
// ### if (percent < minZoom) percent = minZoom;
if ( percent > maxZoom ) percent = maxZoom ;
if ( d - > m_zoomFactor = = percent ) return ;
d - > m_zoomFactor = percent ;
updateZoomFactor ( ) ;
}
void KHTMLPart : : updateZoomFactor ( )
{
if ( d - > m_view ) {
QApplication : : setOverrideCursor ( Qt : : WaitCursor ) ;
d - > m_view - > setZoomLevel ( d - > m_zoomFactor ) ;
QApplication : : restoreOverrideCursor ( ) ;
}
ConstFrameIt it = d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it ) {
if ( KHTMLPart * p = qobject_cast < KHTMLPart * > ( ( * it ) - > m_part . data ( ) ) )
p - > setZoomFactor ( d - > m_zoomFactor ) ;
}
if ( d - > m_guiProfile = = BrowserViewGUI ) {
d - > m_paDecZoomFactor - > setEnabled ( d - > m_zoomFactor > minZoom ) ;
d - > m_paIncZoomFactor - > setEnabled ( d - > m_zoomFactor < maxZoom ) ;
}
}
void KHTMLPart : : slotIncFontSize ( )
{
incFontSize ( zoomSizes , zoomSizeCount ) ;
}
void KHTMLPart : : slotDecFontSize ( )
{
decFontSize ( zoomSizes , zoomSizeCount ) ;
}
void KHTMLPart : : slotIncFontSizeFast ( )
{
incFontSize ( fastZoomSizes , fastZoomSizeCount ) ;
}
void KHTMLPart : : slotDecFontSizeFast ( )
{
decFontSize ( fastZoomSizes , fastZoomSizeCount ) ;
}
void KHTMLPart : : incFontSize ( const int stepping [ ] , int count )
{
int zoomFactor = d - > m_fontScaleFactor ;
if ( zoomFactor < maxZoom ) {
// find the entry nearest to the given zoomsizes
for ( int i = 0 ; i < count ; + + i )
if ( stepping [ i ] > zoomFactor ) {
zoomFactor = stepping [ i ] ;
break ;
}
setFontScaleFactor ( zoomFactor ) ;
}
}
void KHTMLPart : : decFontSize ( const int stepping [ ] , int count )
{
int zoomFactor = d - > m_fontScaleFactor ;
if ( zoomFactor > minZoom ) {
// find the entry nearest to the given zoomsizes
for ( int i = count - 1 ; i > = 0 ; - - i )
if ( stepping [ i ] < zoomFactor ) {
zoomFactor = stepping [ i ] ;
break ;
}
setFontScaleFactor ( zoomFactor ) ;
}
}
void KHTMLPart : : setFontScaleFactor ( int percent )
{
if ( percent < minZoom ) percent = minZoom ;
if ( percent > maxZoom ) percent = maxZoom ;
if ( d - > m_fontScaleFactor = = percent ) return ;
d - > m_fontScaleFactor = percent ;
if ( d - > m_view & & d - > m_doc ) {
QApplication : : setOverrideCursor ( Qt : : WaitCursor ) ;
if ( d - > m_doc - > styleSelector ( ) )
d - > m_doc - > styleSelector ( ) - > computeFontSizes ( d - > m_doc - > logicalDpiY ( ) , d - > m_fontScaleFactor ) ;
d - > m_doc - > recalcStyle ( NodeImpl : : Force ) ;
QApplication : : restoreOverrideCursor ( ) ;
}
ConstFrameIt it = d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it ) {
if ( KHTMLPart * p = qobject_cast < KHTMLPart * > ( ( * it ) - > m_part . data ( ) ) )
p - > setFontScaleFactor ( d - > m_fontScaleFactor ) ;
}
}
int KHTMLPart : : fontScaleFactor ( ) const
{
return d - > m_fontScaleFactor ;
}
void KHTMLPart : : slotZoomView ( int delta )
{
if ( delta < 0 )
slotIncZoom ( ) ;
else
slotDecZoom ( ) ;
}
void KHTMLPart : : setStatusBarText ( const QString & text , StatusBarPriority p )
{
if ( ! d - > m_statusMessagesEnabled )
return ;
d - > m_statusBarText [ p ] = text ;
// shift handling ?
QString tobe = d - > m_statusBarText [ BarHoverText ] ;
if ( tobe . isEmpty ( ) )
tobe = d - > m_statusBarText [ BarOverrideText ] ;
if ( tobe . isEmpty ( ) ) {
tobe = d - > m_statusBarText [ BarDefaultText ] ;
if ( ! tobe . isEmpty ( ) & & d - > m_jobspeed )
tobe + = " " ;
if ( d - > m_jobspeed )
tobe + = i18n ( " (%1/s) " , KIO : : convertSize ( d - > m_jobspeed ) ) ;
}
tobe = " <qt> " + tobe ;
emit ReadOnlyPart : : setStatusBarText ( tobe ) ;
}
void KHTMLPart : : setJSStatusBarText ( const QString & text )
{
setStatusBarText ( text , BarOverrideText ) ;
}
void KHTMLPart : : setJSDefaultStatusBarText ( const QString & text )
{
setStatusBarText ( text , BarDefaultText ) ;
}
QString KHTMLPart : : jsStatusBarText ( ) const
{
return d - > m_statusBarText [ BarOverrideText ] ;
}
QString KHTMLPart : : jsDefaultStatusBarText ( ) const
{
return d - > m_statusBarText [ BarDefaultText ] ;
}
QString KHTMLPart : : referrer ( ) const
{
return d - > m_referrer ;
}
QString KHTMLPart : : pageReferrer ( ) const
{
KUrl referrerURL = KUrl ( d - > m_pageReferrer ) ;
if ( referrerURL . isValid ( ) )
{
QString protocol = referrerURL . protocol ( ) ;
if ( ( protocol = = " http " ) | |
( ( protocol = = " https " ) & & ( url ( ) . protocol ( ) = = " https " ) ) )
{
referrerURL . setRef ( QString ( ) ) ;
referrerURL . setUser ( QString ( ) ) ;
referrerURL . setPass ( QString ( ) ) ;
return referrerURL . url ( ) ;
}
}
return QString ( ) ;
}
QString KHTMLPart : : lastModified ( ) const
{
if ( d - > m_lastModified . isEmpty ( ) & & url ( ) . isLocalFile ( ) ) {
// Local file: set last-modified from the file's mtime.
// Done on demand to save time when this isn't needed - but can lead
// to slightly wrong results if updating the file on disk w/o reloading.
QDateTime lastModif = QFileInfo ( url ( ) . toLocalFile ( ) ) . lastModified ( ) ;
d - > m_lastModified = lastModif . toString ( Qt : : LocalDate ) ;
}
//kDebug(6050) << d->m_lastModified;
return d - > m_lastModified ;
}
void KHTMLPart : : slotLoadImages ( )
{
if ( d - > m_doc )
d - > m_doc - > docLoader ( ) - > setAutoloadImages ( ! d - > m_doc - > docLoader ( ) - > autoloadImages ( ) ) ;
ConstFrameIt it = d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it ) {
if ( KHTMLPart * p = qobject_cast < KHTMLPart * > ( ( * it ) - > m_part . data ( ) ) )
p - > slotLoadImages ( ) ;
}
}
void KHTMLPart : : reparseConfiguration ( )
{
KHTMLSettings * settings = KHTMLGlobal : : defaultHTMLSettings ( ) ;
settings - > init ( ) ;
setAutoloadImages ( settings - > autoLoadImages ( ) ) ;
if ( d - > m_doc )
d - > m_doc - > docLoader ( ) - > setShowAnimations ( settings - > showAnimations ( ) ) ;
d - > m_bOpenMiddleClick = settings - > isOpenMiddleClickEnabled ( ) ;
d - > m_bJScriptEnabled = settings - > isJavaScriptEnabled ( url ( ) . host ( ) ) ;
setDebugScript ( settings - > isJavaScriptDebugEnabled ( ) ) ;
d - > m_bJavaEnabled = settings - > isJavaEnabled ( url ( ) . host ( ) ) ;
d - > m_bPluginsEnabled = settings - > isPluginsEnabled ( url ( ) . host ( ) ) ;
d - > m_metaRefreshEnabled = settings - > isAutoDelayedActionsEnabled ( ) ;
delete d - > m_settings ;
d - > m_settings = new KHTMLSettings ( * KHTMLGlobal : : defaultHTMLSettings ( ) ) ;
QApplication : : setOverrideCursor ( Qt : : WaitCursor ) ;
khtml : : CSSStyleSelector : : reparseConfiguration ( ) ;
if ( d - > m_doc ) d - > m_doc - > updateStyleSelector ( ) ;
QApplication : : restoreOverrideCursor ( ) ;
if ( d - > m_view ) {
KHTMLSettings : : KSmoothScrollingMode ssm = d - > m_settings - > smoothScrolling ( ) ;
if ( ssm = = KHTMLSettings : : KSmoothScrollingDisabled )
d - > m_view - > setSmoothScrollingModeDefault ( KHTMLView : : SSMDisabled ) ;
else if ( ssm = = KHTMLSettings : : KSmoothScrollingWhenEfficient )
d - > m_view - > setSmoothScrollingModeDefault ( KHTMLView : : SSMWhenEfficient ) ;
else
d - > m_view - > setSmoothScrollingModeDefault ( KHTMLView : : SSMEnabled ) ;
}
if ( KHTMLGlobal : : defaultHTMLSettings ( ) - > isAdFilterEnabled ( ) )
runAdFilter ( ) ;
}
QStringList KHTMLPart : : frameNames ( ) const
{
QStringList res ;
ConstFrameIt it = d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it )
if ( ! ( * it ) - > m_bPreloaded & & ( * it ) - > m_part )
res + = ( * it ) - > m_name ;
return res ;
}
QList < KParts : : ReadOnlyPart * > KHTMLPart : : frames ( ) const
{
QList < KParts : : ReadOnlyPart * > res ;
ConstFrameIt it = d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it )
if ( ! ( * it ) - > m_bPreloaded & & ( * it ) - > m_part ) // ### TODO: make sure that we always create an empty
// KHTMLPart for frames so this never happens.
res . append ( ( * it ) - > m_part . data ( ) ) ;
return res ;
}
bool KHTMLPart : : openUrlInFrame ( const KUrl & url , const KParts : : OpenUrlArguments & args , const KParts : : BrowserArguments & browserArgs )
{
kDebug ( 6031 ) < < this < < url ;
FrameIt it = d - > m_frames . find ( browserArgs . frameName ) ;
if ( it = = d - > m_frames . end ( ) )
return false ;
// Inform someone that we are about to show something else.
if ( ! browserArgs . lockHistory ( ) )
emit d - > m_extension - > openUrlNotify ( ) ;
requestObject ( * it , url , args , browserArgs ) ;
return true ;
}
void KHTMLPart : : setDNDEnabled ( bool b )
{
d - > m_bDnd = b ;
}
bool KHTMLPart : : dndEnabled ( ) const
{
return d - > m_bDnd ;
}
void KHTMLPart : : customEvent ( QEvent * event )
{
if ( khtml : : MousePressEvent : : test ( event ) )
{
khtmlMousePressEvent ( static_cast < khtml : : MousePressEvent * > ( event ) ) ;
return ;
}
if ( khtml : : MouseDoubleClickEvent : : test ( event ) )
{
khtmlMouseDoubleClickEvent ( static_cast < khtml : : MouseDoubleClickEvent * > ( event ) ) ;
return ;
}
if ( khtml : : MouseMoveEvent : : test ( event ) )
{
khtmlMouseMoveEvent ( static_cast < khtml : : MouseMoveEvent * > ( event ) ) ;
return ;
}
if ( khtml : : MouseReleaseEvent : : test ( event ) )
{
khtmlMouseReleaseEvent ( static_cast < khtml : : MouseReleaseEvent * > ( event ) ) ;
return ;
}
if ( khtml : : DrawContentsEvent : : test ( event ) )
{
khtmlDrawContentsEvent ( static_cast < khtml : : DrawContentsEvent * > ( event ) ) ;
return ;
}
KParts : : ReadOnlyPart : : customEvent ( event ) ;
}
bool KHTMLPart : : isPointInsideSelection ( int x , int y )
{
// Treat a collapsed selection like no selection.
if ( d - > editor_context . m_selection . state ( ) = = Selection : : CARET )
return false ;
if ( ! xmlDocImpl ( ) - > renderer ( ) )
return false ;
khtml : : RenderObject : : NodeInfo nodeInfo ( true , true ) ;
xmlDocImpl ( ) - > renderer ( ) - > layer ( ) - > nodeAtPoint ( nodeInfo , x , y ) ;
NodeImpl * innerNode = nodeInfo . innerNode ( ) ;
if ( ! innerNode | | ! innerNode - > renderer ( ) )
return false ;
return innerNode - > isPointInsideSelection ( x , y , d - > editor_context . m_selection ) ;
}
/** returns the position of the first inline text box of the line at
* coordinate y in renderNode
*
* This is a helper function for line - by - line text selection .
*/
static bool firstRunAt ( khtml : : RenderObject * renderNode , int y , NodeImpl * & startNode , long & startOffset )
{
for ( khtml : : RenderObject * n = renderNode ; n ; n = n - > nextSibling ( ) ) {
if ( n - > isText ( ) ) {
khtml : : RenderText * const textRenderer = static_cast < khtml : : RenderText * > ( n ) ;
for ( khtml : : InlineTextBox * box = textRenderer - > firstTextBox ( ) ; box ; box = box - > nextTextBox ( ) ) {
if ( box - > m_y = = y & & textRenderer - > element ( ) ) {
startNode = textRenderer - > element ( ) ;
startOffset = box - > m_start ;
return true ;
}
}
}
if ( firstRunAt ( n - > firstChild ( ) , y , startNode , startOffset ) ) {
return true ;
}
}
return false ;
}
/** returns the position of the last inline text box of the line at
* coordinate y in renderNode
*
* This is a helper function for line - by - line text selection .
*/
static bool lastRunAt ( khtml : : RenderObject * renderNode , int y , NodeImpl * & endNode , long & endOffset )
{
khtml : : RenderObject * n = renderNode ;
if ( ! n ) {
return false ;
}
khtml : : RenderObject * next ;
while ( ( next = n - > nextSibling ( ) ) ) {
n = next ;
}
while ( 1 ) {
if ( lastRunAt ( n - > firstChild ( ) , y , endNode , endOffset ) ) {
return true ;
}
if ( n - > isText ( ) ) {
khtml : : RenderText * const textRenderer = static_cast < khtml : : RenderText * > ( n ) ;
for ( khtml : : InlineTextBox * box = textRenderer - > firstTextBox ( ) ; box ; box = box - > nextTextBox ( ) ) {
if ( box - > m_y = = y & & textRenderer - > element ( ) ) {
endNode = textRenderer - > element ( ) ;
endOffset = box - > m_start + box - > m_len ;
return true ;
}
}
}
if ( n = = renderNode ) {
return false ;
}
n = n - > previousSibling ( ) ;
}
}
void KHTMLPart : : handleMousePressEventDoubleClick ( khtml : : MouseDoubleClickEvent * event )
{
QMouseEvent * mouse = event - > qmouseEvent ( ) ;
DOM : : Node innerNode = event - > innerNode ( ) ;
Selection selection ;
if ( mouse - > button ( ) = = Qt : : LeftButton & & ! innerNode . isNull ( ) & & innerNode . handle ( ) - > renderer ( ) & &
innerNode . handle ( ) - > renderer ( ) - > shouldSelect ( ) ) {
Position pos ( innerNode . handle ( ) - > positionForCoordinates ( event - > x ( ) , event - > y ( ) ) . position ( ) ) ;
if ( pos . node ( ) & & ( pos . node ( ) - > nodeType ( ) = = Node : : TEXT_NODE | | pos . node ( ) - > nodeType ( ) = = Node : : CDATA_SECTION_NODE ) ) {
selection . moveTo ( pos ) ;
selection . expandUsingGranularity ( Selection : : WORD ) ;
}
}
if ( selection . state ( ) ! = Selection : : CARET ) {
d - > editor_context . beginSelectingText ( Selection : : WORD ) ;
}
setCaret ( selection ) ;
startAutoScroll ( ) ;
}
void KHTMLPart : : handleMousePressEventTripleClick ( khtml : : MouseDoubleClickEvent * event )
{
QMouseEvent * mouse = event - > qmouseEvent ( ) ;
DOM : : Node innerNode = event - > innerNode ( ) ;
Selection selection ;
if ( mouse - > button ( ) = = Qt : : LeftButton & & ! innerNode . isNull ( ) & & innerNode . handle ( ) - > renderer ( ) & &
innerNode . handle ( ) - > renderer ( ) - > shouldSelect ( ) ) {
Position pos ( innerNode . handle ( ) - > positionForCoordinates ( event - > x ( ) , event - > y ( ) ) . position ( ) ) ;
if ( pos . node ( ) & & ( pos . node ( ) - > nodeType ( ) = = Node : : TEXT_NODE | | pos . node ( ) - > nodeType ( ) = = Node : : CDATA_SECTION_NODE ) ) {
selection . moveTo ( pos ) ;
selection . expandUsingGranularity ( Selection : : LINE ) ;
}
}
if ( selection . state ( ) ! = Selection : : CARET ) {
d - > editor_context . beginSelectingText ( Selection : : LINE ) ;
}
setCaret ( selection ) ;
startAutoScroll ( ) ;
}
void KHTMLPart : : handleMousePressEventSingleClick ( khtml : : MousePressEvent * event )
{
QMouseEvent * mouse = event - > qmouseEvent ( ) ;
DOM : : Node innerNode = event - > innerNode ( ) ;
if ( mouse - > button ( ) = = Qt : : LeftButton ) {
Selection sel ;
if ( ! innerNode . isNull ( ) & & innerNode . handle ( ) - > renderer ( ) & &
innerNode . handle ( ) - > renderer ( ) - > shouldSelect ( ) ) {
bool extendSelection = mouse - > modifiers ( ) & Qt : : ShiftModifier ;
// Don't restart the selection when the mouse is pressed on an
// existing selection so we can allow for text dragging.
if ( ! extendSelection & & isPointInsideSelection ( event - > x ( ) , event - > y ( ) ) ) {
return ;
}
Position pos ( innerNode . handle ( ) - > positionForCoordinates ( event - > x ( ) , event - > y ( ) ) . position ( ) ) ;
if ( pos . isEmpty ( ) )
pos = Position ( innerNode . handle ( ) , innerNode . handle ( ) - > caretMinOffset ( ) ) ;
kDebug ( 6050 ) < < event - > x ( ) < < event - > y ( ) < < pos < < endl ;
sel = caret ( ) ;
if ( extendSelection & & sel . notEmpty ( ) ) {
sel . clearModifyBias ( ) ;
sel . setExtent ( pos ) ;
if ( d - > editor_context . m_selectionGranularity ! = Selection : : CHARACTER ) {
sel . expandUsingGranularity ( d - > editor_context . m_selectionGranularity ) ;
}
d - > editor_context . m_beganSelectingText = true ;
} else {
sel = pos ;
d - > editor_context . m_selectionGranularity = Selection : : CHARACTER ;
}
}
setCaret ( sel ) ;
startAutoScroll ( ) ;
}
}
void KHTMLPart : : khtmlMousePressEvent ( khtml : : MousePressEvent * event )
{
DOM : : DOMString url = event - > url ( ) ;
QMouseEvent * _mouse = event - > qmouseEvent ( ) ;
DOM : : Node innerNode = event - > innerNode ( ) ;
d - > m_mousePressNode = innerNode ;
d - > m_dragStartPos = QPoint ( event - > x ( ) , event - > y ( ) ) ;
if ( ! event - > url ( ) . isNull ( ) ) {
d - > m_strSelectedURL = event - > url ( ) . string ( ) ;
d - > m_strSelectedURLTarget = event - > target ( ) . string ( ) ;
}
else {
d - > m_strSelectedURL . clear ( ) ;
d - > m_strSelectedURLTarget . clear ( ) ;
}
if ( _mouse - > button ( ) = = Qt : : LeftButton | |
_mouse - > button ( ) = = Qt : : MidButton )
{
d - > m_bMousePressed = true ;
# ifdef KHTML_NO_SELECTION
d - > m_dragLastPos = _mouse - > globalPos ( ) ;
# else
if ( _mouse - > button ( ) = = Qt : : LeftButton )
{
if ( ( ! d - > m_strSelectedURL . isNull ( ) & & ! isEditable ( ) )
| | ( ! d - > m_mousePressNode . isNull ( ) & & d - > m_mousePressNode . elementId ( ) = = ID_IMG ) )
return ;
d - > editor_context . m_beganSelectingText = false ;
handleMousePressEventSingleClick ( event ) ;
}
# endif
}
if ( _mouse - > button ( ) = = Qt : : RightButton )
{
popupMenu ( d - > m_strSelectedURL ) ;
// might be deleted, don't touch "this"
}
}
void KHTMLPart : : khtmlMouseDoubleClickEvent ( khtml : : MouseDoubleClickEvent * event )
{
QMouseEvent * _mouse = event - > qmouseEvent ( ) ;
if ( _mouse - > button ( ) = = Qt : : LeftButton )
{
d - > m_bMousePressed = true ;
d - > editor_context . m_beganSelectingText = false ;
if ( event - > clickCount ( ) = = 2 ) {
handleMousePressEventDoubleClick ( event ) ;
return ;
}
if ( event - > clickCount ( ) > = 3 ) {
handleMousePressEventTripleClick ( event ) ;
return ;
}
}
}
# ifndef KHTML_NO_SELECTION
bool KHTMLPart : : isExtendingSelection ( ) const
{
// This is it, the whole detection. khtmlMousePressEvent only sets this
// on LMB or MMB, but never on RMB. As text selection doesn't work for MMB,
// it's sufficient to only rely on this flag to detect selection extension.
return d - > editor_context . m_beganSelectingText ;
}
void KHTMLPart : : extendSelectionTo ( int x , int y , const DOM : : Node & innerNode )
{
// handle making selection
Position pos ( innerNode . handle ( ) - > positionForCoordinates ( x , y ) . position ( ) ) ;
// Don't modify the selection if we're not on a node.
if ( pos . isEmpty ( ) )
return ;
// Restart the selection if this is the first mouse move. This work is usually
// done in khtmlMousePressEvent, but not if the mouse press was on an existing selection.
Selection sel = caret ( ) ;
sel . clearModifyBias ( ) ;
if ( ! d - > editor_context . m_beganSelectingText ) {
// We are beginning a selection during press-drag, when the original click
// wasn't appropriate for one. Make sure to set the granularity.
d - > editor_context . beginSelectingText ( Selection : : CHARACTER ) ;
sel . moveTo ( pos ) ;
}
sel . setExtent ( pos ) ;
if ( d - > editor_context . m_selectionGranularity ! = Selection : : CHARACTER ) {
sel . expandUsingGranularity ( d - > editor_context . m_selectionGranularity ) ;
}
setCaret ( sel ) ;
}
# endif // KHTML_NO_SELECTION
bool KHTMLPart : : handleMouseMoveEventDrag ( khtml : : MouseMoveEvent * event )
{
# ifdef QT_NO_DRAGANDDROP
return false ;
# else
if ( ! dndEnabled ( ) )
return false ;
if ( ( d - > m_bMousePressed & &
( ( ! d - > m_strSelectedURL . isEmpty ( ) & & ! isEditable ( ) )
| | ( ! d - > m_mousePressNode . isNull ( ) & & d - > m_mousePressNode . elementId ( ) = = ID_IMG ) ) )
& & ( d - > m_dragStartPos - QPoint ( event - > x ( ) , event - > y ( ) ) ) . manhattanLength ( ) > KGlobalSettings : : dndEventDelay ( ) ) {
const DOM : : DOMString url = event - > url ( ) ;
DOM : : NodeImpl * innerNodeImpl = event - > innerNode ( ) . handle ( ) ;
QPixmap pix ;
HTMLImageElementImpl * img = 0L ;
KUrl u ;
// qDebug("****************** Event URL: %s", url.string().toLatin1().constData());
// qDebug("****************** Event Target: %s", target.string().toLatin1().constData());
// Normal image...
if ( url . isEmpty ( ) & & innerNodeImpl & & innerNodeImpl - > id ( ) = = ID_IMG )
{
img = static_cast < HTMLImageElementImpl * > ( innerNodeImpl ) ;
u = completeURL ( img - > getAttribute ( ATTR_SRC ) . parsedUrl ( ) . string ( ) ) ;
pix = KIconLoader : : global ( ) - > loadIcon ( " image-x-generic " , KIconLoader : : Desktop ) ;
}
else
{
// Text or image link...
u = completeURL ( d - > m_strSelectedURL ) ;
pix = KIO : : pixmapForUrl ( u , 0 , KIconLoader : : Desktop , KIconLoader : : SizeMedium ) ;
}
u . setPass ( QString ( ) ) ;
QDrag * drag = new QDrag ( d - > m_view - > viewport ( ) ) ;
QMap < QString , QString > metaDataMap ;
if ( ! d - > m_referrer . isEmpty ( ) )
metaDataMap . insert ( " referrer " , d - > m_referrer ) ;
QMimeData * mimeData = new QMimeData ( ) ;
u . populateMimeData ( mimeData , metaDataMap ) ;
drag - > setMimeData ( mimeData ) ;
if ( img & & img - > complete ( ) )
drag - > mimeData ( ) - > setImageData ( img - > currentImage ( ) ) ;
if ( ! pix . isNull ( ) )
drag - > setPixmap ( pix ) ;
stopAutoScroll ( ) ;
drag - > start ( ) ;
// when we finish our drag, we need to undo our mouse press
d - > m_bMousePressed = false ;
d - > m_strSelectedURL . clear ( ) ;
d - > m_strSelectedURLTarget . clear ( ) ;
return true ;
}
return false ;
# endif // QT_NO_DRAGANDDROP
}
bool KHTMLPart : : handleMouseMoveEventOver ( khtml : : MouseMoveEvent * event )
{
// Mouse clicked -> do nothing
if ( d - > m_bMousePressed ) return false ;
DOM : : DOMString url = event - > url ( ) ;
// The mouse is over something
if ( url . length ( ) )
{
DOM : : DOMString target = event - > target ( ) ;
QMouseEvent * _mouse = event - > qmouseEvent ( ) ;
DOM : : Node innerNode = event - > innerNode ( ) ;
bool shiftPressed = ( _mouse - > modifiers ( ) & Qt : : ShiftModifier ) ;
// Image map
if ( ! innerNode . isNull ( ) & & innerNode . elementId ( ) = = ID_IMG )
{
HTMLImageElementImpl * i = static_cast < HTMLImageElementImpl * > ( innerNode . handle ( ) ) ;
if ( i & & i - > isServerMap ( ) )
{
khtml : : RenderObject * r = i - > renderer ( ) ;
if ( r )
{
int absx , absy ;
r - > absolutePosition ( absx , absy ) ;
int x ( event - > x ( ) - absx ) , y ( event - > y ( ) - absy ) ;
d - > m_overURL = url . string ( ) + QString ( " ?%1,%2 " ) . arg ( x ) . arg ( y ) ;
d - > m_overURLTarget = target . string ( ) ;
overURL ( d - > m_overURL , target . string ( ) , shiftPressed ) ;
return true ;
}
}
}
// normal link
if ( d - > m_overURL . isEmpty ( ) | | d - > m_overURL ! = url | | d - > m_overURLTarget ! = target )
{
d - > m_overURL = url . string ( ) ;
d - > m_overURLTarget = target . string ( ) ;
overURL ( d - > m_overURL , target . string ( ) , shiftPressed ) ;
}
}
else // Not over a link...
{
if ( ! d - > m_overURL . isEmpty ( ) ) // and we were over a link -> reset to "default statusbar text"
{
// reset to "default statusbar text"
resetHoverText ( ) ;
}
}
return true ;
}
void KHTMLPart : : handleMouseMoveEventSelection ( khtml : : MouseMoveEvent * event )
{
// Mouse not pressed. Do nothing.
if ( ! d - > m_bMousePressed )
return ;
# ifdef KHTML_NO_SELECTION
if ( d - > m_doc & & d - > m_view ) {
QPoint diff ( mouse - > globalPos ( ) - d - > m_dragLastPos ) ;
if ( abs ( diff . x ( ) ) > 64 | | abs ( diff . y ( ) ) > 64 ) {
d - > m_view - > scrollBy ( - diff . x ( ) , - diff . y ( ) ) ;
d - > m_dragLastPos = mouse - > globalPos ( ) ;
}
}
# else
QMouseEvent * mouse = event - > qmouseEvent ( ) ;
DOM : : Node innerNode = event - > innerNode ( ) ;
if ( ( mouse - > buttons ( ) & Qt : : LeftButton ) = = 0 | | ! innerNode . handle ( ) | | ! innerNode . handle ( ) - > renderer ( ) | |
! innerNode . handle ( ) - > renderer ( ) - > shouldSelect ( ) )
return ;
// handle making selection
extendSelectionTo ( event - > x ( ) , event - > y ( ) , innerNode ) ;
# endif // KHTML_NO_SELECTION
}
void KHTMLPart : : khtmlMouseMoveEvent ( khtml : : MouseMoveEvent * event )
{
if ( handleMouseMoveEventDrag ( event ) )
return ;
if ( handleMouseMoveEventOver ( event ) )
return ;
handleMouseMoveEventSelection ( event ) ;
}
void KHTMLPart : : khtmlMouseReleaseEvent ( khtml : : MouseReleaseEvent * event )
{
DOM : : Node innerNode = event - > innerNode ( ) ;
d - > m_mousePressNode = DOM : : Node ( ) ;
if ( d - > m_bMousePressed ) {
setStatusBarText ( QString ( ) , BarHoverText ) ;
stopAutoScroll ( ) ;
}
// Used to prevent mouseMoveEvent from initiating a drag before
// the mouse is pressed again.
d - > m_bMousePressed = false ;
# ifndef QT_NO_CLIPBOARD
QMouseEvent * _mouse = event - > qmouseEvent ( ) ;
if ( ( d - > m_guiProfile = = BrowserViewGUI ) & & ( _mouse - > button ( ) = = Qt : : MidButton ) & & ( event - > url ( ) . isNull ( ) ) ) {
kDebug ( 6050 ) < < " MMB shouldOpen= " < < d - > m_bOpenMiddleClick ;
if ( d - > m_bOpenMiddleClick ) {
KHTMLPart * p = this ;
while ( p - > parentPart ( ) ) p = p - > parentPart ( ) ;
p - > d - > m_extension - > pasteRequest ( ) ;
}
}
# endif
# ifndef KHTML_NO_SELECTION
{
// Clear the selection if the mouse didn't move after the last mouse press.
// We do this so when clicking on the selection, the selection goes away.
// However, if we are editing, place the caret.
if ( ! d - > editor_context . m_beganSelectingText
& & d - > m_dragStartPos . x ( ) = = event - > x ( )
& & d - > m_dragStartPos . y ( ) = = event - > y ( )
& & d - > editor_context . m_selection . state ( ) = = Selection : : RANGE ) {
Selection selection ;
selection . moveTo ( d - > editor_context . m_selection . base ( ) . node ( ) - > positionForCoordinates ( event - > x ( ) , event - > y ( ) ) . position ( ) ) ;
setCaret ( selection ) ;
}
// get selected text and paste to the clipboard
# ifndef QT_NO_CLIPBOARD
QString text = selectedText ( ) ;
text . replace ( QChar ( 0xa0 ) , ' ' ) ;
if ( ! text . isEmpty ( ) ) {
disconnect ( qApp - > clipboard ( ) , SIGNAL ( selectionChanged ( ) ) , this , SLOT ( slotClearSelection ( ) ) ) ;
qApp - > clipboard ( ) - > setText ( text , QClipboard : : Selection ) ;
connect ( qApp - > clipboard ( ) , SIGNAL ( selectionChanged ( ) ) , SLOT ( slotClearSelection ( ) ) ) ;
}
# endif
//kDebug( 6000 ) << "selectedText = " << text;
emitSelectionChanged ( ) ;
//kDebug(6000) << "rel2: startBefEnd " << d->m_startBeforeEnd << " extAtEnd " << d->m_extendAtEnd << " (" << d->m_startOffset << ") - (" << d->m_endOffset << "), caretOfs " << d->caretOffset();
}
# endif
}
void KHTMLPart : : khtmlDrawContentsEvent ( khtml : : DrawContentsEvent * )
{
}
void KHTMLPart : : guiActivateEvent ( KParts : : GUIActivateEvent * event )
{
if ( event - > activated ( ) )
{
emitSelectionChanged ( ) ;
emit d - > m_extension - > enableAction ( " print " , d - > m_doc ! = 0 ) ;
if ( ! d - > m_settings - > autoLoadImages ( ) & & d - > m_paLoadImages )
{
QList < QAction * > lst ;
lst . append ( d - > m_paLoadImages ) ;
plugActionList ( " loadImages " , lst ) ;
}
}
}
void KHTMLPart : : slotPrintFrame ( )
{
if ( d - > m_frames . count ( ) = = 0 )
return ;
KParts : : ReadOnlyPart * frame = currentFrame ( ) ;
if ( ! frame )
return ;
KParts : : BrowserExtension * ext = KParts : : BrowserExtension : : childObject ( frame ) ;
if ( ! ext )
return ;
const QMetaObject * mo = ext - > metaObject ( ) ;
if ( mo - > indexOfSlot ( " print() " ) ! = - 1 )
QMetaObject : : invokeMethod ( ext , " print() " , Qt : : DirectConnection ) ;
}
void KHTMLPart : : slotSelectAll ( )
{
KParts : : ReadOnlyPart * part = currentFrame ( ) ;
if ( part & & part - > inherits ( " KHTMLPart " ) )
static_cast < KHTMLPart * > ( part ) - > selectAll ( ) ;
}
void KHTMLPart : : startAutoScroll ( )
{
connect ( & d - > m_scrollTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( slotAutoScroll ( ) ) ) ;
d - > m_scrollTimer . setSingleShot ( false ) ;
d - > m_scrollTimer . start ( 100 ) ;
}
void KHTMLPart : : stopAutoScroll ( )
{
disconnect ( & d - > m_scrollTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( slotAutoScroll ( ) ) ) ;
if ( d - > m_scrollTimer . isActive ( ) )
d - > m_scrollTimer . stop ( ) ;
}
void KHTMLPart : : slotAutoScroll ( )
{
if ( d - > m_view )
d - > m_view - > doAutoScroll ( ) ;
else
stopAutoScroll ( ) ; // Safety
}
void KHTMLPart : : runAdFilter ( )
{
if ( parentPart ( ) )
parentPart ( ) - > runAdFilter ( ) ;
if ( ! d - > m_doc )
return ;
QSetIterator < khtml : : CachedObject * > it ( d - > m_doc - > docLoader ( ) - > m_docObjects ) ;
while ( it . hasNext ( ) )
{
khtml : : CachedObject * obj = it . next ( ) ;
if ( obj - > type ( ) = = khtml : : CachedObject : : Image ) {
khtml : : CachedImage * image = static_cast < khtml : : CachedImage * > ( obj ) ;
bool wasBlocked = image - > m_wasBlocked ;
image - > m_wasBlocked = KHTMLGlobal : : defaultHTMLSettings ( ) - > isAdFiltered ( d - > m_doc - > completeURL ( image - > url ( ) . string ( ) ) ) ;
if ( image - > m_wasBlocked ! = wasBlocked )
image - > do_notify ( QRect ( QPoint ( 0 , 0 ) , image - > pixmap_size ( ) ) ) ;
}
}
if ( KHTMLGlobal : : defaultHTMLSettings ( ) - > isHideAdsEnabled ( ) ) {
for ( NodeImpl * nextNode , * node = d - > m_doc ; node ; node = nextNode ) {
// We might be deleting 'node' shortly.
nextNode = node - > traverseNextNode ( ) ;
if ( node - > id ( ) = = ID_IMG | |
node - > id ( ) = = ID_IFRAME | |
( node - > id ( ) = = ID_INPUT & & static_cast < HTMLInputElementImpl * > ( node ) - > inputType ( ) = = HTMLInputElementImpl : : IMAGE ) )
{
if ( KHTMLGlobal : : defaultHTMLSettings ( ) - > isAdFiltered ( d - > m_doc - > completeURL ( static_cast < ElementImpl * > ( node ) - > getAttribute ( ATTR_SRC ) . parsedUrl ( ) . string ( ) ) ) )
{
// Since any kids of node will be deleted, too, fastforward nextNode
// until we get outside of node.
while ( nextNode & & nextNode - > isAncestor ( node ) )
nextNode = nextNode - > traverseNextNode ( ) ;
node - > ref ( ) ;
NodeImpl * parent = node - > parent ( ) ;
if ( parent )
{
int exception = 0 ;
parent - > removeChild ( node , exception ) ;
}
node - > deref ( ) ;
}
}
}
}
}
void KHTMLPart : : selectAll ( )
{
if ( ! d - > m_doc ) return ;
NodeImpl * first ;
if ( d - > m_doc - > isHTMLDocument ( ) )
first = static_cast < HTMLDocumentImpl * > ( d - > m_doc ) - > body ( ) ;
else
first = d - > m_doc ;
NodeImpl * next ;
// Look for first text/cdata node that has a renderer,
// or first childless replaced element
while ( first & & ! ( first - > renderer ( )
& & ( ( first - > nodeType ( ) = = Node : : TEXT_NODE | | first - > nodeType ( ) = = Node : : CDATA_SECTION_NODE )
| | ( first - > renderer ( ) - > isReplaced ( ) & & ! first - > renderer ( ) - > firstChild ( ) ) ) ) )
{
next = first - > firstChild ( ) ;
if ( ! next ) next = first - > nextSibling ( ) ;
while ( first & & ! next )
{
first = first - > parentNode ( ) ;
if ( first )
next = first - > nextSibling ( ) ;
}
first = next ;
}
NodeImpl * last ;
if ( d - > m_doc - > isHTMLDocument ( ) )
last = static_cast < HTMLDocumentImpl * > ( d - > m_doc ) - > body ( ) ;
else
last = d - > m_doc ;
// Look for last text/cdata node that has a renderer,
// or last childless replaced element
// ### Instead of changing this loop, use findLastSelectableNode
// in render_table.cpp (LS)
while ( last & & ! ( last - > renderer ( )
& & ( ( last - > nodeType ( ) = = Node : : TEXT_NODE | | last - > nodeType ( ) = = Node : : CDATA_SECTION_NODE )
| | ( last - > renderer ( ) - > isReplaced ( ) & & ! last - > renderer ( ) - > lastChild ( ) ) ) ) )
{
next = last - > lastChild ( ) ;
if ( ! next ) next = last - > previousSibling ( ) ;
while ( last & & ! next )
{
last = last - > parentNode ( ) ;
if ( last )
next = last - > previousSibling ( ) ;
}
last = next ;
}
if ( ! first | | ! last )
return ;
Q_ASSERT ( first - > renderer ( ) ) ;
Q_ASSERT ( last - > renderer ( ) ) ;
d - > editor_context . m_selection . moveTo ( Position ( first , 0 ) , Position ( last , last - > nodeValue ( ) . length ( ) ) ) ;
d - > m_doc - > updateSelection ( ) ;
emitSelectionChanged ( ) ;
}
bool KHTMLPart : : checkLinkSecurity ( const KUrl & linkURL , const KLocalizedString & message , const QString & button )
{
bool linkAllowed = true ;
if ( d - > m_doc )
linkAllowed = KAuthorized : : authorizeUrlAction ( " redirect " , url ( ) , linkURL ) ;
if ( ! linkAllowed ) {
khtml : : Tokenizer * tokenizer = d - > m_doc - > tokenizer ( ) ;
if ( tokenizer )
tokenizer - > setOnHold ( true ) ;
int response = KMessageBox : : Cancel ;
if ( ! message . isEmpty ( ) )
{
// Dangerous flag makes the Cancel button the default
response = KMessageBox : : warningContinueCancel ( 0 ,
message . subs ( Qt : : escape ( linkURL . prettyUrl ( ) ) ) . toString ( ) ,
i18n ( " Security Warning " ) ,
KGuiItem ( button ) ,
KStandardGuiItem : : cancel ( ) ,
QString ( ) , // no don't ask again info
KMessageBox : : Notify | KMessageBox : : Dangerous ) ;
}
else
{
KMessageBox : : error ( 0 ,
i18n ( " <qt>Access by untrusted page to<br /><b>%1</b><br /> denied.</qt> " , Qt : : escape ( linkURL . prettyUrl ( ) ) ) ,
i18n ( " Security Alert " ) ) ;
}
if ( tokenizer )
tokenizer - > setOnHold ( false ) ;
return ( response = = KMessageBox : : Continue ) ;
}
return true ;
}
void KHTMLPart : : slotPartRemoved ( KParts : : Part * part )
{
// kDebug(6050) << part;
if ( part = = d - > m_activeFrame )
{
d - > m_activeFrame = 0L ;
if ( ! part - > inherits ( " KHTMLPart " ) )
{
if ( factory ( ) ) {
factory ( ) - > removeClient ( part ) ;
}
if ( childClients ( ) . contains ( part ) ) {
removeChildClient ( part ) ;
}
}
}
}
void KHTMLPart : : slotActiveFrameChanged ( KParts : : Part * part )
{
// kDebug(6050) << this << "part=" << part;
if ( part = = this )
{
kError ( 6050 ) < < " strange error! we activated ourselves " ;
assert ( false ) ;
return ;
}
// kDebug(6050) << "d->m_activeFrame=" << d->m_activeFrame;
if ( d - > m_activeFrame & & d - > m_activeFrame - > widget ( ) & & d - > m_activeFrame - > widget ( ) - > inherits ( " QFrame " ) )
{
QFrame * frame = static_cast < QFrame * > ( d - > m_activeFrame - > widget ( ) ) ;
if ( frame - > frameStyle ( ) ! = QFrame : : NoFrame )
{
frame - > setFrameStyle ( QFrame : : StyledPanel | QFrame : : Sunken ) ;
frame - > repaint ( ) ;
}
}
if ( d - > m_activeFrame & & ! d - > m_activeFrame - > inherits ( " KHTMLPart " ) )
{
if ( factory ( ) ) {
factory ( ) - > removeClient ( d - > m_activeFrame ) ;
}
removeChildClient ( d - > m_activeFrame ) ;
}
if ( part & & ! part - > inherits ( " KHTMLPart " ) )
{
if ( factory ( ) ) {
factory ( ) - > addClient ( part ) ;
}
insertChildClient ( part ) ;
}
d - > m_activeFrame = part ;
if ( d - > m_activeFrame & & d - > m_activeFrame - > widget ( ) - > inherits ( " QFrame " ) )
{
QFrame * frame = static_cast < QFrame * > ( d - > m_activeFrame - > widget ( ) ) ;
if ( frame - > frameStyle ( ) ! = QFrame : : NoFrame )
{
frame - > setFrameStyle ( QFrame : : StyledPanel | QFrame : : Plain ) ;
frame - > repaint ( ) ;
}
kDebug ( 6050 ) < < " new active frame " < < d - > m_activeFrame ;
}
updateActions ( ) ;
// (note: childObject returns 0 if the argument is 0)
d - > m_extension - > setExtensionProxy ( KParts : : BrowserExtension : : childObject ( d - > m_activeFrame ) ) ;
}
void KHTMLPart : : setActiveNode ( const DOM : : Node & node )
{
if ( ! d - > m_doc | | ! d - > m_view )
return ;
// Set the document's active node
d - > m_doc - > setFocusNode ( node . handle ( ) ) ;
// Scroll the view if necessary to ensure that the new focus node is visible
QRect rect = node . handle ( ) - > getRect ( ) ;
d - > m_view - > ensureVisible ( rect . right ( ) , rect . bottom ( ) ) ;
d - > m_view - > ensureVisible ( rect . left ( ) , rect . top ( ) ) ;
}
DOM : : Node KHTMLPart : : activeNode ( ) const
{
return DOM : : Node ( d - > m_doc ? d - > m_doc - > focusNode ( ) : 0 ) ;
}
DOM : : EventListener * KHTMLPart : : createHTMLEventListener ( QString code , QString name , NodeImpl * node , bool svg )
{
KJSProxy * proxy = jScript ( ) ;
if ( ! proxy )
return 0 ;
return proxy - > createHTMLEventHandler ( url ( ) . url ( ) , name , code , node , svg ) ;
}
KHTMLPart * KHTMLPart : : opener ( )
{
return d - > m_opener ;
}
void KHTMLPart : : setOpener ( KHTMLPart * _opener )
{
d - > m_opener = _opener ;
}
bool KHTMLPart : : openedByJS ( )
{
return d - > m_openedByJS ;
}
void KHTMLPart : : setOpenedByJS ( bool _openedByJS )
{
d - > m_openedByJS = _openedByJS ;
}
void KHTMLPart : : preloadStyleSheet ( const QString & url , const QString & stylesheet )
{
khtml : : Cache : : preloadStyleSheet ( url , stylesheet ) ;
}
void KHTMLPart : : preloadScript ( const QString & url , const QString & script )
{
khtml : : Cache : : preloadScript ( url , script ) ;
}
long KHTMLPart : : cacheId ( ) const
{
return d - > m_cacheId ;
}
bool KHTMLPart : : restored ( ) const
{
return d - > m_restored ;
}
bool KHTMLPart : : pluginPageQuestionAsked ( const QString & mimetype ) const
{
// parentPart() should be const!
KHTMLPart * parent = const_cast < KHTMLPart * > ( this ) - > parentPart ( ) ;
if ( parent )
return parent - > pluginPageQuestionAsked ( mimetype ) ;
return d - > m_pluginPageQuestionAsked . contains ( mimetype ) ;
}
void KHTMLPart : : setPluginPageQuestionAsked ( const QString & mimetype )
{
if ( parentPart ( ) )
parentPart ( ) - > setPluginPageQuestionAsked ( mimetype ) ;
d - > m_pluginPageQuestionAsked . append ( mimetype ) ;
}
KEncodingDetector * KHTMLPart : : createDecoder ( )
{
KEncodingDetector * dec = new KEncodingDetector ( ) ;
if ( ! d - > m_encoding . isNull ( ) )
dec - > setEncoding ( d - > m_encoding . toLatin1 ( ) . constData ( ) ,
d - > m_haveEncoding ? KEncodingDetector : : UserChosenEncoding : KEncodingDetector : : EncodingFromHTTPHeader ) ;
else {
// Inherit the default encoding from the parent frame if there is one.
QByteArray defaultEncoding = ( parentPart ( ) & & parentPart ( ) - > d - > m_decoder )
? QByteArray ( parentPart ( ) - > d - > m_decoder - > encoding ( ) ) : settings ( ) - > encoding ( ) . toLatin1 ( ) ;
dec - > setEncoding ( defaultEncoding . constData ( ) , KEncodingDetector : : DefaultEncoding ) ;
}
if ( d - > m_doc )
d - > m_doc - > setDecoder ( dec ) ;
dec - > setAutoDetectLanguage ( d - > m_autoDetectLanguage ) ;
return dec ;
}
void KHTMLPart : : emitCaretPositionChanged ( const DOM : : Position & pos ) {
// pos must not be already converted to range-compliant coordinates
Position rng_pos = pos . equivalentRangeCompliantPosition ( ) ;
Node node = rng_pos . node ( ) ;
emit caretPositionChanged ( node , rng_pos . offset ( ) ) ;
}
void KHTMLPart : : restoreScrollPosition ( )
{
const KParts : : OpenUrlArguments args ( arguments ( ) ) ;
if ( url ( ) . hasRef ( ) & & ! d - > m_restoreScrollPosition & & ! args . reload ( ) ) {
if ( ! d - > m_doc | | ! d - > m_doc - > parsing ( ) )
disconnect ( d - > m_view , SIGNAL ( finishedLayout ( ) ) , this , SLOT ( restoreScrollPosition ( ) ) ) ;
if ( ! gotoAnchor ( url ( ) . encodedHtmlRef ( ) ) )
gotoAnchor ( url ( ) . htmlRef ( ) ) ;
return ;
}
// Check whether the viewport has become large enough to encompass the stored
// offsets. If the document has been fully loaded, force the new coordinates,
// even if the canvas is too short (can happen when user resizes the window
// during loading).
if ( d - > m_view - > contentsHeight ( ) - d - > m_view - > visibleHeight ( ) > = args . yOffset ( )
| | d - > m_bComplete ) {
d - > m_view - > setContentsPos ( args . xOffset ( ) , args . yOffset ( ) ) ;
disconnect ( d - > m_view , SIGNAL ( finishedLayout ( ) ) , this , SLOT ( restoreScrollPosition ( ) ) ) ;
}
}
void KHTMLPart : : openWallet ( DOM : : HTMLFormElementImpl * form )
{
# ifndef KHTML_NO_WALLET
KHTMLPart * p ;
for ( p = parentPart ( ) ; p & & p - > parentPart ( ) ; p = p - > parentPart ( ) ) {
}
if ( p ) {
p - > openWallet ( form ) ;
return ;
}
if ( onlyLocalReferences ( ) ) { // avoid triggering on local apps, thumbnails
return ;
}
if ( d - > m_wallet ) {
if ( d - > m_bWalletOpened ) {
if ( d - > m_wallet - > isOpen ( ) ) {
form - > walletOpened ( d - > m_wallet ) ;
return ;
}
d - > m_wallet - > deleteLater ( ) ;
d - > m_wallet = 0L ;
d - > m_bWalletOpened = false ;
}
}
if ( ! d - > m_wq ) {
KWallet : : Wallet * wallet = KWallet : : Wallet : : openWallet ( KWallet : : Wallet : : NetworkWallet ( ) , widget ( ) ? widget ( ) - > topLevelWidget ( ) - > winId ( ) : 0 , KWallet : : Wallet : : Asynchronous ) ;
d - > m_wq = new KHTMLWalletQueue ( this ) ;
d - > m_wq - > wallet = wallet ;
connect ( wallet , SIGNAL ( walletOpened ( bool ) ) , d - > m_wq , SLOT ( walletOpened ( bool ) ) ) ;
connect ( d - > m_wq , SIGNAL ( walletOpened ( KWallet : : Wallet * ) ) , this , SLOT ( walletOpened ( KWallet : : Wallet * ) ) ) ;
}
assert ( form ) ;
d - > m_wq - > callers . append ( KHTMLWalletQueue : : Caller ( form , form - > document ( ) ) ) ;
# endif // KHTML_NO_WALLET
}
void KHTMLPart : : saveToWallet ( const QString & key , const QMap < QString , QString > & data )
{
# ifndef KHTML_NO_WALLET
KHTMLPart * p ;
for ( p = parentPart ( ) ; p & & p - > parentPart ( ) ; p = p - > parentPart ( ) ) {
}
if ( p ) {
p - > saveToWallet ( key , data ) ;
return ;
}
if ( d - > m_wallet ) {
if ( d - > m_bWalletOpened ) {
if ( d - > m_wallet - > isOpen ( ) ) {
if ( ! d - > m_wallet - > hasFolder ( KWallet : : Wallet : : FormDataFolder ( ) ) ) {
d - > m_wallet - > createFolder ( KWallet : : Wallet : : FormDataFolder ( ) ) ;
}
d - > m_wallet - > setFolder ( KWallet : : Wallet : : FormDataFolder ( ) ) ;
d - > m_wallet - > writeMap ( key , data ) ;
return ;
}
d - > m_wallet - > deleteLater ( ) ;
d - > m_wallet = 0L ;
d - > m_bWalletOpened = false ;
}
}
if ( ! d - > m_wq ) {
KWallet : : Wallet * wallet = KWallet : : Wallet : : openWallet ( KWallet : : Wallet : : NetworkWallet ( ) , widget ( ) ? widget ( ) - > topLevelWidget ( ) - > winId ( ) : 0 , KWallet : : Wallet : : Asynchronous ) ;
d - > m_wq = new KHTMLWalletQueue ( this ) ;
d - > m_wq - > wallet = wallet ;
connect ( wallet , SIGNAL ( walletOpened ( bool ) ) , d - > m_wq , SLOT ( walletOpened ( bool ) ) ) ;
connect ( d - > m_wq , SIGNAL ( walletOpened ( KWallet : : Wallet * ) ) , this , SLOT ( walletOpened ( KWallet : : Wallet * ) ) ) ;
}
d - > m_wq - > savers . append ( qMakePair ( key , data ) ) ;
# endif // KHTML_NO_WALLET
}
void KHTMLPart : : dequeueWallet ( DOM : : HTMLFormElementImpl * form ) {
# ifndef KHTML_NO_WALLET
KHTMLPart * p ;
for ( p = parentPart ( ) ; p & & p - > parentPart ( ) ; p = p - > parentPart ( ) ) {
}
if ( p ) {
p - > dequeueWallet ( form ) ;
return ;
}
if ( d - > m_wq ) {
d - > m_wq - > callers . removeAll ( KHTMLWalletQueue : : Caller ( form , form - > document ( ) ) ) ;
}
# endif // KHTML_NO_WALLET
}
void KHTMLPart : : walletOpened ( KWallet : : Wallet * wallet ) {
# ifndef KHTML_NO_WALLET
assert ( ! d - > m_wallet ) ;
assert ( d - > m_wq ) ;
d - > m_wq - > deleteLater ( ) ; // safe?
d - > m_wq = 0L ;
if ( ! wallet ) {
d - > m_bWalletOpened = false ;
return ;
}
d - > m_wallet = wallet ;
d - > m_bWalletOpened = true ;
connect ( d - > m_wallet , SIGNAL ( walletClosed ( ) ) , SLOT ( slotWalletClosed ( ) ) ) ;
d - > m_walletForms . clear ( ) ;
if ( ! d - > m_statusBarWalletLabel ) {
d - > m_statusBarWalletLabel = new KUrlLabel ( d - > m_statusBarExtension - > statusBar ( ) ) ;
d - > m_statusBarWalletLabel - > setSizePolicy ( QSizePolicy ( QSizePolicy : : Fixed , QSizePolicy : : Minimum ) ) ;
d - > m_statusBarWalletLabel - > setUseCursor ( false ) ;
d - > m_statusBarExtension - > addStatusBarItem ( d - > m_statusBarWalletLabel , 0 , false ) ;
d - > m_statusBarWalletLabel - > setPixmap ( SmallIcon ( " wallet-open " ) ) ;
connect ( d - > m_statusBarWalletLabel , SIGNAL ( leftClickedUrl ( ) ) , SLOT ( launchWalletManager ( ) ) ) ;
connect ( d - > m_statusBarWalletLabel , SIGNAL ( rightClickedUrl ( ) ) , SLOT ( walletMenu ( ) ) ) ;
}
d - > m_statusBarWalletLabel - > setToolTip ( i18n ( " The wallet '%1' is open and being used for form data and passwords. " , KWallet : : Wallet : : NetworkWallet ( ) ) ) ;
# endif // KHTML_NO_WALLET
}
KWallet : : Wallet * KHTMLPart : : wallet ( )
{
# ifndef KHTML_NO_WALLET
KHTMLPart * p ;
for ( p = parentPart ( ) ; p & & p - > parentPart ( ) ; p = p - > parentPart ( ) )
;
if ( p )
return p - > wallet ( ) ;
return d - > m_wallet ;
# else
return 0 ;
# endif // !KHTML_NO_WALLET
}
void KHTMLPart : : slotWalletClosed ( )
{
# ifndef KHTML_NO_WALLET
if ( d - > m_wallet ) {
d - > m_wallet - > deleteLater ( ) ;
d - > m_wallet = 0L ;
}
d - > m_bWalletOpened = false ;
if ( d - > m_statusBarWalletLabel ) {
d - > m_statusBarExtension - > removeStatusBarItem ( d - > m_statusBarWalletLabel ) ;
delete d - > m_statusBarWalletLabel ;
d - > m_statusBarWalletLabel = 0L ;
}
# endif // KHTML_NO_WALLET
}
void KHTMLPart : : launchWalletManager ( )
{
# ifndef KHTML_NO_WALLET
QDBusInterface r ( " org.kde.kwalletmanager " , " /kwalletmanager/MainWindow_1 " ,
" org.kde.KMainWindow " ) ;
if ( ! r . isValid ( ) ) {
KToolInvocation : : startServiceByDesktopName ( " kwalletmanager_show " ) ;
} else {
r . call ( QDBus : : NoBlock , " show " ) ;
r . call ( QDBus : : NoBlock , " raise " ) ;
}
# endif // KHTML_NO_WALLET
}
void KHTMLPart : : walletMenu ( )
{
# ifndef KHTML_NO_WALLET
KMenu * menu = new KMenu ( 0L ) ;
QActionGroup * menuActionGroup = new QActionGroup ( menu ) ;
connect ( menuActionGroup , SIGNAL ( triggered ( QAction * ) ) , this , SLOT ( removeStoredPasswordForm ( QAction * ) ) ) ;
menu - > addAction ( i18n ( " &Close Wallet " ) , this , SLOT ( slotWalletClosed ( ) ) ) ;
if ( d - > m_view & & d - > m_view - > nonPasswordStorableSite ( toplevelURL ( ) . host ( ) ) ) {
menu - > addAction ( i18n ( " &Allow storing passwords for this site " ) , this , SLOT ( delNonPasswordStorableSite ( ) ) ) ;
}
// List currently removable form passwords
for ( QStringList : : ConstIterator it = d - > m_walletForms . constBegin ( ) ; it ! = d - > m_walletForms . constEnd ( ) ; + + it ) {
QAction * action = menu - > addAction ( i18n ( " Remove password for form %1 " , * it ) ) ;
action - > setActionGroup ( menuActionGroup ) ;
QVariant var ( * it ) ;
action - > setData ( var ) ;
}
KAcceleratorManager : : manage ( menu ) ;
menu - > popup ( QCursor : : pos ( ) ) ;
# endif // KHTML_NO_WALLET
}
void KHTMLPart : : removeStoredPasswordForm ( QAction * action )
{
# ifndef KHTML_NO_WALLET
assert ( action ) ;
assert ( d - > m_wallet ) ;
QVariant var ( action - > data ( ) ) ;
if ( var . isNull ( ) | | ! var . isValid ( ) | | var . type ( ) ! = QVariant : : String )
return ;
QString key = var . toString ( ) ;
if ( KWallet : : Wallet : : keyDoesNotExist ( KWallet : : Wallet : : NetworkWallet ( ) ,
KWallet : : Wallet : : FormDataFolder ( ) ,
key ) )
return ; // failed
if ( ! d - > m_wallet - > hasFolder ( KWallet : : Wallet : : FormDataFolder ( ) ) )
return ; // failed
d - > m_wallet - > setFolder ( KWallet : : Wallet : : FormDataFolder ( ) ) ;
if ( d - > m_wallet - > removeEntry ( key ) )
return ; // failed
d - > m_walletForms . removeAll ( key ) ;
# endif // KHTML_NO_WALLET
}
void KHTMLPart : : addWalletFormKey ( const QString & walletFormKey )
{
# ifndef KHTML_NO_WALLET
if ( parentPart ( ) ) {
parentPart ( ) - > addWalletFormKey ( walletFormKey ) ;
return ;
}
if ( ! d - > m_walletForms . contains ( walletFormKey ) )
d - > m_walletForms . append ( walletFormKey ) ;
# endif // KHTML_NO_WALLET
}
void KHTMLPart : : delNonPasswordStorableSite ( )
{
# ifndef KHTML_NO_WALLET
if ( d - > m_view )
d - > m_view - > delNonPasswordStorableSite ( toplevelURL ( ) . host ( ) ) ;
# endif // KHTML_NO_WALLET
}
void KHTMLPart : : saveLoginInformation ( const QString & host , const QString & key , const QMap < QString , QString > & walletMap )
{
# ifndef KHTML_NO_WALLET
d - > m_storePass . saveLoginInformation ( host , key , walletMap ) ;
# endif // KHTML_NO_WALLET
}
void KHTMLPart : : slotToggleCaretMode ( )
{
setCaretMode ( d - > m_paToggleCaretMode - > isChecked ( ) ) ;
}
void KHTMLPart : : setFormNotification ( KHTMLPart : : FormNotification fn ) {
d - > m_formNotification = fn ;
}
KHTMLPart : : FormNotification KHTMLPart : : formNotification ( ) const {
return d - > m_formNotification ;
}
KUrl KHTMLPart : : toplevelURL ( )
{
KHTMLPart * part = this ;
while ( part - > parentPart ( ) )
part = part - > parentPart ( ) ;
if ( ! part )
return KUrl ( ) ;
return part - > url ( ) ;
}
bool KHTMLPart : : isModified ( ) const
{
if ( ! d - > m_doc )
return false ;
return d - > m_doc - > unsubmittedFormChanges ( ) ;
}
void KHTMLPart : : setDebugScript ( bool enable )
{
unplugActionList ( " debugScriptList " ) ;
if ( enable ) {
if ( ! d - > m_paDebugScript ) {
d - > m_paDebugScript = new KAction ( i18n ( " JavaScript &Debugger " ) , this ) ;
actionCollection ( ) - > addAction ( " debugScript " , d - > m_paDebugScript ) ;
connect ( d - > m_paDebugScript , SIGNAL ( triggered ( bool ) ) , this , SLOT ( slotDebugScript ( ) ) ) ;
}
d - > m_paDebugScript - > setEnabled ( d - > m_frame ? d - > m_frame - > m_jscript : 0L ) ;
QList < QAction * > lst ;
lst . append ( d - > m_paDebugScript ) ;
plugActionList ( " debugScriptList " , lst ) ;
}
d - > m_bJScriptDebugEnabled = enable ;
}
void KHTMLPart : : setSuppressedPopupIndicator ( bool enable , KHTMLPart * originPart )
{
if ( parentPart ( ) ) {
parentPart ( ) - > setSuppressedPopupIndicator ( enable , originPart ) ;
return ;
}
if ( enable & & originPart ) {
d - > m_openableSuppressedPopups + + ;
if ( d - > m_suppressedPopupOriginParts . indexOf ( originPart ) = = - 1 )
d - > m_suppressedPopupOriginParts . append ( originPart ) ;
}
if ( enable & & ! d - > m_statusBarPopupLabel ) {
d - > m_statusBarPopupLabel = new KUrlLabel ( d - > m_statusBarExtension - > statusBar ( ) ) ;
d - > m_statusBarPopupLabel - > setSizePolicy ( QSizePolicy ( QSizePolicy : : Fixed , QSizePolicy : : Minimum ) ) ;
d - > m_statusBarPopupLabel - > setUseCursor ( false ) ;
d - > m_statusBarExtension - > addStatusBarItem ( d - > m_statusBarPopupLabel , 0 , false ) ;
d - > m_statusBarPopupLabel - > setPixmap ( SmallIcon ( " window-suppressed " ) ) ;
d - > m_statusBarPopupLabel - > setToolTip ( i18n ( " This page was prevented from opening a new window via JavaScript. " ) ) ;
connect ( d - > m_statusBarPopupLabel , SIGNAL ( leftClickedUrl ( ) ) , SLOT ( suppressedPopupMenu ( ) ) ) ;
if ( d - > m_settings - > jsPopupBlockerPassivePopup ( ) ) {
QPixmap px ;
px = MainBarIcon ( " window-suppressed " ) ;
KPassivePopup : : message ( i18n ( " Popup Window Blocked " ) , i18n ( " This page has attempted to open a popup window but was blocked. \n You can click on this icon in the status bar to control this behavior \n or to open the popup. " ) , px , d - > m_statusBarPopupLabel ) ;
}
} else if ( ! enable & & d - > m_statusBarPopupLabel ) {
d - > m_statusBarPopupLabel - > setToolTip ( " " ) ;
d - > m_statusBarExtension - > removeStatusBarItem ( d - > m_statusBarPopupLabel ) ;
delete d - > m_statusBarPopupLabel ;
d - > m_statusBarPopupLabel = 0L ;
}
}
void KHTMLPart : : suppressedPopupMenu ( ) {
KMenu * m = new KMenu ( 0L ) ;
if ( d - > m_openableSuppressedPopups )
m - > addAction ( i18np ( " &Show Blocked Popup Window " , " &Show %1 Blocked Popup Windows " , d - > m_openableSuppressedPopups ) , this , SLOT ( showSuppressedPopups ( ) ) ) ;
QAction * a = m - > addAction ( i18n ( " Show Blocked Window Passive Popup &Notification " ) , this , SLOT ( togglePopupPassivePopup ( ) ) ) ;
a - > setChecked ( d - > m_settings - > jsPopupBlockerPassivePopup ( ) ) ;
m - > addAction ( i18n ( " &Configure JavaScript New Window Policies... " ) , this , SLOT ( launchJSConfigDialog ( ) ) ) ;
m - > popup ( QCursor : : pos ( ) ) ;
}
void KHTMLPart : : togglePopupPassivePopup ( ) {
// Same hack as in disableJSErrorExtension()
d - > m_settings - > setJSPopupBlockerPassivePopup ( ! d - > m_settings - > jsPopupBlockerPassivePopup ( ) ) ;
emit configurationChanged ( ) ;
}
void KHTMLPart : : showSuppressedPopups ( ) {
foreach ( KHTMLPart * part , d - > m_suppressedPopupOriginParts ) {
if ( part ) {
KJS : : Window * w = KJS : : Window : : retrieveWindow ( part ) ;
if ( w ) {
w - > showSuppressedWindows ( ) ;
w - > forgetSuppressedWindows ( ) ;
}
}
}
setSuppressedPopupIndicator ( false ) ;
d - > m_openableSuppressedPopups = 0 ;
d - > m_suppressedPopupOriginParts . clear ( ) ;
}
// Extension to use for "view document source", "save as" etc.
// Using the right extension can help the viewer get into the right mode (#40496)
QString KHTMLPart : : defaultExtension ( ) const
{
if ( ! d - > m_doc )
return " .html " ;
if ( ! d - > m_doc - > isHTMLDocument ( ) )
return " .xml " ;
return d - > m_doc - > htmlMode ( ) = = DOM : : DocumentImpl : : XHtml ? " .xhtml " : " .html " ;
}
bool KHTMLPart : : inProgress ( ) const
{
if ( ! d - > m_bComplete | | d - > m_runningScripts | | ( d - > m_doc & & d - > m_doc - > parsing ( ) ) )
return true ;
// Any frame that hasn't completed yet ?
ConstFrameIt it = d - > m_frames . constBegin ( ) ;
const ConstFrameIt end = d - > m_frames . constEnd ( ) ;
for ( ; it ! = end ; + + it ) {
if ( ( * it ) - > m_run | | ! ( * it ) - > m_bCompleted )
return true ;
}
return d - > m_submitForm | | ! d - > m_redirectURL . isEmpty ( ) | | d - > m_redirectionTimer . isActive ( ) | | d - > m_job ;
}
using namespace KParts ;
# include "moc_khtml_part.cpp"
# include "moc_khtmlpart_p.cpp"
# ifndef KHTML_NO_WALLET
# include "moc_khtml_wallet_p.cpp"
# endif
// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;