Added missing file.
[WebKit-https.git] / WebCore / khtml / khtml_part.cpp
1 // -*- c-basic-offset: 2 -*-
2 /* This file is part of the KDE project
3  *
4  * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
5  *                     1999 Lars Knoll <knoll@kde.org>
6  *                     1999 Antti Koivisto <koivisto@kde.org>
7  *                     2000 Simon Hausmann <hausmann@kde.org>
8  *                     2000 Stefan Schimanski <1Stein@gmx.de>
9  *                     2001 George Staikos <staikos@kde.org>
10  * Copyright (C) 2004 Apple Computer, Inc.
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public License
23  * along with this library; see the file COPYING.LIB.  If not, write to
24  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25  * Boston, MA 02111-1307, USA.
26  */
27
28 #include "khtml_part.h"
29
30 #if APPLE_CHANGES
31 #define DIRECT_LINKAGE_TO_ECMA
32 #define QT_NO_CLIPBOARD
33 #define QT_NO_DRAGANDDROP
34 #endif
35
36 #include "khtml_pagecache.h"
37
38 #include "css/csshelper.h"
39 #include "css/cssproperties.h"
40 #include "css/cssstyleselector.h"
41 #include "css/css_computedstyle.h"
42 #include "css/css_valueimpl.h"
43 #include "dom/dom_string.h"
44 #include "editing/markup.h"
45 #include "editing/htmlediting.h"
46 #include "editing/selection.h"
47 #include "editing/visible_position.h"
48 #include "editing/visible_text.h"
49 #include "editing/visible_units.h"
50 #include "html/html_documentimpl.h"
51 #include "html/html_baseimpl.h"
52 #include "html/html_miscimpl.h"
53 #include "html/html_imageimpl.h"
54 #include "html/html_objectimpl.h"
55 #include "rendering/render_block.h"
56 #include "rendering/render_text.h"
57 #include "rendering/render_frames.h"
58 #include "misc/htmlhashes.h"
59 #include "misc/loader.h"
60 #include "xml/dom2_eventsimpl.h"
61 #include "xml/dom2_rangeimpl.h"
62 #include "xml/xml_tokenizer.h"
63
64 using namespace DOM;
65
66 #include "khtmlview.h"
67 #include <kparts/partmanager.h>
68 #include "ecma/kjs_proxy.h"
69 #include "khtml_settings.h"
70
71 #include <sys/types.h>
72 #include <assert.h>
73 #include <unistd.h>
74
75 #include <kstandarddirs.h>
76 #include <kio/job.h>
77 #include <kio/global.h>
78 #include <kdebug.h>
79 #include <kiconloader.h>
80 #include <klocale.h>
81 #include <kcharsets.h>
82 #include <kmessagebox.h>
83 #include <kstdaction.h>
84 #include <kfiledialog.h>
85 #include <ktrader.h>
86 #include <kdatastream.h>
87 #include <ktempfile.h>
88 #include <kglobalsettings.h>
89 #include <kurldrag.h>
90 #include <kapplication.h>
91 #if !defined(QT_NO_DRAGANDDROP)
92 #include <kmultipledrag.h>
93 #endif
94
95 #include <ksslcertchain.h>
96 #include <ksslinfodlg.h>
97
98 #include <qclipboard.h>
99 #include <qfile.h>
100 #include <qmetaobject.h>
101 #include <qptrlist.h>
102 #include <private/qucomextra_p.h>
103
104 #include "khtmlpart_p.h"
105
106 #if !KHTML_NO_CPLUSPLUS_DOM
107 #include "dom/html_document.h"
108 #endif
109
110 #if APPLE_CHANGES
111 #include <CoreServices/CoreServices.h>
112 #endif
113
114 using khtml::ApplyStyleCommand;
115 using khtml::CHARACTER;
116 using khtml::ChildFrame;
117 using khtml::Decoder;
118 using khtml::EAffinity;
119 using khtml::EditAction;
120 using khtml::EditCommandPtr;
121 using khtml::ETextGranularity;
122 using khtml::FormData;
123 using khtml::InlineTextBox;
124 using khtml::isEndOfDocument;
125 using khtml::isStartOfDocument;
126 using khtml::PARAGRAPH;
127 using khtml::plainText;
128 using khtml::RenderObject;
129 using khtml::RenderText;
130 using khtml::RenderWidget;
131 using khtml::Selection;
132 using khtml::Tokenizer;
133 using khtml::TypingCommand;
134 using khtml::VisiblePosition;
135 using khtml::WORD;
136
137 using KParts::BrowserInterface;
138
139 const int CARET_BLINK_FREQUENCY = 500;
140
141 namespace khtml {
142     class PartStyleSheetLoader : public CachedObjectClient
143     {
144     public:
145         PartStyleSheetLoader(KHTMLPart *part, DOM::DOMString url, DocLoader* dl)
146         {
147             m_part = part;
148             m_cachedSheet = Cache::requestStyleSheet(dl, url );
149             if (m_cachedSheet)
150                 m_cachedSheet->ref( this );
151         }
152         virtual ~PartStyleSheetLoader()
153         {
154             if ( m_cachedSheet ) m_cachedSheet->deref(this);
155         }
156         virtual void setStyleSheet(const DOM::DOMString&, const DOM::DOMString &sheet)
157         {
158           if ( m_part )
159             m_part->setUserStyleSheet( sheet.string() );
160
161             delete this;
162         }
163         QGuardedPtr<KHTMLPart> m_part;
164         khtml::CachedCSSStyleSheet *m_cachedSheet;
165     };
166 }
167
168 FrameList::Iterator FrameList::find( const QString &name )
169 {
170     Iterator it = begin();
171     Iterator e = end();
172
173     for (; it!=e; ++it )
174         if ( (*it).m_name==name )
175             break;
176
177     return it;
178 }
179
180 KHTMLPart::KHTMLPart( QWidget *parentWidget, const char *widgetname, QObject *parent, const char *name,
181                       GUIProfile prof )
182 : KParts::ReadOnlyPart( parent, name )
183 {
184     d = 0;
185     KHTMLFactory::registerPart( this );
186     setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
187 #if !APPLE_CHANGES
188     init( new KHTMLView( this, parentWidget, widgetname ), prof );
189 #endif
190 }
191
192 #if !APPLE_CHANGES
193
194 KHTMLPart::KHTMLPart( KHTMLView *view, QObject *parent, const char *name, GUIProfile prof )
195 : KParts::ReadOnlyPart( parent, name )
196 {
197     d = 0;
198     KHTMLFactory::registerPart( this );
199     setInstance( KHTMLFactory::instance(), prof == BrowserViewGUI && !parentPart() );
200     assert( view );
201     init( view, prof );
202 }
203
204 #endif // APPLE_CHANGES
205
206 void KHTMLPart::init( KHTMLView *view, GUIProfile prof )
207 {
208   AtomicString::init();
209   if ( prof == DefaultGUI )
210     setXMLFile( "khtml.rc" );
211   else if ( prof == BrowserViewGUI )
212     setXMLFile( "khtml_browser.rc" );
213
214   frameCount = 0;
215
216   d = new KHTMLPartPrivate(parent());
217
218   d->m_view = view;
219   setWidget( d->m_view );
220   
221 #if !APPLE_CHANGES
222   d->m_guiProfile = prof;
223 #endif
224   d->m_extension = new KHTMLPartBrowserExtension( this );
225   d->m_hostExtension = new KHTMLPartBrowserHostExtension( this );
226
227   d->m_bSecurityInQuestion = false;
228   d->m_bMousePressed = false;
229 #if !APPLE_CHANGES
230   d->m_paLoadImages = 0;
231   d->m_paViewDocument = new KAction( i18n( "View Document Source" ), 0, this, SLOT( slotViewDocumentSource() ), actionCollection(), "viewDocumentSource" );
232   d->m_paViewFrame = new KAction( i18n( "View Frame Source" ), 0, this, SLOT( slotViewFrameSource() ), actionCollection(), "viewFrameSource" );
233   d->m_paSaveBackground = new KAction( i18n( "Save &Background Image As..." ), 0, this, SLOT( slotSaveBackground() ), actionCollection(), "saveBackground" );
234   d->m_paSaveDocument = new KAction( i18n( "&Save As..." ), CTRL+Key_S, this, SLOT( slotSaveDocument() ), actionCollection(), "saveDocument" );
235   if ( parentPart() )
236       d->m_paSaveDocument->setShortcut( KShortcut() ); // avoid clashes
237   d->m_paSaveFrame = new KAction( i18n( "Save &Frame As..." ), 0, this, SLOT( slotSaveFrame() ), actionCollection(), "saveFrame" );
238   d->m_paSecurity = new KAction( i18n( "Security..." ), "decrypted", 0, this, SLOT( slotSecurity() ), actionCollection(), "security" );
239   d->m_paDebugRenderTree = new KAction( "print rendering tree to stdout", 0, this, SLOT( slotDebugRenderTree() ), actionCollection(), "debugRenderTree" );
240   d->m_paDebugDOMTree = new KAction( "print DOM tree to stdout", 0, this, SLOT( slotDebugDOMTree() ), actionCollection(), "debugDOMTree" );
241
242   QString foo1 = i18n("Show Images");
243   QString foo2 = i18n("Show Animated Images");
244   QString foo3 = i18n("Stop Animated Images");
245
246   d->m_paSetEncoding = new KSelectAction( i18n( "Set &Encoding" ), 0, this, SLOT( slotSetEncoding() ), actionCollection(), "setEncoding" );
247   QStringList encodings = KGlobal::charsets()->descriptiveEncodingNames();
248   encodings.prepend( i18n( "Auto" ) );
249   d->m_paSetEncoding->setItems( encodings );
250   d->m_paSetEncoding->setCurrentItem(0);
251
252   d->m_paUseStylesheet = new KSelectAction( i18n( "&Use Stylesheet"), 0, this, SLOT( slotUseStylesheet() ), actionCollection(), "useStylesheet" );
253
254   d->m_paIncZoomFactor = new KHTMLZoomFactorAction( this, true, i18n( "Increase Font Sizes" ), "viewmag+", this, SLOT( slotIncZoom() ), actionCollection(), "incFontSizes" );
255   d->m_paDecZoomFactor = new KHTMLZoomFactorAction( this, false, i18n( "Decrease Font Sizes" ), "viewmag-", this, SLOT( slotDecZoom() ), actionCollection(), "decFontSizes" );
256
257   d->m_paFind = KStdAction::find( this, SLOT( slotFind() ), actionCollection(), "find" );
258   if ( parentPart() )
259       d->m_paFind->setShortcut( KShortcut() ); // avoid clashes
260
261   d->m_paPrintFrame = new KAction( i18n( "Print Frame" ), "frameprint", 0, this, SLOT( slotPrintFrame() ), actionCollection(), "printFrame" );
262
263   d->m_paSelectAll = KStdAction::selectAll( this, SLOT( slotSelectAll() ), actionCollection(), "selectAll" );
264   if ( parentPart() )
265       d->m_paSelectAll->setShortcut( KShortcut() ); // avoid clashes
266 #endif
267
268 #if !APPLE_CHANGES
269   // set the default java(script) flags according to the current host.
270   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled();
271   d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled();
272   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled();
273   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled();
274 #else
275   // The java, javascript, and plugin settings will be set after the settings
276   // have been initialized.
277   d->m_bJScriptEnabled = true;
278   d->m_bJScriptDebugEnabled = true;
279   d->m_bJavaEnabled = true;
280   d->m_bPluginsEnabled = true;
281 #endif
282
283 #if !APPLE_CHANGES
284   connect( this, SIGNAL( completed() ),
285            this, SLOT( updateActions() ) );
286   connect( this, SIGNAL( completed( bool ) ),
287            this, SLOT( updateActions() ) );
288   connect( this, SIGNAL( started( KIO::Job * ) ),
289            this, SLOT( updateActions() ) );
290
291   d->m_popupMenuXML = KXMLGUIFactory::readConfigFile( locate( "data", "khtml/khtml_popupmenu.rc", KHTMLFactory::instance() ) );
292 #endif
293
294   connect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
295            this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
296   connect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
297            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
298   connect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
299            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
300
301 #if !APPLE_CHANGES
302   findTextBegin(); //reset find variables
303 #endif
304
305   connect( &d->m_redirectionTimer, SIGNAL( timeout() ),
306            this, SLOT( slotRedirect() ) );
307
308   connect(&d->m_lifeSupportTimer, SIGNAL(timeout()), this, SLOT(slotEndLifeSupport()));
309
310 #if !APPLE_CHANGES
311   d->m_dcopobject = new KHTMLPartIface(this);
312 #endif
313 }
314
315 KHTMLPart::~KHTMLPart()
316 {
317   //kdDebug(6050) << "KHTMLPart::~KHTMLPart " << this << endl;
318 #if !APPLE_CHANGES
319   if ( d->m_findDialog )
320       disconnect( d->m_findDialog, SIGNAL( destroyed() ),
321                   this, SLOT( slotFindDialogDestroyed() ) );
322
323   if ( d->m_manager )
324   {
325     d->m_manager->setActivePart( 0 );
326     // Shouldn't we delete d->m_manager here ? (David)
327     // No need to, I would say. We specify "this" as parent qobject
328     // in ::partManager() (Simon)
329   }
330 #endif
331
332   stopAutoScroll();
333   cancelRedirection();
334
335   if (!d->m_bComplete)
336     closeURL();
337
338   disconnect( khtml::Cache::loader(), SIGNAL( requestStarted( khtml::DocLoader*, khtml::CachedObject* ) ),
339            this, SLOT( slotLoaderRequestStarted( khtml::DocLoader*, khtml::CachedObject* ) ) );
340   disconnect( khtml::Cache::loader(), SIGNAL( requestDone( khtml::DocLoader*, khtml::CachedObject *) ),
341            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
342   disconnect( khtml::Cache::loader(), SIGNAL( requestFailed( khtml::DocLoader*, khtml::CachedObject *) ),
343            this, SLOT( slotLoaderRequestDone( khtml::DocLoader*, khtml::CachedObject *) ) );
344
345   clear();
346
347   if ( d->m_view )
348   {
349     d->m_view->hide();
350     d->m_view->viewport()->hide();
351     d->m_view->m_part = 0;
352   }
353   
354 #if APPLE_CHANGES
355   delete d->m_hostExtension;
356 #endif
357
358   delete d; d = 0;
359   KHTMLFactory::deregisterPart( this );
360 }
361
362 bool KHTMLPart::restoreURL( const KURL &url )
363 {
364   kdDebug( 6050 ) << "KHTMLPart::restoreURL " << url.url() << endl;
365
366   cancelRedirection();
367
368   /*
369    * That's not a good idea as it will call closeURL() on all
370    * child frames, preventing them from further loading. This
371    * method gets called from restoreState() in case of a full frameset
372    * restoral, and restoreState() calls closeURL() before restoring
373    * anyway.
374   kdDebug( 6050 ) << "closing old URL" << endl;
375   closeURL();
376   */
377
378   d->m_bComplete = false;
379   d->m_bLoadEventEmitted = false;
380   d->m_workingURL = url;
381
382   // set the java(script) flags according to the current host.
383 #if !APPLE_CHANGES
384   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
385   d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled();
386   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
387   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
388 #else
389   d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled(url.host());
390   d->m_bJScriptDebugEnabled = d->m_settings->isJavaScriptDebugEnabled();
391   d->m_bJavaEnabled = d->m_settings->isJavaEnabled(url.host());
392   d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled(url.host());
393 #endif
394
395   m_url = url;
396
397   KHTMLPageCache::self()->fetchData( d->m_cacheId, this, SLOT(slotRestoreData(const QByteArray &)));
398
399   emit started( 0L );
400
401   return true;
402 }
403
404
405 #if APPLE_CHANGES
406 bool KHTMLPart::didOpenURL(const KURL &url)
407 #else
408 bool KHTMLPart::openURL( const KURL &url )
409 #endif
410 {
411   kdDebug( 6050 ) << "KHTMLPart(" << this << ")::openURL " << url.url() << endl;
412
413   if (d->m_scheduledRedirection == locationChangeScheduledDuringLoad) {
414     // We're about to get a redirect that happened before the document was
415     // created.  This can happen when one frame may change the location of a 
416     // sibling.
417     return false;
418   }
419   
420   cancelRedirection();
421   
422   // clear last edit command
423   d->m_lastEditCommand = EditCommandPtr();
424 #if APPLE_CHANGES
425   KWQ(this)->clearUndoRedoOperations();
426 #endif
427   
428 #if !APPLE_CHANGES
429   // check to see if this is an "error://" URL. This is caused when an error
430   // occurs before this part was loaded (e.g. KonqRun), and is passed to
431   // khtmlpart so that it can display the error.
432   if ( url.protocol() == "error" && url.hasSubURL() ) {
433     closeURL();
434     /**
435      * The format of the error url is that two variables are passed in the query:
436      * error = int kio error code, errText = QString error text from kio
437      * and the URL where the error happened is passed as a sub URL.
438      */
439     KURL::List urls = KURL::split( url );
440     //kdDebug() << "Handling error URL. URL count:" << urls.count() << endl;
441
442     if ( urls.count() > 1 ) {
443       KURL mainURL = urls.first();
444       int error = mainURL.queryItem( "error" ).toInt();
445       // error=0 isn't a valid error code, so 0 means it's missing from the URL
446       if ( error == 0 ) error = KIO::ERR_UNKNOWN;
447       QString errorText = mainURL.queryItem( "errText" );
448       urls.pop_front();
449       d->m_workingURL = KURL::join( urls );
450       //kdDebug() << "Emitting fixed URL " << d->m_workingURL.prettyURL() << endl;
451       emit d->m_extension->setLocationBarURL( d->m_workingURL.prettyURL() );
452       htmlError( error, errorText, d->m_workingURL );
453       return true;
454     }
455   }
456 #endif // APPLE_CHANGES
457
458   KParts::URLArgs args( d->m_extension->urlArgs() );
459
460 #if !APPLE_CHANGES
461   // in case we have a) no frameset (don't test m_frames.count(), iframes get in there)
462   // b) the url is identical with the currently
463   // displayed one (except for the htmlref!) , c) the url request is not a POST
464   // operation and d) the caller did not request to reload the page we try to
465   // be smart and instead of reloading the whole document we just jump to the
466   // request html anchor
467   if (d->m_doc) {
468       bool isFrameSet = false;
469       if ( d->m_doc->isHTMLDocument() ) {
470           HTMLDocumentImpl* htmlDoc = static_cast<HTMLDocumentImpl*>(d->m_doc);
471           isFrameSet = htmlDoc->body() && (htmlDoc->body()->id() == ID_FRAMESET);
472       }
473       if ( !isFrameSet &&
474            urlcmp( url.url(), m_url.url(), true, true ) &&
475            url.hasRef() && !args.doPost() && !args.reload )
476       {
477         kdDebug( 6050 ) << "KHTMLPart::openURL, jumping to anchor. m_url = " << url.url() << endl;
478         m_url = url;
479         emit started( 0L );
480
481         gotoAnchor();
482
483         d->m_bComplete = true;
484         d->m_doc->setParsing(false);
485
486         kdDebug( 6050 ) << "completed..." << endl;
487         emit completed();
488         return true;
489       }
490   }
491 #endif // APPLE_CHANGES
492
493   if (!d->m_restored)
494   {
495     kdDebug( 6050 ) << "closing old URL" << endl;
496     closeURL();
497   }
498
499 #if !APPLE_CHANGES
500   args.metaData().insert("main_frame_request", parentPart() == 0 ? "TRUE" : "FALSE" );
501   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE" : "FALSE" );
502   args.metaData().insert("ssl_activate_warnings", "TRUE" );
503 #endif
504
505   if (d->m_restored)
506      d->m_cachePolicy = KIO::CC_Cache;
507   else if (args.reload)
508      d->m_cachePolicy = KIO::CC_Refresh;
509   else
510      d->m_cachePolicy = KIO::CC_Verify;
511
512   if ( args.doPost() && (url.protocol().startsWith("http")) )
513   {
514       d->m_job = KIO::http_post( url, args.postData, false );
515       d->m_job->addMetaData("content-type", args.contentType() );
516   }
517   else
518   {
519       d->m_job = KIO::get( url, false, false );
520       d->m_job->addMetaData("cache", KIO::getCacheControlString(d->m_cachePolicy));
521   }
522
523   d->m_job->addMetaData(args.metaData());
524
525   connect( d->m_job, SIGNAL( result( KIO::Job * ) ),
526            SLOT( slotFinished( KIO::Job * ) ) );
527 #if !APPLE_CHANGES
528   connect( d->m_job, SIGNAL( data( KIO::Job*, const QByteArray &)),
529            SLOT( slotData( KIO::Job*, const QByteArray &)));
530 #endif
531
532   connect( d->m_job, SIGNAL(redirection(KIO::Job*, const KURL&) ),
533            SLOT( slotRedirection(KIO::Job*,const KURL&) ) );
534
535   d->m_bComplete = false;
536   d->m_bLoadingMainResource = true;
537   d->m_bLoadEventEmitted = false;
538
539   // delete old status bar msg's from kjs (if it _was_ activated on last URL)
540   if( d->m_bJScriptEnabled )
541   {
542      d->m_kjsStatusBarText = QString::null;
543      d->m_kjsDefaultStatusBarText = QString::null;
544   }
545
546   // set the javascript flags according to the current url
547 #if !APPLE_CHANGES
548   d->m_bJScriptDebugEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptDebugEnabled();
549   d->m_bJavaEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaEnabled(url.host());
550   d->m_bPluginsEnabled = KHTMLFactory::defaultHTMLSettings()->isPluginsEnabled(url.host());
551 #else
552   d->m_bJScriptDebugEnabled = d->m_settings->isJavaScriptDebugEnabled();
553   d->m_bJavaEnabled = d->m_settings->isJavaEnabled(url.host());
554   d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled(url.host());
555 #endif
556
557   // 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
558   // data arrives) (Simon)
559   m_url = url;
560   if(m_url.protocol().startsWith( "http" ) && !m_url.host().isEmpty() &&
561      m_url.path().isEmpty()) {
562     m_url.setPath("/");
563     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
564   }
565   // copy to m_workingURL after fixing m_url above
566   d->m_workingURL = m_url;
567
568   kdDebug( 6050 ) << "KHTMLPart::openURL now (before started) m_url = " << m_url.url() << endl;
569
570   connect( d->m_job, SIGNAL( speed( KIO::Job*, unsigned long ) ),
571            this, SLOT( slotJobSpeed( KIO::Job*, unsigned long ) ) );
572
573   connect( d->m_job, SIGNAL( percent( KIO::Job*, unsigned long ) ),
574            this, SLOT( slotJobPercent( KIO::Job*, unsigned long ) ) );
575
576   emit started( 0L );
577
578   return true;
579 }
580
581 void KHTMLPart::didExplicitOpen()
582 {
583   d->m_bComplete = false;
584   d->m_bLoadEventEmitted = false;
585 }
586
587
588 bool KHTMLPart::closeURL()
589 {    
590     if (d->m_doc && d->m_doc->tokenizer()) {
591         d->m_doc->tokenizer()->stopParsing();
592     }
593     
594   if ( d->m_job )
595   {
596     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
597     d->m_job->kill();
598     d->m_job = 0;
599   }
600
601   if ( d->m_doc && d->m_doc->isHTMLDocument() ) {
602     HTMLDocumentImpl* hdoc = static_cast<HTMLDocumentImpl*>( d->m_doc );
603
604     if ( hdoc->body() && d->m_bLoadEventEmitted && !d->m_bUnloadEventEmitted ) {
605       hdoc->body()->dispatchWindowEvent( EventImpl::UNLOAD_EVENT, false, false );
606       if ( d->m_doc )
607         d->m_doc->updateRendering();
608       d->m_bUnloadEventEmitted = true;
609     }
610   }
611     
612   d->m_bComplete = true; // to avoid emitting completed() in slotFinishedParsing() (David)
613   d->m_bLoadingMainResource = false;
614   d->m_bLoadEventEmitted = true; // don't want that one either
615   d->m_cachePolicy = KIO::CC_Verify; // Why here?
616
617   KHTMLPageCache::self()->cancelFetch(this);
618   if ( d->m_doc && d->m_doc->parsing() )
619   {
620     kdDebug( 6050 ) << " was still parsing... calling end " << endl;
621     slotFinishedParsing();
622     d->m_doc->setParsing(false);
623   }
624
625   if ( !d->m_workingURL.isEmpty() )
626   {
627     // Aborted before starting to render
628     kdDebug( 6050 ) << "Aborted before starting to render, reverting location bar to " << m_url.prettyURL() << endl;
629     emit d->m_extension->setLocationBarURL( m_url.prettyURL() );
630   }
631
632   d->m_workingURL = KURL();
633
634   if ( d->m_doc && d->m_doc->docLoader() )
635     khtml::Cache::loader()->cancelRequests( d->m_doc->docLoader() );
636
637   // tell all subframes to stop as well
638   ConstFrameIt it = d->m_frames.begin();
639   ConstFrameIt end = d->m_frames.end();
640   for (; it != end; ++it )
641     if ( !( *it ).m_part.isNull() )
642       ( *it ).m_part->closeURL();
643
644   d->m_bPendingChildRedirection = false;
645
646   // Stop any started redirections as well!! (DA)
647   cancelRedirection();
648
649 #if !KHTML_NO_CPLUSPLUS_DOM
650   // null node activated.
651   emit nodeActivated(Node());
652 #endif
653
654   return true;
655 }
656
657 #if !KHTML_NO_CPLUSPLUS_DOM
658
659 DOM::HTMLDocument KHTMLPart::htmlDocument() const
660 {
661   if (d->m_doc && d->m_doc->isHTMLDocument())
662     return static_cast<HTMLDocumentImpl*>(d->m_doc);
663   else
664     return static_cast<HTMLDocumentImpl*>(0);
665 }
666
667 DOM::Document KHTMLPart::document() const
668 {
669     return d->m_doc;
670 }
671
672 #endif
673
674 KParts::BrowserExtension *KHTMLPart::browserExtension() const
675 {
676   return d->m_extension;
677 }
678
679 KHTMLView *KHTMLPart::view() const
680 {
681   return d->m_view;
682 }
683
684 void KHTMLPart::setJScriptEnabled( bool enable )
685 {
686   if ( !enable && jScriptEnabled() && d->m_jscript ) {
687     d->m_jscript->clear();
688   }
689   d->m_bJScriptForce = enable;
690   d->m_bJScriptOverride = true;
691 }
692
693 bool KHTMLPart::jScriptEnabled() const
694 {
695   if ( d->m_bJScriptOverride )
696       return d->m_bJScriptForce;
697   return d->m_bJScriptEnabled;
698 }
699
700 void KHTMLPart::setMetaRefreshEnabled( bool enable )
701 {
702   d->m_metaRefreshEnabled = enable;
703 }
704
705 bool KHTMLPart::metaRefreshEnabled() const
706 {
707   return d->m_metaRefreshEnabled;
708 }
709
710 // Define this to disable dlopening kjs_html, when directly linking to it.
711 // You need to edit khtml/Makefile.am to add ./ecma/libkjs_html.la to LIBADD
712 // and to edit khtml/ecma/Makefile.am to s/kjs_html/libkjs_html/, remove libkhtml from LIBADD,
713 //        remove LDFLAGS line, and replace kde_module with either lib (shared) or noinst (static)
714 //#define DIRECT_LINKAGE_TO_ECMA
715
716 #ifdef DIRECT_LINKAGE_TO_ECMA
717 extern "C" { KJSProxy *kjs_html_init(KHTMLPart *khtmlpart); }
718 #endif
719
720 KJSProxy *KHTMLPart::jScript()
721 {
722   if (!jScriptEnabled()){
723     return 0;
724   }
725
726   if ( !d->m_jscript )
727   {
728 #ifndef DIRECT_LINKAGE_TO_ECMA
729     KLibrary *lib = KLibLoader::self()->library("kjs_html");
730     if ( !lib ) {
731       setJScriptEnabled( false );
732       return 0;
733     }
734     // look for plain C init function
735     void *sym = lib->symbol("kjs_html_init");
736     if ( !sym ) {
737       lib->unload();
738       setJScriptEnabled( false );
739       return 0;
740     }
741     typedef KJSProxy* (*initFunction)(KHTMLPart *);
742     initFunction initSym = (initFunction) sym;
743     d->m_jscript = (*initSym)(this);
744     d->m_kjs_lib = lib;
745 #else
746     d->m_jscript = kjs_html_init(this);
747     // d->m_kjs_lib remains 0L.
748 #endif
749     if (d->m_bJScriptDebugEnabled)
750         d->m_jscript->setDebugEnabled(true);
751   }
752
753   return d->m_jscript;
754 }
755
756 void KHTMLPart::replaceContentsWithScriptResult( const KURL &url )
757 {
758   QString script = KURL::decode_string(url.url().mid(strlen("javascript:")));
759   QVariant ret = executeScript(script);
760   
761   if (ret.type() == QVariant::String) {
762     begin();
763     write(ret.asString());
764     end();
765   }
766 }
767
768 QVariant KHTMLPart::executeScript( const QString &script, bool forceUserGesture )
769 {
770     return executeScript( 0, script, forceUserGesture );
771 }
772
773 //Enable this to see all JS scripts being executed
774 //#define KJS_VERBOSE
775
776 #if !KHTML_NO_CPLUSPLUS_DOM
777
778 QVariant KHTMLPart::executeScript( const DOM::Node &n, const QString &script, bool forceUserGesture )
779 {
780     return executeScript(n.handle(), script, forceUserGesture);
781 }
782
783 #endif
784
785 QVariant KHTMLPart::executeScript( DOM::NodeImpl *n, const QString &script, bool forceUserGesture )
786 {
787 #ifdef KJS_VERBOSE
788   kdDebug(6070) << "KHTMLPart::executeScript n=" << n.nodeName().string().latin1() << "(" << (n.isNull() ? 0 : n.nodeType()) << ") " << script << endl;
789 #endif
790   KJSProxy *proxy = jScript();
791
792   if (!proxy || proxy->paused())
793     return QVariant();
794   d->m_runningScripts++;
795   // If forceUserGesture is true, then make the script interpreter
796   // treat it as if triggered by a user gesture even if there is no
797   // current DOM event being processed.
798   QVariant ret = proxy->evaluate( forceUserGesture ? QString::null : m_url.url(), 0, script, n );
799   d->m_runningScripts--;
800   if (!d->m_runningScripts && d->m_doc && !d->m_doc->parsing() && d->m_submitForm )
801       submitFormAgain();
802     DocumentImpl::updateDocumentsRendering();
803
804 #ifdef KJS_VERBOSE
805   kdDebug(6070) << "KHTMLPart::executeScript - done" << endl;
806 #endif
807   return ret;
808 }
809
810 bool KHTMLPart::scheduleScript(DOM::NodeImpl *n, const QString& script)
811 {
812     //kdDebug(6050) << "KHTMLPart::scheduleScript "<< script << endl;
813
814     d->scheduledScript = script;
815     d->scheduledScriptNode.reset(n);
816
817     return true;
818 }
819
820 QVariant KHTMLPart::executeScheduledScript()
821 {
822   if( d->scheduledScript.isEmpty() )
823     return QVariant();
824
825   //kdDebug(6050) << "executing delayed " << d->scheduledScript << endl;
826
827   QVariant ret = executeScript( d->scheduledScriptNode.get(), d->scheduledScript );
828   d->scheduledScript = QString();
829   d->scheduledScriptNode.reset();
830
831   return ret;
832 }
833
834 void KHTMLPart::setJavaEnabled( bool enable )
835 {
836   d->m_bJavaForce = enable;
837   d->m_bJavaOverride = true;
838 }
839
840 bool KHTMLPart::javaEnabled() const
841 {
842 #ifndef Q_WS_QWS
843   if( d->m_bJavaOverride )
844       return d->m_bJavaForce;
845   return d->m_bJavaEnabled;
846 #else
847   return false;
848 #endif
849 }
850
851 KJavaAppletContext *KHTMLPart::javaContext()
852 {
853 #ifndef Q_WS_QWS
854   return d->m_javaContext;
855 #else
856   return 0;
857 #endif
858 }
859
860 KJavaAppletContext *KHTMLPart::createJavaContext()
861 {
862 #ifndef Q_WS_QWS
863   if ( !d->m_javaContext ) {
864 #if APPLE_CHANGES
865       d->m_javaContext = new KJavaAppletContext(d->m_dcopobject, this);
866 #else
867       d->m_javaContext = new KJavaAppletContext(d->m_dcopobject);
868       connect( d->m_javaContext, SIGNAL(showStatus(const QString&)),
869                this, SIGNAL(setStatusBarText(const QString&)) );
870       connect( d->m_javaContext, SIGNAL(showDocument(const QString&, const QString&)),
871                this, SLOT(slotShowDocument(const QString&, const QString&)) );
872 #endif
873   }
874
875   return d->m_javaContext;
876 #else
877   return 0;
878 #endif
879 }
880
881 void KHTMLPart::setPluginsEnabled( bool enable )
882 {
883   d->m_bPluginsForce = enable;
884   d->m_bPluginsOverride = true;
885 }
886
887 bool KHTMLPart::pluginsEnabled() const
888 {
889   if ( d->m_bPluginsOverride )
890       return d->m_bPluginsForce;
891   return d->m_bPluginsEnabled;
892 }
893
894 #if !APPLE_CHANGES
895
896 void KHTMLPart::slotShowDocument( const QString &url, const QString &target )
897 {
898   // this is mostly copied from KHTMLPart::slotChildURLRequest. The better approach
899   // would be to put those functions into a single one.
900   khtml::ChildFrame *child = 0;
901   KParts::URLArgs args;
902   args.frameName = target;
903
904   QString frameName = args.frameName.lower();
905   if ( !frameName.isEmpty() )
906   {
907     if ( frameName == QString::fromLatin1( "_top" ) )
908     {
909       emit d->m_extension->openURLRequest( url, args );
910       return;
911     }
912     else if ( frameName == QString::fromLatin1( "_blank" ) )
913     {
914       emit d->m_extension->createNewWindow( url, args );
915       return;
916     }
917     else if ( frameName == QString::fromLatin1( "_parent" ) )
918     {
919       KParts::URLArgs newArgs( args );
920       newArgs.frameName = QString::null;
921
922       emit d->m_extension->openURLRequest( url, newArgs );
923       return;
924     }
925     else if ( frameName != QString::fromLatin1( "_self" ) )
926     {
927       khtml::ChildFrame *_frame = recursiveFrameRequest( url, args );
928
929       if ( !_frame )
930       {
931         emit d->m_extension->openURLRequest( url, args );
932         return;
933       }
934
935       child = _frame;
936     }
937   }
938
939   // TODO: handle child target correctly! currently the script are always executed fur the parent
940   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
941       executeScript( KURL::decode_string( url.right( url.length() - 11) ) );
942       return;
943   }
944
945   if ( child ) {
946       requestObject( child, KURL(url), args );
947   }  else if ( frameName==QString::fromLatin1("_self") ) // this is for embedded objects (via <object>) which want to replace the current document
948   {
949       KParts::URLArgs newArgs( args );
950       newArgs.frameName = QString::null;
951       emit d->m_extension->openURLRequest( KURL(url), newArgs );
952   }
953 }
954
955 #endif // APPLE_CHANGES
956
957 void KHTMLPart::slotDebugDOMTree()
958 {
959   if ( d->m_doc && d->m_doc->firstChild() )
960     qDebug("%s", createMarkup(d->m_doc->firstChild()).latin1());
961 }
962
963 void KHTMLPart::slotDebugRenderTree()
964 {
965 #ifndef NDEBUG
966   if ( d->m_doc )
967     d->m_doc->renderer()->printTree();
968 #endif
969 }
970
971 void KHTMLPart::setAutoloadImages( bool enable )
972 {
973   if ( d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable )
974     return;
975
976   if ( d->m_doc )
977     d->m_doc->docLoader()->setAutoloadImages( enable );
978
979 #if !APPLE_CHANGES
980   unplugActionList( "loadImages" );
981
982   if ( enable ) {
983     delete d->m_paLoadImages;
984     d->m_paLoadImages = 0;
985   }
986   else if ( !d->m_paLoadImages )
987     d->m_paLoadImages = new KAction( i18n( "Display Images on Page" ), "images_display", 0, this, SLOT( slotLoadImages() ), actionCollection(), "loadImages" );
988
989   if ( d->m_paLoadImages ) {
990     QPtrList<KAction> lst;
991     lst.append( d->m_paLoadImages );
992     plugActionList( "loadImages", lst );
993   }
994 #endif
995 }
996
997 bool KHTMLPart::autoloadImages() const
998 {
999   if ( d->m_doc )
1000     return d->m_doc->docLoader()->autoloadImages();
1001
1002   return true;
1003 }
1004
1005 void KHTMLPart::clear()
1006 {
1007   if ( d->m_bCleared )
1008     return;
1009   d->m_bCleared = true;
1010
1011   d->m_bClearing = true;
1012
1013 #if !APPLE_CHANGES
1014   {
1015     ConstFrameIt it = d->m_frames.begin();
1016     ConstFrameIt end = d->m_frames.end();
1017     for(; it != end; ++it )
1018     {
1019       // Stop HTMLRun jobs for frames
1020       if ( (*it).m_run )
1021         (*it).m_run->abort();
1022     }
1023   }
1024
1025   {
1026     QValueList<khtml::ChildFrame>::ConstIterator it = d->m_objects.begin();
1027     QValueList<khtml::ChildFrame>::ConstIterator end = d->m_objects.end();
1028     for(; it != end; ++it )
1029     {
1030       // Stop HTMLRun jobs for objects
1031       if ( (*it).m_run )
1032         (*it).m_run->abort();
1033     }
1034   }
1035
1036
1037   findTextBegin(); // resets d->m_findNode and d->m_findPos
1038 #endif
1039
1040   d->m_mousePressNode.reset();
1041
1042
1043   if ( d->m_doc )
1044     d->m_doc->detach();
1045
1046   // Moving past doc so that onUnload works.
1047   if ( d->m_jscript )
1048     d->m_jscript->clear();
1049
1050   if ( d->m_view )
1051     d->m_view->clear();
1052
1053   // do not dereference the document before the jscript and view are cleared, as some destructors
1054   // might still try to access the document.
1055   if ( d->m_doc )
1056     d->m_doc->deref();
1057   d->m_doc = 0;
1058
1059   if (d->m_decoder)
1060     d->m_decoder->deref();
1061   d->m_decoder = 0;
1062
1063   {
1064     ConstFrameIt it = d->m_frames.begin();
1065     ConstFrameIt end = d->m_frames.end();
1066     for(; it != end; ++it )
1067     {
1068       if ( (*it).m_part )
1069       {
1070         disconnectChild(&*it);
1071 #if !APPLE_CHANGES
1072         partManager()->removePart( (*it).m_part );
1073 #endif
1074         (*it).m_part->deref();
1075       }
1076     }
1077   }
1078   d->m_frames.clear();
1079
1080   {
1081     ConstFrameIt it = d->m_objects.begin();
1082     ConstFrameIt end = d->m_objects.end();
1083     for(; it != end; ++it )
1084     {
1085       if ( (*it).m_part )
1086       {
1087 #if !APPLE_CHANGES
1088         partManager()->removePart( (*it).m_part );
1089 #endif
1090         (*it).m_part->deref();
1091       }
1092     }
1093   }
1094   d->m_objects.clear();
1095
1096 #ifndef Q_WS_QWS
1097   delete d->m_javaContext;
1098   d->m_javaContext = 0;
1099 #endif
1100
1101   d->m_scheduledRedirection = noRedirectionScheduled;
1102   d->m_delayRedirect = 0;
1103   d->m_redirectURL = QString::null;
1104   d->m_redirectReferrer = QString::null;
1105   d->m_redirectLockHistory = true;
1106   d->m_redirectUserGesture = false;
1107   d->m_bHTTPRefresh = false;
1108   d->m_bClearing = false;
1109   d->m_frameNameId = 1;
1110   d->m_bFirstData = true;
1111
1112   d->m_bMousePressed = false;
1113
1114 #ifndef QT_NO_CLIPBOARD
1115   connect( kapp->clipboard(), SIGNAL( selectionChanged()), SLOT( slotClearSelection()));
1116 #endif
1117
1118 #if !APPLE_CHANGES
1119   d->m_totalObjectCount = 0;
1120   d->m_loadedObjects = 0;
1121   d->m_jobPercent = 0;
1122 #endif
1123
1124   if ( !d->m_haveEncoding )
1125     d->m_encoding = QString::null;
1126 #ifdef SPEED_DEBUG
1127   d->m_parsetime.restart();
1128 #endif
1129 }
1130
1131 bool KHTMLPart::openFile()
1132 {
1133   return true;
1134 }
1135
1136 DOM::DocumentImpl *KHTMLPart::xmlDocImpl() const
1137 {
1138     if ( d )
1139         return d->m_doc;
1140     return 0;
1141 }
1142
1143 void KHTMLPart::replaceDocImpl(DocumentImpl* newDoc)
1144 {
1145     if (d) {
1146         if (d->m_doc) {
1147             d->m_doc->detach();
1148             d->m_doc->deref();
1149         }
1150         d->m_doc = newDoc;
1151         if (newDoc)
1152             newDoc->ref();
1153     }
1154 }
1155
1156 /*bool KHTMLPart::isSSLInUse() const
1157 {
1158   return d->m_ssl_in_use;
1159 }*/
1160
1161 void KHTMLPart::receivedFirstData()
1162 {
1163     // Leave indented one extra for easier merging.
1164     
1165       //kdDebug( 6050 ) << "begin!" << endl;
1166
1167     begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
1168
1169
1170     d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
1171     d->m_workingURL = KURL();
1172
1173     d->m_cacheId = KHTMLPageCache::self()->createCacheEntry();
1174
1175     // When the first data arrives, the metadata has just been made available
1176 #if APPLE_CHANGES
1177     QString qData;
1178 #else
1179     d->m_bSecurityInQuestion = false;
1180     d->m_ssl_in_use = (d->m_job->queryMetaData("ssl_in_use") == "TRUE");
1181     kdDebug(6050) << "SSL in use? " << d->m_job->queryMetaData("ssl_in_use") << endl;
1182
1183     {
1184     KHTMLPart *p = parentPart();
1185     if (p && p->d->m_ssl_in_use != d->m_ssl_in_use) {
1186         while (p->parentPart()) p = p->parentPart();
1187
1188         p->d->m_paSecurity->setIcon( "halfencrypted" );
1189         p->d->m_bSecurityInQuestion = true;
1190         kdDebug(6050) << "parent setIcon half done." << endl;
1191     }
1192     }
1193
1194     d->m_paSecurity->setIcon( d->m_ssl_in_use ? "encrypted" : "decrypted" );
1195     kdDebug(6050) << "setIcon " << ( d->m_ssl_in_use ? "encrypted" : "decrypted" ) << " done." << endl;
1196
1197     // Shouldn't all of this be done only if ssl_in_use == true ? (DF)
1198
1199     d->m_ssl_peer_certificate = d->m_job->queryMetaData("ssl_peer_certificate");
1200     d->m_ssl_peer_chain = d->m_job->queryMetaData("ssl_peer_chain");
1201     d->m_ssl_peer_ip = d->m_job->queryMetaData("ssl_peer_ip");
1202     d->m_ssl_cipher = d->m_job->queryMetaData("ssl_cipher");
1203     d->m_ssl_cipher_desc = d->m_job->queryMetaData("ssl_cipher_desc");
1204     d->m_ssl_cipher_version = d->m_job->queryMetaData("ssl_cipher_version");
1205     d->m_ssl_cipher_used_bits = d->m_job->queryMetaData("ssl_cipher_used_bits");
1206     d->m_ssl_cipher_bits = d->m_job->queryMetaData("ssl_cipher_bits");
1207     d->m_ssl_cert_state = d->m_job->queryMetaData("ssl_cert_state");
1208
1209     // Check for charset meta-data
1210     QString qData = d->m_job->queryMetaData("charset");
1211     if ( !qData.isEmpty() && !d->m_haveEncoding ) // only use information if the user didn't override the settings
1212        d->m_encoding = qData;
1213 #endif // APPLE_CHANGES
1214
1215     // Support for http-refresh
1216     qData = d->m_job->queryMetaData("http-refresh");
1217     if( !qData.isEmpty() && d->m_metaRefreshEnabled )
1218     {
1219       kdDebug(6050) << "HTTP Refresh Request: " << qData << endl;
1220       double delay;
1221       int pos = qData.find( ';' );
1222       if ( pos == -1 )
1223         pos = qData.find( ',' );
1224
1225       if( pos == -1 )
1226       {
1227         delay = qData.stripWhiteSpace().toDouble();
1228 #if APPLE_CHANGES
1229         // We want a new history item if the refresh timeout > 1 second
1230         scheduleRedirection( delay, m_url.url(), delay <= 1);
1231 #else
1232         scheduleRedirection( delay, m_url.url());
1233 #endif
1234       }
1235       else
1236       {
1237         int end_pos = qData.length();
1238         delay = qData.left(pos).stripWhiteSpace().toDouble();
1239         while ( qData[++pos] == ' ' );
1240         if ( qData.find( "url", pos, false ) == pos )
1241         {
1242           pos += 3;
1243           while (qData[pos] == ' ' || qData[pos] == '=' )
1244               pos++;
1245           if ( qData[pos] == '"' )
1246           {
1247               pos++;
1248               int index = end_pos-1;
1249               while( index > pos )
1250               {
1251                 if ( qData[index] == '"' )
1252                     break;
1253                 index--;
1254               }
1255               if ( index > pos )
1256                 end_pos = index;
1257           }
1258         }
1259 #if APPLE_CHANGES
1260         // We want a new history item if the refresh timeout > 1 second
1261         scheduleRedirection( delay, d->m_doc->completeURL( qData.mid( pos, end_pos ) ), delay <= 1);
1262 #else
1263         scheduleRedirection( delay, d->m_doc->completeURL( qData.mid( pos, end_pos ) ));
1264 #endif
1265       }
1266       d->m_bHTTPRefresh = true;
1267     }
1268
1269     // Support for http last-modified
1270     d->m_lastModified = d->m_job->queryMetaData("modified");
1271     //kdDebug() << "KHTMLPart::slotData metadata modified: " << d->m_lastModified << endl;
1272 }
1273
1274 #if !APPLE_CHANGES
1275
1276 void KHTMLPart::slotData( KIO::Job* kio_job, const QByteArray &data )
1277 {
1278   assert ( d->m_job == kio_job );
1279
1280   //kdDebug( 6050 ) << "slotData: " << data.size() << endl;
1281   // The first data ?
1282   if ( !d->m_workingURL.isEmpty() )
1283     receivedFirstData( );
1284
1285   KHTMLPageCache::self()->addData(d->m_cacheId, data);
1286   write( data.data(), data.size() );
1287 }
1288
1289 void KHTMLPart::slotRestoreData(const QByteArray &data )
1290 {
1291   // The first data ?
1292   if ( !d->m_workingURL.isEmpty() )
1293   {
1294      long saveCacheId = d->m_cacheId;
1295      begin( d->m_workingURL, d->m_extension->urlArgs().xOffset, d->m_extension->urlArgs().yOffset );
1296      d->m_cacheId = saveCacheId;
1297      d->m_workingURL = KURL();
1298   }
1299
1300   //kdDebug( 6050 ) << "slotRestoreData: " << data.size() << endl;
1301   write( data.data(), data.size() );
1302
1303   if (data.size() == 0)
1304   {
1305       //kdDebug( 6050 ) << "slotRestoreData: <<end of data>>" << endl;
1306      // End of data.
1307     if (d->m_doc && d->m_doc->parsing())
1308         end(); //will emit completed()
1309   }
1310 }
1311
1312 void KHTMLPart::showError( KIO::Job* job )
1313 {
1314   kdDebug() << "KHTMLPart::showError d->m_bParsing=" << (d->m_doc && d->m_doc->parsing()) << " d->m_bComplete=" << d->m_bComplete
1315             << " d->m_bCleared=" << d->m_bCleared << endl;
1316
1317   if (job->error() == KIO::ERR_NO_CONTENT)
1318         return;
1319
1320   if ( (d->m_doc && d->m_doc->parsing()) || d->m_workingURL.isEmpty() ) // if we got any data already
1321     job->showErrorDialog( /*d->m_view*/ );
1322   else
1323   {
1324     htmlError( job->error(), job->errorText(), d->m_workingURL );
1325   }
1326 }
1327
1328 // This is a protected method, placed here because of it's relevance to showError
1329 void KHTMLPart::htmlError( int errorCode, const QString& text, const KURL& reqUrl )
1330 {
1331   kdDebug(6050) << "KHTMLPart::htmlError errorCode=" << errorCode << " text=" << text << endl;
1332   // make sure we're not executing any embedded JS
1333   bool bJSFO = d->m_bJScriptForce;
1334   bool bJSOO = d->m_bJScriptOverride;
1335   d->m_bJScriptForce = false;
1336   d->m_bJScriptOverride = true;
1337   begin();
1338   QString errText = QString::fromLatin1( "<HTML><HEAD><TITLE>" );
1339   errText += i18n( "Error while loading %1" ).arg( reqUrl.htmlURL() );
1340   errText += QString::fromLatin1( "</TITLE></HEAD><BODY><P>" );
1341   errText += i18n( "An error occured while loading <B>%1</B>:" ).arg( reqUrl.htmlURL() );
1342   errText += QString::fromLatin1( "</P><P>" );
1343   QString kioErrString = KIO::buildErrorString( errorCode, text );
1344
1345   kioErrString.replace(QRegExp("&"), QString("&amp;"));
1346   kioErrString.replace(QRegExp("<"), QString("&lt;"));
1347   kioErrString.replace(QRegExp(">"), QString("&gt;"));
1348
1349   // In case the error string has '\n' in it, replace with <BR/>
1350   kioErrString.replace( QRegExp("\n"), "<BR/>" );
1351
1352   errText += kioErrString;
1353   errText += QString::fromLatin1( "</P></BODY></HTML>" );
1354   write(errText);
1355   end();
1356
1357   d->m_bJScriptForce = bJSFO;
1358   d->m_bJScriptOverride = bJSOO;
1359
1360   // make the working url the current url, so that reload works and
1361   // emit the progress signals to advance one step in the history
1362   // (so that 'back' works)
1363   m_url = reqUrl; // same as d->m_workingURL
1364   d->m_workingURL = KURL();
1365   emit started( 0 );
1366   emit completed();
1367   return;
1368   // following disabled until 3.1
1369
1370   QString errorName, techName, description;
1371   QStringList causes, solutions;
1372
1373   QByteArray raw = KIO::rawErrorDetail( errorCode, text, &reqUrl );
1374   QDataStream stream(raw, IO_ReadOnly);
1375
1376   stream >> errorName >> techName >> description >> causes >> solutions;
1377
1378   QString url, protocol, datetime;
1379   url = reqUrl.prettyURL();
1380   protocol = reqUrl.protocol();
1381   datetime = KGlobal::locale()->formatDateTime( QDateTime::currentDateTime(),
1382                                                 false );
1383
1384   QString doc = QString::fromLatin1( "<html><head><title>" );
1385   doc += i18n( "Error: " );
1386   doc += errorName;
1387   doc += QString::fromLatin1( " - %1</title></head><body><h1>" ).arg( url );
1388   doc += i18n( "The requested operation could not be completed" );
1389   doc += QString::fromLatin1( "</h1><h2>" );
1390   doc += errorName;
1391   doc += QString::fromLatin1( "</h2>" );
1392   if ( techName != QString::null ) {
1393     doc += QString::fromLatin1( "<h2>" );
1394     doc += i18n( "Technical Reason: " );
1395     doc += techName;
1396     doc += QString::fromLatin1( "</h2>" );
1397   }
1398   doc += QString::fromLatin1( "<h3>" );
1399   doc += i18n( "Details of the Request:" );
1400   doc += QString::fromLatin1( "</h3><ul><li>" );
1401   doc += i18n( "URL: %1" ).arg( url );
1402   doc += QString::fromLatin1( "</li><li>" );
1403   if ( protocol != QString::null ) {
1404     // uncomment for 3.1... i18n change
1405     // doc += i18n( "Protocol: %1" ).arg( protocol ).arg( protocol );
1406     doc += QString::fromLatin1( "</li><li>" );
1407   }
1408   doc += i18n( "Date and Time: %1" ).arg( datetime );
1409   doc += QString::fromLatin1( "</li><li>" );
1410   doc += i18n( "Additional Information: %1" ).arg( text );
1411   doc += QString::fromLatin1( "</li></ul><h3>" );
1412   doc += i18n( "Description:" );
1413   doc += QString::fromLatin1( "</h3><p>" );
1414   doc += description;
1415   doc += QString::fromLatin1( "</p>" );
1416   if ( causes.count() ) {
1417     doc += QString::fromLatin1( "<h3>" );
1418     doc += i18n( "Possible Causes:" );
1419     doc += QString::fromLatin1( "</h3><ul><li>" );
1420     doc += causes.join( "</li><li>" );
1421     doc += QString::fromLatin1( "</li></ul>" );
1422   }
1423   if ( solutions.count() ) {
1424     doc += QString::fromLatin1( "<h3>" );
1425     doc += i18n( "Possible Solutions:" );
1426     doc += QString::fromLatin1( "</h3><ul><li>" );
1427     doc += solutions.join( "</li><li>" );
1428     doc += QString::fromLatin1( "</li></ul>" );
1429   }
1430   doc += QString::fromLatin1( "</body></html>" );
1431
1432   write( doc );
1433   end();
1434 }
1435
1436 #endif
1437
1438 void KHTMLPart::slotFinished( KIO::Job * job )
1439 {
1440   if (job->error())
1441   {
1442     KHTMLPageCache::self()->cancelEntry(d->m_cacheId);
1443     d->m_job = 0L;
1444 #if !APPLE_CHANGES
1445     emit canceled( job->errorString() );
1446 #endif
1447     // TODO: what else ?
1448     checkCompleted();
1449 #if !APPLE_CHANGES
1450     showError( job );
1451 #endif
1452     return;
1453   }
1454   //kdDebug( 6050 ) << "slotFinished" << endl;
1455
1456   KHTMLPageCache::self()->endData(d->m_cacheId);
1457
1458   if ( d->m_doc && d->m_doc->docLoader()->expireDate() && m_url.protocol().lower().startsWith("http"))
1459       KIO::http_update_cache(m_url, false, d->m_doc->docLoader()->expireDate());
1460
1461   d->m_workingURL = KURL();
1462   d->m_job = 0L;
1463
1464   if (d->m_doc->parsing())
1465       end(); //will emit completed()
1466 }
1467
1468 #if APPLE_CHANGES
1469 void KHTMLPart::childBegin()
1470 {
1471     // We need to do this when the child is created so as to avoid the bogus state of the parent's
1472     // child->m_bCompleted being false but the child's m_bComplete being true.  If the child gets
1473     // an error early on, we had trouble where checkingComplete on the child was a NOP because
1474     // it thought it was already complete, and thus the parent was never signaled, and never set
1475     // its child->m_bComplete.
1476     d->m_bComplete = false;
1477 }
1478 #endif
1479
1480 void KHTMLPart::begin( const KURL &url, int xOffset, int yOffset )
1481 {
1482 #if APPLE_CHANGES
1483   // If we aren't loading an actual URL, then we need to make sure
1484   // that we have at least an empty document. createEmptyDocument will
1485   // do that if we don't have a document already.
1486   if (d->m_workingURL.isEmpty()) {
1487     KWQ(this)->createEmptyDocument();
1488   }
1489 #endif
1490
1491   clear();
1492
1493 #if APPLE_CHANGES
1494   KWQ(this)->partClearedInBegin();
1495 #endif
1496
1497   // Only do this after clearing the part, so that JavaScript can
1498   // clean up properly if it was on for the last load.
1499 #if !APPLE_CHANGES
1500   d->m_bJScriptEnabled = KHTMLFactory::defaultHTMLSettings()->isJavaScriptEnabled(url.host());
1501 #else
1502   d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled(url.host());
1503 #endif
1504
1505   d->m_bCleared = false;
1506   d->m_cacheId = 0;
1507   d->m_bComplete = false;
1508   d->m_bLoadEventEmitted = false;
1509   d->m_bLoadingMainResource = true;
1510
1511   if(url.isValid()) {
1512 #if APPLE_CHANGES
1513       KHTMLFactory::vLinks()->insert( KWQ(this)->requestedURLString() );
1514 #else
1515       QString urlString = url.url();
1516       KHTMLFactory::vLinks()->insert( urlString );
1517       QString urlString2 = url.prettyURL();
1518       if ( urlString != urlString2 ) {
1519           KHTMLFactory::vLinks()->insert( urlString2 );
1520       }
1521 #endif
1522   }
1523
1524   // ###
1525   //stopParser();
1526
1527   KParts::URLArgs args( d->m_extension->urlArgs() );
1528   args.xOffset = xOffset;
1529   args.yOffset = yOffset;
1530   d->m_extension->setURLArgs( args );
1531
1532   KURL ref(url);
1533   ref.setUser(QSTRING_NULL);
1534   ref.setPass(QSTRING_NULL);
1535   ref.setRef(QSTRING_NULL);
1536   d->m_referrer = ref.url();
1537   m_url = url;
1538   KURL baseurl;
1539
1540 #if APPLE_CHANGES
1541   // We don't need KDE chained URI handling or window caption setting
1542   if ( !m_url.isEmpty() )
1543   {
1544     baseurl = m_url;
1545   }
1546 #else
1547   if ( !m_url.isEmpty() )
1548   {
1549     KURL::List lst = KURL::split( m_url );
1550     if ( !lst.isEmpty() )
1551       baseurl = *lst.begin();
1552
1553     KURL title( baseurl );
1554     title.setRef( QString::null );
1555     title.setQuery( QString::null );
1556     emit setWindowCaption( title.url() );
1557   }
1558   else
1559     emit setWindowCaption( i18n( "no title", "* Unknown *" ) );
1560 #endif
1561
1562   if (args.serviceType == "text/xml" || args.serviceType == "application/xml" || args.serviceType == "application/xhtml+xml" ||
1563       args.serviceType == "text/xsl" || args.serviceType == "application/rss+xml" || args.serviceType == "application/atom+xml")
1564     d->m_doc = DOMImplementationImpl::instance()->createDocument( d->m_view );
1565   else
1566     d->m_doc = DOMImplementationImpl::instance()->createHTMLDocument( d->m_view );
1567
1568   d->m_doc->ref();
1569   if (!d->m_doc->attached())
1570     d->m_doc->attach( );
1571   d->m_doc->setURL( m_url.url() );
1572   // We prefer m_baseURL over m_url because m_url changes when we are
1573   // about to load a new page.
1574   d->m_doc->setBaseURL( baseurl.url() );
1575 #if APPLE_CHANGES
1576   if (d->m_decoder)
1577     d->m_doc->setDecoder(d->m_decoder);
1578 #endif
1579 #if !APPLE_CHANGES
1580   d->m_doc->docLoader()->setShowAnimations( KHTMLFactory::defaultHTMLSettings()->showAnimations() );
1581 #else
1582   d->m_doc->docLoader()->setShowAnimations( d->m_settings->showAnimations() );
1583 #endif
1584
1585 #if APPLE_CHANGES
1586   KWQ(this)->updatePolicyBaseURL();
1587 #endif
1588
1589 #if !APPLE_CHANGES
1590   d->m_paUseStylesheet->setItems(QStringList());
1591   d->m_paUseStylesheet->setEnabled( false );
1592 #endif
1593
1594 #if !APPLE_CHANGES
1595   setAutoloadImages( KHTMLFactory::defaultHTMLSettings()->autoLoadImages() );
1596   QString userStyleSheet = KHTMLFactory::defaultHTMLSettings()->userStyleSheet();
1597 #else
1598   setAutoloadImages( d->m_settings->autoLoadImages() );
1599   QString userStyleSheet = d->m_settings->userStyleSheet();
1600 #endif
1601
1602   if ( !userStyleSheet.isEmpty() )
1603     setUserStyleSheet( KURL( userStyleSheet ) );
1604
1605 #if APPLE_CHANGES
1606   KWQ(this)->restoreDocumentState();
1607 #else
1608   d->m_doc->setRestoreState(args.docState);
1609 #endif
1610
1611   d->m_doc->implicitOpen();
1612   // clear widget
1613   if (d->m_view)
1614     d->m_view->resizeContents( 0, 0 );
1615   connect(d->m_doc,SIGNAL(finishedParsing()),this,SLOT(slotFinishedParsing()));
1616
1617 #if !APPLE_CHANGES
1618   emit d->m_extension->enableAction( "print", true );
1619 #endif
1620 }
1621
1622 void KHTMLPart::write( const char *str, int len )
1623 {
1624     if ( !d->m_decoder ) {
1625         d->m_decoder = new Decoder;
1626         if (!d->m_encoding.isNull())
1627             d->m_decoder->setEncoding(d->m_encoding.latin1(),
1628                 d->m_haveEncoding ? Decoder::UserChosenEncoding : Decoder::EncodingFromHTTPHeader);
1629         else {
1630             // Inherit the default encoding from the parent frame if there is one.
1631             const char *defaultEncoding = (parentPart() && parentPart()->d->m_decoder)
1632                 ? parentPart()->d->m_decoder->encoding() : settings()->encoding().latin1();
1633             d->m_decoder->setEncoding(defaultEncoding, Decoder::DefaultEncoding);
1634         }
1635 #if APPLE_CHANGES
1636         if (d->m_doc)
1637             d->m_doc->setDecoder(d->m_decoder);
1638 #endif
1639     }
1640   if ( len == 0 )
1641     return;
1642
1643   if ( len == -1 )
1644     len = strlen( str );
1645
1646   QString decoded = d->m_decoder->decode( str, len );
1647
1648   if(decoded.isEmpty()) return;
1649
1650   if(d->m_bFirstData) {
1651       // determine the parse mode
1652       d->m_doc->determineParseMode( decoded );
1653       d->m_bFirstData = false;
1654
1655   //kdDebug(6050) << "KHTMLPart::write haveEnc = " << d->m_haveEncoding << endl;
1656       // ### this is still quite hacky, but should work a lot better than the old solution
1657       if(d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
1658       d->m_doc->recalcStyle( NodeImpl::Force );
1659   }
1660
1661   if (jScript())
1662     jScript()->appendSourceFile(m_url.url(),decoded);
1663   Tokenizer* t = d->m_doc->tokenizer();
1664
1665   if(t)
1666     t->write( decoded, true );
1667 }
1668
1669 void KHTMLPart::write( const QString &str )
1670 {
1671   if ( str.isNull() )
1672     return;
1673
1674   if(d->m_bFirstData) {
1675       // determine the parse mode
1676       d->m_doc->setParseMode( DocumentImpl::Strict );
1677       d->m_bFirstData = false;
1678   }
1679   if (jScript())
1680     jScript()->appendSourceFile(m_url.url(),str);
1681   Tokenizer* t = d->m_doc->tokenizer();
1682   if(t)
1683     t->write( str, true );
1684 }
1685
1686 void KHTMLPart::end()
1687 {
1688     d->m_bLoadingMainResource = false;
1689     endIfNotLoading();
1690 }
1691
1692 void KHTMLPart::endIfNotLoading()
1693 {
1694     if (d->m_bLoadingMainResource)
1695         return;
1696
1697     // make sure nothing's left in there...
1698     if (d->m_decoder)
1699         write(d->m_decoder->flush());
1700     if (d->m_doc)
1701         d->m_doc->finishParsing();
1702     else
1703         // WebKit partially uses WebCore when loading non-HTML docs.  In these cases doc==nil, but
1704         // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
1705         // become true.  An example is when a subframe is a pure text doc, and that subframe is the
1706         // last one to complete.
1707         checkCompleted();
1708 }
1709
1710 void KHTMLPart::stop()
1711 {
1712     // make sure nothing's left in there...
1713     Tokenizer* t = d->m_doc ? d->m_doc->tokenizer() : 0;
1714     if (t)
1715         t->stopped();
1716     if (d->m_doc)
1717         d->m_doc->finishParsing();
1718     else
1719         // WebKit partially uses WebCore when loading non-HTML docs.  In these cases doc==nil, but
1720         // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
1721         // become true.  An example is when a subframe is a pure text doc, and that subframe is the
1722         // last one to complete.
1723         checkCompleted();
1724 }
1725
1726 #if !APPLE_CHANGES
1727
1728 void KHTMLPart::paint(QPainter *p, const QRect &rc, int yOff, bool *more)
1729 {
1730     if (!d->m_view) return;
1731     d->m_view->paint(p, rc, yOff, more);
1732 }
1733
1734 #endif
1735
1736 void KHTMLPart::stopAnimations()
1737 {
1738   if ( d->m_doc )
1739     d->m_doc->docLoader()->setShowAnimations( KHTMLSettings::KAnimationDisabled );
1740
1741   ConstFrameIt it = d->m_frames.begin();
1742   ConstFrameIt end = d->m_frames.end();
1743   for (; it != end; ++it )
1744     if ( !( *it ).m_part.isNull() && ( *it ).m_part->inherits( "KHTMLPart" ) ) {
1745       KParts::ReadOnlyPart* p = ( *it ).m_part;
1746       static_cast<KHTMLPart*>( p )->stopAnimations();
1747     }
1748 }
1749
1750 void KHTMLPart::gotoAnchor()
1751 {
1752     if (m_url.hasRef()) {
1753         QString ref = m_url.encodedHtmlRef();
1754         if (!gotoAnchor(ref)) {
1755             // Can't use htmlRef() here because it doesn't know which encoding to use to decode.
1756             // Decoding here has to match encoding in completeURL, which means it has to use the
1757             // page's encoding rather than UTF-8.
1758             if (d->m_decoder)
1759 #if !APPLE_CHANGES
1760                 gotoAnchor(KURL::decode_string(ref, d->m_decoder->codec()->mibEnum()));
1761 #else
1762                 gotoAnchor(KURL::decode_string(ref, d->m_decoder->codec()));
1763 #endif
1764         }
1765     }
1766 }
1767
1768 void KHTMLPart::slotFinishedParsing()
1769 {
1770   d->m_doc->setParsing(false);
1771
1772   if (!d->m_view)
1773     return; // We are probably being destructed.
1774     
1775   checkCompleted();
1776
1777   if (!d->m_view)
1778     return; // We are being destroyed by something checkCompleted called.
1779
1780   // check if the scrollbars are really needed for the content
1781   // if not, remove them, relayout, and repaint
1782
1783   d->m_view->restoreScrollBar();
1784   gotoAnchor();
1785 }
1786
1787 void KHTMLPart::slotLoaderRequestStarted( khtml::DocLoader* dl, khtml::CachedObject *obj )
1788 {
1789 #if !APPLE_CHANGES
1790   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
1791     KHTMLPart* p = this;
1792     while ( p ) {
1793       KHTMLPart* op = p;
1794       p->d->m_totalObjectCount++;
1795       p = p->parentPart();
1796       if ( !p && d->m_loadedObjects <= d->m_totalObjectCount )
1797         QTimer::singleShot( 200, op, SLOT( slotProgressUpdate() ) );
1798     }
1799   }
1800 #endif
1801 }
1802
1803 void KHTMLPart::slotLoaderRequestDone( khtml::DocLoader* dl, khtml::CachedObject *obj )
1804 {
1805 #if !APPLE_CHANGES
1806   if ( obj && obj->type() == khtml::CachedObject::Image && d->m_doc && d->m_doc->docLoader() == dl ) {
1807     KHTMLPart* p = this;
1808     while ( p ) {
1809       KHTMLPart* op = p;
1810       p->d->m_loadedObjects++;
1811       p = p->parentPart();
1812       if ( !p && d->m_loadedObjects <= d->m_totalObjectCount && d->m_jobPercent >= 100 )
1813         QTimer::singleShot( 200, op, SLOT( slotProgressUpdate() ) );
1814     }
1815   }
1816 #endif
1817   // We really only need to call checkCompleted when our own resources are done loading.
1818   // So we should check that d->m_doc->docLoader() == dl here.
1819   // That might help with performance by skipping some unnecessary work, but it's too
1820   // risky to make that change right now (2005-02-07), because we might be accidentally
1821   // depending on the extra checkCompleted calls.
1822   if (d->m_doc) {
1823     checkCompleted();
1824   }
1825 }
1826
1827 #if !APPLE_CHANGES
1828
1829 void KHTMLPart::slotProgressUpdate()
1830 {
1831   int percent;
1832   if ( d->m_loadedObjects < d->m_totalObjectCount )
1833     percent = d->m_jobPercent / 4 + ( d->m_loadedObjects*300 ) / ( 4*d->m_totalObjectCount );
1834   else
1835     percent = d->m_jobPercent;
1836
1837   if ( d->m_loadedObjects < d->m_totalObjectCount && percent >= 75 )
1838     emit d->m_extension->infoMessage( i18n( "%1 of 1 Image loaded", "%1 of %n Images loaded", d->m_totalObjectCount ).arg( d->m_loadedObjects ) );
1839
1840   emit d->m_extension->loadingProgress( percent );
1841 }
1842
1843 void KHTMLPart::slotJobSpeed( KIO::Job* /*job*/, unsigned long speed )
1844 {
1845   emit d->m_extension->speedProgress( speed );
1846 }
1847
1848 void KHTMLPart::slotJobPercent( KIO::Job* /*job*/, unsigned long percent )
1849 {
1850   d->m_jobPercent = percent;
1851
1852   if ( !parentPart() )
1853     QTimer::singleShot( 0, this, SLOT( slotProgressUpdate() ) );
1854 }
1855
1856 #endif
1857
1858 void KHTMLPart::checkCompleted()
1859 {
1860 //   kdDebug( 6050 ) << "KHTMLPart::checkCompleted() parsing: " << d->m_doc->parsing() << endl;
1861 //   kdDebug( 6050 ) << "                           complete: " << d->m_bComplete << endl;
1862
1863 #if !APPLE_CHANGES
1864   // restore the cursor position
1865   if (d->m_doc && !d->m_doc->parsing() && !d->m_focusNodeRestored)
1866   {
1867       if (d->m_focusNodeNumber >= 0)
1868           d->m_doc->setFocusNode(d->m_doc->nodeWithAbsIndex(d->m_focusNodeNumber));
1869       else
1870           d->m_doc->setFocusNode(0);
1871       d->m_focusNodeRestored = true;
1872   }
1873 #endif
1874
1875   // Any frame that hasn't completed yet ?
1876   ConstFrameIt it = d->m_frames.begin();
1877   ConstFrameIt end = d->m_frames.end();
1878   for (; it != end; ++it )
1879     if ( !(*it).m_bCompleted )
1880       return;
1881
1882   // Have we completed before?
1883   if ( d->m_bComplete )
1884     return;
1885
1886   // Are we still parsing?
1887   if ( d->m_doc && d->m_doc->parsing() )
1888     return;
1889
1890   // Still waiting for images/scripts from the loader ?
1891   int requests = 0;
1892   if ( d->m_doc && d->m_doc->docLoader() )
1893     requests = khtml::Cache::loader()->numRequests( d->m_doc->docLoader() );
1894
1895   if ( requests > 0 )
1896     return;
1897
1898   // OK, completed.
1899   // Now do what should be done when we are really completed.
1900   d->m_bComplete = true;
1901
1902   checkEmitLoadEvent(); // if we didn't do it before
1903
1904 #if !APPLE_CHANGES
1905   // check that the view has not been moved by the user  
1906   if ( !m_url.hasRef() && d->m_view->contentsY() == 0 )
1907       d->m_view->setContentsPos( d->m_extension->urlArgs().xOffset,
1908                                  d->m_extension->urlArgs().yOffset );
1909 #endif
1910
1911   if ( d->m_scheduledRedirection != noRedirectionScheduled )
1912   {
1913     // Do not start redirection for frames here! That action is
1914     // deferred until the parent emits a completed signal.
1915     if ( parentPart() == 0 )
1916       d->m_redirectionTimer.start( (int)(1000 * d->m_delayRedirect), true );
1917
1918     emit completed( true );
1919   }
1920   else
1921   {
1922     if ( d->m_bPendingChildRedirection )
1923       emit completed ( true );
1924     else
1925       emit completed();
1926   }
1927
1928 #if !APPLE_CHANGES
1929   // find the alternate stylesheets
1930   QStringList sheets;
1931   if (d->m_doc)
1932      sheets = d->m_doc->availableStyleSheets();
1933   d->m_paUseStylesheet->setItems( sheets );
1934   d->m_paUseStylesheet->setEnabled( !sheets.isEmpty() );
1935   if (!sheets.isEmpty())
1936   {
1937     d->m_paUseStylesheet->setCurrentItem(kMax(sheets.findIndex(d->m_sheetUsed), 0));
1938     slotUseStylesheet();
1939   }
1940
1941   if (!parentPart())
1942       emit setStatusBarText(i18n("Done."));
1943 #endif
1944
1945 #ifdef SPEED_DEBUG
1946   kdDebug(6050) << "DONE: " <<d->m_parsetime.elapsed() << endl;
1947 #endif
1948 }
1949
1950 void KHTMLPart::checkEmitLoadEvent()
1951 {
1952   if ( d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing() ) return;
1953
1954   ConstFrameIt it = d->m_frames.begin();
1955   ConstFrameIt end = d->m_frames.end();
1956   for (; it != end; ++it )
1957     if ( !(*it).m_bCompleted ) // still got a frame running -> too early
1958       return;
1959
1960
1961   // All frames completed -> set their domain to the frameset's domain
1962   // This must only be done when loading the frameset initially (#22039),
1963   // not when following a link in a frame (#44162).
1964   if ( d->m_doc )
1965   {
1966     DOMString domain = d->m_doc->domain();
1967     ConstFrameIt it = d->m_frames.begin();
1968     ConstFrameIt end = d->m_frames.end();
1969     for (; it != end; ++it )
1970     {
1971       KParts::ReadOnlyPart *p = (*it).m_part;
1972       if ( p && p->inherits( "KHTMLPart" ))
1973       {
1974         KHTMLPart* htmlFrame = static_cast<KHTMLPart *>(p);
1975         if (htmlFrame->d->m_doc)
1976         {
1977           kdDebug() << "KHTMLPart::checkCompleted setting frame domain to " << domain.string() << endl;
1978           htmlFrame->d->m_doc->setDomain( domain );
1979         }
1980       }
1981     }
1982   }
1983
1984   d->m_bLoadEventEmitted = true;
1985   d->m_bUnloadEventEmitted = false;
1986   if (d->m_doc)
1987     d->m_doc->implicitClose();
1988 }
1989
1990 const KHTMLSettings *KHTMLPart::settings() const
1991 {
1992   return d->m_settings;
1993 }
1994
1995 #ifndef KDE_NO_COMPAT
1996 KURL KHTMLPart::baseURL() const
1997 {
1998   if ( !d->m_doc ) return KURL();
1999
2000   return d->m_doc->baseURL();
2001 }
2002
2003 QString KHTMLPart::baseTarget() const
2004 {
2005   if ( !d->m_doc ) return QString::null;
2006
2007   return d->m_doc->baseTarget();
2008 }
2009 #endif
2010
2011 KURL KHTMLPart::completeURL( const QString &url )
2012 {
2013   if ( !d->m_doc ) return url;
2014
2015 #if !APPLE_CHANGES
2016   if (d->m_decoder)
2017     return KURL(d->m_doc->completeURL(url), d->m_decoder->codec()->mibEnum());
2018 #endif
2019
2020   return KURL( d->m_doc->completeURL( url ) );
2021 }
2022
2023 void KHTMLPart::scheduleRedirection( double delay, const QString &url, bool doLockHistory)
2024 {
2025     kdDebug(6050) << "KHTMLPart::scheduleRedirection delay=" << delay << " url=" << url << endl;
2026     if (delay < 0 || delay > INT_MAX / 1000)
2027       return;
2028     if ( d->m_scheduledRedirection == noRedirectionScheduled || delay <= d->m_delayRedirect )
2029     {
2030        d->m_scheduledRedirection = redirectionScheduled;
2031        d->m_delayRedirect = delay;
2032        d->m_redirectURL = url;
2033        d->m_redirectReferrer = QString::null;
2034        d->m_redirectLockHistory = doLockHistory;
2035        d->m_redirectUserGesture = false;
2036
2037        d->m_redirectionTimer.stop();
2038        if ( d->m_bComplete )
2039          d->m_redirectionTimer.start( (int)(1000 * d->m_delayRedirect), true );
2040     }
2041 }
2042
2043 void KHTMLPart::scheduleLocationChange(const QString &url, const QString &referrer, bool lockHistory, bool userGesture)
2044 {
2045     // Handle a location change of a page with no document as a special case.
2046     // This may happen when a frame changes the location of another frame.
2047     d->m_scheduledRedirection = d->m_doc ? locationChangeScheduled : locationChangeScheduledDuringLoad;
2048     d->m_delayRedirect = 0;
2049     d->m_redirectURL = url;
2050     d->m_redirectReferrer = referrer;
2051     d->m_redirectLockHistory = lockHistory;
2052     d->m_redirectUserGesture = userGesture;
2053     d->m_redirectionTimer.stop();
2054     if (d->m_bComplete)
2055         d->m_redirectionTimer.start(0, true);
2056 }
2057
2058 bool KHTMLPart::isScheduledLocationChangePending() const
2059 {
2060     switch (d->m_scheduledRedirection) {
2061         case noRedirectionScheduled:
2062         case redirectionScheduled:
2063             return false;
2064         case historyNavigationScheduled:
2065         case locationChangeScheduled:
2066         case locationChangeScheduledDuringLoad:
2067             return true;
2068     }
2069     return false;
2070 }
2071
2072 void KHTMLPart::scheduleHistoryNavigation( int steps )
2073 {
2074 #if APPLE_CHANGES
2075     // navigation will always be allowed in the 0 steps case, which is OK because
2076     // that's supposed to force a reload.
2077     if (!KWQ(this)->canGoBackOrForward(steps)) {
2078         cancelRedirection();
2079         return;
2080     }
2081 #endif
2082
2083     d->m_scheduledRedirection = historyNavigationScheduled;
2084     d->m_delayRedirect = 0;
2085     d->m_redirectURL = QString::null;
2086     d->m_redirectReferrer = QString::null;
2087     d->m_scheduledHistoryNavigationSteps = steps;
2088     d->m_redirectionTimer.stop();
2089     if (d->m_bComplete)
2090         d->m_redirectionTimer.start(0, true);
2091 }
2092
2093 void KHTMLPart::cancelRedirection(bool cancelWithLoadInProgress)
2094 {
2095     if (d) {
2096         d->m_cancelWithLoadInProgress = cancelWithLoadInProgress;
2097         d->m_scheduledRedirection = noRedirectionScheduled;
2098         d->m_redirectionTimer.stop();
2099     }
2100 }
2101
2102 void KHTMLPart::slotRedirect()
2103 {
2104     if (d->m_scheduledRedirection == historyNavigationScheduled) {
2105         d->m_scheduledRedirection = noRedirectionScheduled;
2106
2107         // Special case for go(0) from a frame -> reload only the frame
2108         // go(i!=0) from a frame navigates into the history of the frame only,
2109         // in both IE and NS (but not in Mozilla).... we can't easily do that
2110         // in Konqueror...
2111         if (d->m_scheduledHistoryNavigationSteps == 0) // add && parentPart() to get only frames, but doesn't matter
2112             openURL( url() ); /// ## need args.reload=true?
2113         else {
2114             if (d->m_extension) {
2115                 BrowserInterface *interface = d->m_extension->browserInterface();
2116                 if (interface)
2117                     interface->callMethod( "goHistory(int)", d->m_scheduledHistoryNavigationSteps );
2118             }
2119         }
2120         return;
2121     }
2122   
2123   QString u = d->m_redirectURL;
2124
2125   d->m_scheduledRedirection = noRedirectionScheduled;
2126   d->m_delayRedirect = 0;
2127   d->m_redirectURL = QString::null;
2128   if ( u.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
2129   {
2130     QString script = KURL::decode_string( u.right( u.length() - 11 ) );
2131     //kdDebug( 6050 ) << "KHTMLPart::slotRedirect script=" << script << endl;
2132     QVariant res = executeScript( script, d->m_redirectUserGesture );
2133     if ( res.type() == QVariant::String ) {
2134       begin( url() );
2135       write( res.asString() );
2136       end();
2137     }
2138     return;
2139   }
2140   KParts::URLArgs args;
2141   if ( urlcmp( u, m_url.url(), true, false ) )
2142     args.reload = true;
2143
2144   args.setLockHistory( d->m_redirectLockHistory );
2145   if (!d->m_redirectReferrer.isEmpty())
2146     args.metaData()["referrer"] = d->m_redirectReferrer;
2147   d->m_redirectReferrer = QString::null;
2148
2149   urlSelected( u, 0, 0, "_self", args );
2150 }
2151
2152 void KHTMLPart::slotRedirection(KIO::Job*, const KURL& url)
2153 {
2154   // the slave told us that we got redirected
2155   // kdDebug( 6050 ) << "redirection by KIO to " << url.url() << endl;
2156   emit d->m_extension->setLocationBarURL( url.prettyURL() );
2157   d->m_workingURL = url;
2158 }
2159
2160 #if !APPLE_CHANGES
2161
2162 bool KHTMLPart::setEncoding( const QString &name, bool override )
2163 {
2164     d->m_encoding = name;
2165     d->m_haveEncoding = override;
2166
2167     if( !m_url.isEmpty() ) {
2168         // reload document
2169         closeURL();
2170         KURL url = m_url;
2171         m_url = 0;
2172         d->m_restored = true;
2173         openURL(url);
2174         d->m_restored = false;
2175     }
2176
2177     return true;
2178 }
2179
2180 #endif
2181
2182 QString KHTMLPart::encoding() const
2183 {
2184     if(d->m_haveEncoding && !d->m_encoding.isEmpty())
2185         return d->m_encoding;
2186
2187     if(d->m_decoder && d->m_decoder->encoding())
2188         return QString(d->m_decoder->encoding());
2189
2190     return(settings()->encoding());
2191 }
2192
2193 void KHTMLPart::setUserStyleSheet(const KURL &url)
2194 {
2195   if ( d->m_doc && d->m_doc->docLoader() )
2196     (void) new khtml::PartStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
2197 }
2198
2199 void KHTMLPart::setUserStyleSheet(const QString &styleSheet)
2200 {
2201   if ( d->m_doc )
2202     d->m_doc->setUserStyleSheet( styleSheet );
2203 }
2204
2205 bool KHTMLPart::gotoAnchor( const QString &name )
2206 {
2207   if (!d->m_doc)
2208     return false;
2209
2210   NodeImpl *n = d->m_doc->getElementById(name);
2211   if (!n) {
2212     HTMLCollectionImpl *anchors =
2213         new HTMLCollectionImpl( d->m_doc, HTMLCollectionImpl::DOC_ANCHORS);
2214     anchors->ref();
2215     n = anchors->namedItem(name, !d->m_doc->inCompatMode());
2216     anchors->deref();
2217   }
2218
2219   d->m_doc->setCSSTarget(n); // Setting to null will clear the current target.
2220   
2221   // Implement the rule that "" and "top" both mean top of page as in other browsers.
2222   if (!n && !(name.isEmpty() || name.lower() == "top")) {
2223     kdDebug(6050) << "KHTMLPart::gotoAnchor node '" << name << "' not found" << endl;
2224     return false;
2225   }
2226
2227   // We need to update the layout before scrolling, otherwise we could
2228   // really mess things up if an anchor scroll comes at a bad moment.
2229   if ( d->m_doc ) {
2230     d->m_doc->updateRendering();
2231     // Only do a layout if changes have occurred that make it necessary.      
2232     if ( d->m_view && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout() ) {
2233       d->m_view->layout();
2234     }
2235   }
2236   
2237   int x = 0, y = 0;
2238   if (n) {
2239     static_cast<HTMLElementImpl *>(n)->getUpperLeftCorner(x, y);
2240   }
2241   // Scroll to actual top left of element with no slop, since some pages expect anchors to be exactly scrolled to.
2242 #if APPLE_CHANGES
2243   // Call recursive version so this will expose correctly from within nested frames.
2244   d->m_view->setContentsPosRecursive(x, y);
2245 #else
2246   d->m_view->setContentsPos(x, y);
2247 #endif
2248
2249   return true;
2250 }
2251
2252 void KHTMLPart::setStandardFont( const QString &name )
2253 {
2254     d->m_settings->setStdFontName(name);
2255 }
2256
2257 void KHTMLPart::setFixedFont( const QString &name )
2258 {
2259     d->m_settings->setFixedFontName(name);
2260 }
2261
2262 #if !APPLE_CHANGES
2263
2264 void KHTMLPart::setURLCursor( const QCursor &c )
2265 {
2266   d->m_linkCursor = c;
2267 }
2268
2269 #endif
2270
2271 QCursor KHTMLPart::urlCursor() const
2272 {
2273 #if APPLE_CHANGES
2274   // Don't load the link cursor until it's actually used.
2275   // Also, we don't need setURLCursor.
2276   // This speeds up startup time.
2277   return KCursor::handCursor();
2278 #else
2279   return d->m_linkCursor;
2280 #endif
2281 }
2282
2283 bool KHTMLPart::onlyLocalReferences() const
2284 {
2285   return d->m_onlyLocalReferences;
2286 }
2287
2288 void KHTMLPart::setOnlyLocalReferences(bool enable)
2289 {
2290   d->m_onlyLocalReferences = enable;
2291 }
2292
2293 #if !APPLE_CHANGES
2294
2295 void KHTMLPart::findTextBegin(NodeImpl *startNode, int startPos)
2296 {
2297     d->m_findPos = startPos;
2298     d->m_findNode = startNode;
2299 }
2300
2301 bool KHTMLPart::findTextNext( const QString &str, bool forward, bool caseSensitive, bool isRegExp )
2302 {
2303     if ( !d->m_doc )
2304         return false;
2305
2306     if(!d->m_findNode) {
2307         if (d->m_doc->isHTMLDocument())
2308             d->m_findNode = static_cast<HTMLDocumentImpl*>(d->m_doc)->body();
2309         else
2310             d->m_findNode = d->m_doc;
2311     }
2312
2313     if ( !d->m_findNode )
2314     {
2315       kdDebug() << "KHTMLPart::findTextNext no findNode -> return false" << endl;
2316       return false;
2317     }
2318     if ( d->m_findNode->id() == ID_FRAMESET )
2319     {
2320       kdDebug() << "KHTMLPart::findTextNext FRAMESET -> return false" << endl;
2321       return false;
2322     }
2323
2324     while(1)
2325     {
2326         if( (d->m_findNode->nodeType() == Node::TEXT_NODE || d->m_findNode->nodeType() == Node::CDATA_SECTION_NODE) && d->m_findNode->renderer() )
2327         {
2328             DOMString nodeText = d->m_findNode->nodeValue();
2329             DOMStringImpl *t = nodeText.implementation();
2330             QConstString s(t->s, t->l);
2331
2332             int matchLen = 0;
2333             if ( isRegExp ) {
2334               QRegExp matcher( str );
2335               matcher.setCaseSensitive( caseSensitive );
2336               d->m_findPos = matcher.search(s.string(), d->m_findPos+1);
2337               if ( d->m_findPos != -1 )
2338                 matchLen = matcher.matchedLength();
2339             }
2340             else {
2341               d->m_findPos = s.string().find(str, d->m_findPos+1, caseSensitive);
2342               matchLen = str.length();
2343             }
2344
2345             if(d->m_findPos != -1)
2346             {
2347                 int x = 0, y = 0;
2348                 static_cast<khtml::RenderText *>(d->m_findNode->renderer())
2349                   ->posOfChar(d->m_findPos, x, y);
2350                 d->m_view->setContentsPos(x-50, y-50);
2351                 Position p1(d->m_findNode, d->m_findPos);
2352                 Position p2(d->m_findNode, d->m_findPos + matchLen);
2353                 setSelection(Selection(p1, khtml::DOWNSTREAM, p2, khtml::SEL_PREFER_UPSTREAM_AFFINITY));
2354                 return true;
2355             }
2356         }
2357         d->m_findPos = -1;
2358
2359         NodeImpl *next;
2360
2361         if ( forward )
2362         {
2363           next = d->m_findNode->firstChild();
2364
2365           if(!next) next = d->m_findNode->nextSibling();
2366           while(d->m_findNode && !next) {
2367               d->m_findNode = d->m_findNode->parentNode();
2368               if( d->m_findNode ) {
2369                   next = d->m_findNode->nextSibling();
2370               }
2371           }
2372         }
2373         else
2374         {
2375           next = d->m_findNode->lastChild();
2376
2377           if (!next ) next = d->m_findNode->previousSibling();
2378           while ( d->m_findNode && !next )
2379           {
2380             d->m_findNode = d->m_findNode->parentNode();
2381             if( d->m_findNode )
2382             {
2383               next = d->m_findNode->previousSibling();
2384             }
2385           }
2386         }
2387
2388         d->m_findNode = next;
2389         if(!d->m_findNode) return false;
2390     }
2391 }
2392
2393 #endif // APPLE_CHANGES
2394
2395 #if !KHTML_NO_CPLUSPLUS_DOM
2396
2397 QString KHTMLPart::text(const DOM::Range &r) const
2398 {
2399     return plainText(r.handle());
2400 }
2401
2402 #endif
2403
2404 QString KHTMLPart::selectedText() const
2405 {
2406     return plainText(selection().toRange().get());
2407 }
2408
2409 bool KHTMLPart::hasSelection() const
2410 {
2411     return d->m_selection.isCaretOrRange();
2412 }
2413
2414 const Selection &KHTMLPart::selection() const
2415 {
2416     return d->m_selection;
2417 }
2418
2419 ETextGranularity KHTMLPart::selectionGranularity() const
2420 {
2421     return d->m_selectionGranularity;
2422 }
2423
2424 void KHTMLPart::setSelectionGranularity(ETextGranularity granularity) const
2425 {
2426     d->m_selectionGranularity = granularity;
2427 }
2428
2429 const Selection &KHTMLPart::dragCaret() const
2430 {
2431     return d->m_dragCaret;
2432 }
2433
2434 const Selection &KHTMLPart::mark() const
2435 {
2436     return d->m_mark;
2437 }
2438
2439 void KHTMLPart::setMark(const Selection &s)
2440 {
2441     d->m_mark = s;
2442 }
2443
2444 void KHTMLPart::setSelection(const Selection &s, bool closeTyping, bool keepTypingStyle)
2445 {
2446     if (d->m_selection == s) {
2447         return;
2448     }
2449     
2450     clearCaretRectIfNeeded();
2451
2452 #if APPLE_CHANGES
2453     Selection oldSelection = d->m_selection;
2454 #endif
2455
2456     d->m_selection = s;
2457     if (!s.isNone())
2458         setFocusNodeIfNeeded();
2459
2460     selectionLayoutChanged();
2461
2462     // Always clear the x position used for vertical arrow navigation.
2463     // It will be restored by the vertical arrow navigation code if necessary.
2464     d->m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation;
2465
2466     if (closeTyping)
2467         TypingCommand::closeTyping(lastEditCommand());
2468
2469     if (!keepTypingStyle)
2470         clearTypingStyle();
2471     
2472 #if APPLE_CHANGES
2473     KWQ(this)->respondToChangedSelection(oldSelection, closeTyping);
2474 #endif
2475
2476     emitSelectionChanged();
2477 }
2478
2479 void KHTMLPart::setDragCaret(const Selection &dragCaret)
2480 {
2481     if (d->m_dragCaret != dragCaret) {
2482         d->m_dragCaret.needsCaretRepaint();
2483         d->m_dragCaret = dragCaret;
2484         d->m_dragCaret.needsCaretRepaint();
2485     }
2486 }
2487
2488 void KHTMLPart::clearSelection()
2489 {
2490     setSelection(Selection());
2491 }
2492
2493 void KHTMLPart::invalidateSelection()
2494 {
2495     clearCaretRectIfNeeded();
2496     d->m_selection.setNeedsLayout();
2497     selectionLayoutChanged();
2498 }
2499
2500 void KHTMLPart::setCaretVisible(bool flag)
2501 {
2502     if (d->m_caretVisible == flag)
2503         return;
2504     clearCaretRectIfNeeded();
2505     if (flag)
2506         setFocusNodeIfNeeded();
2507     d->m_caretVisible = flag;
2508     selectionLayoutChanged();
2509 }
2510
2511 #if !APPLE_CHANGES
2512 void KHTMLPart::slotClearSelection()
2513 {
2514     clearSelection();
2515 }
2516 #endif
2517
2518 void KHTMLPart::clearCaretRectIfNeeded()
2519 {
2520     if (d->m_caretPaint) {
2521         d->m_caretPaint = false;
2522         d->m_selection.needsCaretRepaint();
2523     }        
2524 }
2525
2526 // Helper function that tells whether a particular node is an element that has an entire
2527 // KHTMLPart and KHTMLView, a <frame>, <iframe>, or <object>.
2528 static bool isFrame(const NodeImpl *n)
2529 {
2530     if (!n)
2531         return false;
2532     RenderObject *renderer = n->renderer();
2533     if (!renderer || !renderer->isWidget())
2534         return false;
2535     QWidget *widget = static_cast<RenderWidget *>(renderer)->widget();
2536     return widget && widget->inherits("KHTMLView");
2537 }
2538
2539 void KHTMLPart::setFocusNodeIfNeeded()
2540 {
2541     if (!xmlDocImpl() || d->m_selection.isNone() || !d->m_isFocused)
2542         return;
2543
2544     NodeImpl *n = d->m_selection.start().node();
2545     NodeImpl *target = (n && n->isContentEditable()) ? n : 0;
2546     if (!target) {
2547         while (n && n != d->m_selection.end().node()) {
2548             if (n->isContentEditable()) {
2549                 target = n;
2550                 break;
2551             }
2552             n = n->traverseNextNode();
2553         }
2554     }
2555     assert(target == 0 || target->isContentEditable());
2556     
2557     if (target) {
2558         for ( ; target; target = target->parentNode()) {
2559             // We don't want to set focus on a subframe when selecting in a parent frame,
2560             // so add the !isFrame check here. There's probably a better way to make this
2561             // work in the long term, but this is the safest fix at this time.
2562             if (target->isMouseFocusable() && !isFrame(target)) {
2563                 xmlDocImpl()->setFocusNode(target);
2564                 return;
2565             }
2566         }
2567         xmlDocImpl()->setFocusNode(0);
2568     }
2569 }
2570
2571 void KHTMLPart::selectionLayoutChanged()
2572 {
2573     // kill any caret blink timer now running
2574     if (d->m_caretBlinkTimer >= 0) {
2575         killTimer(d->m_caretBlinkTimer);
2576         d->m_caretBlinkTimer = -1;
2577     }
2578
2579     // see if a new caret blink timer needs to be started
2580     if (d->m_caretVisible && d->m_caretBlinks && 
2581         d->m_selection.isCaret() && d->m_selection.start().node()->isContentEditable()) {
2582         d->m_caretBlinkTimer = startTimer(CARET_BLINK_FREQUENCY);
2583         d->m_caretPaint = true;
2584         d->m_selection.needsCaretRepaint();
2585     }
2586
2587     if (d->m_doc)
2588         d->m_doc->updateSelection();
2589 }
2590
2591 void KHTMLPart::setXPosForVerticalArrowNavigation(int x)
2592 {
2593     d->m_xPosForVerticalArrowNavigation = x;
2594 }
2595
2596 int KHTMLPart::xPosForVerticalArrowNavigation() const
2597 {
2598     return d->m_xPosForVerticalArrowNavigation;
2599 }
2600
2601 void KHTMLPart::timerEvent(QTimerEvent *e)
2602 {
2603     if (e->timerId() == d->m_caretBlinkTimer && 
2604         d->m_caretVisible && 
2605         d->m_caretBlinks && 
2606         d->m_selection.isCaret()) {
2607         if (d->m_bMousePressed) {
2608             if (!d->m_caretPaint) {
2609                 d->m_caretPaint = true;
2610                 d->m_selection.needsCaretRepaint();
2611             }
2612         }
2613         else {
2614             d->m_caretPaint = !d->m_caretPaint;
2615             d->m_selection.needsCaretRepaint();
2616         }
2617     }
2618 }
2619
2620 void KHTMLPart::paintCaret(QPainter *p, const QRect &rect) const
2621 {
2622     if (d->m_caretPaint)
2623         d->m_selection.paintCaret(p, rect);
2624 }
2625
2626 void KHTMLPart::paintDragCaret(QPainter *p, const QRect &rect) const
2627 {
2628     d->m_dragCaret.paintCaret(p, rect);
2629 }
2630
2631 #if !APPLE_CHANGES
2632
2633 void KHTMLPart::overURL( const QString &url, const QString &target, bool shiftPressed )
2634 {
2635   if ( !d->m_kjsStatusBarText.isEmpty() && !shiftPressed ) {
2636     emit onURL( url );
2637     emit setStatusBarText( d->m_kjsStatusBarText );
2638     d->m_kjsStatusBarText = QString::null;
2639     return;
2640   }
2641
2642   emit onURL( url );
2643
2644   if ( url.isEmpty() )
2645   {
2646     emit setStatusBarText(completeURL(url).htmlURL());
2647     return;
2648   }
2649
2650   if (url.find( QString::fromLatin1( "javascript:" ),0, false ) != -1 )
2651   {
2652     emit setStatusBarText( KURL::decode_string( url.mid( url.find( "javascript:", 0, false ) ) ) );
2653     return;
2654   }
2655
2656   KURL u = completeURL(url);
2657
2658   // special case for <a href="">
2659   if ( url.isEmpty() )
2660     u.setFileName( url );
2661
2662   QString com;
2663
2664   KMimeType::Ptr typ = KMimeType::findByURL( u );
2665
2666   if ( typ )
2667     com = typ->comment( u, false );
2668
2669   if ( u.isMalformed() )
2670   {
2671     emit setStatusBarText(u.htmlURL());
2672     return;
2673   }
2674
2675   if ( u.isLocalFile() )
2676   {
2677     // TODO : use KIO::stat() and create a KFileItem out of its result,
2678     // to use KFileItem::statusBarText()
2679     QCString path = QFile::encodeName( u.path() );
2680
2681     struct stat buff;
2682     bool ok = !stat( path.data(), &buff );
2683
2684     struct stat lbuff;
2685     if (ok) ok = !lstat( path.data(), &lbuff );
2686
2687     QString text = u.htmlURL();
2688     QString text2 = text;
2689
2690     if (ok && S_ISLNK( lbuff.st_mode ) )
2691     {
2692       QString tmp;
2693       if ( com.isNull() )
2694         tmp = i18n( "Symbolic Link");
2695       else
2696         tmp = i18n("%1 (Link)").arg(com);
2697       char buff_two[1024];
2698       text += " -> ";
2699       int n = readlink ( path.data(), buff_two, 1022);
2700       if (n == -1)
2701       {
2702         text2 += "  ";
2703         text2 += tmp;
2704         emit setStatusBarText(text2);
2705         return;
2706       }
2707       buff_two[n] = 0;
2708
2709       text += buff_two;
2710       text += "  ";
2711       text += tmp;
2712     }
2713     else if ( ok && S_ISREG( buff.st_mode ) )
2714     {
2715       if (buff.st_size < 1024)
2716         text = i18n("%2 (%1 bytes)").arg((long) buff.st_size).arg(text2); // always put the URL last, in case it contains '%'
2717       else
2718       {
2719         float d = (float) buff.st_size/1024.0;
2720         text = i18n("%1 (%2 K)").arg(text2).arg(KGlobal::locale()->formatNumber(d, 2)); // was %.2f
2721       }
2722       text += "  ";
2723       text += com;
2724     }
2725     else if ( ok && S_ISDIR( buff.st_mode ) )
2726     {
2727       text += "  ";
2728       text += com;
2729     }
2730     else
2731     {
2732       text += "  ";
2733       text += com;
2734     }
2735     emit setStatusBarText(text);
2736   }
2737   else
2738   {
2739     QString extra;
2740     if (target == QString::fromLatin1("_blank"))
2741     {
2742       extra = i18n(" (In new window)");
2743     }
2744     else if (!target.isEmpty() &&
2745              (target != QString::fromLatin1("_top")) &&
2746              (target != QString::fromLatin1("_self")) &&
2747              (target != QString::fromLatin1("_parent")))
2748     {
2749       extra = i18n(" (In other frame)");
2750     }
2751
2752     if (u.protocol() == QString::fromLatin1("mailto")) {
2753       QString mailtoMsg/* = QString::fromLatin1("<img src=%1>").arg(locate("icon", QString::fromLatin1("locolor/16x16/actions/mail_send.png")))*/;
2754       mailtoMsg += i18n("Email to: ") + KURL::decode_string(u.path());
2755       QStringList queries = QStringList::split('&', u.query().mid(1));
2756       for (QStringList::Iterator it = queries.begin(); it != queries.end(); ++it)
2757         if ((*it).startsWith(QString::fromLatin1("subject=")))
2758           mailtoMsg += i18n(" - Subject: ") + KURL::decode_string((*it).mid(8));
2759         else if ((*it).startsWith(QString::fromLatin1("cc=")))
2760           mailtoMsg += i18n(" - CC: ") + KURL::decode_string((*it).mid(3));
2761         else if ((*it).startsWith(QString::fromLatin1("bcc=")))
2762           mailtoMsg += i18n(" - BCC: ") + KURL::decode_string((*it).mid(4));
2763       mailtoMsg.replace(QRegExp("&"), QString("&amp;"));
2764       mailtoMsg.replace(QRegExp("<"), QString("&lt;"));
2765       mailtoMsg.replace(QRegExp(">"), QString("&gt;"));
2766       mailtoMsg.replace(QRegExp("([\n\r\t]|[ ]{10})"), "");
2767       emit setStatusBarText(mailtoMsg);
2768       return;
2769     }
2770    // Is this check neccessary at all? (Frerich)
2771 #if 0
2772     else if (u.protocol() == QString::fromLatin1("http")) {
2773         DOM::Node hrefNode = nodeUnderMouse().parentNode();
2774         while (hrefNode.nodeName().string() != QString::fromLatin1("A") && !hrefNode.isNull())
2775           hrefNode = hrefNode.parentNode();
2776
2777         if (!hrefNode.isNull()) {
2778           DOM::Node hreflangNode = hrefNode.attributes().getNamedItem("HREFLANG");
2779           if (!hreflangNode.isNull()) {
2780             QString countryCode = hreflangNode.nodeValue().string().lower();
2781             // Map the language code to an appropriate country code.
2782             if (countryCode == QString::fromLatin1("en"))
2783               countryCode = QString::fromLatin1("gb");
2784             QString flagImg = QString::fromLatin1("<img src=%1>").arg(
2785                 locate("locale", QString::fromLatin1("l10n/")
2786                 + countryCode
2787                 + QString::fromLatin1("/flag.png")));
2788             emit setStatusBarText(flagImg + u.prettyURL() + extra);
2789           }
2790         }
2791       }
2792 #endif
2793     emit setStatusBarText(u.htmlURL() + extra);
2794   }
2795 }
2796
2797 #endif // APPLE_CHANGES
2798
2799 void KHTMLPart::urlSelected( const QString &url, int button, int state, const QString &_target,
2800                              KParts::URLArgs args )
2801 {
2802   bool hasTarget = false;
2803
2804   QString target = _target;
2805   if ( target.isEmpty() && d->m_doc )
2806     target = d->m_doc->baseTarget();
2807   if ( !target.isEmpty() )
2808       hasTarget = true;
2809
2810   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
2811   {
2812     executeScript( KURL::decode_string( url.right( url.length() - 11) ), true );
2813     return;
2814   }
2815
2816   KURL cURL = completeURL(url);
2817 #if !APPLE_CHANGES
2818   // special case for <a href="">
2819   if ( url.isEmpty() )
2820     cURL.setFileName( url );
2821 #endif
2822
2823   if ( !cURL.isValid() )
2824     // ### ERROR HANDLING
2825     return;
2826
2827   //kdDebug( 6000 ) << "urlSelected: complete URL:" << cURL.url() << " target = " << target << endl;
2828
2829 #if !APPLE_CHANGES
2830   if ( button == LeftButton && ( state & ShiftButton ) )
2831   {
2832     KIO::MetaData metaData;
2833     metaData["referrer"] = d->m_referrer;
2834     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As..." ), cURL, metaData );
2835     return;
2836   }
2837
2838   if (!checkLinkSecurity(cURL,
2839                          i18n( "<qt>The link <B>%1</B><BR>leads from this untrusted page to your local filesystem.<BR>Do you want to follow the link?" ),
2840                          i18n( "Follow" )))
2841     return;
2842 #endif
2843
2844   args.frameName = target;
2845
2846   if ( d->m_bHTTPRefresh )
2847   {
2848     d->m_bHTTPRefresh = false;
2849     args.metaData()["cache"] = "refresh";
2850   }
2851
2852 #if !APPLE_CHANGES
2853   args.metaData().insert("main_frame_request",
2854                          parentPart() == 0 ? "TRUE":"FALSE");
2855   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
2856   args.metaData().insert("ssl_activate_warnings", "TRUE");
2857 #endif
2858
2859 #if APPLE_CHANGES
2860   args.metaData()["referrer"] = d->m_referrer;
2861   KWQ(this)->urlSelected(cURL, button, state, args);
2862 #else
2863   if ( hasTarget )
2864   {
2865     // unknown frame names should open in a new window.
2866     khtml::ChildFrame *frame = recursiveFrameRequest( cURL, args, false );
2867     if ( frame )
2868     {
2869       args.metaData()["referrer"] = d->m_referrer;
2870       requestObject( frame, cURL, args );
2871       return;
2872     }
2873   }
2874
2875   if ( !d->m_bComplete && !hasTarget )
2876     closeURL();
2877
2878   if (!d->m_referrer.isEmpty())
2879     args.metaData()["referrer"] = d->m_referrer;
2880
2881   if ( button == MidButton && (state & ShiftButton) )
2882   {
2883     KParts::WindowArgs winArgs;
2884     winArgs.lowerWindow = true;
2885     KParts::ReadOnlyPart *newPart = 0;
2886     emit d->m_extension->createNewWindow( cURL, args, winArgs, newPart );
2887     return;
2888   }
2889   emit d->m_extension->openURLRequest( cURL, args );
2890 #endif // APPLE_CHANGES
2891 }
2892
2893 #if !APPLE_CHANGES
2894
2895 void KHTMLPart::slotViewDocumentSource()
2896 {
2897   KURL url(m_url);
2898   if (!(url.isLocalFile()) && KHTMLPageCache::self()->isValid(d->m_cacheId))
2899   {
2900      KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
2901      if (sourceFile.status() == 0)
2902      {
2903         KHTMLPageCache::self()->saveData(d->m_cacheId, sourceFile.dataStream());
2904         url = KURL();
2905         url.setPath(sourceFile.name());
2906      }
2907   }
2908
2909   //  emit d->m_extension->openURLRequest( m_url, KParts::URLArgs( false, 0, 0, QString::fromLatin1( "text/plain" ) ) );
2910   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
2911 }
2912
2913 void KHTMLPart::slotViewFrameSource()
2914 {
2915   KParts::ReadOnlyPart *frame = currentFrame();
2916   if ( !frame )
2917     return;
2918
2919   KURL url = frame->url();
2920   if (!(url.isLocalFile()) && frame->inherits("KHTMLPart"))
2921   {
2922        long cacheId = static_cast<KHTMLPart *>(frame)->d->m_cacheId;
2923
2924        if (KHTMLPageCache::self()->isValid(cacheId))
2925        {
2926            KTempFile sourceFile(QString::null, QString::fromLatin1(".html"));
2927            if (sourceFile.status() == 0)
2928            {
2929                KHTMLPageCache::self()->saveData(cacheId, sourceFile.dataStream());
2930                url = KURL();
2931                url.setPath(sourceFile.name());
2932            }
2933      }
2934   }
2935
2936   (void) KRun::runURL( url, QString::fromLatin1("text/plain") );
2937 }
2938
2939 KURL KHTMLPart::backgroundURL() const
2940 {
2941   // ### what about XML documents? get from CSS?
2942   if (!d->m_doc || !d->m_doc->isHTMLDocument())
2943     return KURL();
2944
2945   QString relURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
2946
2947   return KURL( m_url, relURL );
2948 }
2949
2950 void KHTMLPart::slotSaveBackground()
2951 {
2952   KIO::MetaData metaData;
2953   metaData["referrer"] = d->m_referrer;
2954   KHTMLPopupGUIClient::saveURL( d->m_view, i18n("Save background image as"), backgroundURL(), metaData );
2955 }
2956
2957 void KHTMLPart::slotSaveDocument()
2958 {
2959   KURL srcURL( m_url );
2960
2961   if ( srcURL.fileName(false).isEmpty() )
2962     srcURL.setFileName( "index.html" );
2963
2964   KIO::MetaData metaData;
2965   // Referre unknown?
2966   KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files"), d->m_cacheId );
2967 }
2968
2969 void KHTMLPart::slotSecurity()
2970 {
2971 //   kdDebug( 6050 ) << "Meta Data:" << endl
2972 //                   << d->m_ssl_peer_cert_subject
2973 //                   << endl
2974 //                   << d->m_ssl_peer_cert_issuer
2975 //                   << endl
2976 //                   << d->m_ssl_cipher
2977 //                   << endl
2978 //                   << d->m_ssl_cipher_desc
2979 //                   << endl
2980 //                   << d->m_ssl_cipher_version
2981 //                   << endl
2982 //                   << d->m_ssl_good_from
2983 //                   << endl
2984 //                   << d->m_ssl_good_until
2985 //                   << endl
2986 //                   << d->m_ssl_cert_state
2987 //                   << endl;
2988
2989   KSSLInfoDlg *kid = new KSSLInfoDlg(d->m_ssl_in_use, widget(), "kssl_info_dlg", true );
2990
2991   if (d->m_bSecurityInQuestion)
2992           kid->setSecurityInQuestion(true);
2993
2994   if (d->m_ssl_in_use) {
2995     KSSLCertificate *x = KSSLCertificate::fromString(d->m_ssl_peer_certificate.local8Bit());
2996     if (x) {
2997        // Set the chain back onto the certificate
2998        QStringList cl = QStringList::split(QString("\n"), d->m_ssl_peer_chain);
2999        QPtrList<KSSLCertificate> ncl;
3000
3001        ncl.setAutoDelete(true);
3002        for (QStringList::Iterator it = cl.begin(); it != cl.end(); ++it) {
3003           KSSLCertificate *y = KSSLCertificate::fromString((*it).local8Bit());
3004           if (y) ncl.append(y);
3005        }
3006
3007        if (ncl.count() > 0)
3008           x->chain().setChain(ncl);
3009
3010        kid->setup(x,
3011                   d->m_ssl_peer_ip,
3012                   m_url.url(),
3013                   d->m_ssl_cipher,
3014                   d->m_ssl_cipher_desc,
3015                   d->m_ssl_cipher_version,
3016                   d->m_ssl_cipher_used_bits.toInt(),
3017                   d->m_ssl_cipher_bits.toInt(),
3018                   (KSSLCertificate::KSSLValidation) d->m_ssl_cert_state.toInt()
3019                   );
3020         kid->exec();
3021         delete x;
3022      } else kid->exec();
3023   } else kid->exec();
3024 }
3025
3026 void KHTMLPart::slotSaveFrame()
3027 {
3028     if ( !d->m_activeFrame )
3029         return; // should never be the case, but one never knows :-)
3030
3031     KURL srcURL( static_cast<KParts::ReadOnlyPart *>( d->m_activeFrame )->url() );
3032
3033     if ( srcURL.fileName(false).isEmpty() )
3034         srcURL.setFileName( "index.html" );
3035
3036     KIO::MetaData metaData;
3037     // Referrer unknown?
3038     KHTMLPopupGUIClient::saveURL( d->m_view, i18n( "Save As" ), srcURL, metaData, i18n("*.html *.htm|HTML files") );
3039 }
3040
3041 void KHTMLPart::slotSetEncoding()
3042 {
3043     // first Item is always auto
3044     if(d->m_paSetEncoding->currentItem() == 0)
3045         setEncoding(QString::null, false);
3046     else {
3047         // strip of the language to get the raw encoding again.
3048         QString enc = KGlobal::charsets()->encodingForName(d->m_paSetEncoding->currentText());
3049         setEncoding(enc, true);
3050     }
3051 }
3052
3053 void KHTMLPart::slotUseStylesheet()
3054 {
3055   if (d->m_doc && d->m_paUseStylesheet->currentText() != d->m_sheetUsed) {
3056     d->m_sheetUsed = d->m_paUseStylesheet->currentText();
3057     d->m_doc->updateStyleSelector();
3058   }
3059 }
3060
3061 void KHTMLPart::updateActions()
3062 {
3063   bool frames = false;
3064
3065   QValueList<khtml::ChildFrame>::ConstIterator it = d->m_frames.begin();
3066   QValueList<khtml::ChildFrame>::ConstIterator end = d->m_frames.end();
3067   for (; it != end; ++it )
3068       if ( (*it).m_type == khtml::ChildFrame::Frame )
3069       {
3070           frames = true;
3071           break;
3072       }
3073
3074   d->m_paViewFrame->setEnabled( frames );
3075   d->m_paSaveFrame->setEnabled( frames );
3076
3077   if ( frames )
3078     d->m_paFind->setText( i18n( "&Find in Frame..." ) );
3079   else
3080     d->m_paFind->setText( i18n( "&Find..." ) );
3081
3082   KParts::Part *frame = 0;
3083
3084   if ( frames )
3085     frame = currentFrame();
3086
3087   bool enableFindAndSelectAll = true;
3088
3089   if ( frame )
3090     enableFindAndSelectAll = frame->inherits( "KHTMLPart" );
3091
3092   d->m_paFind->setEnabled( enableFindAndSelectAll );
3093   d->m_paSelectAll->setEnabled( enableFindAndSelectAll );
3094
3095   bool enablePrintFrame = false;
3096
3097   if ( frame )
3098   {
3099     QObject *ext = KParts::BrowserExtension::childObject( frame );
3100     if ( ext )
3101       enablePrintFrame = ext->metaObject()->slotNames().contains( "print()" );
3102   }
3103
3104   d->m_paPrintFrame->setEnabled( enablePrintFrame );
3105
3106   QString bgURL;
3107
3108   // ### frames
3109   if ( d->m_doc && d->m_doc->isHTMLDocument() && static_cast<HTMLDocumentImpl*>(d->m_doc)->body() && !d->m_bClearing )
3110     bgURL = static_cast<HTMLDocumentImpl*>(d->m_doc)->body()->getAttribute( ATTR_BACKGROUND ).string();
3111
3112   d->m_paSaveBackground->setEnabled( !bgURL.isEmpty() );
3113 }
3114
3115 #endif
3116
3117 bool KHTMLPart::requestFrame( khtml::RenderPart *frame, const QString &url, const QString &frameName,
3118                               const QStringList &paramNames, const QStringList &paramValues, bool isIFrame )
3119 {
3120 //  kdDebug( 6050 ) << "childRequest( ..., " << url << ", " << frameName << " )" << endl;
3121   FrameIt it = d->m_frames.find( frameName );
3122   if ( it == d->m_frames.end() )
3123   {
3124     khtml::ChildFrame child;
3125 //    kdDebug( 6050 ) << "inserting new frame into frame map " << frameName << endl;
3126     child.m_name = frameName;
3127     it = d->m_frames.append( child );
3128   }
3129
3130   (*it).m_type = isIFrame ? khtml::ChildFrame::IFrame : khtml::ChildFrame::Frame;
3131   (*it).m_frame = frame;
3132   (*it).m_paramValues = paramNames;
3133   (*it).m_paramNames = paramValues;
3134
3135   // Support for <frame src="javascript:string">
3136   if ( url.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 )
3137   {
3138     if (!processObjectRequest(&(*it), "about:blank", "text/html" ))
3139       return false;
3140
3141     KHTMLPart *newPart = static_cast<KHTMLPart *>(&*(*it).m_part); 
3142     newPart->replaceContentsWithScriptResult( url );
3143
3144     return true;
3145   }
3146
3147   return requestObject( &(*it), completeURL( url ));
3148 }
3149
3150 QString KHTMLPart::requestFrameName()
3151 {
3152 #if APPLE_CHANGES
3153     return KWQ(this)->generateFrameName();
3154 #else
3155     return QString::fromLatin1("<!--frame %1-->").arg(d->m_frameNameId++);
3156 #endif
3157 }
3158
3159 bool KHTMLPart::requestObject( khtml::RenderPart *frame, const QString &url, const QString &serviceType,
3160                                const QStringList &paramNames, const QStringList &paramValues )
3161 {
3162   khtml::ChildFrame child;
3163   QValueList<khtml::ChildFrame>::Iterator it = d->m_objects.append( child );
3164   (*it).m_frame = frame;
3165   (*it).m_type = khtml::ChildFrame::Object;
3166   (*it).m_paramNames = paramNames;
3167   (*it).m_paramValues = paramValues;
3168   (*it).m_hasFallbackContent = frame->hasFallbackContent();
3169
3170   KURL completedURL;
3171   if (!url.isEmpty())
3172     completedURL = completeURL(url);
3173
3174   KParts::URLArgs args;
3175   args.serviceType = serviceType;
3176   return requestObject( &(*it), completedURL, args );
3177 }
3178
3179 bool KHTMLPart::requestObject( khtml::ChildFrame *child, const KURL &url, const KParts::URLArgs &_args )
3180 {
3181 #if !APPLE_CHANGES
3182   if (!checkLinkSecurity(url))
3183     return false;
3184 #endif
3185   if ( child->m_bPreloaded )
3186   {
3187     // kdDebug(6005) << "KHTMLPart::requestObject preload" << endl;
3188     if ( child->m_frame && child->m_part && child->m_part->widget() )
3189       child->m_frame->setWidget( child->m_part->widget() );
3190
3191     child->m_bPreloaded = false;
3192     return true;
3193   }
3194
3195   KParts::URLArgs args( _args );
3196
3197 #if !APPLE_CHANGES
3198   if ( child->m_run )
3199     child->m_run->abort();
3200 #endif
3201
3202   if ( child->m_part && !args.reload && urlcmp( child->m_part->url().url(), url.url(), true, true ) )
3203     args.serviceType = child->m_serviceType;
3204
3205   child->m_args = args;
3206   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
3207   child->m_serviceName = QString::null;
3208   if (!d->m_referrer.isEmpty() && !child->m_args.metaData().contains( "referrer" ))
3209     child->m_args.metaData()["referrer"] = d->m_referrer;
3210
3211 #if !APPLE_CHANGES
3212   child->m_args.metaData().insert("main_frame_request",
3213                                   parentPart() == 0 ? "TRUE":"FALSE");
3214   child->m_args.metaData().insert("ssl_was_in_use",
3215                                   d->m_ssl_in_use ? "TRUE":"FALSE");
3216   child->m_args.metaData().insert("ssl_activate_warnings", "TRUE");
3217 #endif
3218
3219   // We want a KHTMLPart if the HTML says <frame src=""> or <frame src="about:blank">
3220   if ((url.isEmpty() || url.url() == "about:blank") && args.serviceType.isEmpty())
3221     args.serviceType = QString::fromLatin1( "text/html" );
3222
3223 #if APPLE_CHANGES
3224   return processObjectRequest( child, url, args.serviceType );
3225 #else
3226   if ( args.serviceType.isEmpty() ) {
3227     child->m_run = new KHTMLRun( this, child, url, child->m_args,
3228                                  child->m_type != khtml::ChildFrame::Frame );
3229     return false;
3230   } else {
3231     return processObjectRequest( child, url, args.serviceType );
3232   }
3233 #endif
3234 }
3235
3236 bool KHTMLPart::processObjectRequest( khtml::ChildFrame *child, const KURL &_url, const QString &mimetype )
3237 {
3238   //kdDebug( 6050 ) << "KHTMLPart::processObjectRequest trying to create part for " << mimetype << endl;
3239
3240   // IMPORTANT: create a copy of the url here, because it is just a reference, which was likely to be given
3241   // by an emitting frame part (emit openURLRequest( blahurl, ... ) . A few lines below we delete the part
3242   // though -> the reference becomes invalid -> crash is likely
3243   KURL url( _url );
3244
3245   // khtmlrun called us this way to indicate a loading error
3246   if ( d->m_onlyLocalReferences || ( url.isEmpty() && mimetype.isEmpty() ) )
3247   {
3248       checkEmitLoadEvent();
3249       child->m_bCompleted = true;
3250       return true;
3251   }
3252
3253   if (child->m_bNotify)
3254   {
3255       child->m_bNotify = false;
3256       if ( !child->m_args.lockHistory() )
3257           emit d->m_extension->openURLNotify();
3258   }
3259
3260 #if APPLE_CHANGES
3261   if ( child->m_part )
3262   {
3263     KHTMLPart *part = static_cast<KHTMLPart *>(&*child->m_part);
3264     if (part && part->inherits("KHTMLPart")) {
3265       KParts::URLArgs args;
3266       if (!d->m_referrer.isEmpty())
3267         args.metaData()["referrer"] = d->m_referrer;
3268       KWQ(part)->openURLRequest(url, args);
3269     }
3270   }
3271   else
3272   {
3273     KParts::ReadOnlyPart *part = KWQ(this)->createPart(*child, url, mimetype);
3274     KHTMLPart *khtml_part = static_cast<KHTMLPart *>(part);
3275     if (khtml_part && khtml_part->inherits("KHTMLPart"))
3276       khtml_part->childBegin();
3277 #else
3278   if ( !child->m_services.contains( mimetype ) )
3279   {
3280     KParts::ReadOnlyPart *part = createPart( d->m_view->viewport(), child->m_name.ascii(), this, child->m_name.ascii(), mimetype, child->m_serviceName, child->m_services, child->m_params );
3281 #endif
3282
3283     if (!part) {
3284         checkEmitLoadEvent();
3285         return false;
3286     }
3287
3288     //CRITICAL STUFF
3289     if ( child->m_part )
3290     {
3291       disconnectChild(child);
3292 #if !APPLE_CHANGES
3293       partManager()->removePart( (KParts::ReadOnlyPart *)child->m_part );
3294 #endif
3295       child->m_part->deref();
3296     }
3297
3298     child->m_serviceType = mimetype;
3299     if ( child->m_frame && part->widget() )
3300       child->m_frame->setWidget( part->widget() );
3301
3302 #if !APPLE_CHANGES
3303     if ( child->m_type != khtml::ChildFrame::Object )
3304       partManager()->addPart( part, false );
3305 //  else
3306 //      kdDebug(6005) << "AH! NO FRAME!!!!!" << endl;
3307 #endif
3308
3309     child->m_part = part;
3310     assert( ((void*) child->m_part) != 0);
3311
3312     connectChild(child);
3313
3314 #if APPLE_CHANGES
3315   }
3316 #else
3317     child->m_extension = KParts::BrowserExtension::childObject( part );
3318
3319     if ( child->m_extension )
3320     {
3321       connect( child->m_extension, SIGNAL( openURLNotify() ),
3322                d->m_extension, SIGNAL( openURLNotify() ) );
3323
3324       connect( child->m_extension, SIGNAL( openURLRequestDelayed( const KURL &, const KParts::URLArgs & ) ),
3325                this, SLOT( slotChildURLRequest( const KURL &, const KParts::URLArgs & ) ) );
3326
3327       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ),
3328                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & ) ) );
3329       connect( child->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs &, const KParts::WindowArgs &, KParts::ReadOnlyPart *& ) ),
3330                d->m_extension, SIGNAL( createNewWindow( const KURL &, const KParts::URLArgs & , const KParts::WindowArgs &, KParts::ReadOnlyPart *&) ) );
3331
3332       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ),
3333                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KFileItemList & ) ) );
3334       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ),
3335                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KFileItemList & ) ) );
3336       connect( child->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ),
3337                d->m_extension, SIGNAL( popupMenu( const QPoint &, const KURL &, const QString &, mode_t ) ) );
3338       connect( child->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ),
3339                d->m_extension, SIGNAL( popupMenu( KXMLGUIClient *, const QPoint &, const KURL &, const QString &, mode_t ) ) );
3340
3341       connect( child->m_extension, SIGNAL( infoMessage( const QString & ) ),
3342                d->m_extension, SIGNAL( infoMessage( const QString & ) ) );
3343
3344       child->m_extension->setBrowserInterface( d->m_extension->browserInterface() );
3345     }
3346   }
3347 #endif
3348
3349   checkEmitLoadEvent();
3350   // Some JS code in the load event may have destroyed the part
3351   // In that case, abort
3352   if ( !child->m_part )
3353     return false;
3354
3355   if ( child->m_bPreloaded )
3356   {
3357     if ( child->m_frame && child->m_part )
3358       child->m_frame->setWidget( child->m_part->widget() );
3359
3360     child->m_bPreloaded = false;
3361     return true;
3362   }
3363
3364   child->m_args.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
3365
3366   // make sure the part has a way to find out about the mimetype.
3367   // we actually set it in child->m_args in requestObject already,
3368   // but it's useless if we had to use a KHTMLRun instance, as the
3369   // point the run object is to find out exactly the mimetype.
3370   child->m_args.serviceType = mimetype;
3371
3372   child->m_bCompleted = false;
3373   if ( child->m_extension )
3374     child->m_extension->setURLArgs( child->m_args );
3375
3376 #if APPLE_CHANGES
3377   // In these cases, the synchronous load would have finished
3378   // before we could connect the signals, so make sure to send the 
3379   // completed() signal for the child by hand
3380   // FIXME: In this case the KHTMLPart will have finished loading before 
3381   // it's being added to the child list.  It would be a good idea to
3382   // create the child first, then invoke the loader separately  
3383   if (url.isEmpty() || url.url() == "about:blank") {
3384       ReadOnlyPart *readOnlyPart = child->m_part;
3385       KHTMLPart *part = static_cast<KHTMLPart *>(readOnlyPart);
3386       if (part && part->inherits("KHTMLPart")) {
3387           part->completed();
3388           part->checkCompleted();
3389       }
3390   }
3391 #else
3392   if(url.protocol() == "javascript" || url.url() == "about:blank") {
3393       if (!child->m_part->inherits("KHTMLPart"))
3394           return false;
3395
3396       KHTMLPart* p = static_cast<KHTMLPart*>(static_cast<KParts::ReadOnlyPart *>(child->m_part));
3397
3398       p->begin();
3399       if (d->m_doc && p->d->m_doc)
3400         p->d->m_doc->setBaseURL(d->m_doc->baseURL());
3401       if (!url.url().startsWith("about:")) {
3402         p->write(url.path());
3403       } else {
3404         p->m_url = url;
3405       }
3406       p->end();
3407       return true;
3408   }
3409   else if ( !url.isEmpty() )
3410   {
3411       //kdDebug( 6050 ) << "opening " << url.url() << " in frame " << child->m_part << endl;
3412       return child->m_part->openURL( url );
3413   }
3414   else
3415 #endif
3416       return true;
3417 }
3418
3419 #if !APPLE_CHANGES
3420
3421 KParts::ReadOnlyPart *KHTMLPart::createPart( QWidget *parentWidget, const char *widgetName,
3422                                              QObject *parent, const char *name, const QString &mimetype,
3423                                              QString &serviceName, QStringList &serviceTypes,
3424                                              const QStringList &params )
3425 {
3426   QString constr;
3427   if ( !serviceName.isEmpty() )
3428     constr.append( QString::fromLatin1( "Name == '%1'" ).arg( serviceName ) );
3429
3430   KTrader::OfferList offers = KTrader::self()->query( mimetype, "KParts/ReadOnlyPart", constr, QString::null );
3431
3432   if ( offers.isEmpty() )
3433     return 0L;
3434
3435   KService::Ptr service = *offers.begin();
3436
3437   KLibFactory *factory = KLibLoader::self()->factory( QFile::encodeName(service->library()) );
3438
3439   if ( !factory )
3440     return 0L;
3441
3442   KParts::ReadOnlyPart *res = 0L;
3443
3444   const char *className = "KParts::ReadOnlyPart";
3445   if ( service->serviceTypes().contains( "Browser/View" ) )
3446     className = "Browser/View";
3447
3448   if ( factory->inherits( "KParts::Factory" ) )
3449     res = static_cast<KParts::ReadOnlyPart *>(static_cast<KParts::Factory *>( factory )->createPart( parentWidget, widgetName, parent, name, className, params ));
3450   else
3451   res = static_cast<KParts::ReadOnlyPart *>(factory->create( parentWidget, widgetName, className ));
3452
3453   if ( !res )
3454     return res;
3455
3456   serviceTypes = service->serviceTypes();
3457   serviceName = service->name();
3458
3459   return res;
3460 }
3461
3462 KParts::PartManager *KHTMLPart::partManager()
3463 {
3464   if ( !d->m_manager )
3465   {
3466     d->m_manager = new KParts::PartManager( d->m_view->topLevelWidget(), this, "khtml part manager" );
3467     d->m_manager->setAllowNestedParts( true );
3468     connect( d->m_manager, SIGNAL( activePartChanged( KParts::Part * ) ),
3469              this, SLOT( slotActiveFrameChanged( KParts::Part * ) ) );
3470     connect( d->m_manager, SIGNAL( partRemoved( KParts::Part * ) ),
3471              this, SLOT( slotPartRemoved( KParts::Part * ) ) );
3472   }
3473
3474   return d->m_manager;
3475 }
3476
3477 #endif
3478
3479 void KHTMLPart::submitFormAgain()
3480 {
3481   if( d->m_doc && !d->m_doc->parsing() && d->m_submitForm)
3482     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 );
3483
3484   delete d->m_submitForm;
3485   d->m_submitForm = 0;
3486   disconnect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
3487 }
3488
3489 void KHTMLPart::submitForm( const char *action, const QString &url, const FormData &formData, const QString &_target, const QString& contentType, const QString& boundary )
3490 {
3491   kdDebug(6000) << this << ": KHTMLPart::submitForm target=" << _target << " url=" << url << endl;
3492   KURL u = completeURL( url );
3493
3494   if ( !u.isValid() )
3495   {
3496     // ### ERROR HANDLING!
3497     return;
3498   }
3499
3500 #if !APPLE_CHANGES
3501   // Form security checks
3502   //
3503
3504   /* This is separate for a reason.  It has to be _before_ all script, etc,
3505    * AND I don't want to break anything that uses checkLinkSecurity() in
3506    * other places.
3507    */
3508
3509   // This causes crashes... needs to be fixed.
3510   if (!d->m_submitForm && u.protocol() != "https" && u.protocol() != "mailto") {
3511         if (d->m_ssl_in_use) {    // Going from SSL -> nonSSL
3512                 int rc = KMessageBox::warningContinueCancel(NULL, i18n("Warning:  This is a secure form but it is attempting to send your data back unencrypted."
3513                                         "\nA third party may be able to intercept and view this information."
3514                                         "\nAre you sure you wish to continue?"),
3515                                 i18n("SSL"));
3516                 if (rc == KMessageBox::Cancel)
3517                         return;
3518         } else {                  // Going from nonSSL -> nonSSL
3519                 KSSLSettings kss(true);
3520                 if (kss.warnOnUnencrypted()) {
3521                         int rc = KMessageBox::warningContinueCancel(NULL,
3522                                         i18n("Warning: Your data is about to be transmitted across the network unencrypted."
3523                                         "\nAre you sure you wish to continue?"),
3524                                         i18n("KDE"),
3525                                                                     QString::null,
3526                                         "WarnOnUnencryptedForm");
3527                         // Move this setting into KSSL instead
3528                         KConfig *config = kapp->config();
3529                         QString grpNotifMsgs = QString::fromLatin1("Notification Messages");
3530                         KConfigGroupSaver saver( config, grpNotifMsgs );
3531
3532                         if (!config->readBoolEntry("WarnOnUnencryptedForm", true)) {
3533                                 config->deleteEntry("WarnOnUnencryptedForm");
3534                                 config->sync();
3535                                 kss.setWarnOnUnencrypted(false);
3536                                 kss.save();
3537                         }
3538                         if (rc == KMessageBox::Cancel)
3539                           return;
3540         }
3541     }
3542   }
3543
3544   if (!d->m_submitForm && u.protocol() == "mailto") {
3545      int rc = KMessageBox::warningContinueCancel(NULL, 
3546                  i18n("This site is attempting to submit form data via email."),
3547                  i18n("KDE"), 
3548                  QString::null, 
3549                  "WarnTriedEmailSubmit");
3550
3551      if (rc == KMessageBox::Cancel) {
3552          return;
3553      }
3554   }
3555
3556   // End form security checks
3557   //
3558 #endif // APPLE_CHANGES
3559
3560   QString urlstring = u.url();
3561
3562   if ( urlstring.find( QString::fromLatin1( "javascript:" ), 0, false ) == 0 ) {
3563     urlstring = KURL::decode_string(urlstring);
3564     d->m_executingJavaScriptFormAction = true;
3565     executeScript( urlstring.right( urlstring.length() - 11) );
3566     d->m_executingJavaScriptFormAction = false;
3567     return;
3568   }
3569
3570 #if !APPLE_CHANGES
3571   if (!checkLinkSecurity(u,
3572                          i18n( "<qt>The form will be submitted to <BR><B>%1</B><BR>on your local filesystem.<BR>Do you want to submit the form?" ),
3573                          i18n( "Submit" )))
3574     return;
3575 #endif
3576
3577   KParts::URLArgs args;
3578
3579   if (!d->m_referrer.isEmpty())
3580      args.metaData()["referrer"] = d->m_referrer;
3581
3582 #if !APPLE_CHANGES
3583   args.metaData().insert("main_frame_request",
3584                          parentPart() == 0 ? "TRUE":"FALSE");
3585   args.metaData().insert("ssl_was_in_use", d->m_ssl_in_use ? "TRUE":"FALSE");
3586   args.metaData().insert("ssl_activate_warnings", "TRUE");
3587 #endif
3588   args.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
3589
3590   // Handle mailto: forms
3591   if (u.protocol() == "mailto") {
3592       // 1)  Check for attach= and strip it
3593       QString q = u.query().mid(1);
3594       QStringList nvps = QStringList::split("&", q);
3595       bool triedToAttach = false;
3596
3597       for (QStringList::Iterator nvp = nvps.begin(); nvp != nvps.end(); ++nvp) {
3598          QStringList pair = QStringList::split("=", *nvp);
3599          if (pair.count() >= 2) {
3600             if (pair.first().lower() == "attach") {
3601                nvp = nvps.remove(nvp);
3602                triedToAttach = true;
3603             }
3604          }
3605       }
3606
3607 #if !APPLE_CHANGES
3608       if (triedToAttach)
3609          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");
3610 #endif
3611
3612       // 2)  Append body=
3613       QString bodyEnc;
3614       if (contentType.lower() == "multipart/form-data") {
3615          // FIXME: is this correct?  I suspect not
3616          bodyEnc = KURL::encode_string(formData.flattenToString());
3617       } else if (contentType.lower() == "text/plain") {
3618          // Convention seems to be to decode, and s/&/\n/
3619          QString tmpbody = formData.flattenToString();
3620          tmpbody.replace('&', '\n');
3621          tmpbody.replace('+', ' ');
3622          tmpbody = KURL::decode_string(tmpbody);  // Decode the rest of it
3623          bodyEnc = KURL::encode_string(tmpbody);  // Recode for the URL
3624       } else {
3625          bodyEnc = KURL::encode_string(formData.flattenToString());
3626       }
3627
3628       nvps.append(QString("body=%1").arg(bodyEnc));
3629       q = nvps.join("&");
3630       u.setQuery(q);
3631   } 
3632
3633   if ( strcmp( action, "get" ) == 0 ) {
3634     if (u.protocol() != "mailto")
3635        u.setQuery( formData.flattenToString() );
3636     args.setDoPost( false );
3637   }
3638   else {
3639 #if APPLE_CHANGES
3640     args.postData = formData;
3641 #else
3642     args.postData = formData.flatten();
3643 #endif
3644     args.setDoPost( true );
3645
3646     // construct some user headers if necessary
3647     if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
3648       args.setContentType( "Content-Type: application/x-www-form-urlencoded" );
3649     else // contentType must be "multipart/form-data"
3650       args.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
3651   }
3652
3653   if ( d->m_doc->parsing() || d->m_runningScripts > 0 ) {
3654     if( d->m_submitForm ) {
3655       kdDebug(6000) << "KHTMLPart::submitForm ABORTING!" << endl;
3656       return;
3657     }
3658     d->m_submitForm = new KHTMLPartPrivate::SubmitForm;
3659     d->m_submitForm->submitAction = action;
3660     d->m_submitForm->submitUrl = url;
3661     d->m_submitForm->submitFormData = formData;
3662     d->m_submitForm->target = _target;
3663     d->m_submitForm->submitContentType = contentType;
3664     d->m_submitForm->submitBoundary = boundary;
3665     connect(this, SIGNAL(completed()), this, SLOT(submitFormAgain()));
3666   }
3667   else
3668   {
3669 #if APPLE_CHANGES
3670     KWQ(this)->submitForm( u, args);
3671 #else
3672     emit d->m_extension->openURLRequest( u, args );
3673 #endif
3674   }
3675 }
3676
3677 #if !APPLE_CHANGES
3678
3679 void KHTMLPart::popupMenu( const QString &linkUrl )
3680 {
3681   KURL popupURL;
3682   KURL linkKURL;
3683   if ( linkUrl.isEmpty() ) // click on background
3684     popupURL = this->url();
3685   else {               // click on link
3686     popupURL = completeURL( linkUrl );
3687     linkKURL = popupURL;
3688   }
3689
3690   KXMLGUIClient *client = new KHTMLPopupGUIClient( this, d->m_popupMenuXML, linkKURL );
3691
3692   emit d->m_extension->popupMenu( client, QCursor::pos(), popupURL,
3693                                   QString::fromLatin1( "text/html" ), S_IFREG /*always a file*/ );
3694
3695   delete client;
3696
3697   emit popupMenu(linkUrl, QCursor::pos());
3698 }
3699
3700 #endif
3701
3702 void KHTMLPart::slotParentCompleted()
3703 {
3704   if ( d->m_scheduledRedirection != noRedirectionScheduled && !d->m_redirectionTimer.isActive() )
3705   {
3706     // kdDebug(6050) << this << ": Child redirection -> " << d->m_redirectURL << endl;