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