28973637445d7f63a3d42084010f4b3c88475668
[WebKit-https.git] / WebCore / page / Frame.cpp
1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
4  *                     1999 Lars Knoll <knoll@kde.org>
5  *                     1999 Antti Koivisto <koivisto@kde.org>
6  *                     2000 Simon Hausmann <hausmann@kde.org>
7  *                     2000 Stefan Schimanski <1Stein@gmx.de>
8  *                     2001 George Staikos <staikos@kde.org>
9  * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
10  * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
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 "config.h"
29 #include "Frame.h"
30 #include "FramePrivate.h"
31
32 #include "ApplyStyleCommand.h"
33 #include "CSSComputedStyleDeclaration.h"
34 #include "CSSProperty.h"
35 #include "CSSPropertyNames.h"
36 #include "Cache.h"
37 #include "CachedCSSStyleSheet.h"
38 #include "DOMImplementation.h"
39 #include "DOMWindow.h"
40 #include "Decoder.h"
41 #include "DocLoader.h"
42 #include "DocumentType.h"
43 #include "EditingText.h"
44 #include "Event.h"
45 #include "EventNames.h"
46 #include "FloatRect.h"
47 #include "Frame.h"
48 #include "GraphicsContext.h"
49 #include "HTMLFormElement.h"
50 #include "HTMLFrameElement.h"
51 #include "HTMLGenericFormElement.h"
52 #include "HTMLInputElement.h"
53 #include "HTMLNames.h"
54 #include "HTMLObjectElement.h"
55 #include "HTMLViewSourceDocument.h"
56 #include "ImageDocument.h"
57 #include "loader/icon/IconDatabase.h"
58 #include "loader/icon/IconLoader.h"
59 #include "MediaFeatureNames.h"
60 #include "MouseEventWithHitTestResults.h"
61 #include "NodeList.h"
62 #include "Page.h"
63 #include "PlatformScrollBar.h"
64 #include "PlugInInfoStore.h"
65 #include "Plugin.h"
66 #include "PluginDocument.h"
67 #include "RenderListBox.h"
68 #include "RenderPart.h"
69 #include "RenderTextControl.h"
70 #include "RenderTheme.h"
71 #include "RenderView.h"
72 #include "SegmentedString.h"
73 #include "TextDocument.h"
74 #include "TextIterator.h"
75 #include "TypingCommand.h"
76 #include "XMLTokenizer.h"
77 #include "cssstyleselector.h"
78 #include "htmlediting.h"
79 #include "kjs_window.h"
80 #include "markup.h"
81 #include "visible_units.h"
82 #include "xmlhttprequest.h"
83 #include <math.h>
84 #include <sys/types.h>
85 #include <wtf/Platform.h>
86
87 #if PLATFORM(MAC)
88 #include "FrameMac.h"
89 #endif
90
91 #if !PLATFORM(WIN_OS)
92 #include <unistd.h>
93 #endif
94
95 #ifdef SVG_SUPPORT
96 #include "SVGNames.h"
97 #include "XLinkNames.h"
98 #include "XMLNames.h"
99 #include "SVGDocument.h"
100 #include "SVGDocumentExtensions.h"
101 #endif
102
103 using namespace std;
104
105 using KJS::JSLock;
106 using KJS::JSValue;
107 using KJS::Location;
108 using KJS::PausedTimeouts;
109 using KJS::SavedProperties;
110 using KJS::SavedBuiltins;
111 using KJS::UString;
112 using KJS::Window;
113
114 namespace WebCore {
115
116 using namespace EventNames;
117 using namespace HTMLNames;
118
119 const double caretBlinkFrequency = 0.5;
120 const double autoscrollInterval = 0.1;
121
122 class UserStyleSheetLoader : public CachedResourceClient {
123 public:
124     UserStyleSheetLoader(Frame* frame, const String& url, DocLoader* dl)
125         : m_frame(frame)
126         , m_cachedSheet(Cache::requestCSSStyleSheet(dl, url, false, 0, ""))
127     {
128         m_cachedSheet->ref(this);
129     }
130     ~UserStyleSheetLoader()
131     {
132         m_cachedSheet->deref(this);
133     }
134 private:
135     virtual void setCSSStyleSheet(const String& /*URL*/, const String& /*charset*/, const String& sheet)
136     {
137         m_frame->setUserStyleSheet(sheet);
138     }
139     Frame* m_frame;
140     CachedCSSStyleSheet* m_cachedSheet;
141 };
142
143 #ifndef NDEBUG
144 struct FrameCounter { 
145     static int count; 
146     ~FrameCounter() { if (count != 0) fprintf(stderr, "LEAK: %d Frame\n", count); }
147 };
148 int FrameCounter::count = 0;
149 static FrameCounter frameCounter;
150 #endif
151
152 static inline Frame* parentFromOwnerElement(Element* ownerElement)
153 {
154     if (!ownerElement)
155         return 0;
156     return ownerElement->document()->frame();
157 }
158
159 Frame::Frame(Page* page, Element* ownerElement) 
160     : d(new FramePrivate(page, parentFromOwnerElement(ownerElement), this, ownerElement))
161 {
162     AtomicString::init();
163     Cache::init();
164     EventNames::init();
165     HTMLNames::init();
166     QualifiedName::init();
167     MediaFeatureNames::init();
168
169 #ifdef SVG_SUPPORT
170     SVGNames::init();
171     XLinkNames::init();
172     XMLNames::init();
173 #endif
174
175     if (d->m_ownerElement)
176         d->m_page->incrementFrameCount();
177
178     // FIXME: Frames were originally created with a refcount of 1, leave this
179     // ref call here until we can straighten that out.
180     ref();
181 #ifndef NDEBUG
182     ++FrameCounter::count;
183 #endif
184 }
185
186 Frame::~Frame()
187 {
188     // FIXME: We should not be doing all this work inside the destructor
189
190     ASSERT(!d->m_lifeSupportTimer.isActive());
191
192 #ifndef NDEBUG
193     --FrameCounter::count;
194 #endif
195
196     if (d->m_jscript && d->m_jscript->haveInterpreter())
197         if (Window* w = Window::retrieveWindow(this)) {
198             w->disconnectFrame();
199             // Must clear the window pointer, otherwise we will not
200             // garbage-collect collect the window (inside the call to
201             // delete d below).
202             w = 0;
203         }
204
205     disconnectOwnerElement();
206     
207     if (d->m_domWindow)
208         d->m_domWindow->disconnectFrame();
209             
210     setOpener(0);
211     HashSet<Frame*> openedBy = d->m_openedFrames;
212     HashSet<Frame*>::iterator end = openedBy.end();
213     for (HashSet<Frame*>::iterator it = openedBy.begin(); it != end; ++it)
214         (*it)->setOpener(0);
215     
216     if (d->m_view) {
217         d->m_view->hide();
218         d->m_view->m_frame = 0;
219     }
220   
221     ASSERT(!d->m_lifeSupportTimer.isActive());
222
223     delete d->m_userStyleSheetLoader;
224     delete d;
225     d = 0;
226 }
227
228 KURL Frame::iconURL()
229 {
230     // If this isn't a top level frame, return nothing
231     if (tree() && tree()->parent())
232         return "";
233         
234     // If we have an iconURL from a Link element, return that
235     if (document() && !document()->iconURL().isEmpty())
236         return KURL(document()->iconURL().deprecatedString());
237         
238     // Don't return a favicon iconURL unless we're http or https
239     if (d->m_url.protocol() != "http" && d->m_url.protocol() != "https")
240         return "";
241         
242     KURL url;
243     url.setProtocol(d->m_url.protocol());
244     url.setHost(d->m_url.host());
245     url.setPath("/favicon.ico");
246     return url;
247 }
248
249 bool Frame::didOpenURL(const KURL& url)
250 {
251   if (d->m_scheduledRedirection == locationChangeScheduledDuringLoad) {
252     // A redirect was shceduled before the document was created. This can happen
253     // when one frame changes another frame's location.
254     return false;
255   }
256   
257   cancelRedirection();
258   
259   // clear last edit command
260   d->m_lastEditCommand = 0;
261   
262   closeURL();
263
264   d->m_bComplete = false;
265   d->m_bLoadingMainResource = true;
266   d->m_bLoadEventEmitted = false;
267
268   d->m_kjsStatusBarText = String();
269   d->m_kjsDefaultStatusBarText = String();
270
271   d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
272   d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
273   d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();
274
275   // initializing d->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
276   // data arrives) (Simon)
277   d->m_url = url;
278   if (d->m_url.protocol().startsWith("http") && !d->m_url.host().isEmpty() && d->m_url.path().isEmpty())
279     d->m_url.setPath("/");
280   d->m_workingURL = d->m_url;
281
282   started();
283
284   return true;
285 }
286
287 void Frame::didExplicitOpen()
288 {
289   d->m_bComplete = false;
290   d->m_bLoadEventEmitted = false;
291     
292   // Prevent window.open(url) -- eg window.open("about:blank") -- from blowing away results
293   // from a subsequent window.document.open / window.document.write call. 
294   // Cancelling redirection here works for all cases because document.open 
295   // implicitly precedes document.write.
296   cancelRedirection(); 
297   d->m_url = d->m_doc->URL();
298 }
299
300 void Frame::stopLoading(bool sendUnload)
301 {
302   if (d->m_doc && d->m_doc->tokenizer())
303     d->m_doc->tokenizer()->stopParsing();
304   
305   d->m_metaData.clear();
306
307   if (sendUnload) {
308     if (d->m_doc) {
309       if (d->m_bLoadEventEmitted && !d->m_bUnloadEventEmitted) {
310         Node* currentFocusNode = d->m_doc->focusNode();
311         if (currentFocusNode)
312             currentFocusNode->aboutToUnload();
313         d->m_doc->dispatchWindowEvent(unloadEvent, false, false);
314         if (d->m_doc)
315           d->m_doc->updateRendering();
316         d->m_bUnloadEventEmitted = true;
317       }
318     }
319     
320     if (d->m_doc && !d->m_doc->inPageCache())
321       d->m_doc->removeAllEventListenersFromAllNodes();
322   }
323
324   d->m_bComplete = true; // to avoid calling completed() in finishedParsing() (David)
325   d->m_bLoadingMainResource = false;
326   d->m_bLoadEventEmitted = true; // don't want that one either
327   d->m_cachePolicy = CachePolicyVerify; // Why here?
328
329   if (d->m_doc && d->m_doc->parsing()) {
330     finishedParsing();
331     d->m_doc->setParsing(false);
332   }
333   
334   d->m_workingURL = KURL();
335
336   if (Document *doc = d->m_doc.get()) {
337     if (DocLoader *docLoader = doc->docLoader())
338       Cache::loader()->cancelRequests(docLoader);
339       XMLHttpRequest::cancelRequests(doc);
340   }
341
342   // tell all subframes to stop as well
343   for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
344       child->stopLoading(sendUnload);
345
346   d->m_bPendingChildRedirection = false;
347
348   cancelRedirection();
349 }
350
351 BrowserExtension *Frame::browserExtension() const
352 {
353   return d->m_extension;
354 }
355
356 FrameView* Frame::view() const
357 {
358     return d->m_view.get();
359 }
360
361 void Frame::setView(FrameView* view)
362 {
363     // Detach the document now, so any onUnload handlers get run - if
364     // we wait until the view is destroyed, then things won't be
365     // hooked up enough for some JavaScript calls to work.
366     if (d->m_doc && view == 0)
367         d->m_doc->detach();
368
369     d->m_view = view;
370 }
371
372 bool Frame::jScriptEnabled() const
373 {
374     return d->m_bJScriptEnabled;
375 }
376
377 KJSProxy *Frame::jScript()
378 {
379     if (!d->m_bJScriptEnabled)
380         return 0;
381
382     if (!d->m_jscript)
383         d->m_jscript = new KJSProxy(this);
384
385     return d->m_jscript;
386 }
387
388 static bool getString(JSValue* result, String& string)
389 {
390     if (!result)
391         return false;
392     JSLock lock;
393     UString ustring;
394     if (!result->getString(ustring))
395         return false;
396     string = ustring;
397     return true;
398 }
399
400 void Frame::replaceContentsWithScriptResult(const KURL& url)
401 {
402     JSValue* ret = executeScript(0, KURL::decode_string(url.url().mid(strlen("javascript:"))));
403     String scriptResult;
404     if (getString(ret, scriptResult)) {
405         begin();
406         write(scriptResult);
407         end();
408     }
409 }
410
411 JSValue* Frame::executeScript(Node* n, const String& script, bool forceUserGesture)
412 {
413   KJSProxy *proxy = jScript();
414
415   if (!proxy)
416     return 0;
417
418   d->m_runningScripts++;
419   // If forceUserGesture is true, then make the script interpreter
420   // treat it as if triggered by a user gesture even if there is no
421   // current DOM event being processed.
422   JSValue* ret = proxy->evaluate(forceUserGesture ? DeprecatedString::null : d->m_url.url(), 0, script, n);
423   d->m_runningScripts--;
424
425   if (!d->m_runningScripts)
426       submitFormAgain();
427
428   Document::updateDocumentsRendering();
429
430   return ret;
431 }
432
433 bool Frame::javaEnabled() const
434 {
435     return d->m_settings->isJavaEnabled();
436 }
437
438 bool Frame::pluginsEnabled() const
439 {
440     return d->m_bPluginsEnabled;
441 }
442
443 void Frame::setAutoloadImages(bool enable)
444 {
445   if (d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable)
446     return;
447
448   if (d->m_doc)
449     d->m_doc->docLoader()->setAutoloadImages(enable);
450 }
451
452 bool Frame::autoloadImages() const
453 {
454   if (d->m_doc)
455     return d->m_doc->docLoader()->autoloadImages();
456
457   return true;
458 }
459
460 void Frame::cancelAndClear()
461 {
462     cancelRedirection();
463
464     if (!d->m_bComplete)
465         closeURL();
466
467     clear(false);
468 }
469
470 void Frame::clear(bool clearWindowProperties)
471 {
472   if (d->m_bCleared)
473     return;
474   d->m_bCleared = true;
475   d->m_mousePressNode = 0;
476
477 #if !PLATFORM(MAC)
478   // FIXME: This is a temporary hack to work around a mismatch between WebCore and WebKit
479   // regarding frame lifetime. The proper solution is to move all frame management
480   // into WebCore, so frames can work the same way on all platforms.
481   detachChildren();
482 #endif
483
484   if (d->m_doc) {
485     d->m_doc->cancelParsing();
486     d->m_doc->detach();
487   }
488
489   // Moving past doc so that onUnload works.
490   if (clearWindowProperties && d->m_jscript)
491     d->m_jscript->clear();
492
493   if (d->m_view)
494     d->m_view->clear();
495
496   // do not drop the document before the jscript and view are cleared, as some destructors
497   // might still try to access the document.
498   d->m_doc = 0;
499   d->m_decoder = 0;
500
501   d->m_plugins.clear();
502   cleanupPluginObjects();
503   
504   d->m_scheduledRedirection = noRedirectionScheduled;
505   d->m_delayRedirect = 0;
506   d->m_redirectURL = DeprecatedString::null;
507   d->m_redirectReferrer = String();
508   d->m_redirectLockHistory = true;
509   d->m_redirectUserGesture = false;
510   d->m_bHTTPRefresh = false;
511   d->m_bFirstData = true;
512
513   d->m_bMousePressed = false;
514
515   if (!d->m_haveEncoding)
516     d->m_encoding = String();
517 }
518
519 Document *Frame::document() const
520 {
521     if (d)
522         return d->m_doc.get();
523     return 0;
524 }
525
526 void Frame::setDocument(Document* newDoc)
527 {
528     if (d) {
529         if (d->m_doc)
530             d->m_doc->detach();
531         d->m_doc = newDoc;
532         if (newDoc)
533             newDoc->attach();
534     }
535 }
536
537 void Frame::receivedFirstData()
538 {
539     begin(d->m_workingURL);
540
541     d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
542     d->m_workingURL = KURL();
543
544     // When the first data arrives, the metadata has just been made available
545     DeprecatedString qData;
546
547     // Support for http-refresh
548     qData = d->m_metaData.get("http-refresh").deprecatedString();
549     if (!qData.isEmpty()) {
550       double delay;
551       int pos = qData.find(';');
552       if (pos == -1)
553         pos = qData.find(',');
554
555       if (pos == -1) {
556         delay = qData.stripWhiteSpace().toDouble();
557         // We want a new history item if the refresh timeout > 1 second
558         scheduleRedirection(delay, d->m_url.url(), delay <= 1);
559       } else {
560         int end_pos = qData.length();
561         delay = qData.left(pos).stripWhiteSpace().toDouble();
562         while (qData[++pos] == ' ');
563         if (qData.find("url", pos, false) == pos) {
564           pos += 3;
565           while (qData[pos] == ' ' || qData[pos] == '=')
566               pos++;
567           if (qData[pos] == '"') {
568               pos++;
569               int index = end_pos-1;
570               while (index > pos) {
571                 if (qData[index] == '"')
572                     break;
573                 index--;
574               }
575               if (index > pos)
576                 end_pos = index;
577           }
578         }
579         // We want a new history item if the refresh timeout > 1 second
580         scheduleRedirection(delay, d->m_doc->completeURL(qData.mid(pos, end_pos)), delay <= 1);
581       }
582       d->m_bHTTPRefresh = true;
583     }
584
585     // Support for http last-modified
586     d->m_lastModified = d->m_metaData.get("modified");
587 }
588
589 void Frame::childBegin()
590 {
591     // We need to do this when the child is created so as to avoid the parent thining the child
592     // is complete before it has even started loading.
593     // FIXME: do we really still need this?
594     d->m_bComplete = false;
595 }
596
597 void Frame::setResourceRequest(const ResourceRequest& request)
598 {
599     d->m_request = request;
600 }
601
602 const ResourceRequest& Frame::resourceRequest() const
603 {
604     return d->m_request;
605 }
606
607 void Frame::setResponseMIMEType(const String& contentType)
608 {
609     d->m_responseMIMEType = contentType;
610 }
611
612 const String& Frame::responseMIMEType() const
613 {
614     return d->m_responseMIMEType;
615 }
616
617 void Frame::begin(const KURL& url)
618 {
619   if (d->m_workingURL.isEmpty())
620     createEmptyDocument(); // Creates an empty document if we don't have one already
621
622   clear();
623   partClearedInBegin();
624
625   d->m_bCleared = false;
626   d->m_bComplete = false;
627   d->m_bLoadEventEmitted = false;
628   d->m_bLoadingMainResource = true;
629
630   KURL ref(url);
631   ref.setUser(DeprecatedString());
632   ref.setPass(DeprecatedString());
633   ref.setRef(DeprecatedString());
634   d->m_referrer = ref.url();
635   d->m_url = url;
636   KURL baseurl;
637
638   // We don't need KDE chained URI handling or window caption setting
639   if (!d->m_url.isEmpty())
640     baseurl = d->m_url;
641
642 #ifdef SVG_SUPPORT
643   if (d->m_responseMIMEType == "image/svg+xml")
644     d->m_doc = DOMImplementation::instance()->createSVGDocument(d->m_view.get());
645   else
646 #endif
647   if (DOMImplementation::isXMLMIMEType(d->m_responseMIMEType))
648     d->m_doc = DOMImplementation::instance()->createDocument(d->m_view.get());
649   else if (DOMImplementation::isTextMIMEType(d->m_responseMIMEType))
650     d->m_doc = new TextDocument(DOMImplementation::instance(), d->m_view.get());
651   else if ((d->m_responseMIMEType == "application/pdf" || d->m_responseMIMEType == "text/pdf") && PlugInInfoStore::supportsMIMEType(d->m_responseMIMEType))
652     d->m_doc = new PluginDocument(DOMImplementation::instance(), d->m_view.get());
653   else if (Image::supportsType(d->m_responseMIMEType))
654     d->m_doc = new ImageDocument(DOMImplementation::instance(), d->m_view.get());
655   else if (PlugInInfoStore::supportsMIMEType(d->m_responseMIMEType))
656     d->m_doc = new PluginDocument(DOMImplementation::instance(), d->m_view.get());
657   else if (inViewSourceMode())
658     d->m_doc = new HTMLViewSourceDocument(DOMImplementation::instance(), d->m_view.get());
659   else
660     d->m_doc = DOMImplementation::instance()->createHTMLDocument(d->m_view.get());
661
662   if (!d->m_doc->attached())
663     d->m_doc->attach();
664   d->m_doc->setURL(d->m_url.url());
665   // We prefer m_baseURL over d->m_url because d->m_url changes when we are
666   // about to load a new page.
667   d->m_doc->setBaseURL(baseurl.url());
668   if (d->m_decoder)
669     d->m_doc->setDecoder(d->m_decoder.get());
670
671   updatePolicyBaseURL();
672
673   setAutoloadImages(d->m_settings->autoLoadImages());
674   const KURL& userStyleSheet = d->m_settings->userStyleSheetLocation();
675
676   if (!userStyleSheet.isEmpty())
677     setUserStyleSheetLocation(KURL(userStyleSheet));
678
679   restoreDocumentState();
680
681   d->m_doc->implicitOpen();
682   // clear widget
683   if (d->m_view)
684     d->m_view->resizeContents(0, 0);
685 }
686
687 void Frame::write(const char* str, int len)
688 {
689     if (len == 0)
690         return;
691     
692     if (len == -1)
693         len = strlen(str);
694
695     if (Tokenizer* t = d->m_doc->tokenizer()) {
696         if (t->wantsRawData()) {
697             t->writeRawData(str, len);
698             return;
699         }
700     }
701     
702     if (!d->m_decoder) {
703         d->m_decoder = new Decoder(d->m_responseMIMEType, settings()->encoding());
704         if (!d->m_encoding.isNull())
705             d->m_decoder->setEncoding(d->m_encoding,
706                 d->m_haveEncoding ? Decoder::UserChosenEncoding : Decoder::EncodingFromHTTPHeader);
707         if (d->m_doc)
708             d->m_doc->setDecoder(d->m_decoder.get());
709     }
710
711     String decoded = d->m_decoder->decode(str, len);
712
713     if (decoded.isEmpty())
714         return;
715
716     if (d->m_bFirstData) {
717         d->m_bFirstData = false;
718         d->m_doc->determineParseMode(decoded);
719         if (d->m_decoder->encoding().usesVisualOrdering())
720             d->m_doc->setVisuallyOrdered();
721         d->m_doc->recalcStyle(Node::Force);
722     }
723
724     if (Tokenizer* t = d->m_doc->tokenizer()) {
725         ASSERT(!t->wantsRawData());
726         t->write(decoded, true);
727     }
728 }
729
730 void Frame::write(const String& str)
731 {
732     if (str.isNull())
733         return;
734
735     if (d->m_bFirstData) {
736         // determine the parse mode
737         d->m_doc->setParseMode(Document::Strict);
738         d->m_bFirstData = false;
739     }
740     Tokenizer* t = d->m_doc->tokenizer();
741     if (t)
742         t->write(str, true);
743 }
744
745 void Frame::end()
746 {
747     d->m_bLoadingMainResource = false;
748     endIfNotLoading();
749 }
750
751 void Frame::endIfNotLoading()
752 {
753     // http://bugzilla.opendarwin.org/show_bug.cgi?id=10854
754     // The frame's last ref may be remove and it be deleted by checkCompleted(), 
755     // so we'll add a protective refcount
756     RefPtr<Frame> protector(this);
757     
758     if (d->m_bLoadingMainResource)
759         return;
760
761     // make sure nothing's left in there...
762     if (d->m_doc) {
763         if (d->m_decoder) {
764             String decoded = d->m_decoder->flush();
765             if (d->m_bFirstData) {
766                 d->m_bFirstData = false;
767                 d->m_doc->determineParseMode(decoded);
768             }
769             write(decoded);
770         }
771         d->m_doc->finishParsing();
772     } else
773         // WebKit partially uses WebCore when loading non-HTML docs.  In these cases doc==nil, but
774         // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
775         // become true.  An example is when a subframe is a pure text doc, and that subframe is the
776         // last one to complete.
777         checkCompleted();
778     
779     // FIXME - Right now, we kick off the icon loader when the frame is done receiving all its main resource.
780     // We could kick off the icon loader after we're done parsing the HEAD element, if that becomes convinient to find
781     // at a future date
782     
783     // Don't load an icon if -
784     // 1) This is not the main frame 
785     // 2) The database is disabled
786     // 3) We have no valid icon URL
787     // 4) We already have an unexpired icon
788     
789     if (tree()->parent())
790         return;
791         
792     
793     if (IconDatabase* sharedIconDatabase = IconDatabase::sharedIconDatabase()) {
794         if (!sharedIconDatabase->enabled())
795             return;
796         
797         String url(iconURL().url());
798         if (url.isEmpty())
799             return;
800         
801         // If we already have an unexpired icon, we won't kick off a load but we *will* map the appropriate URLs to it
802         if (sharedIconDatabase->hasEntryForIconURL(url) && !isLoadTypeReload() && !sharedIconDatabase->isIconExpiredForIconURL(url)) {
803             commitIconURLToIconDatabase();
804             return;
805         }
806         
807         if (!d->m_iconLoader)
808             d->m_iconLoader = IconLoader::createForFrame(this);
809         d->m_iconLoader->startLoading();
810     }
811 }
812
813 void Frame::commitIconURLToIconDatabase()
814 {
815     KURL icon = iconURL();
816     
817     IconDatabase* iconDatabase = IconDatabase::sharedIconDatabase();
818     ASSERT(iconDatabase);
819     iconDatabase->setIconURLForPageURL(icon.url(), this->url().url());
820     iconDatabase->setIconURLForPageURL(icon.url(), originalRequestURL().url());
821 }
822
823 void Frame::stop()
824 {
825     // http://bugzilla.opendarwin.org/show_bug.cgi?id=10854
826     // The frame's last ref may be remove and it be deleted by checkCompleted(), 
827     // so we'll add a protective refcount
828     RefPtr<Frame> protector(this);
829     
830     if (d->m_doc) {
831         if (d->m_doc->tokenizer())
832             d->m_doc->tokenizer()->stopParsing();
833         d->m_doc->finishParsing();
834     } else
835         // WebKit partially uses WebCore when loading non-HTML docs.  In these cases doc==nil, but
836         // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
837         // become true.  An example is when a subframe is a pure text doc, and that subframe is the
838         // last one to complete.
839         checkCompleted();
840     if (d->m_iconLoader)
841         d->m_iconLoader->stopLoading();
842 }
843
844 void Frame::gotoAnchor()
845 {
846     // If our URL has no ref, then we have no place we need to jump to.
847     if (!d->m_url.hasRef())
848         return;
849
850     DeprecatedString ref = d->m_url.encodedHtmlRef();
851     if (!gotoAnchor(ref)) {
852         // Can't use htmlRef() here because it doesn't know which encoding to use to decode.
853         // Decoding here has to match encoding in completeURL, which means it has to use the
854         // page's encoding rather than UTF-8.
855         if (d->m_decoder)
856             gotoAnchor(KURL::decode_string(ref, d->m_decoder->encoding()));
857     }
858 }
859
860 void Frame::finishedParsing()
861 {
862   // This method can be called from our destructor, in which case we shouldn't protect ourselves
863   // because doing so will cause us to re-enter our destructor when protector goes out of scope.
864   RefPtr<Frame> protector = refCount() > 0 ? this : 0;
865   checkCompleted();
866
867   if (!d->m_view)
868     return; // We are being destroyed by something checkCompleted called.
869
870   // check if the scrollbars are really needed for the content
871   // if not, remove them, relayout, and repaint
872
873   d->m_view->restoreScrollbar();
874   gotoAnchor();
875 }
876
877 void Frame::loadDone()
878 {
879     if (d->m_doc)
880         checkCompleted();
881 }
882
883 void Frame::checkCompleted()
884 {
885   // Any frame that hasn't completed yet ?
886   for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
887       if (!child->d->m_bComplete)
888           return;
889
890   // Have we completed before?
891   if (d->m_bComplete)
892       return;
893
894   // Are we still parsing?
895   if (d->m_doc && d->m_doc->parsing())
896       return;
897
898   // Still waiting for images/scripts from the loader ?
899   int requests = 0;
900   if (d->m_doc && d->m_doc->docLoader())
901       requests = Cache::loader()->numRequests(d->m_doc->docLoader());
902
903   if (requests > 0)
904       return;
905
906   // OK, completed.
907   // Now do what should be done when we are really completed.
908   d->m_bComplete = true;
909
910   checkEmitLoadEvent(); // if we didn't do it before
911
912   if (d->m_scheduledRedirection != noRedirectionScheduled) {
913       // Do not start redirection for frames here! That action is
914       // deferred until the parent emits a completed signal.
915       if (!tree()->parent())
916           startRedirectionTimer();
917
918       completed(true);
919   } else {
920       completed(d->m_bPendingChildRedirection);
921   }
922 }
923
924 void Frame::checkEmitLoadEvent()
925 {
926     if (d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing())
927         return;
928
929     for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
930         if (!child->d->m_bComplete) // still got a frame running -> too early
931             return;
932
933     // All frames completed -> set their domain to the frameset's domain
934     // This must only be done when loading the frameset initially (#22039),
935     // not when following a link in a frame (#44162).
936     if (d->m_doc) {
937         String domain = d->m_doc->domain();
938         for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
939             if (child->d->m_doc)
940                 child->d->m_doc->setDomain(domain);
941     }
942
943     d->m_bLoadEventEmitted = true;
944     d->m_bUnloadEventEmitted = false;
945     if (d->m_doc)
946         d->m_doc->implicitClose();
947 }
948
949 const Settings *Frame::settings() const
950 {
951   return d->m_settings;
952 }
953
954 KURL Frame::baseURL() const
955 {
956     if (!d->m_doc)
957         return KURL();
958     return d->m_doc->baseURL();
959 }
960
961 String Frame::baseTarget() const
962 {
963     if (!d->m_doc)
964         return String();
965     return d->m_doc->baseTarget();
966 }
967
968 KURL Frame::completeURL(const DeprecatedString& url)
969 {
970     if (!d->m_doc)
971         return url;
972
973     return KURL(d->m_doc->completeURL(url));
974 }
975
976 void Frame::scheduleRedirection(double delay, const DeprecatedString& url, bool doLockHistory)
977 {
978     if (delay < 0 || delay > INT_MAX / 1000)
979       return;
980     if (d->m_scheduledRedirection == noRedirectionScheduled || delay <= d->m_delayRedirect)
981     {
982        d->m_scheduledRedirection = redirectionScheduled;
983        d->m_delayRedirect = delay;
984        d->m_redirectURL = url;
985        d->m_redirectReferrer = String();
986        d->m_redirectLockHistory = doLockHistory;
987        d->m_redirectUserGesture = false;
988
989        stopRedirectionTimer();
990        if (d->m_bComplete)
991          startRedirectionTimer();
992     }
993 }
994
995 void Frame::scheduleLocationChange(const DeprecatedString& url, const String& referrer, bool lockHistory, bool userGesture)
996 {
997     KURL u(url);
998     
999     // If the URL we're going to navigate to is the same as the current one, except for the
1000     // fragment part, we don't need to schedule the location change.
1001     if (u.hasRef() && equalIgnoringRef(d->m_url, u)) {
1002         changeLocation(url, referrer, lockHistory, userGesture);
1003         return;
1004     }
1005         
1006     // Handle a location change of a page with no document as a special case.
1007     // This may happen when a frame changes the location of another frame.
1008     d->m_scheduledRedirection = d->m_doc ? locationChangeScheduled : locationChangeScheduledDuringLoad;
1009     
1010     // If a redirect was scheduled during a load, then stop the current load.
1011     // Otherwise when the current load transitions from a provisional to a 
1012     // committed state, pending redirects may be cancelled. 
1013     if (d->m_scheduledRedirection == locationChangeScheduledDuringLoad) {
1014         stopLoading(true);   
1015     }
1016
1017     d->m_delayRedirect = 0;
1018     d->m_redirectURL = url;
1019     d->m_redirectReferrer = referrer;
1020     d->m_redirectLockHistory = lockHistory;
1021     d->m_redirectUserGesture = userGesture;
1022     stopRedirectionTimer();
1023     if (d->m_bComplete)
1024         startRedirectionTimer();
1025 }
1026
1027 void Frame::scheduleRefresh(bool userGesture)
1028 {
1029     // Handle a location change of a page with no document as a special case.
1030     // This may happen when a frame requests a refresh of another frame.
1031     d->m_scheduledRedirection = d->m_doc ? locationChangeScheduled : locationChangeScheduledDuringLoad;
1032     
1033     // If a refresh was scheduled during a load, then stop the current load.
1034     // Otherwise when the current load transitions from a provisional to a 
1035     // committed state, pending redirects may be cancelled. 
1036     if (d->m_scheduledRedirection == locationChangeScheduledDuringLoad)
1037         stopLoading(true);   
1038
1039     d->m_delayRedirect = 0;
1040     d->m_redirectURL = url().url();
1041     d->m_redirectReferrer = referrer();
1042     d->m_redirectLockHistory = true;
1043     d->m_redirectUserGesture = userGesture;
1044     d->m_cachePolicy = CachePolicyRefresh;
1045     stopRedirectionTimer();
1046     if (d->m_bComplete)
1047         startRedirectionTimer();
1048 }
1049
1050 bool Frame::isScheduledLocationChangePending() const
1051 {
1052     switch (d->m_scheduledRedirection) {
1053         case noRedirectionScheduled:
1054         case redirectionScheduled:
1055             return false;
1056         case historyNavigationScheduled:
1057         case locationChangeScheduled:
1058         case locationChangeScheduledDuringLoad:
1059             return true;
1060     }
1061     return false;
1062 }
1063
1064 void Frame::scheduleHistoryNavigation(int steps)
1065 {
1066     // navigation will always be allowed in the 0 steps case, which is OK because
1067     // that's supposed to force a reload.
1068     if (!canGoBackOrForward(steps)) {
1069         cancelRedirection();
1070         return;
1071     }
1072
1073     // If the URL we're going to navigate to is the same as the current one, except for the
1074     // fragment part, we don't need to schedule the navigation.
1075     if (d->m_extension) {
1076         KURL u = d->m_extension->historyURL(steps);
1077         
1078         if (equalIgnoringRef(d->m_url, u)) {
1079             d->m_extension->goBackOrForward(steps);
1080             return;
1081         }
1082     }
1083     
1084     d->m_scheduledRedirection = historyNavigationScheduled;
1085     d->m_delayRedirect = 0;
1086     d->m_redirectURL = DeprecatedString::null;
1087     d->m_redirectReferrer = String();
1088     d->m_scheduledHistoryNavigationSteps = steps;
1089     stopRedirectionTimer();
1090     if (d->m_bComplete)
1091         startRedirectionTimer();
1092 }
1093
1094 void Frame::cancelRedirection(bool cancelWithLoadInProgress)
1095 {
1096     if (d) {
1097         d->m_cancelWithLoadInProgress = cancelWithLoadInProgress;
1098         d->m_scheduledRedirection = noRedirectionScheduled;
1099         stopRedirectionTimer();
1100     }
1101 }
1102
1103 void Frame::changeLocation(const DeprecatedString& URL, const String& referrer, bool lockHistory, bool userGesture)
1104 {
1105     if (URL.find("javascript:", 0, false) == 0) {
1106         String script = KURL::decode_string(URL.mid(11));
1107         JSValue* result = executeScript(0, script, userGesture);
1108         String scriptResult;
1109         if (getString(result, scriptResult)) {
1110             begin(url());
1111             write(scriptResult);
1112             end();
1113         }
1114         return;
1115     }
1116
1117     ResourceRequest request(completeURL(URL));
1118     request.setLockHistory(lockHistory);
1119     if (!referrer.isEmpty())
1120         request.setReferrer(referrer);
1121
1122     request.reload = (d->m_cachePolicy == CachePolicyReload) || (d->m_cachePolicy == CachePolicyRefresh);
1123     
1124     urlSelected(request, "_self");
1125 }
1126
1127 void Frame::redirectionTimerFired(Timer<Frame>*)
1128 {
1129     if (d->m_scheduledRedirection == historyNavigationScheduled) {
1130         d->m_scheduledRedirection = noRedirectionScheduled;
1131
1132         // Special case for go(0) from a frame -> reload only the frame
1133         // go(i!=0) from a frame navigates into the history of the frame only,
1134         // in both IE and NS (but not in Mozilla).... we can't easily do that
1135         // in Konqueror...
1136         if (d->m_scheduledHistoryNavigationSteps == 0) // add && parent() to get only frames, but doesn't matter
1137             openURL(url()); /// ## need args.reload=true?
1138         else {
1139             if (d->m_extension) {
1140                 d->m_extension->goBackOrForward(d->m_scheduledHistoryNavigationSteps);
1141             }
1142         }
1143         return;
1144     }
1145
1146     DeprecatedString URL = d->m_redirectURL;
1147     String referrer = d->m_redirectReferrer;
1148     bool lockHistory = d->m_redirectLockHistory;
1149     bool userGesture = d->m_redirectUserGesture;
1150
1151     d->m_scheduledRedirection = noRedirectionScheduled;
1152     d->m_delayRedirect = 0;
1153     d->m_redirectURL = DeprecatedString::null;
1154     d->m_redirectReferrer = String();
1155
1156     changeLocation(URL, referrer, lockHistory, userGesture);
1157 }
1158
1159 String Frame::encoding() const
1160 {
1161     if (d->m_haveEncoding && !d->m_encoding.isEmpty())
1162         return d->m_encoding;
1163     if (d->m_decoder && d->m_decoder->encoding().isValid())
1164         return d->m_decoder->encoding().name();
1165     return settings()->encoding();
1166 }
1167
1168 void Frame::setUserStyleSheetLocation(const KURL& url)
1169 {
1170     delete d->m_userStyleSheetLoader;
1171     d->m_userStyleSheetLoader = 0;
1172     if (d->m_doc && d->m_doc->docLoader())
1173         d->m_userStyleSheetLoader = new UserStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
1174 }
1175
1176 void Frame::setUserStyleSheet(const String& styleSheet)
1177 {
1178     delete d->m_userStyleSheetLoader;
1179     d->m_userStyleSheetLoader = 0;
1180     if (d->m_doc)
1181         d->m_doc->setUserStyleSheet(styleSheet);
1182 }
1183
1184 bool Frame::gotoAnchor(const String& name)
1185 {
1186   if (!d->m_doc)
1187     return false;
1188
1189   Node *n = d->m_doc->getElementById(AtomicString(name));
1190   if (!n)
1191       n = d->m_doc->anchors()->namedItem(name, !d->m_doc->inCompatMode());
1192
1193   d->m_doc->setCSSTarget(n); // Setting to null will clear the current target.
1194   
1195   // Implement the rule that "" and "top" both mean top of page as in other browsers.
1196   if (!n && !(name.isEmpty() || name.lower() == "top"))
1197       return false;
1198
1199   // We need to update the layout before scrolling, otherwise we could
1200   // really mess things up if an anchor scroll comes at a bad moment.
1201   if (d->m_doc) {
1202     d->m_doc->updateRendering();
1203     // Only do a layout if changes have occurred that make it necessary.      
1204     if (d->m_view && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout()) {
1205       d->m_view->layout();
1206     }
1207   }
1208   
1209   // Scroll nested layers and frames to reveal the anchor.
1210   RenderObject *renderer;
1211   IntRect rect;
1212   if (n) {
1213       renderer = n->renderer();
1214       rect = n->getRect();
1215   } else {
1216     // If there's no node, we should scroll to the top of the document.
1217       renderer = d->m_doc->renderer();
1218       rect = IntRect();
1219   }
1220
1221   if (renderer) {
1222     // Align to the top and to the closest side (this matches other browsers).
1223     renderer->enclosingLayer()->scrollRectToVisible(rect, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
1224   }
1225   
1226   return true;
1227 }
1228
1229 void Frame::setStandardFont(const String& name)
1230 {
1231     d->m_settings->setStdFontName(AtomicString(name));
1232 }
1233
1234 void Frame::setFixedFont(const String& name)
1235 {
1236     d->m_settings->setFixedFontName(AtomicString(name));
1237 }
1238
1239 String Frame::selectedText() const
1240 {
1241     return plainText(selectionController()->toRange().get());
1242 }
1243
1244 bool Frame::hasSelection() const
1245 {
1246     return selectionController()->isCaretOrRange();
1247 }
1248
1249 SelectionController* Frame::selectionController() const
1250 {
1251     return &(d->m_selectionController);
1252 }
1253
1254 CommandByName* Frame::command() const
1255 {
1256     return &(d->m_command);
1257 }
1258
1259 TextGranularity Frame::selectionGranularity() const
1260 {
1261     return d->m_selectionGranularity;
1262 }
1263
1264 void Frame::setSelectionGranularity(TextGranularity granularity) const
1265 {
1266     d->m_selectionGranularity = granularity;
1267 }
1268
1269 SelectionController* Frame::dragCaretController() const
1270 {
1271     return d->m_page->dragCaretController();
1272 }
1273
1274 const Selection& Frame::mark() const
1275 {
1276     return d->m_mark;
1277 }
1278
1279 void Frame::setMark(const Selection& s)
1280 {
1281     ASSERT(!s.base().node() || s.base().node()->document() == document());
1282     ASSERT(!s.extent().node() || s.extent().node()->document() == document());
1283     ASSERT(!s.start().node() || s.start().node()->document() == document());
1284     ASSERT(!s.end().node() || s.end().node()->document() == document());
1285
1286     d->m_mark = s;
1287 }
1288
1289 void Frame::notifyRendererOfSelectionChange(bool userTriggered)
1290 {
1291     RenderObject* renderer = 0;
1292     if (selectionController()->rootEditableElement())
1293         renderer = selectionController()->rootEditableElement()->shadowAncestorNode()->renderer();
1294
1295     // If the current selection is in a textfield or textarea, notify the renderer that the selection has changed
1296     if (renderer && (renderer->isTextArea() || renderer->isTextField()))
1297         static_cast<RenderTextControl*>(renderer)->selectionChanged(userTriggered);
1298 }
1299
1300 void Frame::invalidateSelection()
1301 {
1302     selectionController()->setNeedsLayout();
1303     selectionLayoutChanged();
1304 }
1305
1306 void Frame::setCaretVisible(bool flag)
1307 {
1308     if (d->m_caretVisible == flag)
1309         return;
1310     clearCaretRectIfNeeded();
1311     if (flag)
1312         setFocusNodeIfNeeded();
1313     d->m_caretVisible = flag;
1314     selectionLayoutChanged();
1315 }
1316
1317
1318 void Frame::clearCaretRectIfNeeded()
1319 {
1320     if (d->m_caretPaint) {
1321         d->m_caretPaint = false;
1322         selectionController()->invalidateCaretRect();
1323     }        
1324 }
1325
1326 // Helper function that tells whether a particular node is an element that has an entire
1327 // Frame and FrameView, a <frame>, <iframe>, or <object>.
1328 static bool isFrameElement(const Node *n)
1329 {
1330     if (!n)
1331         return false;
1332     RenderObject *renderer = n->renderer();
1333     if (!renderer || !renderer->isWidget())
1334         return false;
1335     Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
1336     return widget && widget->isFrameView();
1337 }
1338
1339 void Frame::setFocusNodeIfNeeded()
1340 {
1341     if (!document() || selectionController()->isNone() || !d->m_isActive)
1342         return;
1343
1344     Node* target = selectionController()->rootEditableElement();
1345     if (target) {
1346         RenderObject* renderer = target->renderer();
1347
1348         // Walk up the render tree to search for a node to focus.
1349         // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
1350         while (renderer) {
1351             // We don't want to set focus on a subframe when selecting in a parent frame,
1352             // so add the !isFrameElement check here. There's probably a better way to make this
1353             // work in the long term, but this is the safest fix at this time.
1354             if (target && target->isMouseFocusable() && !isFrameElement(target)) {
1355                 document()->setFocusNode(target);
1356                 return;
1357             }
1358             renderer = renderer->parent();
1359             if (renderer)
1360                 target = renderer->element();
1361         }
1362         document()->setFocusNode(0);
1363     }
1364 }
1365
1366 void Frame::selectionLayoutChanged()
1367 {
1368     bool caretRectChanged = selectionController()->recomputeCaretRect();
1369
1370     bool shouldBlink = d->m_caretVisible
1371         && selectionController()->isCaret() && selectionController()->isContentEditable();
1372
1373     // If the caret moved, stop the blink timer so we can restart with a
1374     // black caret in the new location.
1375     if (caretRectChanged || !shouldBlink)
1376         d->m_caretBlinkTimer.stop();
1377
1378     // Start blinking with a black caret. Be sure not to restart if we're
1379     // already blinking in the right location.
1380     if (shouldBlink && !d->m_caretBlinkTimer.isActive()) {
1381         d->m_caretBlinkTimer.startRepeating(caretBlinkFrequency);
1382         d->m_caretPaint = true;
1383     }
1384
1385     if (d->m_doc)
1386         d->m_doc->updateSelection();
1387 }
1388
1389 void Frame::setXPosForVerticalArrowNavigation(int x)
1390 {
1391     d->m_xPosForVerticalArrowNavigation = x;
1392 }
1393
1394 int Frame::xPosForVerticalArrowNavigation() const
1395 {
1396     return d->m_xPosForVerticalArrowNavigation;
1397 }
1398
1399 void Frame::caretBlinkTimerFired(Timer<Frame>*)
1400 {
1401     ASSERT(d->m_caretVisible);
1402     ASSERT(selectionController()->isCaret());
1403     bool caretPaint = d->m_caretPaint;
1404     if (d->m_bMousePressed && caretPaint)
1405         return;
1406     d->m_caretPaint = !caretPaint;
1407     selectionController()->invalidateCaretRect();
1408 }
1409
1410 void Frame::paintCaret(GraphicsContext* p, const IntRect& rect) const
1411 {
1412     if (d->m_caretPaint)
1413         selectionController()->paintCaret(p, rect);
1414 }
1415
1416 void Frame::paintDragCaret(GraphicsContext* p, const IntRect& rect) const
1417 {
1418     SelectionController* dragCaretController = d->m_page->dragCaretController();
1419     assert(dragCaretController->selection().isCaret());
1420     if (dragCaretController->selection().start().node()->document()->frame() == this)
1421         dragCaretController->paintCaret(p, rect);
1422 }
1423
1424 void Frame::urlSelected(const DeprecatedString& url, const String& target)
1425 {
1426     urlSelected(ResourceRequest(completeURL(url)), target);
1427 }
1428
1429 void Frame::urlSelected(const ResourceRequest& request, const String& _target)
1430 {
1431   String target = _target;
1432   if (target.isEmpty() && d->m_doc)
1433     target = d->m_doc->baseTarget();
1434
1435   const KURL& url = request.url();
1436
1437   if (url.url().startsWith("javascript:", false)) {
1438     executeScript(0, KURL::decode_string(url.url().mid(11)), true);
1439     return;
1440   }
1441
1442   if (!url.isValid())
1443     // ### ERROR HANDLING
1444     return;
1445
1446   ResourceRequest requestCopy = request;
1447   requestCopy.frameName = target;
1448
1449   if (d->m_bHTTPRefresh)
1450     d->m_bHTTPRefresh = false;
1451
1452   if (!d->m_referrer.isEmpty())
1453     requestCopy.setReferrer(d->m_referrer);
1454
1455   urlSelected(requestCopy);
1456 }
1457
1458 bool Frame::requestFrame(Element* ownerElement, const String& urlParam, const AtomicString& frameName)
1459 {
1460     DeprecatedString _url = urlParam.deprecatedString();
1461     // Support for <frame src="javascript:string">
1462     KURL scriptURL;
1463     KURL url;
1464     if (_url.startsWith("javascript:", false)) {
1465         scriptURL = _url;
1466         url = "about:blank";
1467     } else
1468         url = completeURL(_url);
1469
1470     Frame* frame = tree()->child(frameName);
1471     if (frame) {
1472         ResourceRequest request(url);
1473         request.setReferrer(d->m_referrer);
1474         request.reload = (d->m_cachePolicy == CachePolicyReload) || (d->m_cachePolicy == CachePolicyRefresh);
1475         frame->openURLRequest(request);
1476     } else
1477         frame = loadSubframe(ownerElement, url, frameName, d->m_referrer);
1478     
1479     if (!frame)
1480         return false;
1481
1482     if (!scriptURL.isEmpty())
1483         frame->replaceContentsWithScriptResult(scriptURL);
1484
1485     return true;
1486 }
1487
1488 bool Frame::requestObject(RenderPart* renderer, const String& url, const AtomicString& frameName,
1489                           const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues)
1490 {
1491     KURL completedURL;
1492     if (!url.isEmpty())
1493         completedURL = completeURL(url.deprecatedString());
1494     
1495     if (url.isEmpty() && mimeType.isEmpty())
1496         return true;
1497     
1498     bool useFallback;
1499     if (shouldUsePlugin(renderer->element(), completedURL, mimeType, renderer->hasFallbackContent(), useFallback))
1500         return loadPlugin(renderer, completedURL, mimeType, paramNames, paramValues, useFallback);
1501
1502     ASSERT(renderer->node()->hasTagName(objectTag) || renderer->node()->hasTagName(embedTag));
1503     AtomicString uniqueFrameName = tree()->uniqueChildName(frameName);
1504     static_cast<HTMLPlugInElement*>(renderer->node())->setFrameName(uniqueFrameName);
1505     
1506     // FIXME: ok to always make a new one? when does the old frame get removed?
1507     return loadSubframe(static_cast<Element*>(renderer->node()), completedURL, uniqueFrameName, d->m_referrer);
1508 }
1509
1510 bool Frame::shouldUsePlugin(Node* element, const KURL& url, const String& mimeType, bool hasFallback, bool& useFallback)
1511 {
1512     useFallback = false;
1513     ObjectContentType objectType = objectContentType(url, mimeType);
1514
1515     // if an object's content can't be handled and it has no fallback, let
1516     // it be handled as a plugin to show the broken plugin icon
1517     if (objectType == ObjectContentNone && hasFallback)
1518         useFallback = true;
1519
1520     return objectType == ObjectContentNone || objectType == ObjectContentPlugin;
1521 }
1522
1523
1524 bool Frame::loadPlugin(RenderPart *renderer, const KURL& url, const String& mimeType, 
1525                        const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback)
1526 {
1527     if (useFallback) {
1528         checkEmitLoadEvent();
1529         return false;
1530     }
1531
1532     Element *pluginElement;
1533     if (renderer && renderer->node() && renderer->node()->isElementNode())
1534         pluginElement = static_cast<Element*>(renderer->node());
1535     else
1536         pluginElement = 0;
1537         
1538     Plugin* plugin = createPlugin(pluginElement, url, paramNames, paramValues, mimeType);
1539     if (!plugin) {
1540         checkEmitLoadEvent();
1541         return false;
1542     }
1543     d->m_plugins.append(plugin);
1544     
1545     if (renderer && plugin->view())
1546         renderer->setWidget(plugin->view());
1547     
1548     checkEmitLoadEvent();
1549     
1550     return true;
1551 }
1552
1553 Frame* Frame::loadSubframe(Element* ownerElement, const KURL& url, const String& name, const String& referrer)
1554 {
1555     Frame* frame = createFrame(url, name, ownerElement, referrer);
1556     if (!frame)  {
1557         checkEmitLoadEvent();
1558         return 0;
1559     }
1560     
1561     frame->childBegin();
1562     
1563     if (ownerElement->renderer() && frame->view())
1564         static_cast<RenderWidget*>(ownerElement->renderer())->setWidget(frame->view());
1565     
1566     checkEmitLoadEvent();
1567     
1568     // In these cases, the synchronous load would have finished
1569     // before we could connect the signals, so make sure to send the 
1570     // completed() signal for the child by hand
1571     // FIXME: In this case the Frame will have finished loading before 
1572     // it's being added to the child list. It would be a good idea to
1573     // create the child first, then invoke the loader separately.
1574     if (url.isEmpty() || url == "about:blank") {
1575         frame->completed(false);
1576         frame->checkCompleted();
1577     }
1578
1579     return frame;
1580 }
1581
1582 void Frame::clearRecordedFormValues()
1583 {
1584     d->m_formAboutToBeSubmitted = 0;
1585     d->m_formValuesAboutToBeSubmitted.clear();
1586 }
1587
1588 void Frame::recordFormValue(const String& name, const String& value, PassRefPtr<HTMLFormElement> element)
1589 {
1590     d->m_formAboutToBeSubmitted = element;
1591     d->m_formValuesAboutToBeSubmitted.set(name, value);
1592 }
1593
1594 void Frame::submitFormAgain()
1595 {
1596     FramePrivate::SubmitForm* form = d->m_submitForm;
1597     d->m_submitForm = 0;
1598     if (d->m_doc && !d->m_doc->parsing() && form)
1599         submitForm(form->submitAction, form->submitUrl, form->submitFormData,
1600             form->target, form->submitContentType, form->submitBoundary);
1601     delete form;
1602 }
1603
1604 void Frame::submitForm(const char *action, const String& url, const FormData& formData, const String& _target, const String& contentType, const String& boundary)
1605 {
1606   KURL u = completeURL(url.deprecatedString());
1607
1608   if (!u.isValid())
1609     // ### ERROR HANDLING!
1610     return;
1611
1612   DeprecatedString urlstring = u.url();
1613   if (urlstring.startsWith("javascript:", false)) {
1614     urlstring = KURL::decode_string(urlstring);
1615     d->m_executingJavaScriptFormAction = true;
1616     executeScript(0, urlstring.mid(11));
1617     d->m_executingJavaScriptFormAction = false;
1618     return;
1619   }
1620
1621   ResourceRequest request;
1622
1623   if (!d->m_referrer.isEmpty())
1624      request.setReferrer(d->m_referrer);
1625
1626   request.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;
1627
1628   // Handle mailto: forms
1629   if (u.protocol() == "mailto") {
1630       // 2)  Append body=
1631       DeprecatedString bodyEnc;
1632       if (contentType.lower() == "multipart/form-data")
1633          // FIXME: is this correct?  I suspect not
1634          bodyEnc = KURL::encode_string(formData.flattenToString().deprecatedString());
1635       else if (contentType.lower() == "text/plain") {
1636          // Convention seems to be to decode, and s/&/\n/
1637          DeprecatedString tmpbody = formData.flattenToString().deprecatedString();
1638          tmpbody.replace('&', '\n');
1639          tmpbody.replace('+', ' ');
1640          tmpbody = KURL::decode_string(tmpbody);  // Decode the rest of it
1641          bodyEnc = KURL::encode_string(tmpbody);  // Recode for the URL
1642       } else
1643          bodyEnc = KURL::encode_string(formData.flattenToString().deprecatedString());
1644
1645       DeprecatedString query = u.query();
1646       if (!query.isEmpty())
1647           query += '&';
1648       query += "body=" + bodyEnc;
1649       
1650       u.setQuery(query);
1651   } 
1652
1653   if (strcmp(action, "get") == 0) {
1654     if (u.protocol() != "mailto")
1655        u.setQuery(formData.flattenToString().deprecatedString());
1656     request.setDoPost(false);
1657   } else {
1658     request.postData = formData;
1659     request.setDoPost(true);
1660
1661     // construct some user headers if necessary
1662     if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
1663       request.setContentType("Content-Type: application/x-www-form-urlencoded");
1664     else // contentType must be "multipart/form-data"
1665       request.setContentType("Content-Type: " + contentType + "; boundary=" + boundary);
1666   }
1667
1668   if (d->m_runningScripts > 0) {
1669     if (d->m_submitForm)
1670         return;
1671     d->m_submitForm = new FramePrivate::SubmitForm;
1672     d->m_submitForm->submitAction = action;
1673     d->m_submitForm->submitUrl = url;
1674     d->m_submitForm->submitFormData = formData;
1675     d->m_submitForm->target = _target;
1676     d->m_submitForm->submitContentType = contentType;
1677     d->m_submitForm->submitBoundary = boundary;
1678   } else {
1679       request.setURL(u);
1680       submitForm(request);
1681   }
1682 }
1683
1684 void Frame::parentCompleted()
1685 {
1686     if (d->m_scheduledRedirection != noRedirectionScheduled && !d->m_redirectionTimer.isActive())
1687         startRedirectionTimer();
1688 }
1689
1690 void Frame::childCompleted(bool complete)
1691 {
1692     if (complete && !tree()->parent())
1693         d->m_bPendingChildRedirection = true;
1694     checkCompleted();
1695 }
1696
1697 int Frame::zoomFactor() const
1698 {
1699   return d->m_zoomFactor;
1700 }
1701
1702 void Frame::setZoomFactor(int percent)
1703 {  
1704   if (d->m_zoomFactor == percent)
1705       return;
1706
1707   d->m_zoomFactor = percent;
1708
1709   if (d->m_doc)
1710       d->m_doc->recalcStyle(Node::Force);
1711
1712   for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
1713       child->setZoomFactor(d->m_zoomFactor);
1714
1715   if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout())
1716       view()->layout();
1717 }
1718
1719 void Frame::setJSStatusBarText(const String& text)
1720 {
1721     d->m_kjsStatusBarText = text;
1722     setStatusBarText(d->m_kjsStatusBarText);
1723 }
1724
1725 void Frame::setJSDefaultStatusBarText(const String& text)
1726 {
1727     d->m_kjsDefaultStatusBarText = text;
1728     setStatusBarText(d->m_kjsDefaultStatusBarText);
1729 }
1730
1731 String Frame::jsStatusBarText() const
1732 {
1733     return d->m_kjsStatusBarText;
1734 }
1735
1736 String Frame::jsDefaultStatusBarText() const
1737 {
1738    return d->m_kjsDefaultStatusBarText;
1739 }
1740
1741 String Frame::referrer() const
1742 {
1743     return d->m_referrer;
1744 }
1745
1746 String Frame::lastModified() const
1747 {
1748     return d->m_lastModified;
1749 }
1750
1751 void Frame::reparseConfiguration()
1752 {
1753     setAutoloadImages(d->m_settings->autoLoadImages());
1754         
1755     d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
1756     d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
1757     d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();
1758
1759     const KURL& userStyleSheetLocation = d->m_settings->userStyleSheetLocation();
1760     if (!userStyleSheetLocation.isEmpty())
1761         setUserStyleSheetLocation(userStyleSheetLocation);
1762     else
1763         setUserStyleSheet(String());
1764
1765     // FIXME: It's not entirely clear why the following is needed.
1766     // The document automatically does this as required when you set the style sheet.
1767     // But we had problems when this code was removed. Details are in
1768     // <http://bugzilla.opendarwin.org/show_bug.cgi?id=8079>.
1769     if (d->m_doc)
1770         d->m_doc->updateStyleSelector();
1771 }
1772
1773 bool Frame::shouldDragAutoNode(Node *node, const IntPoint& point) const
1774 {
1775     // No KDE impl yet
1776     return false;
1777 }
1778
1779 bool Frame::isPointInsideSelection(const IntPoint& point)
1780 {
1781     // Treat a collapsed selection like no selection.
1782     if (!selectionController()->isRange())
1783         return false;
1784     if (!document()->renderer()) 
1785         return false;
1786     
1787     RenderObject::NodeInfo nodeInfo(true, true);
1788     document()->renderer()->layer()->hitTest(nodeInfo, point);
1789     Node *innerNode = nodeInfo.innerNode();
1790     if (!innerNode || !innerNode->renderer())
1791         return false;
1792     
1793     Position pos(innerNode->renderer()->positionForPoint(point).deepEquivalent());
1794     if (pos.isNull())
1795         return false;
1796
1797     Node *n = selectionController()->start().node();
1798     while (n) {
1799         if (n == pos.node()) {
1800             if ((n == selectionController()->start().node() && pos.offset() < selectionController()->start().offset()) ||
1801                 (n == selectionController()->end().node() && pos.offset() > selectionController()->end().offset())) {
1802                 return false;
1803             }
1804             return true;
1805         }
1806         if (n == selectionController()->end().node())
1807             break;
1808         n = n->traverseNextNode();
1809     }
1810
1811    return false;
1812 }
1813
1814 void Frame::selectClosestWordFromMouseEvent(const PlatformMouseEvent& mouse, Node *innerNode)
1815 {
1816     Selection newSelection;
1817
1818     if (innerNode && innerNode->renderer() && mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
1819         IntPoint vPoint = view()->windowToContents(mouse.pos());
1820         VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
1821         if (pos.isNotNull()) {
1822             newSelection = Selection(pos);
1823             newSelection.expandUsingGranularity(WordGranularity);
1824         }
1825     }
1826     
1827     if (newSelection.isRange()) {
1828         d->m_selectionGranularity = WordGranularity;
1829         d->m_beganSelectingText = true;
1830     }
1831     
1832     if (shouldChangeSelection(newSelection))
1833         selectionController()->setSelection(newSelection);
1834 }
1835
1836 void Frame::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
1837 {
1838     if (event.event().button() == LeftButton) {
1839         if (selectionController()->isRange())
1840             // A double-click when range is already selected
1841             // should not change the selection.  So, do not call
1842             // selectClosestWordFromMouseEvent, but do set
1843             // m_beganSelectingText to prevent handleMouseReleaseEvent
1844             // from setting caret selection.
1845             d->m_beganSelectingText = true;
1846         else
1847             selectClosestWordFromMouseEvent(event.event(), event.targetNode());
1848     }
1849 }
1850
1851 void Frame::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
1852 {
1853     Node *innerNode = event.targetNode();
1854     
1855     if (event.event().button() == LeftButton && innerNode && innerNode->renderer() &&
1856         mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
1857         Selection newSelection;
1858         IntPoint vPoint = view()->windowToContents(event.event().pos());
1859         VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
1860         if (pos.isNotNull()) {
1861             newSelection = Selection(pos);
1862             newSelection.expandUsingGranularity(ParagraphGranularity);
1863         }
1864         if (newSelection.isRange()) {
1865             d->m_selectionGranularity = ParagraphGranularity;
1866             d->m_beganSelectingText = true;
1867         }
1868         
1869         if (shouldChangeSelection(newSelection))
1870             selectionController()->setSelection(newSelection);
1871     }
1872 }
1873
1874 void Frame::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
1875 {
1876     Node *innerNode = event.targetNode();
1877     
1878     if (event.event().button() == LeftButton) {
1879         if (innerNode && innerNode->renderer() &&
1880             mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
1881             
1882             // Extend the selection if the Shift key is down, unless the click is in a link.
1883             bool extendSelection = event.event().shiftKey() && !event.isOverLink();
1884
1885             // Don't restart the selection when the mouse is pressed on an
1886             // existing selection so we can allow for text dragging.
1887             IntPoint vPoint = view()->windowToContents(event.event().pos());
1888             if (!extendSelection && isPointInsideSelection(vPoint))
1889                 return;
1890
1891             VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(vPoint));
1892             if (visiblePos.isNull())
1893                 visiblePos = VisiblePosition(innerNode, innerNode->caretMinOffset(), DOWNSTREAM);
1894             Position pos = visiblePos.deepEquivalent();
1895             
1896             Selection newSelection = selectionController()->selection();
1897             if (extendSelection && newSelection.isCaretOrRange()) {
1898                 selectionController()->clearModifyBias();
1899                 
1900                 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection 
1901                 // was created right-to-left
1902                 Position start = newSelection.start();
1903                 Position end = newSelection.end();
1904                 short before = Range::compareBoundaryPoints(pos.node(), pos.offset(), start.node(), start.offset());
1905                 if (before <= 0)
1906                     newSelection = Selection(pos, end);
1907                 else
1908                     newSelection = Selection(start, pos);
1909
1910                 if (d->m_selectionGranularity != CharacterGranularity)
1911                     newSelection.expandUsingGranularity(d->m_selectionGranularity);
1912                 d->m_beganSelectingText = true;
1913             } else {
1914                 newSelection = Selection(visiblePos);
1915                 d->m_selectionGranularity = CharacterGranularity;
1916             }
1917             
1918             if (shouldChangeSelection(newSelection))
1919                 selectionController()->setSelection(newSelection);
1920         }
1921     }
1922 }
1923
1924 void Frame::handleMousePressEvent(const MouseEventWithHitTestResults& event)
1925 {
1926     Node *innerNode = event.targetNode();
1927
1928     d->m_mousePressNode = innerNode;
1929     d->m_dragStartPos = event.event().pos();
1930
1931     if (event.event().button() == LeftButton || event.event().button() == MiddleButton) {
1932         d->m_bMousePressed = true;
1933         d->m_beganSelectingText = false;
1934
1935         if (event.event().clickCount() == 2) {
1936             handleMousePressEventDoubleClick(event);
1937             return;
1938         }
1939         if (event.event().clickCount() >= 3) {
1940             handleMousePressEventTripleClick(event);
1941             return;
1942         }
1943         handleMousePressEventSingleClick(event);
1944     }
1945     
1946    setMouseDownMayStartAutoscroll(mouseDownMayStartSelect() || 
1947         (d->m_mousePressNode && d->m_mousePressNode->renderer() && d->m_mousePressNode->renderer()->shouldAutoscroll()));
1948 }
1949
1950 void Frame::handleMouseMoveEvent(const MouseEventWithHitTestResults& event)
1951 {
1952     // Mouse not pressed. Do nothing.
1953     if (!d->m_bMousePressed)
1954         return;
1955
1956     Node *innerNode = event.targetNode();
1957
1958     if (event.event().button() != 0 || !innerNode || !innerNode->renderer())
1959         return;
1960
1961      if (mouseDownMayStartAutoscroll()) {            
1962         // If the selection is contained in a layer that can scroll, that layer should handle the autoscroll
1963         // Otherwise, let the bridge handle it so the view can scroll itself.
1964         RenderObject* renderer = innerNode->renderer();
1965         while (renderer && !renderer->shouldAutoscroll())
1966             renderer = renderer->parent();
1967         if (renderer)
1968             handleAutoscroll(renderer);
1969                 
1970         setMouseDownMayStartDrag(false);
1971         view()->invalidateClick();
1972     }
1973     
1974     if (mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
1975         // handle making selection
1976         IntPoint vPoint = view()->windowToContents(event.event().pos());        
1977         VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
1978
1979         updateSelectionForMouseDragOverPosition(pos);
1980     }
1981
1982 }
1983
1984 void Frame::updateSelectionForMouseDragOverPosition(const VisiblePosition& pos)
1985 {
1986     // Don't modify the selection if we're not on a node.
1987     if (pos.isNull())
1988         return;
1989
1990     // Restart the selection if this is the first mouse move. This work is usually
1991     // done in handleMousePressEvent, but not if the mouse press was on an existing selection.
1992     Selection newSelection = selectionController()->selection();
1993     selectionController()->clearModifyBias();
1994     
1995     if (!d->m_beganSelectingText) {
1996         d->m_beganSelectingText = true;
1997         newSelection = Selection(pos);
1998     }
1999
2000     newSelection.setExtent(pos);
2001     if (d->m_selectionGranularity != CharacterGranularity)
2002         newSelection.expandUsingGranularity(d->m_selectionGranularity);
2003
2004     if (shouldChangeSelection(newSelection))
2005         selectionController()->setSelection(newSelection);
2006 }
2007
2008 void Frame::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
2009 {
2010     stopAutoscrollTimer();
2011     
2012     // Used to prevent mouseMoveEvent from initiating a drag before
2013     // the mouse is pressed again.
2014     d->m_bMousePressed = false;
2015   
2016     // Clear the selection if the mouse didn't move after the last mouse press.
2017     // We do this so when clicking on the selection, the selection goes away.
2018     // However, if we are editing, place the caret.
2019     if (mouseDownMayStartSelect() && !d->m_beganSelectingText
2020             && d->m_dragStartPos == event.event().pos()
2021             && selectionController()->isRange()) {
2022         Selection newSelection;
2023         Node *node = event.targetNode();
2024         if (node && node->isContentEditable() && node->renderer()) {
2025             IntPoint vPoint = view()->windowToContents(event.event().pos());
2026             VisiblePosition pos = node->renderer()->positionForPoint(vPoint);
2027             newSelection = Selection(pos);
2028         }
2029         if (shouldChangeSelection(newSelection))
2030             selectionController()->setSelection(newSelection);
2031     }
2032
2033     notifyRendererOfSelectionChange(true);
2034
2035     selectFrameElementInParentIfFullySelected();
2036 }
2037
2038 void Frame::selectAll()
2039 {
2040     if (!d->m_doc)
2041         return;
2042     
2043     Node* root = selectionController()->isContentEditable() ? selectionController()->rootEditableElement() : d->m_doc->documentElement();
2044     selectContentsOfNode(root);
2045     selectFrameElementInParentIfFullySelected();
2046     notifyRendererOfSelectionChange(true);
2047 }
2048
2049 bool Frame::selectContentsOfNode(Node* node)
2050 {
2051     Selection newSelection(Selection::selectionFromContentsOfNode(node));
2052     if (shouldChangeSelection(newSelection)) {
2053         selectionController()->setSelection(newSelection);
2054         return true;
2055     }
2056     return false;
2057 }
2058
2059 bool Frame::shouldChangeSelection(const Selection& newSelection) const
2060 {
2061     return shouldChangeSelection(selectionController()->selection(), newSelection, newSelection.affinity(), false);
2062 }
2063
2064 bool Frame::shouldDeleteSelection(const Selection& newSelection) const
2065 {
2066     return true;
2067 }
2068
2069 bool Frame::shouldBeginEditing(const Range *range) const
2070 {
2071     return true;
2072 }
2073
2074 bool Frame::shouldEndEditing(const Range *range) const
2075 {
2076     return true;
2077 }
2078
2079 bool Frame::isContentEditable() const 
2080 {
2081     if (!d->m_doc)
2082         return false;
2083     return d->m_doc->inDesignMode();
2084 }
2085
2086 void Frame::textFieldDidBeginEditing(Element* input)
2087 {
2088 }
2089
2090 void Frame::textFieldDidEndEditing(Element* input)
2091 {
2092 }
2093
2094 void Frame::textDidChangeInTextField(Element* input)
2095 {
2096 }
2097
2098 bool Frame::doTextFieldCommandFromEvent(Element* input, const PlatformKeyboardEvent* evt)
2099 {
2100     return false;
2101 }
2102
2103 void Frame::textWillBeDeletedInTextField(Element* input)
2104 {
2105 }
2106
2107 void Frame::textDidChangeInTextArea(Element* input)
2108 {
2109 }
2110
2111 bool Frame::isSelectionInPasswordField()
2112 {
2113     Node* startNode = selectionController()->start().node();
2114     if (startNode)
2115         startNode = startNode->shadowAncestorNode();
2116     return startNode && startNode->hasTagName(inputTag) && static_cast<HTMLInputElement*>(startNode)->inputType() == HTMLInputElement::PASSWORD;
2117 }
2118   
2119 EditCommand* Frame::lastEditCommand()
2120 {
2121     return d->m_lastEditCommand.get();
2122 }
2123
2124 static void dispatchEditableContentChangedEvents(const EditCommand& command)
2125 {
2126      Element* startRoot = command.startingRootEditableElement();
2127      Element* endRoot = command.endingRootEditableElement();
2128      ExceptionCode ec;
2129      if (startRoot)
2130          startRoot->dispatchEvent(new Event(khtmlEditableContentChangedEvent, false, false), ec, true);
2131      if (endRoot && endRoot != startRoot)
2132          endRoot->dispatchEvent(new Event(khtmlEditableContentChangedEvent, false, false), ec, true);
2133 }
2134
2135 void Frame::appliedEditing(PassRefPtr<EditCommand> cmd)
2136 {
2137     dispatchEditableContentChangedEvents(*cmd);
2138  
2139     Selection newSelection(cmd->endingSelection());
2140     if (shouldChangeSelection(newSelection))
2141         selectionController()->setSelection(newSelection, false);
2142     
2143     // Now set the typing style from the command. Clear it when done.
2144     // This helps make the case work where you completely delete a piece
2145     // of styled text and then type a character immediately after.
2146     // That new character needs to take on the style of the just-deleted text.
2147     // FIXME: Improve typing style.
2148     // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
2149     if (cmd->typingStyle()) {
2150         setTypingStyle(cmd->typingStyle());
2151         cmd->setTypingStyle(0);
2152     }
2153
2154     // Command will be equal to last edit command only in the case of typing
2155     if (d->m_lastEditCommand == cmd)
2156         assert(cmd->isTypingCommand());
2157     else {
2158         // Only register a new undo command if the command passed in is
2159         // different from the last command
2160         d->m_lastEditCommand = cmd.get();
2161         registerCommandForUndo(cmd);
2162     }
2163     respondToChangedContents(newSelection);
2164 }
2165
2166 void Frame::unappliedEditing(PassRefPtr<EditCommand> cmd)
2167 {
2168     dispatchEditableContentChangedEvents(*cmd);
2169
2170     Selection newSelection(cmd->startingSelection());
2171     if (shouldChangeSelection(newSelection))
2172         selectionController()->setSelection(newSelection, true);
2173         
2174     d->m_lastEditCommand = 0;
2175     registerCommandForRedo(cmd);
2176     respondToChangedContents(newSelection);
2177 }
2178
2179 void Frame::reappliedEditing(PassRefPtr<EditCommand> cmd)
2180 {
2181     dispatchEditableContentChangedEvents(*cmd);
2182
2183     Selection newSelection(cmd->endingSelection());
2184     if (shouldChangeSelection(newSelection))
2185         selectionController()->setSelection(newSelection, true);
2186         
2187     d->m_lastEditCommand = 0;
2188     registerCommandForUndo(cmd);
2189     respondToChangedContents(newSelection);
2190 }
2191
2192 CSSMutableStyleDeclaration *Frame::typingStyle() const
2193 {
2194     return d->m_typingStyle.get();
2195 }
2196
2197 void Frame::setTypingStyle(CSSMutableStyleDeclaration *style)
2198 {
2199     d->m_typingStyle = style;
2200 }
2201
2202 void Frame::clearTypingStyle()
2203 {
2204     d->m_typingStyle = 0;
2205 }
2206
2207 JSValue* Frame::executeScript(const String& filename, int baseLine, Node* n, const String& script)
2208 {
2209     // FIXME: This is missing stuff that the other executeScript has.
2210     // --> d->m_runningScripts and submitFormAgain.
2211     // Why is that OK?
2212     KJSProxy* proxy = jScript();
2213     if (!proxy)
2214         return 0;
2215     JSValue* ret = proxy->evaluate(filename, baseLine, script, n);
2216     Document::updateDocumentsRendering();
2217     return ret;
2218 }
2219
2220 Frame *Frame::opener()
2221 {
2222     return d->m_opener;
2223 }
2224
2225 void Frame::setOpener(Frame* opener)
2226 {
2227     if (d->m_opener)
2228         d->m_opener->d->m_openedFrames.remove(this);
2229     if (opener)
2230         opener->d->m_openedFrames.add(this);
2231     d->m_opener = opener;
2232 }
2233
2234 bool Frame::openedByJS()
2235 {
2236     return d->m_openedByJS;
2237 }
2238
2239 void Frame::setOpenedByJS(bool _openedByJS)
2240 {
2241     d->m_openedByJS = _openedByJS;
2242 }
2243
2244 bool Frame::tabsToLinks() const
2245 {
2246     return true;
2247 }
2248
2249 bool Frame::tabsToAllControls() const
2250 {
2251     return true;
2252 }
2253
2254 void Frame::copyToPasteboard()
2255 {
2256     issueCopyCommand();
2257 }
2258
2259 void Frame::cutToPasteboard()
2260 {
2261     issueCutCommand();
2262 }
2263
2264 void Frame::pasteFromPasteboard()
2265 {
2266     issuePasteCommand();
2267 }
2268
2269 void Frame::pasteAndMatchStyle()
2270 {
2271     issuePasteAndMatchStyleCommand();
2272 }
2273
2274 bool Frame::mayCopy()
2275 {
2276     return !isSelectionInPasswordField();
2277 }
2278
2279 void Frame::transpose()
2280 {
2281     issueTransposeCommand();
2282 }
2283
2284 void Frame::redo()
2285 {
2286     issueRedoCommand();
2287 }
2288
2289 void Frame::undo()
2290 {
2291     issueUndoCommand();
2292 }
2293
2294
2295 void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction)
2296 {
2297     if (!style || style->length() == 0) {
2298         clearTypingStyle();
2299         return;
2300     }
2301
2302     // Calculate the current typing style.
2303     RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
2304     if (typingStyle()) {
2305         typingStyle()->merge(mutableStyle.get());
2306         mutableStyle = typingStyle();
2307     }
2308
2309     Node *node = selectionController()->selection().visibleStart().deepEquivalent().node();
2310     CSSComputedStyleDeclaration computedStyle(node);
2311     computedStyle.diff(mutableStyle.get());
2312     
2313     // Handle block styles, substracting these from the typing style.
2314     RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();
2315     blockStyle->diff(mutableStyle.get());
2316     if (document() && blockStyle->length() > 0)
2317         applyCommand(new ApplyStyleCommand(document(), blockStyle.get(), editingAction));
2318     
2319     // Set the remaining style as the typing style.
2320     d->m_typingStyle = mutableStyle.release();
2321 }
2322
2323 void Frame::applyStyle(CSSStyleDeclaration *style, EditAction editingAction)
2324 {
2325     switch (selectionController()->state()) {
2326         case Selection::NONE:
2327             // do nothing
2328             break;
2329         case Selection::CARET: {
2330             computeAndSetTypingStyle(style, editingAction);
2331             break;
2332         }
2333         case Selection::RANGE:
2334             if (document() && style)
2335                 applyCommand(new ApplyStyleCommand(document(), style, editingAction));
2336             break;
2337     }
2338 }
2339
2340 void Frame::applyParagraphStyle(CSSStyleDeclaration *style, EditAction editingAction)
2341 {
2342     switch (selectionController()->state()) {
2343         case Selection::NONE:
2344             // do nothing
2345             break;
2346         case Selection::CARET:
2347         case Selection::RANGE:
2348             if (document() && style)
2349                 applyCommand(new ApplyStyleCommand(document(), style, editingAction, ApplyStyleCommand::ForceBlockProperties));
2350             break;
2351     }
2352 }
2353
2354 static void updateState(CSSMutableStyleDeclaration *desiredStyle, CSSComputedStyleDeclaration *computedStyle, bool& atStart, Frame::TriState& state)
2355 {
2356     DeprecatedValueListConstIterator<CSSProperty> end;
2357     for (DeprecatedValueListConstIterator<CSSProperty> it = desiredStyle->valuesIterator(); it != end; ++it) {
2358         int propertyID = (*it).id();
2359         String desiredProperty = desiredStyle->getPropertyValue(propertyID);
2360         String computedProperty = computedStyle->getPropertyValue(propertyID);
2361         Frame::TriState propertyState = equalIgnoringCase(desiredProperty, computedProperty)
2362             ? Frame::trueTriState : Frame::falseTriState;
2363         if (atStart) {
2364             state = propertyState;
2365             atStart = false;
2366         } else if (state != propertyState) {
2367             state = Frame::mixedTriState;
2368             break;
2369         }
2370     }
2371 }
2372
2373 Frame::TriState Frame::selectionListState() const
2374 {
2375     TriState state = falseTriState;
2376
2377     if (!selectionController()->isRange()) {
2378         Node* selectionNode = selectionController()->selection().start().node();
2379         if (enclosingList(selectionNode))
2380             return trueTriState;
2381     } else {
2382         //FIXME: Support ranges
2383     }
2384
2385     return state;
2386 }
2387
2388 Frame::TriState Frame::selectionHasStyle(CSSStyleDeclaration *style) const
2389 {
2390     bool atStart = true;
2391     TriState state = falseTriState;
2392
2393     RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
2394
2395     if (!selectionController()->isRange()) {
2396         Node* nodeToRemove;
2397         RefPtr<CSSComputedStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
2398         if (!selectionStyle)
2399             return falseTriState;
2400         updateState(mutableStyle.get(), selectionStyle.get(), atStart, state);
2401         if (nodeToRemove) {
2402             ExceptionCode ec = 0;
2403             nodeToRemove->remove(ec);
2404             assert(ec == 0);
2405         }
2406     } else {
2407         for (Node* node = selectionController()->start().node(); node; node = node->traverseNextNode()) {
2408             RefPtr<CSSComputedStyleDeclaration> computedStyle = new CSSComputedStyleDeclaration(node);
2409             if (computedStyle)
2410                 updateState(mutableStyle.get(), computedStyle.get(), atStart, state);
2411             if (state == mixedTriState)
2412                 break;
2413             if (node == selectionController()->end().node())
2414                 break;
2415         }
2416     }
2417
2418     return state;
2419 }
2420
2421 bool Frame::selectionStartHasStyle(CSSStyleDeclaration *style) const
2422 {
2423     Node* nodeToRemove;
2424     RefPtr<CSSStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
2425     if (!selectionStyle)
2426         return false;
2427
2428     RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
2429
2430     bool match = true;
2431     DeprecatedValueListConstIterator<CSSProperty> end;
2432     for (DeprecatedValueListConstIterator<CSSProperty> it = mutableStyle->valuesIterator(); it != end; ++it) {
2433         int propertyID = (*it).id();
2434         if (!equalIgnoringCase(mutableStyle->getPropertyValue(propertyID), selectionStyle->getPropertyValue(propertyID))) {
2435             match = false;
2436             break;
2437         }
2438     }
2439
2440     if (nodeToRemove) {
2441         ExceptionCode ec = 0;
2442         nodeToRemove->remove(ec);
2443         assert(ec == 0);
2444     }
2445
2446     return match;
2447 }
2448
2449 String Frame::selectionStartStylePropertyValue(int stylePropertyID) const
2450 {
2451     Node *nodeToRemove;
2452     RefPtr<CSSStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
2453     if (!selectionStyle)
2454         return String();
2455
2456     String value = selectionStyle->getPropertyValue(stylePropertyID);
2457
2458     if (nodeToRemove) {
2459         ExceptionCode ec = 0;
2460         nodeToRemove->remove(ec);
2461         assert(ec == 0);
2462     }
2463
2464     return value;
2465 }
2466
2467 CSSComputedStyleDeclaration *Frame::selectionComputedStyle(Node *&nodeToRemove) const
2468 {
2469     nodeToRemove = 0;
2470
2471     if (!document())
2472         return 0;
2473
2474     if (selectionController()->isNone())
2475         return 0;
2476
2477     RefPtr<Range> range(selectionController()->toRange());
2478     Position pos = range->editingStartPosition();
2479
2480     Element *elem = pos.element();
2481     if (!elem)
2482         return 0;
2483     
2484     RefPtr<Element> styleElement = elem;
2485     ExceptionCode ec = 0;
2486
2487     if (d->m_typingStyle) {
2488         styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
2489         assert(ec == 0);
2490
2491         styleElement->setAttribute(styleAttr, d->m_typingStyle->cssText().impl(), ec);
2492         assert(ec == 0);
2493         
2494         styleElement->appendChild(document()->createEditingTextNode(""), ec);
2495         assert(ec == 0);
2496
2497         if (elem->renderer() && elem->renderer()->canHaveChildren()) {
2498             elem->appendChild(styleElement, ec);
2499         } else {
2500             Node *parent = elem->parent();
2501             Node *next = elem->nextSibling();
2502
2503             if (next) {
2504                 parent->insertBefore(styleElement, next, ec);
2505             } else {
2506                 parent->appendChild(styleElement, ec);
2507             }
2508         }
2509         assert(ec == 0);
2510
2511         nodeToRemove = styleElement.get();
2512     }
2513
2514     return new CSSComputedStyleDeclaration(styleElement);
2515 }
2516
2517 void Frame::applyEditingStyleToBodyElement() const
2518 {
2519     if (!d->m_doc)
2520         return;
2521         
2522     RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body");
2523     unsigned len = list->length();
2524     for (unsigned i = 0; i < len; i++) {
2525         applyEditingStyleToElement(static_cast<Element*>(list->item(i)));    
2526     }
2527 }
2528
2529 void Frame::removeEditingStyleFromBodyElement() const
2530 {
2531     if (!d->m_doc)
2532         return;
2533         
2534     RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body");
2535     unsigned len = list->length();
2536     for (unsigned i = 0; i < len; i++) {
2537         removeEditingStyleFromElement(static_cast<Element*>(list->item(i)));    
2538     }
2539 }
2540
2541 void Frame::applyEditingStyleToElement(Element* element) const
2542 {
2543     if (!element)
2544         return;
2545
2546     CSSStyleDeclaration* style = element->style();
2547     ASSERT(style);
2548
2549     ExceptionCode ec = 0;
2550     style->setProperty(CSS_PROP_WORD_WRAP, "break-word", false, ec);
2551     ASSERT(ec == 0);
2552     style->setProperty(CSS_PROP__WEBKIT_NBSP_MODE, "space", false, ec);
2553     ASSERT(ec == 0);
2554     style->setProperty(CSS_PROP__WEBKIT_LINE_BREAK, "after-white-space", false, ec);
2555     ASSERT(ec == 0);
2556 }
2557
2558 void Frame::removeEditingStyleFromElement(Element*) const
2559 {
2560 }
2561
2562 bool Frame::isCharacterSmartReplaceExempt(UChar, bool)
2563 {
2564     // no smart replace
2565     return true;
2566 }
2567
2568 #ifndef NDEBUG
2569 static HashSet<Frame*> lifeSupportSet;
2570 #endif
2571
2572 void Frame::endAllLifeSupport()
2573 {
2574 #ifndef NDEBUG
2575     HashSet<Frame*> lifeSupportCopy = lifeSupportSet;
2576     HashSet<Frame*>::iterator end = lifeSupportCopy.end();
2577     for (HashSet<Frame*>::iterator it = lifeSupportCopy.begin(); it != end; ++it)
2578         (*it)->endLifeSupport();
2579 #endif
2580 }
2581
2582 void Frame::keepAlive()
2583 {
2584     if (d->m_lifeSupportTimer.isActive())
2585         return;
2586     ref();
2587 #ifndef NDEBUG
2588     lifeSupportSet.add(this);
2589 #endif
2590     d->m_lifeSupportTimer.startOneShot(0);
2591 }
2592
2593 void Frame::endLifeSupport()
2594 {
2595     if (!d->m_lifeSupportTimer.isActive())
2596         return;
2597     d->m_lifeSupportTimer.stop();
2598 #ifndef NDEBUG
2599     lifeSupportSet.remove(this);
2600 #endif
2601     deref();
2602 }
2603
2604 void Frame::lifeSupportTimerFired(Timer<Frame>*)
2605 {
2606 #ifndef NDEBUG
2607     lifeSupportSet.remove(this);
2608 #endif
2609     deref();
2610 }
2611
2612 // Workaround for the fact that it's hard to delete a frame.
2613 // Call this after doing user-triggered selections to make it easy to delete the frame you entirely selected.
2614 // Can't do this implicitly as part of every setSelection call because in some contexts it might not be good
2615 // for the focus to move to another frame. So instead we call it from places where we are selecting with the
2616 // mouse or the keyboard after setting the selection.
2617 void Frame::selectFrameElementInParentIfFullySelected()
2618 {
2619     // Find the parent frame; if there is none, then we have nothing to do.
2620     Frame *parent = tree()->parent();
2621     if (!parent)
2622         return;
2623     FrameView *parentView = parent->view();
2624     if (!parentView)
2625         return;
2626
2627     // Check if the selection contains the entire frame contents; if not, then there is nothing to do.
2628     if (!selectionController()->isRange())
2629         return;
2630     if (!isStartOfDocument(selectionController()->selection().visibleStart()))
2631         return;
2632     if (!isEndOfDocument(selectionController()->selection().visibleEnd()))
2633         return;
2634
2635     // Get to the <iframe> or <frame> (or even <object>) element in the parent frame.
2636     Document *doc = document();
2637     if (!doc)
2638         return;
2639     Element *ownerElement = doc->ownerElement();
2640     if (!ownerElement)
2641         return;
2642     Node *ownerElementParent = ownerElement->parentNode();
2643     if (!ownerElementParent)
2644         return;
2645         
2646     // This method's purpose is it to make it easier to select iframes (in order to delete them).  Don't do anything if the iframe isn't deletable.
2647     if (!ownerElementParent->isContentEditable())
2648         return;
2649
2650     // Create compute positions before and after the element.
2651     unsigned ownerElementNodeIndex = ownerElement->nodeIndex();
2652     VisiblePosition beforeOwnerElement(VisiblePosition(ownerElementParent, ownerElementNodeIndex, SEL_DEFAULT_AFFINITY));
2653     VisiblePosition afterOwnerElement(VisiblePosition(ownerElementParent, ownerElementNodeIndex + 1, VP_UPSTREAM_IF_POSSIBLE));
2654
2655     // Focus on the parent frame, and then select from before this element to after.
2656     Selection newSelection(beforeOwnerElement, afterOwnerElement);
2657     if (parent->shouldChangeSelection(newSelection)) {
2658         parentView->setFocus();
2659         parent->selectionController()->setSelection(newSelection);
2660     }
2661 }
2662
2663 bool Frame::mouseDownMayStartAutoscroll() const
2664 {
2665     return d->m_mouseDownMayStartAutoscroll;
2666 }
2667
2668 void Frame::setMouseDownMayStartAutoscroll(bool b)
2669 {
2670     d->m_mouseDownMayStartAutoscroll = b;
2671 }
2672
2673 bool Frame::mouseDownMayStartDrag() const
2674 {
2675     return d->m_mouseDownMayStartDrag;
2676 }
2677
2678 void Frame::setMouseDownMayStartDrag(bool b)
2679 {
2680     d->m_mouseDownMayStartDrag = b;
2681 }
2682
2683 void Frame::handleFallbackContent()
2684 {
2685     Element* owner = ownerElement();
2686     if (!owner || !owner->hasTagName(objectTag))
2687         return;
2688     static_cast<HTMLObjectElement*>(owner)->renderFallbackContent();
2689 }
2690
2691 void Frame::setSettings(Settings *settings)
2692 {
2693     d->m_settings = settings;
2694 }
2695
2696 void Frame::provisionalLoadStarted()
2697 {
2698     // we don't want to wait until we get an actual http response back
2699     // to cancel pending redirects, otherwise they might fire before
2700     // that happens.
2701     cancelRedirection(true);
2702 }
2703
2704 bool Frame::userGestureHint()
2705 {
2706     Frame *rootFrame = this;
2707     while (rootFrame->tree()->parent())
2708         rootFrame = rootFrame->tree()->parent();
2709
2710     if (rootFrame->jScript())
2711         return rootFrame->jScript()->interpreter()->wasRunByUserGesture();
2712
2713     return true; // If JavaScript is disabled, a user gesture must have initiated the navigation
2714 }
2715
2716 RenderObject *Frame::renderer() const
2717 {
2718     Document *doc = document();
2719     return doc ? doc->renderer() : 0;
2720 }
2721
2722 Element* Frame::ownerElement()
2723 {
2724     return d->m_ownerElement;
2725 }
2726
2727 RenderPart* Frame::ownerRenderer()
2728 {
2729     Element* ownerElement = d->m_ownerElement;
2730     if (!ownerElement)
2731         return 0;
2732     return static_cast<RenderPart*>(ownerElement->renderer());
2733 }
2734
2735 IntRect Frame::selectionRect() const
2736 {
2737     RenderView *root = static_cast<RenderView*>(renderer());
2738     if (!root)
2739         return IntRect();
2740
2741     return root->selectionRect();
2742 }
2743
2744 // returns FloatRect because going through IntRect would truncate any floats
2745 FloatRect Frame::visibleSelectionRect() const
2746 {
2747     if (!d->m_view)
2748         return FloatRect();
2749     
2750     return intersection(selectionRect(), d->m_view->visibleContentRect());
2751 }
2752
2753 bool Frame::isFrameSet() const
2754 {
2755     Document* document = d->m_doc.get();
2756     if (!document || !document->isHTMLDocument())
2757         return false;
2758     Node *body = static_cast<HTMLDocument*>(document)->body();
2759     return body && body->renderer() && body->hasTagName(framesetTag);
2760 }
2761
2762 bool Frame::openURL(const KURL& URL)
2763 {
2764     ASSERT_NOT_REACHED();
2765     return true;
2766 }
2767
2768 void Frame::didNotOpenURL(const KURL& URL)
2769 {
2770     if (d->m_submittedFormURL == URL)
2771         d->m_submittedFormURL = KURL();
2772 }
2773
2774 // Scans logically forward from "start", including any child frames
2775 static HTMLFormElement *scanForForm(Node *start)
2776 {
2777     Node *n;
2778     for (n = start; n; n = n->traverseNextNode()) {
2779         if (n->hasTagName(formTag))
2780             return static_cast<HTMLFormElement*>(n);
2781         else if (n->isHTMLElement() && static_cast<HTMLElement*>(n)->isGenericFormElement())
2782             return static_cast<HTMLGenericFormElement*>(n)->form();
2783         else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) {
2784             Node *childDoc = static_cast<HTMLFrameElement*>(n)->contentDocument();
2785             if (HTMLFormElement *frameResult = scanForForm(childDoc))
2786                 return frameResult;
2787         }
2788     }
2789     return 0;
2790 }
2791
2792 // We look for either the form containing the current focus, or for one immediately after it
2793 HTMLFormElement *Frame::currentForm() const
2794 {
2795     // start looking either at the active (first responder) node, or where the selection is
2796     Node *start = d->m_doc ? d->m_doc->focusNode() : 0;
2797     if (!start)
2798         start = selectionController()->start().node();
2799     
2800     // try walking up the node tree to find a form element
2801     Node *n;
2802     for (n = start; n; n = n->parentNode()) {
2803         if (n->hasTagName(formTag))
2804             return static_cast<HTMLFormElement*>(n);
2805         else if (n->isHTMLElement()
2806                    && static_cast<HTMLElement*>(n)->isGenericFormElement())
2807             return static_cast<HTMLGenericFormElement*>(n)->form();
2808     }
2809     
2810     // try walking forward in the node tree to find a form element
2811     return start ? scanForForm(start) : 0;
2812 }
2813
2814 void Frame::setEncoding(const String& name, bool userChosen)
2815 {
2816     if (!d->m_workingURL.isEmpty())
2817         receivedFirstData();
2818     d->m_encoding = name;
2819     d->m_haveEncoding = userChosen;
2820 }
2821
2822 void Frame::addData(const char *bytes, int length)
2823 {
2824     ASSERT(d->m_workingURL.isEmpty());
2825     ASSERT(d->m_doc);
2826     ASSERT(d->m_doc->parsing());
2827     write(bytes, length);
2828 }
2829
2830 // FIXME: should this go in SelectionController?
2831 void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
2832 {
2833     IntRect rect;
2834     
2835     switch (selectionController()->state()) {
2836         case Selection::NONE:
2837             return;
2838             
2839         case Selection::CARET:
2840             rect = selectionController()->caretRect();
2841             break;
2842             
2843         case Selection::RANGE:
2844             rect = selectionRect();
2845             break;
2846     }
2847
2848     Position start = selectionController()->start();
2849     Position end = selectionController()->end();
2850
2851     ASSERT(start.node());
2852     if (start.node() && start.node()->renderer()) {
2853         RenderLayer *layer = start.node()->renderer()->enclosingLayer();
2854         if (layer) {
2855             ASSERT(!end.node() || !end.node()->renderer() 
2856                    || (end.node()->renderer()->enclosingLayer() == layer));
2857             layer->scrollRectToVisible(rect, alignment, alignment);
2858         }
2859     }
2860 }
2861
2862 void Frame::revealCaret(const RenderLayer::ScrollAlignment& alignment) const
2863 {
2864     if (!hasSelection())
2865         return;
2866
2867     Position extent = selectionController()->extent();
2868     if (extent.node() && extent.node()->renderer()) {
2869         IntRect extentRect = VisiblePosition(extent).caretRect();
2870         RenderLayer* layer = extent.node()->renderer()->enclosingLayer();
2871         if (layer)
2872             layer->scrollRectToVisible(extentRect, alignment, alignment);
2873     }
2874 }
2875
2876 // FIXME: should this be here?
2877 bool Frame::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity)
2878 {
2879     if (!document()) {
2880         return false;
2881     }
2882     
2883     Node *node = document()->focusNode();
2884     if (node == 0) {
2885         node = d->m_mousePressNode.get();
2886     }
2887     
2888     if (node != 0) {
2889         RenderObject *r = node->renderer();
2890         if (r != 0 && !r->isListBox()) {
2891             return r->scroll(direction, granularity);
2892         }
2893     }
2894     
2895     return false;
2896 }
2897
2898 void Frame::handleAutoscroll(RenderObject* renderer)
2899 {
2900     if (d->m_autoscrollTimer.isActive())
2901         return;
2902     setAutoscrollRenderer(renderer);
2903     startAutoscrollTimer();
2904 }
2905
2906 void Frame::autoscrollTimerFired(Timer<Frame>*)
2907 {
2908     if (!d->m_bMousePressed){
2909         stopAutoscrollTimer();
2910         return;
2911     }
2912     if (RenderObject* r = autoscrollRenderer())
2913         r->autoscroll();
2914 }
2915
2916 RenderObject* Frame::autoscrollRenderer() const
2917 {
2918     return d->m_autoscrollRenderer;
2919 }
2920
2921 void Frame::setAutoscrollRenderer(RenderObject* renderer)
2922 {
2923     d->m_autoscrollRenderer = renderer;
2924 }
2925
2926 RenderObject::NodeInfo Frame::nodeInfoAtPoint(const IntPoint& point, bool allowShadowContent)
2927 {
2928     RenderObject::NodeInfo nodeInfo(true, true);
2929     renderer()->layer()->hitTest(nodeInfo, point);
2930
2931     Node *n;
2932     Widget *widget = 0;
2933     IntPoint widgetPoint(point);
2934     
2935     while (true) {
2936         n = nodeInfo.innerNode();
2937         if (!n || !n->renderer() || !n->renderer()->isWidget())
2938             break;
2939         widget = static_cast<RenderWidget*>(n->renderer())->widget();
2940         if (!widget || !widget->isFrameView())
2941             break;
2942         Frame* frame = static_cast<HTMLFrameElement*>(n)->contentFrame();
2943         if (!frame || !frame->renderer())
2944             break;
2945         int absX, absY;
2946         n->renderer()->absolutePosition(absX, absY, true);
2947         FrameView *view = static_cast<FrameView*>(widget);
2948         widgetPoint.setX(widgetPoint.x() - absX + view->contentsX());
2949         widgetPoint.setY(widgetPoint.y() - absY + view->contentsY());
2950
2951         RenderObject::NodeInfo widgetNodeInfo(true, true);
2952         frame->renderer()->layer()->hitTest(widgetNodeInfo, widgetPoint);
2953         nodeInfo = widgetNodeInfo;
2954     }
2955     
2956     if (!allowShadowContent) {
2957         Node* node = nodeInfo.innerNode();
2958         if (node)
2959             node = node->shadowAncestorNode();
2960         nodeInfo.setInnerNode(node);
2961         node = nodeInfo.innerNonSharedNode();
2962         if (node)
2963             node = node->shadowAncestorNode();
2964         nodeInfo.setInnerNonSharedNode(node); 
2965     }
2966     return nodeInfo;
2967 }
2968
2969 bool Frame::hasSelection()
2970 {
2971     if (selectionController()->isNone())
2972         return false;
2973
2974     // If a part has a selection, it should also have a document.        
2975     ASSERT(document());
2976
2977     return true;
2978 }
2979
2980 void Frame::startAutoscrollTimer()
2981 {
2982     d->m_autoscrollTimer.startRepeating(autoscrollInterval);
2983 }
2984
2985 void Frame::stopAutoscrollTimer()
2986 {
2987     setAutoscrollRenderer(0);
2988     d->m_autoscrollTimer.stop();
2989 }
2990
2991 // FIXME: why is this here instead of on the FrameView?
2992 void Frame::paint(GraphicsContext* p, const IntRect& rect)
2993 {
2994 #ifndef NDEBUG
2995     bool fillWithRed;
2996     if (!document() || document()->printing())
2997         fillWithRed = false; // Printing, don't fill with red (can't remember why).
2998     else if (document()->ownerElement())
2999         fillWithRed = false; // Subframe, don't fill with red.
3000     else if (view() && view()->isTransparent())
3001         fillWithRed = false; // Transparent, don't fill with red.
3002     else if (d->m_paintRestriction == PaintRestrictionSelectionOnly || d->m_paintRestriction == PaintRestrictionSelectionOnlyWhiteText)
3003         fillWithRed = false; // Selections are transparent, don't fill with red.
3004     else if (d->m_elementToDraw)
3005         fillWithRed = false; // Element images are transparent, don't fill with red.
3006     else
3007         fillWithRed = true;
3008     
3009     if (fillWithRed)
3010         p->fillRect(rect, Color(0xFF, 0, 0));
3011 #endif
3012     
3013     if (renderer()) {
3014         // d->m_elementToDraw is used to draw only one element
3015         RenderObject *eltRenderer = d->m_elementToDraw ? d->m_elementToDraw->renderer() : 0;
3016         if (d->m_paintRestriction == PaintRestrictionNone)
3017             renderer()->document()->invalidateRenderedRectsForMarkersInRect(rect);
3018         renderer()->layer()->paint(p, rect, d->m_paintRestriction, eltRenderer);
3019
3020 #if __APPLE__
3021         // Regions may have changed as a result of the visibility/z-index of element changing.
3022         if (renderer()->document()->dashboardRegionsDirty())
3023             renderer()->view()->frameView()->updateDashboardRegions();
3024 #endif
3025     } else
3026         LOG_ERROR("called Frame::paint with nil renderer");
3027 }
3028
3029 #if __APPLE__
3030
3031 void Frame::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float bottomLimit)
3032 {
3033     RenderView *root = static_cast<RenderView*>(document()->renderer());
3034     if (root) {
3035         // Use a context with painting disabled.
3036         GraphicsContext context(0);
3037         root->setTruncatedAt((int)floorf(oldBottom));
3038         IntRect dirtyRect(0, (int)floorf(oldTop), root->docWidth(), (int)ceilf(oldBottom - oldTop));
3039         root->layer()->paint(&context, dirtyRect);
3040         *newBottom = root->bestTruncatedAt();
3041         if (*newBottom == 0)
3042             *newBottom = oldBottom;
3043     } else
3044         *newBottom = oldBottom;
3045 }
3046
3047 #endif
3048
3049 PausedTimeouts *Frame::pauseTimeouts()
3050 {
3051 #ifdef SVG_SUPPORT
3052     if (d->m_doc && d->m_doc->svgExtensions())
3053         d->m_doc->accessSVGExtensions()->pauseAnimations();
3054 #endif
3055
3056     if (d->m_doc && d->m_jscript) {
3057         if (Window* w = Window::retrieveWindow(this))
3058             return w->pauseTimeouts();
3059     }
3060     return 0;
3061 }
3062
3063 void Frame::resumeTimeouts(PausedTimeouts* t)
3064 {
3065 #ifdef SVG_SUPPORT
3066     if (d->m_doc && d->m_doc->svgExtensions())
3067         d->m_doc->accessSVGExtensions()->unpauseAnimations();
3068 #endif
3069
3070     if (d->m_doc && d->m_jscript && d->m_bJScriptEnabled) {
3071         if (Window* w = Window::retrieveWindow(this))
3072             w->resumeTimeouts(t);
3073     }
3074 }
3075
3076 bool Frame::canCachePage()
3077 {
3078     // Only save page state if:
3079     // 1.  We're not a frame or frameset.
3080     // 2.  The page has no unload handler.
3081     // 3.  The page has no password fields.
3082     // 4.  The URL for the page is not https.
3083     // 5.  The page has no applets.
3084     if (tree()->childCount() || d->m_plugins.size() ||
3085         tree()->parent() ||
3086         d->m_url.protocol().startsWith("https") || 
3087         (d->m_doc && (d->m_doc->applets()->length() != 0 ||
3088                       d->m_doc->hasWindowEventListener(unloadEvent) ||
3089                       d->m_doc->hasPasswordField()))) {
3090         return false;
3091     }
3092     return true;
3093 }
3094
3095 void Frame::saveWindowProperties(KJS::SavedProperties *windowProperties)
3096 {
3097     Window *window = Window::retrieveWindow(this);
3098     if (window)
3099         window->saveProperties(*windowProperties);
3100 }
3101
3102 void Frame::saveLocationProperties(SavedProperties *locationProperties)
3103 {
3104     Window *window = Window::retrieveWindow(this);
3105     if (window) {
3106         JSLock lock;
3107         Location *location = window->location();
3108         location->saveProperties(*locationProperties);
3109     }
3110 }
3111
3112 void Frame::restoreWindowProperties(SavedProperties *windowProperties)
3113 {
3114     Window *window = Window::retrieveWindow(this);
3115     if (window)
3116         window->restoreProperties(*windowProperties);
3117 }
3118
3119 void Frame::restoreLocationProperties(SavedProperties *locationProperties)
3120 {
3121     Window *window = Window::retrieveWindow(this);
3122     if (window) {
3123         JSLock lock;
3124         Location *location = window->location();
3125         location->restoreProperties(*locationProperties);
3126     }
3127 }
3128
3129 void Frame::saveInterpreterBuiltins(SavedBuiltins& interpreterBuiltins)
3130 {
3131     if (jScript())
3132         jScript()->interpreter()->saveBuiltins(interpreterBuiltins);
3133 }
3134
3135 void Frame::restoreInterpreterBuiltins(const SavedBuiltins& interpreterBuiltins)
3136 {
3137     if (jScript())
3138         jScript()->interpreter()->restoreBuiltins(interpreterBuiltins);
3139 }
3140
3141 Frame *Frame::frameForWidget(const Widget *widget)
3142 {
3143     ASSERT_ARG(widget, widget);
3144     
3145     Node *node = nodeForWidget(widget);
3146     if (node)
3147         return frameForNode(node);
3148     
3149     // Assume all widgets are either form controls, or FrameViews.
3150     ASSERT(widget->isFrameView());
3151     return static_cast<const FrameView*>(widget)->frame();
3152 }
3153
3154 Frame *Frame::frameForNode(Node *node)
3155 {
3156     ASSERT_ARG(node, node);
3157     return node->document()->frame();
3158 }
3159
3160 Node* Frame::nodeForWidget(const Widget* widget)
3161 {
3162     ASSERT_ARG(widget, widget);
3163     WidgetClient* client = widget->client();
3164     if (!client)
3165         return 0;
3166     return client->element(const_cast<Widget*>(widget));
3167 }
3168
3169 void Frame::clearDocumentFocus(Widget *widget)
3170 {
3171     Node *node = nodeForWidget(widget);
3172     ASSERT(node);
3173     node->document()->setFocusNode(0);
3174 }
3175
3176 void Frame::updatePolicyBaseURL()
3177 {
3178     if (tree()->parent() && tree()->parent()->document())
3179         setPolicyBaseURL(tree()->parent()->document()->policyBaseURL());
3180     else
3181         setPolicyBaseURL(d->m_url.url());
3182 }
3183
3184 void Frame::setPolicyBaseURL(const String& s)
3185 {
3186     if (document())
3187         document()->setPolicyBaseURL(s);
3188     for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
3189         child->setPolicyBaseURL(s);
3190 }
3191
3192 void Frame::forceLayout()
3193 {
3194     FrameView *v = d->m_view.get();
3195     if (v) {
3196         v->layout(false);
3197         // We cannot unschedule a pending relayout, since the force can be called with
3198         // a tiny rectangle from a drawRect update.  By unscheduling we in effect
3199         // "validate" and stop the necessary full repaint from occurring.  Basically any basic
3200         // append/remove DHTML is broken by this call.  For now, I have removed the optimization
3201         // until we have a better invalidation stategy. -dwh
3202         //v->unscheduleRelayout();
3203     }
3204 }
3205
3206 void Frame::forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth)
3207 {
3208     // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
3209     // the state of things before and after the layout
3210     RenderView *root = static_cast<RenderView*>(document()->renderer());
3211     if (root) {
3212         // This magic is basically copied from khtmlview::print
3213         int pageW = (int)ceilf(minPageWidth);
3214         root->setWidth(pageW);
3215         root->setNeedsLayoutAndMinMaxRecalc();
3216         forceLayout();
3217         
3218         // If we don't fit in the minimum page width, we'll lay out again. If we don't fit in the
3219         // maximum page width, we will lay out to the maximum page width and clip extra content.
3220         // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
3221         // implementation should not do this!
3222         int rightmostPos = root->rightmostPosition();
3223         if (rightmostPos > minPageWidth) {
3224             pageW = min(rightmostPos, (int)ceilf(maxPageWidth));
3225             root->setWidth(pageW);
3226             root->setNeedsLayoutAndMinMaxRecalc();
3227             forceLayout();
3228         }
3229     }
3230 }
3231
3232 void Frame::sendResizeEvent()
3233 {
3234     if (Document* doc = document())
3235         doc->dispatchWindowEvent(EventNames::resizeEvent, false, false);
3236 }
3237
3238 void Frame::sendScrollEvent()
3239 {
3240     FrameView *v = d->m_view.get();
3241     if (v) {
3242         Document *doc = document();
3243         if (!doc)
3244             return;
3245         doc->dispatchHTMLEvent(scrollEvent, true, false);
3246     }
3247 }
3248
3249 bool Frame::scrollbarsVisible()
3250 {
3251     if (!view())
3252         return false;
3253     
3254     if (view()->hScrollbarMode() == ScrollbarAlwaysOff || view()->vScrollbarMode() == ScrollbarAlwaysOff)
3255         return false;
3256     
3257     return true;
3258 }
3259
3260 void Frame::addMetaData(const String& key, const String& value)
3261 {
3262     d->m_metaData.set(key, value);
3263 }
3264
3265 // This does the same kind of work that Frame::openURL does, except it relies on the fact
3266 // that a higher level already checked that the URLs match and the scrolling is the right thing to do.
3267 void Frame::scrollToAnchor(const KURL& URL)
3268 {
3269     d->m_url = URL;
3270     started();
3271     
3272     gotoAnchor();
3273     
3274     // It's important to model this as a load that starts and immediately finishes.
3275     // Otherwise, the parent frame may think we never finished loading.
3276     d->m_bComplete = false;
3277     checkCompleted();
3278 }
3279
3280 bool Frame::closeURL()
3281 {
3282     saveDocumentState();
3283     stopLoading(true);
3284     clearUndoRedoOperations();
3285     return true;
3286 }
3287
3288 bool Frame::canMouseDownStartSelect(Node* node)
3289 {
3290     if (!node || !node->renderer())
3291         return true;
3292     
3293     // Check to see if -webkit-user-select has been set to none
3294     if (!node->renderer()->canSelect())
3295         return false;
3296     
3297     // Some controls and images can't start a select on a mouse down.
3298     for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {
3299         if (curr->style()->userSelect() == SELECT_IGNORE)
3300             return false;
3301     }
3302     
3303     return true;
3304 }
3305
3306 void Frame::clearTimers(FrameView *view)
3307 {
3308     if (view) {
3309         view->unscheduleRelayout();
3310         if (view->frame()) {
3311             Document* document = view->frame()->document();
3312             if (document && document->renderer() && document->renderer()->layer())
3313                 document->renderer()->layer()->suspendMarquees();
3314         }
3315     }
3316 }
3317
3318 void Frame::clearTimers()
3319 {
3320     clearTimers(d->m_view.get());
3321 }
3322
3323 RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
3324 {
3325     nodeToRemove = 0;
3326     
3327     if (!document())
3328         return 0;
3329     if (selectionController()->isNone())
3330         return 0;
3331     
3332     Position pos = selectionController()->selection().visibleStart().deepEquivalent();
3333     if (!pos.inRenderedContent())
3334         return 0;
3335     Node *node = pos.node();
3336     if (!node)
3337         return 0;
3338     
3339     if (!d->m_typingStyle)
3340         return node->renderer()->style();
3341     
3342     ExceptionCode ec = 0;
3343     RefPtr<Element> styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
3344     ASSERT(ec == 0);
3345     
3346     styleElement->setAttribute(styleAttr, d->m_typingStyle->cssText().impl(), ec);
3347     ASSERT(ec == 0);
3348     
3349     styleElement->appendChild(document()->createEditingTextNode(""), ec);
3350     ASSERT(ec == 0);
3351     
3352     node->parentNode()->appendChild(styleElement, ec);
3353     ASSERT(ec == 0);
3354     
3355     nodeToRemove = styleElement.get();    
3356     return styleElement->renderer()->style();
3357 }
3358
3359 void Frame::setMediaType(const String& type)
3360 {
3361     if (d->m_view)
3362         d->m_view->setMediaType(type);
3363 }
3364
3365 void Frame::setSelectionFromNone()
3366 {
3367     // Put a caret inside the body if the entire frame is editable (either the 
3368     // entire WebView is editable or designMode is on for this document).
3369     Document *doc = document();
3370     if (!doc || !selectionController()->isNone() || !isContentEditable())
3371         return;
3372         
3373     Node* node = doc->documentElement();
3374     while (node && !node->hasTagName(bodyTag))
3375         node = node->traverseNextNode();
3376     if (node)
3377         selectionController()->setSelection(Selection(Position(node, 0), DOWNSTREAM));
3378 }
3379
3380 bool Frame::isActive() const
3381 {
3382     return d->m_isActive;
3383 }
3384
3385 void Frame::setIsActive(bool flag)
3386 {
3387     if (d->m_isActive == flag)
3388         return;
3389     
3390     d->m_isActive = flag;
3391
3392     // This method does the job of updating the view based on whether the view is "active".
3393     // This involves three kinds of drawing updates:
3394
3395     // 1. The background color used to draw behind selected content (active | inactive color)
3396     if (d->m_view)
3397         d->m_view->updateContents(enclosingIntRect(visibleSelectionRect()));
3398
3399     // 2. Caret blinking (blinks | does not blink)
3400     if (flag)
3401         setSelectionFromNone();
3402     setCaretVisible(flag);
3403     
3404     // 3. The drawing of a focus ring around links in web pages.
3405     Document *doc = document();
3406     if (doc) {
3407         Node *node = doc->focusNode();
3408         if (node) {
3409             node->setChanged();
3410             if (node->renderer() && node->renderer()->style()->hasAppearance())
3411                 theme()->stateChanged(node->renderer(), FocusState);
3412         }
3413     }
3414     
3415     // 4. Changing the tint of controls from clear to aqua/graphite and vice versa.  We
3416     // do a "fake" paint.  When the theme gets a paint call, it can then do an invalidate.  This is only
3417     // done if the theme supports control tinting.
3418     if (doc && d->m_view && theme()->supportsControlTints() && renderer()) {
3419         doc->updateLayout(); // Ensure layout is up to date.
3420         IntRect visibleRect(enclosingIntRect(d->m_view->visibleContentRect()));
3421         GraphicsContext context((PlatformGraphicsContext*)0);
3422         context.setUpdatingControlTints(true);
3423         paint(&context, visibleRect);
3424     }
3425    
3426     // 5. Enable or disable secure keyboard entry
3427     if ((flag && !isSecureKeyboardEntry() && doc && doc->focusNode() && doc->focusNode()->hasTagName(inputTag) && 
3428             static_cast<HTMLInputElement*>(doc->focusNode())->inputType() == HTMLInputElement::PASSWORD) ||
3429         (!flag && isSecureKeyboardEntry()))
3430             setSecureKeyboardEntry(flag);
3431 }
3432
3433 void Frame::setWindowHasFocus(bool flag)
3434 {
3435     if (d->m_windowHasFocus == flag)
3436         return;
3437     d->m_windowHasFocus = flag;
3438     
3439     if (Document *doc = document())
3440         doc->dispatchWindowEvent(flag ? focusEvent : blurEvent, false, false);
3441 }
3442
3443 bool Frame::inViewSourceMode() const
3444 {
3445     return d->m_inViewSourceMode;
3446 }
3447
3448 void Frame::setInViewSourceMode(bool mode) const
3449 {
3450     d->m_inViewSourceMode = mode;
3451 }
3452   
3453 UChar Frame::backslashAsCurrencySymbol() const
3454 {
3455     Document *doc = document();
3456     if (!doc)
3457         return '\\';
3458     Decoder *decoder = doc->decoder();
3459     if (!decoder)
3460         return '\\';
3461
3462     return decoder->encoding().backslashAsCurrencySymbol();
3463 }
3464
3465 bool Frame::markedTextUsesUnderlines() const
3466 {
3467     return d->m_markedTextUsesUnderlines;
3468 }
3469
3470 const Vector<MarkedTextUnderline>& Frame::markedTextUnderlines() const
3471 {
3472     return d->m_markedTextUnderlines;
3473 }
3474
3475 // Searches from the beginning of the document if nothing is selected.
3476 bool Frame::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag)
3477 {
3478     if (target.isEmpty())
3479         return false;
3480     
3481     // Initially search from the start (if forward) or end (if backward) of the selection, and search to edge of document.
3482     RefPtr<Range> searchRange(rangeOfContents(document()));
3483     Selection selection(selectionController()->selection());
3484     if (!selection.isNone()) {
3485         if (forward)
3486             setStart(searchRange.get(), selection.visibleStart());
3487         else
3488             setEnd(searchRange.get(), selection.visibleEnd());
3489     }
3490     RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
3491     // If the found range is already selected, find again.
3492     // Build a selection with the found range to remove collapsed whitespace.
3493     // Compare ranges instead of selection objects to ignore the way that the current selection was made.
3494     if (!selection.isNone() && *Selection(resultRange.get()).toRange() == *selection.toRange()) {
3495         searchRange = rangeOfContents(document());
3496         if (forward)
3497             setStart(searchRange.get(), selection.visibleEnd());
3498         else
3499             setEnd(searchRange.get(), selection.visibleStart());
3500         resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
3501     }
3502     
3503     int exception = 0;
3504     
3505     // If we didn't find anything and we're wrapping, search again in the entire document (this will
3506     // redundantly re-search the area already searched in some cases).
3507     if (resultRange->collapsed(exception) && wrapFlag) {
3508         searchRange = rangeOfContents(document());
3509         resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
3510         // We used to return false here if we ended up with the same range that we started with
3511         // (e.g., the selection was already the only instance of this text). But we decided that
3512         // this should be a success case instead, so we'll just fall through in that case.
3513     }
3514
3515     if (resultRange->collapsed(exception))
3516         return false;
3517
3518     selectionController()->setSelection(Selection(resultRange.get(), DOWNSTREAM));
3519     revealSelection();
3520     return true;
3521 }
3522
3523 unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsigned limit)
3524 {
3525     if (target.isEmpty())
3526         return 0;
3527     
3528     RefPtr<Range> searchRange(rangeOfContents(document()));
3529     
3530     int exception = 0;
3531     unsigned matchCount = 0;
3532     do {
3533         RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));
3534         if (resultRange->collapsed(exception))
3535             break;
3536         
3537         // A non-collapsed result range can in some funky whitespace cases still not
3538         // advance the range's start position (4509328). Break to avoid infinite loop.
3539         VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
3540         if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
3541             break;
3542
3543         ++matchCount;
3544         
3545         document()->addMarker(resultRange.get(), DocumentMarker::TextMatch);        
3546         
3547         // Stop looking if we hit the specified limit. A limit of 0 means no limit.
3548         if (limit > 0 && matchCount >= limit)
3549             break;
3550         
3551         setStart(searchRange.get(), newStart);
3552     } while (true);
3553     
3554     // Do a "fake" paint in order to execute the code that computes the rendered rect for 
3555     // each text match.
3556     Document* doc = document();
3557     if (doc && d->m_view && renderer()) {
3558         doc->updateLayout(); // Ensure layout is up to date.
3559         IntRect visibleRect(enclosingIntRect(d->m_view->visibleContentRect()));
3560         GraphicsContext context((PlatformGraphicsContext*)0);
3561         context.setPaintingDisabled(true);
3562         paint(&context, visibleRect);
3563     }
3564     
3565     return matchCount;
3566 }
3567
3568 bool Frame::markedTextMatchesAreHighlighted() const
3569 {
3570     return d->m_highlightTextMatches;
3571 }
3572
3573 void Frame::setMarkedTextMatchesAreHighlighted(bool flag)
3574 {
3575     if (flag == d->m_highlightTextMatches)
3576         return;
3577     
3578     d->m_highlightTextMatches = flag;
3579     document()->repaintMarkers(DocumentMarker::TextMatch);
3580 }
3581
3582 void Frame::prepareForUserAction()
3583 {
3584     // Reset the multiple form submission protection code.
3585     // We'll let you submit the same form twice if you do two separate user actions.
3586     d->m_submittedFormURL = KURL();
3587 }
3588
3589 Node *Frame::mousePressNode()
3590 {
3591     return d->m_mousePressNode.get();
3592 }
3593
3594 bool Frame::isComplete() const
3595 {
3596     return d->m_bComplete;
3597 }
3598
3599 bool Frame::isLoadingMainResource() const
3600 {
3601     return d->m_bLoadingMainResource;
3602 }
3603
3604 FrameTree* Frame::tree() const
3605 {
3606     return &d->m_treeNode;
3607 }
3608
3609 DOMWindow* Frame::domWindow() const
3610 {
3611     if (!d->m_domWindow)
3612         d->m_domWindow = new DOMWindow(const_cast<Frame*>(this));
3613
3614     return d->m_domWindow.get();
3615 }
3616
3617 KURL Frame::url() const
3618 {
3619     return d->m_url;
3620 }
3621
3622 void Frame::startRedirectionTimer()
3623 {
3624     d->m_redirectionTimer.startOneShot(d->m_delayRedirect);
3625 }
3626
3627 void Frame::stopRedirectionTimer()
3628 {
3629     d->m_redirectionTimer.stop();
3630 }
3631
3632 void Frame::frameDetached()
3633 {
3634 }
3635
3636 void Frame::detachChildren()
3637 {
3638     // FIXME: is it really necessary to do this in reverse order any more?
3639     while (Frame* child = tree()->lastChild())
3640         tree()->removeChild(child);
3641 }
3642
3643 void Frame::updateBaseURLForEmptyDocument()
3644 {
3645     Element* owner = ownerElement();
3646     // FIXME: Should embed be included?
3647     if (owner && (owner->hasTagName(iframeTag) || owner->hasTagName(objectTag) || owner->hasTagName(embedTag)))
3648         d->m_doc->setBaseURL(tree()->parent()->d->m_doc->baseURL());
3649 }
3650
3651 Page* Frame::page() const
3652 {
3653     return d->m_page;
3654 }
3655
3656 void Frame::pageDestroyed()
3657 {
3658     d->m_page = 0;
3659
3660     // This will stop any JS timers
3661     if (d->m_jscript && d->m_jscript->haveInterpreter())
3662         if (Window* w = Window::retrieveWindow(this))
3663             w->disconnectFrame();
3664 }
3665
3666 void Frame::completed(bool complete)
3667 {
3668     ref();
3669     for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
3670         child->parentCompleted();
3671     if (Frame* parent = tree()->parent())
3672         parent->childCompleted(complete);
3673     submitFormAgain();
3674     deref();
3675 }
3676
3677 void Frame::setStatusBarText(const String&)
3678 {
3679 }
3680
3681 void Frame::started()
3682 {
3683     for (Frame* frame = this; frame; frame = frame->tree()->parent())
3684         frame->d->m_bComplete = false;
3685 }
3686
3687 void Frame::disconnectOwnerElement()
3688 {
3689     if (d->m_ownerElement && d->m_page)
3690         d->m_page->decrementFrameCount();
3691         
3692     d->m_ownerElement = 0;
3693 }
3694
3695 String Frame::documentTypeString() const
3696 {
3697     if (Document *doc = document())
3698         if (DocumentType *doctype = doc->realDocType())
3699             return doctype->toString();
3700
3701     return String();
3702 }
3703
3704 bool Frame::containsPlugins() const 
3705
3706     return d->m_plugins.size() != 0;
3707 }
3708
3709 bool Frame::prohibitsScrolling() const
3710 {
3711     return d->m_prohibitsScrolling;
3712 }
3713
3714 void Frame::setProhibitsScrolling(const bool prohibit)
3715 {
3716     d->m_prohibitsScrolling = prohibit;
3717 }
3718
3719 } // namespace WebCore