/* This file is part of the KDE project
 *
 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
 *                     1999 Lars Knoll <knoll@kde.org>
 *                     1999 Antti Koivisto <koivisto@kde.org>
 *                     2000 Simon Hausmann <hausmann@kde.org>
 *                     2000 Stefan Schimanski <1Stein@gmx.de>
 *                     2001 George Staikos <staikos@kde.org>
 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
 * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "config.h"
#include "Frame.h"
#include "FramePrivate.h"

#include "ApplyStyleCommand.h"
#include "CSSComputedStyleDeclaration.h"
#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "Cache.h"
#include "CachedCSSStyleSheet.h"
#include "DOMImplementation.h"
#include "DOMWindow.h"
#include "Decoder.h"
#include "DocLoader.h"
#include "DocumentType.h"
#include "EditingText.h"
#include "EventNames.h"
#include "FloatRect.h"
#include "Frame.h"
#include "GraphicsContext.h"
#include "HTMLDocument.h"
#include "HTMLFormElement.h"
#include "HTMLFrameElement.h"
#include "HTMLGenericFormElement.h"
#include "HTMLNames.h"
#include "MediaFeatureNames.h"
#include "HTMLObjectElement.h"
#include "ImageDocument.h"
#include "MouseEventWithHitTestResults.h"
#include "NodeList.h"
#include "Page.h"
#include "Plugin.h"
#include "RenderPart.h"
#include "RenderTheme.h"
#include "RenderView.h"
#include "SegmentedString.h"
#include "TextDocument.h"
#include "TextIterator.h"
#include "TransferJob.h"
#include "TypingCommand.h"
#include "cssstyleselector.h"
#include "dom2_eventsimpl.h"
#include "htmlediting.h"
#include "kjs_window.h"
#include "markup.h"
#include "visible_units.h"
#include "xml_tokenizer.h"
#include "xmlhttprequest.h"
#include <math.h>
#include <sys/types.h>

#if !WIN32
#include <unistd.h>
#endif

#if SVG_SUPPORT
#include "SVGNames.h"
#include "XLinkNames.h"
#include "XMLNames.h"
#include "SVGDocumentExtensions.h"
#include "SVGDOMImplementation.h"
#endif

using namespace std;

using KJS::JSLock;
using KJS::JSValue;
using KJS::Location;
using KJS::PausedTimeouts;
using KJS::SavedProperties;
using KJS::SavedBuiltins;
using KJS::UString;
using KJS::Window;

namespace WebCore {

using namespace EventNames;
using namespace HTMLNames;

const double caretBlinkFrequency = 0.5;
const double autoscrollInterval = 0.1;

class UserStyleSheetLoader : public CachedObjectClient {
public:
    UserStyleSheetLoader(Frame* frame, const String& url, DocLoader* dl)
        : m_frame(frame)
        , m_cachedSheet(Cache::requestStyleSheet(dl, url, false, 0, ""))
    {
        m_cachedSheet->ref(this);
    }
    ~UserStyleSheetLoader()
    {
        m_cachedSheet->deref(this);
    }
private:
    virtual void setStyleSheet(const String& /*URL*/, const String& sheet)
    {
        m_frame->setUserStyleSheet(sheet.deprecatedString());
    }
    Frame* m_frame;
    CachedCSSStyleSheet* m_cachedSheet;
};

#ifndef NDEBUG
struct FrameCounter { 
    static int count; 
    ~FrameCounter() { if (count != 0) fprintf(stderr, "LEAK: %d Frame\n", count); }
};
int FrameCounter::count = 0;
static FrameCounter frameCounter;
#endif

static inline Frame* parentFromOwnerRenderer(RenderPart* ownerRenderer)
{
    if (!ownerRenderer)
        return 0;
    return ownerRenderer->node()->document()->frame();
}

Frame::Frame(Page* page, RenderPart* ownerRenderer) 
    : d(new FramePrivate(page, parentFromOwnerRenderer(ownerRenderer), this, ownerRenderer))
{
    AtomicString::init();
    Cache::init();
    EventNames::init();
    HTMLNames::init();
    QualifiedName::init();
    MediaFeatureNames::init();

#if SVG_SUPPORT
    SVGNames::init();
    XLinkNames::init();
    XMLNames::init();
#endif

    // FIXME: Frames were originally created with a refcount of 1, leave this
    // ref call here until we can straighten that out.
    ref();
#ifndef NDEBUG
    ++FrameCounter::count;
#endif

    if (ownerRenderer)
        ownerRenderer->setFrame(this);
}

Frame::~Frame()
{
    ASSERT(!d->m_lifeSupportTimer.isActive());

#ifndef NDEBUG
    --FrameCounter::count;
#endif

    cancelRedirection();

    if (!d->m_bComplete)
        closeURL();

    clear(false);

    if (d->m_jscript && d->m_jscript->haveInterpreter())
        if (Window* w = Window::retrieveWindow(this)) {
            w->disconnectFrame();
            // Must clear the window pointer, otherwise we will not
            // garbage-collect collect the window (inside the call to
            // delete d below).
            w = 0;
        }

    if (d->m_domWindow)
        d->m_domWindow->disconnectFrame();
            
    setOpener(0);
    HashSet<Frame*> openedBy = d->m_openedFrames;
    HashSet<Frame*>::iterator end = openedBy.end();
    for (HashSet<Frame*>::iterator it = openedBy.begin(); it != end; ++it)
        (*it)->setOpener(0);

    if (d->m_ownerRenderer)
        d->m_ownerRenderer->setFrame(0);
    ASSERT(!d->m_ownerRenderer);

    if (d->m_view) {
        d->m_view->hide();
        d->m_view->m_frame = 0;
    }
  
    ASSERT(!d->m_lifeSupportTimer.isActive());

    delete d->m_userStyleSheetLoader;
    delete d;
    d = 0;
}

bool Frame::didOpenURL(const KURL& url)
{
  if (d->m_scheduledRedirection == locationChangeScheduledDuringLoad) {
    // A redirect was shceduled before the document was created. This can happen
    // when one frame changes another frame's location.
    return false;
  }
  
  cancelRedirection();
  
  // clear last edit command
  d->m_lastEditCommand = EditCommandPtr();
  
  closeURL();

  if (d->m_request.reload)
     d->m_cachePolicy = KIO::CC_Refresh;
  else
     d->m_cachePolicy = KIO::CC_Verify;

  if (d->m_request.doPost() && url.protocol().startsWith("http")) {
      d->m_job = new TransferJob(this, "POST", url, d->m_request.postData);
      d->m_job->addMetaData("content-type", d->m_request.contentType());
  } else
      d->m_job = new TransferJob(this, "GET", url);

  d->m_bComplete = false;
  d->m_bLoadingMainResource = true;
  d->m_bLoadEventEmitted = false;

  d->m_kjsStatusBarText = String();
  d->m_kjsDefaultStatusBarText = String();

  d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
  d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
  d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();

  // 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
  // data arrives) (Simon)
  d->m_url = url;
  if (d->m_url.protocol().startsWith("http") && !d->m_url.host().isEmpty() && d->m_url.path().isEmpty())
    d->m_url.setPath("/");
  d->m_workingURL = d->m_url;

  started();

  return true;
}

void Frame::didExplicitOpen()
{
  d->m_bComplete = false;
  d->m_bLoadEventEmitted = false;
    
  // Prevent window.open(url) -- eg window.open("about:blank") -- from blowing away results
  // from a subsequent window.document.open / window.document.write call. 
  // Cancelling redirection here works for all cases because document.open 
  // implicitly precedes document.write.
  cancelRedirection(); 
}

void Frame::stopLoading(bool sendUnload)
{
  if (d->m_doc && d->m_doc->tokenizer())
    d->m_doc->tokenizer()->stopParsing();
    
  if (d->m_job)
  {
    d->m_job->kill();
    d->m_job = 0;
  }

  if (sendUnload) {
    if (d->m_doc) {
      if (d->m_bLoadEventEmitted && !d->m_bUnloadEventEmitted) {
        d->m_doc->dispatchWindowEvent(unloadEvent, false, false);
        if (d->m_doc)
          d->m_doc->updateRendering();
        d->m_bUnloadEventEmitted = true;
      }
    }
    
    if (d->m_doc && !d->m_doc->inPageCache())
      d->m_doc->removeAllEventListenersFromAllNodes();
  }

  d->m_bComplete = true; // to avoid calling completed() in finishedParsing() (David)
  d->m_bLoadingMainResource = false;
  d->m_bLoadEventEmitted = true; // don't want that one either
  d->m_cachePolicy = KIO::CC_Verify; // Why here?

  if (d->m_doc && d->m_doc->parsing()) {
    finishedParsing();
    d->m_doc->setParsing(false);
  }
  
  d->m_workingURL = KURL();

  if (Document *doc = d->m_doc.get()) {
    if (DocLoader *docLoader = doc->docLoader())
      Cache::loader()->cancelRequests(docLoader);
      XMLHttpRequest::cancelRequests(doc);
  }

  // tell all subframes to stop as well
  for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
      child->stopLoading(sendUnload);

  d->m_bPendingChildRedirection = false;

  cancelRedirection();
}

BrowserExtension *Frame::browserExtension() const
{
  return d->m_extension;
}

FrameView* Frame::view() const
{
    return d->m_view.get();
}

void Frame::setView(FrameView* view)
{
    d->m_view = view;
}

bool Frame::jScriptEnabled() const
{
    return d->m_bJScriptEnabled;
}

KJSProxy *Frame::jScript()
{
    if (!d->m_bJScriptEnabled)
        return 0;

    if (!d->m_jscript)
        d->m_jscript = new KJSProxy(this);

    return d->m_jscript;
}

static bool getString(JSValue* result, DeprecatedString& string)
{
    if (!result)
        return false;
    JSLock lock;
    UString ustring;
    if (!result->getString(ustring))
        return false;
    string = ustring;
    return true;
}

void Frame::replaceContentsWithScriptResult(const KURL& url)
{
    JSValue* ret = executeScript(0, KURL::decode_string(url.url().mid(strlen("javascript:"))));
    DeprecatedString scriptResult;
    if (getString(ret, scriptResult)) {
        begin();
        write(scriptResult);
        end();
    }
}

JSValue* Frame::executeScript(Node* n, const DeprecatedString& script, bool forceUserGesture)
{
  KJSProxy *proxy = jScript();

  if (!proxy)
    return 0;

  d->m_runningScripts++;
  // If forceUserGesture is true, then make the script interpreter
  // treat it as if triggered by a user gesture even if there is no
  // current DOM event being processed.
  JSValue* ret = proxy->evaluate(forceUserGesture ? DeprecatedString::null : d->m_url.url(), 0, script, n);
  d->m_runningScripts--;

  if (!d->m_runningScripts)
      submitFormAgain();

  Document::updateDocumentsRendering();

  return ret;
}

bool Frame::javaEnabled() const
{
    return d->m_settings->isJavaEnabled();
}

bool Frame::pluginsEnabled() const
{
    return d->m_bPluginsEnabled;
}

void Frame::setAutoloadImages(bool enable)
{
  if (d->m_doc && d->m_doc->docLoader()->autoloadImages() == enable)
    return;

  if (d->m_doc)
    d->m_doc->docLoader()->setAutoloadImages(enable);
}

bool Frame::autoloadImages() const
{
  if (d->m_doc)
    return d->m_doc->docLoader()->autoloadImages();

  return true;
}

void Frame::clear(bool clearWindowProperties)
{
  if (d->m_bCleared)
    return;
  d->m_bCleared = true;
  d->m_mousePressNode = 0;

  if (d->m_doc) {
    d->m_doc->cancelParsing();
    d->m_doc->detach();
  }

  // Moving past doc so that onUnload works.
  if (clearWindowProperties && d->m_jscript)
    d->m_jscript->clear();

  if (d->m_view)
    d->m_view->clear();

  // do not drop the document before the jscript and view are cleared, as some destructors
  // might still try to access the document.
  d->m_doc = 0;
  d->m_decoder = 0;

  d->m_plugins.clear();

  d->m_scheduledRedirection = noRedirectionScheduled;
  d->m_delayRedirect = 0;
  d->m_redirectURL = DeprecatedString::null;
  d->m_redirectReferrer = DeprecatedString::null;
  d->m_redirectLockHistory = true;
  d->m_redirectUserGesture = false;
  d->m_bHTTPRefresh = false;
  d->m_bFirstData = true;

  d->m_bMousePressed = false;

  if (!d->m_haveEncoding)
    d->m_encoding = DeprecatedString::null;
}

Document *Frame::document() const
{
    if (d)
        return d->m_doc.get();
    return 0;
}

void Frame::setDocument(Document* newDoc)
{
    if (d) {
        if (d->m_doc)
            d->m_doc->detach();
        d->m_doc = newDoc;
        if (newDoc)
            newDoc->attach();
    }
}

void Frame::receivedFirstData()
{
    begin(d->m_workingURL);

    d->m_doc->docLoader()->setCachePolicy(d->m_cachePolicy);
    d->m_workingURL = KURL();

    // When the first data arrives, the metadata has just been made available
    DeprecatedString qData;

    // Support for http-refresh
    qData = d->m_job->queryMetaData("http-refresh").deprecatedString();
    if (!qData.isEmpty()) {
      double delay;
      int pos = qData.find(';');
      if (pos == -1)
        pos = qData.find(',');

      if (pos == -1) {
        delay = qData.stripWhiteSpace().toDouble();
        // We want a new history item if the refresh timeout > 1 second
        scheduleRedirection(delay, d->m_url.url(), delay <= 1);
      } else {
        int end_pos = qData.length();
        delay = qData.left(pos).stripWhiteSpace().toDouble();
        while (qData[++pos] == ' ');
        if (qData.find("url", pos, false) == pos) {
          pos += 3;
          while (qData[pos] == ' ' || qData[pos] == '=')
              pos++;
          if (qData[pos] == '"') {
              pos++;
              int index = end_pos-1;
              while (index > pos) {
                if (qData[index] == '"')
                    break;
                index--;
              }
              if (index > pos)
                end_pos = index;
          }
        }
        // We want a new history item if the refresh timeout > 1 second
        scheduleRedirection(delay, d->m_doc->completeURL(qData.mid(pos, end_pos)), delay <= 1);
      }
      d->m_bHTTPRefresh = true;
    }

    // Support for http last-modified
    d->m_lastModified = d->m_job->queryMetaData("modified");
}

void Frame::receivedAllData(TransferJob* job)
{
    d->m_job = 0;

    if (job->error()) {
        checkCompleted();
        return;
    }

    d->m_workingURL = KURL();

    if (d->m_doc->parsing())
        end(); // will call completed()
}

void Frame::childBegin()
{
    // We need to do this when the child is created so as to avoid the parent thining the child
    // is complete before it has even started loading.
    // FIXME: do we really still need this?
    d->m_bComplete = false;
}

void Frame::setResourceRequest(const ResourceRequest& request)
{
    d->m_request = request;
}

const ResourceRequest& Frame::resourceRequest() const
{
    return d->m_request;
}

void Frame::begin(const KURL& url)
{
  if (d->m_workingURL.isEmpty())
    createEmptyDocument(); // Creates an empty document if we don't have one already

  clear();
  partClearedInBegin();

  d->m_bCleared = false;
  d->m_bComplete = false;
  d->m_bLoadEventEmitted = false;
  d->m_bLoadingMainResource = true;

  KURL ref(url);
  ref.setUser(DeprecatedString());
  ref.setPass(DeprecatedString());
  ref.setRef(DeprecatedString());
  d->m_referrer = ref.url();
  d->m_url = url;
  KURL baseurl;

  // We don't need KDE chained URI handling or window caption setting
  if (!d->m_url.isEmpty())
    baseurl = d->m_url;

#if SVG_SUPPORT
  if (d->m_request.m_responseMIMEType == "image/svg+xml")
    d->m_doc = SVGDOMImplementation::instance()->createDocument(d->m_view.get());
  else
#endif
  if (DOMImplementation::isXMLMIMEType(d->m_request.m_responseMIMEType))
    d->m_doc = DOMImplementation::instance()->createDocument(d->m_view.get());
  else if (DOMImplementation::isTextMIMEType(d->m_request.m_responseMIMEType))
    d->m_doc = new TextDocument(DOMImplementation::instance(), d->m_view.get());
 else if (Image::supportsType(d->m_request.m_responseMIMEType))
    d->m_doc = new ImageDocument(DOMImplementation::instance(), d->m_view.get());
  else
    d->m_doc = DOMImplementation::instance()->createHTMLDocument(d->m_view.get());

  if (!d->m_doc->attached())
    d->m_doc->attach();
  d->m_doc->setURL(d->m_url.url());
  // We prefer m_baseURL over d->m_url because d->m_url changes when we are
  // about to load a new page.
  d->m_doc->setBaseURL(baseurl.url());
  if (d->m_decoder)
    d->m_doc->setDecoder(d->m_decoder.get());

  updatePolicyBaseURL();

  setAutoloadImages(d->m_settings->autoLoadImages());
  const KURL& userStyleSheet = d->m_settings->userStyleSheetLocation();

  if (!userStyleSheet.isEmpty())
    setUserStyleSheetLocation(KURL(userStyleSheet));

  restoreDocumentState();

  d->m_doc->implicitOpen();
  // clear widget
  if (d->m_view)
    d->m_view->resizeContents(0, 0);
}

void Frame::write(const char* str, int len)
{
    if (len == 0)
        return;
    
    if (len == -1)
        len = strlen(str);

    if (Tokenizer* t = d->m_doc->tokenizer()) {
        if (t->wantsRawData()) {
            t->writeRawData(str, len);
            return;
        }
    }
    
    if (!d->m_decoder) {
        d->m_decoder = new Decoder;
        if (!d->m_encoding.isNull())
            d->m_decoder->setEncodingName(d->m_encoding.latin1(),
                d->m_haveEncoding ? Decoder::UserChosenEncoding : Decoder::EncodingFromHTTPHeader);
        else
            d->m_decoder->setEncodingName(settings()->encoding().latin1(), Decoder::DefaultEncoding);

        if (d->m_doc)
            d->m_doc->setDecoder(d->m_decoder.get());
    }
  DeprecatedString decoded = d->m_decoder->decode(str, len);

  if (decoded.isEmpty())
    return;

  if (d->m_bFirstData) {
      // determine the parse mode
      d->m_doc->determineParseMode(decoded);
      d->m_bFirstData = false;

      // ### this is still quite hacky, but should work a lot better than the old solution
      if (d->m_decoder->visuallyOrdered()) d->m_doc->setVisuallyOrdered();
      d->m_doc->recalcStyle(Node::Force);
  }

  if (Tokenizer* t = d->m_doc->tokenizer()) {
      ASSERT(!t->wantsRawData());
      t->write(decoded, true);
  }
}

void Frame::write(const DeprecatedString& str)
{
  if (str.isNull())
    return;

  if (d->m_bFirstData) {
      // determine the parse mode
      d->m_doc->setParseMode(Document::Strict);
      d->m_bFirstData = false;
  }
  Tokenizer* t = d->m_doc->tokenizer();
  if (t)
    t->write(str, true);
}

void Frame::end()
{
    d->m_bLoadingMainResource = false;
    endIfNotLoading();
}

void Frame::endIfNotLoading()
{
    if (d->m_bLoadingMainResource)
        return;

    // make sure nothing's left in there...
    if (d->m_doc) {
        if (d->m_decoder) {
            DeprecatedString decoded = d->m_decoder->flush();
            if (d->m_bFirstData) {
                d->m_doc->determineParseMode(decoded);
                d->m_bFirstData = false;
            }
            write(decoded);
        }
        d->m_doc->finishParsing();
    } else
        // WebKit partially uses WebCore when loading non-HTML docs.  In these cases doc==nil, but
        // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
        // become true.  An example is when a subframe is a pure text doc, and that subframe is the
        // last one to complete.
        checkCompleted();
}

void Frame::stop()
{
    if (d->m_doc) {
        if (d->m_doc->tokenizer())
            d->m_doc->tokenizer()->stopParsing();
        d->m_doc->finishParsing();
    } else
        // WebKit partially uses WebCore when loading non-HTML docs.  In these cases doc==nil, but
        // WebCore is enough involved that we need to checkCompleted() in order for m_bComplete to
        // become true.  An example is when a subframe is a pure text doc, and that subframe is the
        // last one to complete.
        checkCompleted();
}

void Frame::gotoAnchor()
{
    // If our URL has no ref, then we have no place we need to jump to.
    if (!d->m_url.hasRef())
        return;

    DeprecatedString ref = d->m_url.encodedHtmlRef();
    if (!gotoAnchor(ref)) {
        // Can't use htmlRef() here because it doesn't know which encoding to use to decode.
        // Decoding here has to match encoding in completeURL, which means it has to use the
        // page's encoding rather than UTF-8.
        if (d->m_decoder)
            gotoAnchor(KURL::decode_string(ref, d->m_decoder->encoding()));
    }
}

void Frame::finishedParsing()
{
  RefPtr<Frame> protector(this);
  checkCompleted();

  if (!d->m_view)
    return; // We are being destroyed by something checkCompleted called.

  // check if the scrollbars are really needed for the content
  // if not, remove them, relayout, and repaint

  d->m_view->restoreScrollBar();
  gotoAnchor();
}

void Frame::loadDone()
{
    if (d->m_doc)
        checkCompleted();
}

void Frame::checkCompleted()
{
  // Any frame that hasn't completed yet ?
  for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
      if (!child->d->m_bComplete)
          return;

  // Have we completed before?
  if (d->m_bComplete)
      return;

  // Are we still parsing?
  if (d->m_doc && d->m_doc->parsing())
      return;

  // Still waiting for images/scripts from the loader ?
  int requests = 0;
  if (d->m_doc && d->m_doc->docLoader())
      requests = Cache::loader()->numRequests(d->m_doc->docLoader());

  if (requests > 0)
      return;

  // OK, completed.
  // Now do what should be done when we are really completed.
  d->m_bComplete = true;

  checkEmitLoadEvent(); // if we didn't do it before

  if (d->m_scheduledRedirection != noRedirectionScheduled) {
      // Do not start redirection for frames here! That action is
      // deferred until the parent emits a completed signal.
      if (!tree()->parent())
          startRedirectionTimer();

      completed(true);
  } else {
      completed(d->m_bPendingChildRedirection);
  }
}

void Frame::checkEmitLoadEvent()
{
    if (d->m_bLoadEventEmitted || !d->m_doc || d->m_doc->parsing())
        return;

    for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
        if (!child->d->m_bComplete) // still got a frame running -> too early
            return;

    // All frames completed -> set their domain to the frameset's domain
    // This must only be done when loading the frameset initially (#22039),
    // not when following a link in a frame (#44162).
    if (d->m_doc) {
        String domain = d->m_doc->domain();
        for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
            if (child->d->m_doc)
                child->d->m_doc->setDomain(domain);
    }

    d->m_bLoadEventEmitted = true;
    d->m_bUnloadEventEmitted = false;
    if (d->m_doc)
        d->m_doc->implicitClose();
}

const KHTMLSettings *Frame::settings() const
{
  return d->m_settings;
}

KURL Frame::baseURL() const
{
    if (!d->m_doc)
        return KURL();
    return d->m_doc->baseURL();
}

String Frame::baseTarget() const
{
    if (!d->m_doc)
        return DeprecatedString();
    return d->m_doc->baseTarget();
}

KURL Frame::completeURL(const DeprecatedString& url)
{
    if (!d->m_doc)
        return url;

    return KURL(d->m_doc->completeURL(url));
}

void Frame::scheduleRedirection(double delay, const DeprecatedString& url, bool doLockHistory)
{
    if (delay < 0 || delay > INT_MAX / 1000)
      return;
    if (d->m_scheduledRedirection == noRedirectionScheduled || delay <= d->m_delayRedirect)
    {
       d->m_scheduledRedirection = redirectionScheduled;
       d->m_delayRedirect = delay;
       d->m_redirectURL = url;
       d->m_redirectReferrer = DeprecatedString::null;
       d->m_redirectLockHistory = doLockHistory;
       d->m_redirectUserGesture = false;

       stopRedirectionTimer();
       if (d->m_bComplete)
         startRedirectionTimer();
    }
}

void Frame::scheduleLocationChange(const DeprecatedString& url, const DeprecatedString& referrer, bool lockHistory, bool userGesture)
{
    KURL u(url);
    
    // If the URL we're going to navigate to is the same as the current one, except for the
    // fragment part, we don't need to schedule the location change.
    if (u.hasRef() && equalIgnoringRef(d->m_url, u)) {
        changeLocation(url, referrer, lockHistory, userGesture);
        return;
    }
        
    // Handle a location change of a page with no document as a special case.
    // This may happen when a frame changes the location of another frame.
    d->m_scheduledRedirection = d->m_doc ? locationChangeScheduled : locationChangeScheduledDuringLoad;
    
    // If a redirect was scheduled during a load, then stop the current load.
    // Otherwise when the current load transitions from a provisional to a 
    // committed state, pending redirects may be cancelled. 
    if (d->m_scheduledRedirection == locationChangeScheduledDuringLoad) {
        stopLoading(true);   
    }

    d->m_delayRedirect = 0;
    d->m_redirectURL = url;
    d->m_redirectReferrer = referrer;
    d->m_redirectLockHistory = lockHistory;
    d->m_redirectUserGesture = userGesture;
    stopRedirectionTimer();
    if (d->m_bComplete)
        startRedirectionTimer();
}

bool Frame::isScheduledLocationChangePending() const
{
    switch (d->m_scheduledRedirection) {
        case noRedirectionScheduled:
        case redirectionScheduled:
            return false;
        case historyNavigationScheduled:
        case locationChangeScheduled:
        case locationChangeScheduledDuringLoad:
            return true;
    }
    return false;
}

void Frame::scheduleHistoryNavigation(int steps)
{
    // navigation will always be allowed in the 0 steps case, which is OK because
    // that's supposed to force a reload.
    if (!canGoBackOrForward(steps)) {
        cancelRedirection();
        return;
    }

    // If the URL we're going to navigate to is the same as the current one, except for the
    // fragment part, we don't need to schedule the navigation.
    if (d->m_extension) {
        KURL u = d->m_extension->historyURL(steps);
        
        if (equalIgnoringRef(d->m_url, u)) {
            d->m_extension->goBackOrForward(steps);
            return;
        }
    }
    
    d->m_scheduledRedirection = historyNavigationScheduled;
    d->m_delayRedirect = 0;
    d->m_redirectURL = DeprecatedString::null;
    d->m_redirectReferrer = DeprecatedString::null;
    d->m_scheduledHistoryNavigationSteps = steps;
    stopRedirectionTimer();
    if (d->m_bComplete)
        startRedirectionTimer();
}

void Frame::cancelRedirection(bool cancelWithLoadInProgress)
{
    if (d) {
        d->m_cancelWithLoadInProgress = cancelWithLoadInProgress;
        d->m_scheduledRedirection = noRedirectionScheduled;
        stopRedirectionTimer();
    }
}

void Frame::changeLocation(const DeprecatedString& URL, const DeprecatedString& referrer, bool lockHistory, bool userGesture)
{
    if (URL.find("javascript:", 0, false) == 0) {
        DeprecatedString script = KURL::decode_string(URL.mid(11));
        JSValue* result = executeScript(0, script, userGesture);
        DeprecatedString scriptResult;
        if (getString(result, scriptResult)) {
            begin(url());
            write(scriptResult);
            end();
        }
        return;
    }

    ResourceRequest request(completeURL(URL));
    request.setLockHistory(lockHistory);
    if (!referrer.isEmpty())
        request.setReferrer(referrer);

    urlSelected(request, "_self");
}

void Frame::redirectionTimerFired(Timer<Frame>*)
{
    if (d->m_scheduledRedirection == historyNavigationScheduled) {
        d->m_scheduledRedirection = noRedirectionScheduled;

        // Special case for go(0) from a frame -> reload only the frame
        // go(i!=0) from a frame navigates into the history of the frame only,
        // in both IE and NS (but not in Mozilla).... we can't easily do that
        // in Konqueror...
        if (d->m_scheduledHistoryNavigationSteps == 0) // add && parent() to get only frames, but doesn't matter
            openURL(url()); /// ## need args.reload=true?
        else {
            if (d->m_extension) {
                d->m_extension->goBackOrForward(d->m_scheduledHistoryNavigationSteps);
            }
        }
        return;
    }

    DeprecatedString URL = d->m_redirectURL;
    DeprecatedString referrer = d->m_redirectReferrer;
    bool lockHistory = d->m_redirectLockHistory;
    bool userGesture = d->m_redirectUserGesture;

    d->m_scheduledRedirection = noRedirectionScheduled;
    d->m_delayRedirect = 0;
    d->m_redirectURL = DeprecatedString::null;
    d->m_redirectReferrer = DeprecatedString::null;

    changeLocation(URL, referrer, lockHistory, userGesture);
}

void Frame::receivedRedirect(TransferJob*, const KURL& url)
{
    d->m_workingURL = url;
}

DeprecatedString Frame::encoding() const
{
    if (d->m_haveEncoding && !d->m_encoding.isEmpty())
        return d->m_encoding;

    if (d->m_decoder && d->m_decoder->encoding().isValid())
        return d->m_decoder->encodingName();

    return settings()->encoding();
}

void Frame::setUserStyleSheetLocation(const KURL& url)
{
    delete d->m_userStyleSheetLoader;
    d->m_userStyleSheetLoader = 0;
    if (d->m_doc && d->m_doc->docLoader())
        d->m_userStyleSheetLoader = new UserStyleSheetLoader(this, url.url(), d->m_doc->docLoader());
}

void Frame::setUserStyleSheet(const String& styleSheet)
{
    delete d->m_userStyleSheetLoader;
    d->m_userStyleSheetLoader = 0;
    if (d->m_doc)
        d->m_doc->setUserStyleSheet(styleSheet);
}

bool Frame::gotoAnchor(const String& name)
{
  if (!d->m_doc)
    return false;

  Node *n = d->m_doc->getElementById(AtomicString(name));
  if (!n) {
    HTMLCollection *anchors =
        new HTMLCollection(d->m_doc.get(), HTMLCollection::DOC_ANCHORS);
    anchors->ref();
    n = anchors->namedItem(name, !d->m_doc->inCompatMode());
    anchors->deref();
  }

  d->m_doc->setCSSTarget(n); // Setting to null will clear the current target.
  
  // Implement the rule that "" and "top" both mean top of page as in other browsers.
  if (!n && !(name.isEmpty() || name.lower() == "top"))
      return false;

  // We need to update the layout before scrolling, otherwise we could
  // really mess things up if an anchor scroll comes at a bad moment.
  if (d->m_doc) {
    d->m_doc->updateRendering();
    // Only do a layout if changes have occurred that make it necessary.      
    if (d->m_view && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout()) {
      d->m_view->layout();
    }
  }
  
  // Scroll nested layers and frames to reveal the anchor.
  RenderObject *renderer;
  IntRect rect;
  if (n) {
      renderer = n->renderer();
      rect = n->getRect();
  } else {
    // If there's no node, we should scroll to the top of the document.
      renderer = d->m_doc->renderer();
      rect = IntRect();
  }

  if (renderer) {
    // Align to the top and to the closest side (this matches other browsers).
    renderer->enclosingLayer()->scrollRectToVisible(rect, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignTopAlways);
  }
  
  return true;
}

void Frame::setStandardFont(const String& name)
{
    d->m_settings->setStdFontName(AtomicString(name));
}

void Frame::setFixedFont(const String& name)
{
    d->m_settings->setFixedFontName(AtomicString(name));
}

String Frame::selectedText() const
{
    return plainText(selection().toRange().get());
}

bool Frame::hasSelection() const
{
    return d->m_selection.isCaretOrRange();
}

SelectionController& Frame::selection() const
{
    return d->m_selection;
}

TextGranularity Frame::selectionGranularity() const
{
    return d->m_selectionGranularity;
}

void Frame::setSelectionGranularity(TextGranularity granularity) const
{
    d->m_selectionGranularity = granularity;
}

SelectionController& Frame::dragCaret() const
{
    return d->m_page->dragCaret();
}

const Selection& Frame::mark() const
{
    return d->m_mark;
}

void Frame::setMark(const Selection& s)
{
    ASSERT(!s.base().node() || s.base().node()->document() == document());
    ASSERT(!s.extent().node() || s.extent().node()->document() == document());
    ASSERT(!s.start().node() || s.start().node()->document() == document());
    ASSERT(!s.end().node() || s.end().node()->document() == document());

    d->m_mark = s;
}

void Frame::setSelection(const SelectionController& s, bool closeTyping, bool keepTypingStyle)
{
    if (d->m_selection == s)
        return;

    ASSERT(!s.base().node() || s.base().node()->document() == document());
    ASSERT(!s.extent().node() || s.extent().node()->document() == document());
    ASSERT(!s.start().node() || s.start().node()->document() == document());
    ASSERT(!s.end().node() || s.end().node()->document() == document());
    
    clearCaretRectIfNeeded();

    SelectionController oldSelection = d->m_selection;

    d->m_selection = s;
    if (!s.isNone())
        setFocusNodeIfNeeded();
    
    selectionLayoutChanged();

    // Always clear the x position used for vertical arrow navigation.
    // It will be restored by the vertical arrow navigation code if necessary.
    d->m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation;

    if (closeTyping)
        TypingCommand::closeTyping(lastEditCommand());

    if (!keepTypingStyle)
        clearTypingStyle();
    
    respondToChangedSelection(oldSelection, closeTyping);
}

void Frame::setDragCaret(const SelectionController& dragCaret)
{
    d->m_page->setDragCaret(dragCaret);
}

void Frame::invalidateSelection()
{
    clearCaretRectIfNeeded();
    d->m_selection.setNeedsLayout();
    selectionLayoutChanged();
}

void Frame::setCaretVisible(bool flag)
{
    if (d->m_caretVisible == flag)
        return;
    clearCaretRectIfNeeded();
    if (flag)
        setFocusNodeIfNeeded();
    d->m_caretVisible = flag;
    selectionLayoutChanged();
}


void Frame::clearCaretRectIfNeeded()
{
    if (d->m_caretPaint) {
        d->m_caretPaint = false;
        d->m_selection.needsCaretRepaint();
    }        
}

// Helper function that tells whether a particular node is an element that has an entire
// Frame and FrameView, a <frame>, <iframe>, or <object>.
static bool isFrameElement(const Node *n)
{
    if (!n)
        return false;
    RenderObject *renderer = n->renderer();
    if (!renderer || !renderer->isWidget())
        return false;
    Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
    return widget && widget->isFrameView();
}

void Frame::setFocusNodeIfNeeded()
{
    if (!document() || d->m_selection.isNone() || !d->m_isFocused)
        return;

    Node *startNode = d->m_selection.start().node();
    Node *target = startNode ? startNode->rootEditableElement() : 0;
    
    if (target) {
        RenderObject* renderer = target->renderer();

        // Walk up the render tree to search for a node to focus.
        // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
        while (renderer) {
            // We don't want to set focus on a subframe when selecting in a parent frame,
            // so add the !isFrameElement check here. There's probably a better way to make this
            // work in the long term, but this is the safest fix at this time.
            if (target && target->isMouseFocusable() && !isFrameElement(target)) {
                document()->setFocusNode(target);
                return;
            }
            renderer = renderer->parent();
            if (renderer)
                target = renderer->element();
        }
        document()->setFocusNode(0);
    }
}

void Frame::selectionLayoutChanged()
{
    // kill any caret blink timer now running
    d->m_caretBlinkTimer.stop();

    // see if a new caret blink timer needs to be started
    if (d->m_caretVisible && d->m_caretBlinks && 
        d->m_selection.isCaret() && d->m_selection.start().node()->isContentEditable()) {
        d->m_caretBlinkTimer.startRepeating(caretBlinkFrequency);
        d->m_caretPaint = true;
        d->m_selection.needsCaretRepaint();
    }

    if (d->m_doc)
        d->m_doc->updateSelection();
}

void Frame::setXPosForVerticalArrowNavigation(int x)
{
    d->m_xPosForVerticalArrowNavigation = x;
}

int Frame::xPosForVerticalArrowNavigation() const
{
    return d->m_xPosForVerticalArrowNavigation;
}

void Frame::caretBlinkTimerFired(Timer<Frame>*)
{
    // Might be better to turn the timer off during some of these circumstances
    // and assert rather then letting the timer fire and do nothing here.
    // Could do that in selectionLayoutChanged.

    if (!d->m_caretVisible)
        return;
    if (!d->m_caretBlinks)
        return;
    if (!d->m_selection.isCaret())
        return;
    bool caretPaint = d->m_caretPaint;
    if (d->m_bMousePressed && caretPaint)
        return;
    d->m_caretPaint = !caretPaint;
    d->m_selection.needsCaretRepaint();
}

void Frame::paintCaret(GraphicsContext* p, const IntRect& rect) const
{
    if (d->m_caretPaint)
        d->m_selection.paintCaret(p, rect);
}

void Frame::paintDragCaret(GraphicsContext* p, const IntRect& rect) const
{
    SelectionController& dragCaret = d->m_page->dragCaret();
    assert(dragCaret.selection().isCaret());
    if (dragCaret.selection().start().node()->document()->frame() == this)
        dragCaret.paintCaret(p, rect);
}

void Frame::urlSelected(const DeprecatedString& url, const String& target)
{
    urlSelected(ResourceRequest(completeURL(url)), target);
}

void Frame::urlSelected(const ResourceRequest& request, const String& _target)
{
  String target = _target;
  if (target.isEmpty() && d->m_doc)
    target = d->m_doc->baseTarget();

  const KURL& url = request.url();

  if (url.url().startsWith("javascript:", false)) {
    executeScript(0, KURL::decode_string(url.url().mid(11)), true);
    return;
  }

  if (!url.isValid())
    // ### ERROR HANDLING
    return;

  ResourceRequest requestCopy = request;
  requestCopy.frameName = target;

  if (d->m_bHTTPRefresh)
    d->m_bHTTPRefresh = false;

  if (!d->m_referrer.isEmpty())
    requestCopy.setReferrer(d->m_referrer);

  urlSelected(requestCopy);
}

bool Frame::requestFrame(RenderPart* renderer, const String& urlParam, const AtomicString& frameName)
{
    DeprecatedString _url = urlParam.deprecatedString();
    // Support for <frame src="javascript:string">
    KURL scriptURL;
    KURL url;
    if (_url.startsWith("javascript:", false)) {
        scriptURL = _url;
        url = "about:blank";
    } else
        url = completeURL(_url);

    Frame* frame = tree()->child(frameName);
    if (frame) {
        ResourceRequest request(url);
        request.setReferrer(d->m_referrer);
        request.reload = (d->m_cachePolicy == KIO::CC_Reload) || (d->m_cachePolicy == KIO::CC_Refresh);
        frame->openURLRequest(request);
    } else
        frame = loadSubframe(renderer, url, frameName, d->m_referrer);
    
    if (!frame)
        return false;

    if (!scriptURL.isEmpty())
        frame->replaceContentsWithScriptResult(scriptURL);

    return true;
}

bool Frame::requestObject(RenderPart* renderer, const String& url, const AtomicString& frameName,
                          const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues)
{
    KURL completedURL;
    if (!url.isEmpty())
        completedURL = completeURL(url.deprecatedString());
    
    if (url.isEmpty() && mimeType.isEmpty())
        return true;
    
    bool useFallback;
    if (shouldUsePlugin(renderer->element(), completedURL, mimeType, renderer->hasFallbackContent(), useFallback))
        return loadPlugin(renderer, completedURL, mimeType, paramNames, paramValues, useFallback);

    // FIXME: ok to always make a new one? when does the old frame get removed?
    return loadSubframe(renderer, completedURL, frameName, d->m_referrer);
}

bool Frame::shouldUsePlugin(Node* element, const KURL& url, const String& mimeType, bool hasFallback, bool& useFallback)
{
    useFallback = false;
    ObjectContentType objectType = objectContentType(url, mimeType);

    // if an object's content can't be handled and it has no fallback, let
    // it be handled as a plugin to show the broken plugin icon
    if (objectType == ObjectContentNone && hasFallback)
        useFallback = true;

    return objectType == ObjectContentNone || objectType == ObjectContentPlugin;
}


bool Frame::loadPlugin(RenderPart *renderer, const KURL& url, const String& mimeType, 
                       const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback)
{
    if (useFallback) {
        checkEmitLoadEvent();
        return false;
    }

    Element *pluginElement;
    if (renderer && renderer->node() && renderer->node()->isElementNode())
        pluginElement = static_cast<Element*>(renderer->node());
    else
        pluginElement = 0;
        
    Plugin* plugin = createPlugin(pluginElement, url, paramNames, paramValues, mimeType);
    if (!plugin) {
        checkEmitLoadEvent();
        return false;
    }
    d->m_plugins.append(plugin);
    
    if (renderer && plugin->view())
        renderer->setWidget(plugin->view());
    
    checkEmitLoadEvent();
    
    return true;
}

Frame* Frame::loadSubframe(RenderPart* renderer, const KURL& url, const String& name, const String& referrer)
{
    Frame* frame = createFrame(url, name, renderer, referrer);
    if (!frame)  {
        checkEmitLoadEvent();
        return 0;
    }
    
    frame->childBegin();
    
    if (renderer && frame->view())
        renderer->setWidget(frame->view());
    
    checkEmitLoadEvent();
    
    // In these cases, the synchronous load would have finished
    // before we could connect the signals, so make sure to send the 
    // completed() signal for the child by hand
    // FIXME: In this case the Frame will have finished loading before 
    // it's being added to the child list. It would be a good idea to
    // create the child first, then invoke the loader separately.
    if (url.isEmpty() || url == "about:blank") {
        frame->completed(false);
        frame->checkCompleted();
    }

    return frame;
}

void Frame::clearRecordedFormValues()
{
    d->m_formAboutToBeSubmitted = 0;
    d->m_formValuesAboutToBeSubmitted.clear();
}

void Frame::recordFormValue(const String& name, const String& value, PassRefPtr<HTMLFormElement> element)
{
    d->m_formAboutToBeSubmitted = element;
    d->m_formValuesAboutToBeSubmitted.set(name, value);
}

void Frame::submitFormAgain()
{
    FramePrivate::SubmitForm* form = d->m_submitForm;
    d->m_submitForm = 0;
    if (d->m_doc && !d->m_doc->parsing() && form)
        submitForm(form->submitAction, form->submitUrl, form->submitFormData,
            form->target, form->submitContentType, form->submitBoundary);
    delete form;
}

void Frame::submitForm(const char *action, const String& url, const FormData& formData, const String& _target, const String& contentType, const String& boundary)
{
  KURL u = completeURL(url.deprecatedString());

  if (!u.isValid())
    // ### ERROR HANDLING!
    return;

  DeprecatedString urlstring = u.url();
  if (urlstring.startsWith("javascript:", false)) {
    urlstring = KURL::decode_string(urlstring);
    d->m_executingJavaScriptFormAction = true;
    executeScript(0, urlstring.mid(11));
    d->m_executingJavaScriptFormAction = false;
    return;
  }

  ResourceRequest request;

  if (!d->m_referrer.isEmpty())
     request.setReferrer(d->m_referrer);

  request.frameName = _target.isEmpty() ? d->m_doc->baseTarget() : _target ;

  // Handle mailto: forms
  if (u.protocol() == "mailto") {
      // 1)  Check for attach= and strip it
      DeprecatedString q = u.query().mid(1);
      DeprecatedStringList nvps = DeprecatedStringList::split("&", q);
      bool triedToAttach = false;

      for (DeprecatedStringList::Iterator nvp = nvps.begin(); nvp != nvps.end(); ++nvp) {
         DeprecatedStringList pair = DeprecatedStringList::split("=", *nvp);
         if (pair.count() >= 2) {
            if (pair.first().lower() == "attach") {
               nvp = nvps.remove(nvp);
               triedToAttach = true;
            }
         }
      }


      // 2)  Append body=
      DeprecatedString bodyEnc;
      if (contentType.lower() == "multipart/form-data")
         // FIXME: is this correct?  I suspect not
         bodyEnc = KURL::encode_string(formData.flattenToString());
      else if (contentType.lower() == "text/plain") {
         // Convention seems to be to decode, and s/&/\n/
         DeprecatedString tmpbody = formData.flattenToString();
         tmpbody.replace('&', '\n');
         tmpbody.replace('+', ' ');
         tmpbody = KURL::decode_string(tmpbody);  // Decode the rest of it
         bodyEnc = KURL::encode_string(tmpbody);  // Recode for the URL
      } else
         bodyEnc = KURL::encode_string(formData.flattenToString());

      nvps.append(String::sprintf("body=%s", bodyEnc.latin1()).deprecatedString());
      q = nvps.join("&");
      u.setQuery(q);
  } 

  if (strcmp(action, "get") == 0) {
    if (u.protocol() != "mailto")
       u.setQuery(formData.flattenToString());
    request.setDoPost(false);
  } else {
    request.postData = formData;
    request.setDoPost(true);

    // construct some user headers if necessary
    if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
      request.setContentType("Content-Type: application/x-www-form-urlencoded");
    else // contentType must be "multipart/form-data"
      request.setContentType("Content-Type: " + contentType + "; boundary=" + boundary);
  }

  if (d->m_doc->parsing() || d->m_runningScripts > 0) {
    if (d->m_submitForm)
        return;
    d->m_submitForm = new FramePrivate::SubmitForm;
    d->m_submitForm->submitAction = action;
    d->m_submitForm->submitUrl = url;
    d->m_submitForm->submitFormData = formData;
    d->m_submitForm->target = _target;
    d->m_submitForm->submitContentType = contentType;
    d->m_submitForm->submitBoundary = boundary;
  } else {
      request.setURL(u);
      submitForm(request);
  }
}

void Frame::parentCompleted()
{
    if (d->m_scheduledRedirection != noRedirectionScheduled && !d->m_redirectionTimer.isActive())
        startRedirectionTimer();
}

void Frame::childCompleted(bool complete)
{
    if (complete && !tree()->parent())
        d->m_bPendingChildRedirection = true;
    checkCompleted();
}

int Frame::zoomFactor() const
{
  return d->m_zoomFactor;
}

void Frame::setZoomFactor(int percent)
{  
  if (d->m_zoomFactor == percent)
      return;

  d->m_zoomFactor = percent;

  if (d->m_doc)
      d->m_doc->recalcStyle(Node::Force);

  for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
      child->setZoomFactor(d->m_zoomFactor);

  if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout())
      view()->layout();
}

void Frame::setJSStatusBarText(const String& text)
{
    d->m_kjsStatusBarText = text;
    setStatusBarText(d->m_kjsStatusBarText);
}

void Frame::setJSDefaultStatusBarText(const String& text)
{
    d->m_kjsDefaultStatusBarText = text;
    setStatusBarText(d->m_kjsDefaultStatusBarText);
}

String Frame::jsStatusBarText() const
{
    return d->m_kjsStatusBarText;
}

String Frame::jsDefaultStatusBarText() const
{
   return d->m_kjsDefaultStatusBarText;
}

DeprecatedString Frame::referrer() const
{
    return d->m_referrer;
}

String Frame::lastModified() const
{
    return d->m_lastModified;
}

void Frame::reparseConfiguration()
{
    setAutoloadImages(d->m_settings->autoLoadImages());
        
    d->m_bJScriptEnabled = d->m_settings->isJavaScriptEnabled();
    d->m_bJavaEnabled = d->m_settings->isJavaEnabled();
    d->m_bPluginsEnabled = d->m_settings->isPluginsEnabled();

    const KURL& userStyleSheetLocation = d->m_settings->userStyleSheetLocation();
    if (!userStyleSheetLocation.isEmpty())
        setUserStyleSheetLocation(userStyleSheetLocation);
    else
        setUserStyleSheet(String());

    // FIXME: It's not entirely clear why the following is needed.
    // The document automatically does this as required when you set the style sheet.
    // But we had problems when this code was removed. Details are in
    // <http://bugzilla.opendarwin.org/show_bug.cgi?id=8079>.
    if (d->m_doc)
        d->m_doc->updateStyleSelector();
}

bool Frame::shouldDragAutoNode(Node *node, const IntPoint& point) const
{
    // No KDE impl yet
    return false;
}

bool Frame::isPointInsideSelection(const IntPoint& point)
{
    // Treat a collapsed selection like no selection.
    if (!d->m_selection.isRange())
        return false;
    if (!document()->renderer()) 
        return false;
    
    RenderObject::NodeInfo nodeInfo(true, true);
    document()->renderer()->layer()->hitTest(nodeInfo, point);
    Node *innerNode = nodeInfo.innerNode();
    if (!innerNode || !innerNode->renderer())
        return false;
    
    Position pos(innerNode->renderer()->positionForPoint(point).deepEquivalent());
    if (pos.isNull())
        return false;

    Node *n = d->m_selection.start().node();
    while (n) {
        if (n == pos.node()) {
            if ((n == d->m_selection.start().node() && pos.offset() < d->m_selection.start().offset()) ||
                (n == d->m_selection.end().node() && pos.offset() > d->m_selection.end().offset())) {
                return false;
            }
            return true;
        }
        if (n == d->m_selection.end().node())
            break;
        n = n->traverseNextNode();
    }

   return false;
}

void Frame::selectClosestWordFromMouseEvent(const PlatformMouseEvent& mouse, Node *innerNode)
{
    SelectionController selection;

    if (innerNode && innerNode->renderer() && mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
        IntPoint vPoint = view()->viewportToContents(mouse.pos());
        VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
        if (pos.isNotNull()) {
            selection.moveTo(pos);
            selection.expandUsingGranularity(WordGranularity);
        }
    }
    
    if (selection.isRange()) {
        d->m_selectionGranularity = WordGranularity;
        d->m_beganSelectingText = true;
    }
    
    if (shouldChangeSelection(selection))
        setSelection(selection);
}

void Frame::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
{
    if (event.event().button() == LeftButton) {
        if (selection().isRange())
            // A double-click when range is already selected
            // should not change the selection.  So, do not call
            // selectClosestWordFromMouseEvent, but do set
            // m_beganSelectingText to prevent handleMouseReleaseEvent
            // from setting caret selection.
            d->m_beganSelectingText = true;
        else
            selectClosestWordFromMouseEvent(event.event(), event.targetNode());
    }
}

void Frame::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
{
    Node *innerNode = event.targetNode();
    
    if (event.event().button() == LeftButton && innerNode && innerNode->renderer() &&
        mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
        SelectionController selection;
        IntPoint vPoint = view()->viewportToContents(event.event().pos());
        VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
        if (pos.isNotNull()) {
            selection.moveTo(pos);
            selection.expandUsingGranularity(ParagraphGranularity);
        }
        if (selection.isRange()) {
            d->m_selectionGranularity = ParagraphGranularity;
            d->m_beganSelectingText = true;
        }
        
        if (shouldChangeSelection(selection))
            setSelection(selection);
    }
}

void Frame::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
{
    Node *innerNode = event.targetNode();
    
    if (event.event().button() == LeftButton) {
        if (innerNode && innerNode->renderer() &&
            mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
            SelectionController sel;
            
            // Extend the selection if the Shift key is down, unless the click is in a link.
            bool extendSelection = event.event().shiftKey() && !event.isOverLink();

            // Don't restart the selection when the mouse is pressed on an
            // existing selection so we can allow for text dragging.
            IntPoint vPoint = view()->viewportToContents(event.event().pos());
            if (!extendSelection && isPointInsideSelection(vPoint))
                return;

            VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(vPoint));
            if (visiblePos.isNull())
                visiblePos = VisiblePosition(innerNode, innerNode->caretMinOffset(), DOWNSTREAM);
            Position pos = visiblePos.deepEquivalent();
            
            sel = selection();
            if (extendSelection && sel.isCaretOrRange()) {
                sel.clearModifyBias();
                
                // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection 
                // was created right-to-left
                Position start = sel.start();
                short before = Range::compareBoundaryPoints(pos.node(), pos.offset(), start.node(), start.offset());
                if (before <= 0)
                    sel.setBaseAndExtent(pos.node(), pos.offset(), sel.end().node(), sel.end().offset());
                else
                    sel.setBaseAndExtent(start.node(), start.offset(), pos.node(), pos.offset());

                if (d->m_selectionGranularity != CharacterGranularity)
                    sel.expandUsingGranularity(d->m_selectionGranularity);
                d->m_beganSelectingText = true;
            } else {
                sel = SelectionController(visiblePos);
                d->m_selectionGranularity = CharacterGranularity;
            }
            
            if (shouldChangeSelection(sel))
                setSelection(sel);
        }
    }
}

void Frame::handleMousePressEvent(const MouseEventWithHitTestResults& event)
{
    Node *innerNode = event.targetNode();

    d->m_mousePressNode = innerNode;
    d->m_dragStartPos = event.event().pos();

    if (event.event().button() == LeftButton || event.event().button() == MiddleButton) {
        d->m_bMousePressed = true;
        d->m_beganSelectingText = false;

        if (event.event().clickCount() == 2) {
            handleMousePressEventDoubleClick(event);
            return;
        }
        if (event.event().clickCount() >= 3) {
            handleMousePressEventTripleClick(event);
            return;
        }
        handleMousePressEventSingleClick(event);
    }
}

void Frame::handleMouseMoveEvent(const MouseEventWithHitTestResults& event)
{
    // Mouse not pressed. Do nothing.
    if (!d->m_bMousePressed)
        return;

    Node *innerNode = event.targetNode();

    if (event.event().button() != 0 || !innerNode || !innerNode->renderer() || !mouseDownMayStartSelect() || !innerNode->renderer()->shouldSelect())
        return;

    // handle making selection
    IntPoint vPoint = view()->viewportToContents(event.event().pos());
    VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));

    // Don't modify the selection if we're not on a node.
    if (pos.isNull())
        return;

    // Restart the selection if this is the first mouse move. This work is usually
    // done in handleMousePressEvent, but not if the mouse press was on an existing selection.
    SelectionController sel = selection();
    sel.clearModifyBias();
    
    if (!d->m_beganSelectingText) {
        d->m_beganSelectingText = true;
        sel.moveTo(pos);
    }

    sel.setExtent(pos);
    if (d->m_selectionGranularity != CharacterGranularity)
        sel.expandUsingGranularity(d->m_selectionGranularity);

    if (shouldChangeSelection(sel))
        setSelection(sel);
}

void Frame::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
{
    stopAutoscrollTimer();
    
    // Used to prevent mouseMoveEvent from initiating a drag before
    // the mouse is pressed again.
    d->m_bMousePressed = false;
  
    // Clear the selection if the mouse didn't move after the last mouse press.
    // We do this so when clicking on the selection, the selection goes away.
    // However, if we are editing, place the caret.
    if (mouseDownMayStartSelect() && !d->m_beganSelectingText
            && d->m_dragStartPos == event.event().pos()
            && d->m_selection.isRange()) {
        SelectionController selection;
        Node *node = event.targetNode();
        if (node && node->isContentEditable() && node->renderer()) {
            IntPoint vPoint = view()->viewportToContents(event.event().pos());
            VisiblePosition pos = node->renderer()->positionForPoint(vPoint);
            selection.moveTo(pos);
        }
        if (shouldChangeSelection(selection))
            setSelection(selection);
    }
    selectFrameElementInParentIfFullySelected();
}

void Frame::selectAll()
{
    if (!d->m_doc)
        return;
    
    Node *startNode = d->m_selection.start().node();
    Node *root = startNode && startNode->isContentEditable() ? startNode->rootEditableElement() : d->m_doc->documentElement();
    
    selectContentsOfNode(root);
    selectFrameElementInParentIfFullySelected();
}

bool Frame::selectContentsOfNode(Node* node)
{
    SelectionController sel = SelectionController(Selection::selectionFromContentsOfNode(node));    
    if (shouldChangeSelection(sel)) {
        setSelection(sel);
        return true;
    }
    return false;
}

bool Frame::shouldChangeSelection(const SelectionController& newselection) const
{
    return shouldChangeSelection(d->m_selection, newselection, newselection.affinity(), false);
}

bool Frame::shouldBeginEditing(const Range *range) const
{
    return true;
}

bool Frame::shouldEndEditing(const Range *range) const
{
    return true;
}

bool Frame::isContentEditable() const 
{
    if (!d->m_doc)
        return false;
    return d->m_doc->inDesignMode();
}

void Frame::textFieldDidBeginEditing(Element* input)
{
}

void Frame::textFieldDidEndEditing(Element* input)
{
}

void Frame::textDidChangeInTextField(Element* input)
{
}

bool Frame::doTextFieldCommandFromEvent(Element* input, const PlatformKeyboardEvent* evt)
{
    return false;
}

void Frame::textWillBeDeletedInTextField(Element* input)
{
}

void Frame::textDidChangeInTextArea(Element* input)
{
}

EditCommandPtr Frame::lastEditCommand()
{
    return d->m_lastEditCommand;
}

void dispatchEditableContentChangedEvent(Node* root)
{
    if (!root)
        return;
        
    ExceptionCode ec = 0;
    RefPtr<Event> evt = new Event(khtmlEditableContentChangedEvent, false, false);
    EventTargetNodeCast(root)->dispatchEvent(evt, ec, true);
}

void Frame::appliedEditing(EditCommandPtr& cmd)
{
    SelectionController sel(cmd.endingSelection());
    if (shouldChangeSelection(sel))
        setSelection(sel, false);
    
    dispatchEditableContentChangedEvent(!selection().isNone() ? selection().start().node()->rootEditableElement() : 0);

    // Now set the typing style from the command. Clear it when done.
    // This helps make the case work where you completely delete a piece
    // of styled text and then type a character immediately after.
    // That new character needs to take on the style of the just-deleted text.
    // FIXME: Improve typing style.
    // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
    if (cmd.typingStyle()) {
        setTypingStyle(cmd.typingStyle());
        cmd.setTypingStyle(0);
    }

    // Command will be equal to last edit command only in the case of typing
    if (d->m_lastEditCommand == cmd) {
        assert(cmd.isTypingCommand());
    }
    else {
        // Only register a new undo command if the command passed in is
        // different from the last command
        registerCommandForUndo(cmd);
        d->m_lastEditCommand = cmd;
    }
    respondToChangedContents();
}

void Frame::unappliedEditing(EditCommandPtr& cmd)
{
    SelectionController sel(cmd.startingSelection());
    if (shouldChangeSelection(sel))
        setSelection(sel, true);
    
    dispatchEditableContentChangedEvent(!selection().isNone() ? selection().start().node()->rootEditableElement() : 0);
        
    registerCommandForRedo(cmd);
    respondToChangedContents();
    d->m_lastEditCommand = EditCommandPtr::emptyCommand();
}

void Frame::reappliedEditing(EditCommandPtr& cmd)
{
    SelectionController sel(cmd.endingSelection());
    if (shouldChangeSelection(sel))
        setSelection(sel, true);
    
    dispatchEditableContentChangedEvent(!selection().isNone() ? selection().start().node()->rootEditableElement() : 0);
        
    registerCommandForUndo(cmd);
    respondToChangedContents();
    d->m_lastEditCommand = EditCommandPtr::emptyCommand();
}

CSSMutableStyleDeclaration *Frame::typingStyle() const
{
    return d->m_typingStyle.get();
}

void Frame::setTypingStyle(CSSMutableStyleDeclaration *style)
{
    d->m_typingStyle = style;
}

void Frame::clearTypingStyle()
{
    d->m_typingStyle = 0;
}

JSValue* Frame::executeScript(const String& filename, int baseLine, Node* n, const DeprecatedString& script)
{
  // FIXME: This is missing stuff that the other executeScript has.
  // --> d->m_runningScripts and submitFormAgain.
  // Why is that OK?
  KJSProxy *proxy = jScript();
  if (!proxy)
    return 0;
  JSValue* ret = proxy->evaluate(filename, baseLine, script, n);
  Document::updateDocumentsRendering();
  return ret;
}

Frame *Frame::opener()
{
    return d->m_opener;
}

void Frame::setOpener(Frame* opener)
{
    if (d->m_opener)
        d->m_opener->d->m_openedFrames.remove(this);
    if (opener)
        opener->d->m_openedFrames.add(this);
    d->m_opener = opener;
}

bool Frame::openedByJS()
{
    return d->m_openedByJS;
}

void Frame::setOpenedByJS(bool _openedByJS)
{
    d->m_openedByJS = _openedByJS;
}

bool Frame::tabsToLinks() const
{
    return true;
}

bool Frame::tabsToAllControls() const
{
    return true;
}

void Frame::copyToPasteboard()
{
    issueCopyCommand();
}

void Frame::cutToPasteboard()
{
    issueCutCommand();
}

void Frame::pasteFromPasteboard()
{
    issuePasteCommand();
}

void Frame::pasteAndMatchStyle()
{
    issuePasteAndMatchStyleCommand();
}

void Frame::transpose()
{
    issueTransposeCommand();
}

void Frame::redo()
{
    issueRedoCommand();
}

void Frame::undo()
{
    issueUndoCommand();
}


void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction editingAction)
{
    if (!style || style->length() == 0) {
        clearTypingStyle();
        return;
    }

    // Calculate the current typing style.
    RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();
    if (typingStyle()) {
        typingStyle()->merge(mutableStyle.get());
        mutableStyle = typingStyle();
    }

    Node *node = VisiblePosition(selection().start(), selection().affinity()).deepEquivalent().node();
    CSSComputedStyleDeclaration computedStyle(node);
    computedStyle.diff(mutableStyle.get());
    
    // Handle block styles, substracting these from the typing style.
    RefPtr<CSSMutableStyleDeclaration> blockStyle = mutableStyle->copyBlockProperties();
    blockStyle->diff(mutableStyle.get());
    if (document() && blockStyle->length() > 0) {
        EditCommandPtr cmd(new ApplyStyleCommand(document(), blockStyle.get(), editingAction));
        cmd.apply();
    }
    
    // Set the remaining style as the typing style.
    d->m_typingStyle = mutableStyle.release();
}

void Frame::applyStyle(CSSStyleDeclaration *style, EditAction editingAction)
{
    switch (selection().state()) {
        case Selection::NONE:
            // do nothing
            break;
        case Selection::CARET: {
            computeAndSetTypingStyle(style, editingAction);
            break;
        }
        case Selection::RANGE:
            if (document() && style) {
                EditCommandPtr cmd(new ApplyStyleCommand(document(), style, editingAction));
                cmd.apply();
            }
            break;
    }
}

void Frame::applyParagraphStyle(CSSStyleDeclaration *style, EditAction editingAction)
{
    switch (selection().state()) {
        case Selection::NONE:
            // do nothing
            break;
        case Selection::CARET:
        case Selection::RANGE:
            if (document() && style) {
                EditCommandPtr cmd(new ApplyStyleCommand(document(), style, editingAction, ApplyStyleCommand::ForceBlockProperties));
                cmd.apply();
            }
            break;
    }
}

static void updateState(CSSMutableStyleDeclaration *desiredStyle, CSSComputedStyleDeclaration *computedStyle, bool& atStart, Frame::TriState& state)
{
    DeprecatedValueListConstIterator<CSSProperty> end;
    for (DeprecatedValueListConstIterator<CSSProperty> it = desiredStyle->valuesIterator(); it != end; ++it) {
        int propertyID = (*it).id();
        String desiredProperty = desiredStyle->getPropertyValue(propertyID);
        String computedProperty = computedStyle->getPropertyValue(propertyID);
        Frame::TriState propertyState = equalIgnoringCase(desiredProperty, computedProperty)
            ? Frame::trueTriState : Frame::falseTriState;
        if (atStart) {
            state = propertyState;
            atStart = false;
        } else if (state != propertyState) {
            state = Frame::mixedTriState;
            break;
        }
    }
}

Frame::TriState Frame::selectionListState() const
{
    TriState state = falseTriState;

    if (!d->m_selection.isRange()) {
        Node* selectionNode = d->m_selection.selection().start().node();
        if (enclosingList(selectionNode))
            return trueTriState;
    } else {
        //FIXME: Support ranges
    }

    return state;
}

Frame::TriState Frame::selectionHasStyle(CSSStyleDeclaration *style) const
{
    bool atStart = true;
    TriState state = falseTriState;

    RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();

    if (!d->m_selection.isRange()) {
        Node* nodeToRemove;
        RefPtr<CSSComputedStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
        if (!selectionStyle)
            return falseTriState;
        updateState(mutableStyle.get(), selectionStyle.get(), atStart, state);
        if (nodeToRemove) {
            ExceptionCode ec = 0;
            nodeToRemove->remove(ec);
            assert(ec == 0);
        }
    } else {
        for (Node* node = d->m_selection.start().node(); node; node = node->traverseNextNode()) {
            RefPtr<CSSComputedStyleDeclaration> computedStyle = new CSSComputedStyleDeclaration(node);
            if (computedStyle)
                updateState(mutableStyle.get(), computedStyle.get(), atStart, state);
            if (state == mixedTriState)
                break;
            if (node == d->m_selection.end().node())
                break;
        }
    }

    return state;
}

bool Frame::selectionStartHasStyle(CSSStyleDeclaration *style) const
{
    Node* nodeToRemove;
    RefPtr<CSSStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
    if (!selectionStyle)
        return false;

    RefPtr<CSSMutableStyleDeclaration> mutableStyle = style->makeMutable();

    bool match = true;
    DeprecatedValueListConstIterator<CSSProperty> end;
    for (DeprecatedValueListConstIterator<CSSProperty> it = mutableStyle->valuesIterator(); it != end; ++it) {
        int propertyID = (*it).id();
        if (!equalIgnoringCase(mutableStyle->getPropertyValue(propertyID), selectionStyle->getPropertyValue(propertyID))) {
            match = false;
            break;
        }
    }

    if (nodeToRemove) {
        ExceptionCode ec = 0;
        nodeToRemove->remove(ec);
        assert(ec == 0);
    }

    return match;
}

String Frame::selectionStartStylePropertyValue(int stylePropertyID) const
{
    Node *nodeToRemove;
    RefPtr<CSSStyleDeclaration> selectionStyle = selectionComputedStyle(nodeToRemove);
    if (!selectionStyle)
        return String();

    String value = selectionStyle->getPropertyValue(stylePropertyID);

    if (nodeToRemove) {
        ExceptionCode ec = 0;
        nodeToRemove->remove(ec);
        assert(ec == 0);
    }

    return value;
}

CSSComputedStyleDeclaration *Frame::selectionComputedStyle(Node *&nodeToRemove) const
{
    nodeToRemove = 0;

    if (!document())
        return 0;

    if (d->m_selection.isNone())
        return 0;

    RefPtr<Range> range(d->m_selection.toRange());
    Position pos = range->editingStartPosition();

    Element *elem = pos.element();
    if (!elem)
        return 0;
    
    RefPtr<Element> styleElement = elem;
    ExceptionCode ec = 0;

    if (d->m_typingStyle) {
        styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
        assert(ec == 0);

        styleElement->setAttribute(styleAttr, d->m_typingStyle->cssText().impl(), ec);
        assert(ec == 0);
        
        styleElement->appendChild(document()->createEditingTextNode(""), ec);
        assert(ec == 0);

        if (elem->renderer() && elem->renderer()->canHaveChildren()) {
            elem->appendChild(styleElement, ec);
        } else {
            Node *parent = elem->parent();
            Node *next = elem->nextSibling();

            if (next) {
                parent->insertBefore(styleElement, next, ec);
            } else {
                parent->appendChild(styleElement, ec);
            }
        }
        assert(ec == 0);

        nodeToRemove = styleElement.get();
    }

    return new CSSComputedStyleDeclaration(styleElement);
}

void Frame::applyEditingStyleToBodyElement() const
{
    if (!d->m_doc)
        return;
        
    RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body");
    unsigned len = list->length();
    for (unsigned i = 0; i < len; i++) {
        applyEditingStyleToElement(static_cast<Element*>(list->item(i)));    
    }
}

void Frame::removeEditingStyleFromBodyElement() const
{
    if (!d->m_doc)
        return;
        
    RefPtr<NodeList> list = d->m_doc->getElementsByTagName("body");
    unsigned len = list->length();
    for (unsigned i = 0; i < len; i++) {
        removeEditingStyleFromElement(static_cast<Element*>(list->item(i)));    
    }
}

void Frame::applyEditingStyleToElement(Element *element) const
{
    if (!element || !element->isHTMLElement())
        return;
    
    static_cast<HTMLElement*>(element)->setContentEditable("true");
}

void Frame::removeEditingStyleFromElement(Element *element) const
{
    if (!element || !element->isHTMLElement())
        return;
        
    static_cast<HTMLElement*>(element)->setContentEditable("false");        
}


bool Frame::isCharacterSmartReplaceExempt(const QChar&, bool)
{
    // no smart replace
    return true;
}

#ifndef NDEBUG
static HashSet<Frame*> lifeSupportSet;
#endif

void Frame::endAllLifeSupport()
{
#ifndef NDEBUG
    HashSet<Frame*> lifeSupportCopy = lifeSupportSet;
    HashSet<Frame*>::iterator end = lifeSupportCopy.end();
    for (HashSet<Frame*>::iterator it = lifeSupportCopy.begin(); it != end; ++it)
        (*it)->endLifeSupport();
#endif
}

void Frame::keepAlive()
{
    if (d->m_lifeSupportTimer.isActive())
        return;
    ref();
#ifndef NDEBUG
    lifeSupportSet.add(this);
#endif
    d->m_lifeSupportTimer.startOneShot(0);
}

void Frame::endLifeSupport()
{
    if (!d->m_lifeSupportTimer.isActive())
        return;
    d->m_lifeSupportTimer.stop();
#ifndef NDEBUG
    lifeSupportSet.remove(this);
#endif
    deref();
}

void Frame::lifeSupportTimerFired(Timer<Frame>*)
{
#ifndef NDEBUG
    lifeSupportSet.remove(this);
#endif
    deref();
}

// Workaround for the fact that it's hard to delete a frame.
// Call this after doing user-triggered selections to make it easy to delete the frame you entirely selected.
// Can't do this implicitly as part of every setSelection call because in some contexts it might not be good
// for the focus to move to another frame. So instead we call it from places where we are selecting with the
// mouse or the keyboard after setting the selection.
void Frame::selectFrameElementInParentIfFullySelected()
{
    // Find the parent frame; if there is none, then we have nothing to do.
    Frame *parent = tree()->parent();
    if (!parent)
        return;
    FrameView *parentView = parent->view();
    if (!parentView)
        return;

    // Check if the selection contains the entire frame contents; if not, then there is nothing to do.
    if (!d->m_selection.isRange())
        return;
    if (!isStartOfDocument(VisiblePosition(d->m_selection.start(), d->m_selection.affinity())))
        return;
    if (!isEndOfDocument(VisiblePosition(d->m_selection.end(), d->m_selection.affinity())))
        return;

    // Get to the <iframe> or <frame> (or even <object>) element in the parent frame.
    Document *doc = document();
    if (!doc)
        return;
    Element *ownerElement = doc->ownerElement();
    if (!ownerElement)
        return;
    Node *ownerElementParent = ownerElement->parentNode();
    if (!ownerElementParent)
        return;
        
    // 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.
    if (!ownerElementParent->isContentEditable())
        return;

    // Create compute positions before and after the element.
    unsigned ownerElementNodeIndex = ownerElement->nodeIndex();
    VisiblePosition beforeOwnerElement(VisiblePosition(ownerElementParent, ownerElementNodeIndex, SEL_DEFAULT_AFFINITY));
    VisiblePosition afterOwnerElement(VisiblePosition(ownerElementParent, ownerElementNodeIndex + 1, VP_UPSTREAM_IF_POSSIBLE));

    // Focus on the parent frame, and then select from before this element to after.
    if (parent->shouldChangeSelection(SelectionController(beforeOwnerElement, afterOwnerElement))) {
        parentView->setFocus();
        parent->setSelection(SelectionController(beforeOwnerElement, afterOwnerElement));
    }
}

void Frame::handleFallbackContent()
{
    Element* owner = ownerElement();
    if (!owner || !owner->hasTagName(objectTag))
        return;
    static_cast<HTMLObjectElement*>(owner)->renderFallbackContent();
}

void Frame::setSettings(KHTMLSettings *settings)
{
    d->m_settings = settings;
}

void Frame::provisionalLoadStarted()
{
    // we don't want to wait until we get an actual http response back
    // to cancel pending redirects, otherwise they might fire before
    // that happens.
    cancelRedirection(true);
}

bool Frame::userGestureHint()
{
    Frame *rootFrame = this;
    while (rootFrame->tree()->parent())
        rootFrame = rootFrame->tree()->parent();

    if (rootFrame->jScript())
        return rootFrame->jScript()->interpreter()->wasRunByUserGesture();

    return true; // If JavaScript is disabled, a user gesture must have initiated the navigation
}

RenderObject *Frame::renderer() const
{
    Document *doc = document();
    return doc ? doc->renderer() : 0;
}

Element* Frame::ownerElement()
{
    RenderPart* ownerElementRenderer = d->m_ownerRenderer;
    if (!ownerElementRenderer)
        return 0;
    return static_cast<Element*>(ownerElementRenderer->element());
}

RenderPart* Frame::ownerRenderer()
{
    return d->m_ownerRenderer;
}

IntRect Frame::selectionRect() const
{
    RenderView *root = static_cast<RenderView*>(renderer());
    if (!root)
        return IntRect();

    return root->selectionRect();
}

// returns FloatRect because going through IntRect would truncate any floats
FloatRect Frame::visibleSelectionRect() const
{
    if (!d->m_view)
        return FloatRect();
    
    return intersection(selectionRect(), d->m_view->visibleContentRect());
}

bool Frame::isFrameSet() const
{
    Document* document = d->m_doc.get();
    if (!document || !document->isHTMLDocument())
        return false;
    Node *body = static_cast<HTMLDocument*>(document)->body();
    return body && body->renderer() && body->hasTagName(framesetTag);
}

bool Frame::openURL(const KURL& URL)
{
    ASSERT_NOT_REACHED();
    return true;
}

void Frame::didNotOpenURL(const KURL& URL)
{
    if (d->m_submittedFormURL == URL)
        d->m_submittedFormURL = KURL();
}

// Scans logically forward from "start", including any child frames
static HTMLFormElement *scanForForm(Node *start)
{
    Node *n;
    for (n = start; n; n = n->traverseNextNode()) {
        if (n->hasTagName(formTag))
            return static_cast<HTMLFormElement*>(n);
        else if (n->isHTMLElement() && static_cast<HTMLElement*>(n)->isGenericFormElement())
            return static_cast<HTMLGenericFormElement*>(n)->form();
        else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) {
            Node *childDoc = static_cast<HTMLFrameElement*>(n)->contentDocument();
            if (HTMLFormElement *frameResult = scanForForm(childDoc))
                return frameResult;
        }
    }
    return 0;
}

// We look for either the form containing the current focus, or for one immediately after it
HTMLFormElement *Frame::currentForm() const
{
    // start looking either at the active (first responder) node, or where the selection is
    Node *start = d->m_doc ? d->m_doc->focusNode() : 0;
    if (!start)
        start = selection().start().node();
    
    // try walking up the node tree to find a form element
    Node *n;
    for (n = start; n; n = n->parentNode()) {
        if (n->hasTagName(formTag))
            return static_cast<HTMLFormElement*>(n);
        else if (n->isHTMLElement()
                   && static_cast<HTMLElement*>(n)->isGenericFormElement())
            return static_cast<HTMLGenericFormElement*>(n)->form();
    }
    
    // try walking forward in the node tree to find a form element
    return start ? scanForForm(start) : 0;
}

void Frame::setEncoding(const DeprecatedString& name, bool userChosen)
{
    if (!d->m_workingURL.isEmpty())
        receivedFirstData();
    d->m_encoding = name;
    d->m_haveEncoding = userChosen;
}

void Frame::addData(const char *bytes, int length)
{
    ASSERT(d->m_workingURL.isEmpty());
    ASSERT(d->m_doc);
    ASSERT(d->m_doc->parsing());
    write(bytes, length);
}

// FIXME: should this go in SelectionController?
void Frame::revealSelection()
{
    IntRect rect;
    
    switch (selection().state()) {
        case Selection::NONE:
            return;
            
        case Selection::CARET:
            rect = selection().caretRect();
            break;
            
        case Selection::RANGE:
            rect = selectionRect();
            break;
    }
    
    Position start = selection().start();
    Position end = selection().end();
    ASSERT(start.node());
    if (start.node() && start.node()->renderer()) {
        RenderLayer *layer = start.node()->renderer()->enclosingLayer();
        if (layer) {
            ASSERT(!end.node() || !end.node()->renderer() 
                   || (end.node()->renderer()->enclosingLayer() == layer));
            layer->scrollRectToVisible(rect);
        }
    }
}

// FIXME: should this be here?
bool Frame::scrollOverflow(KWQScrollDirection direction, KWQScrollGranularity granularity)
{
    if (!document()) {
        return false;
    }
    
    Node *node = document()->focusNode();
    if (node == 0) {
        node = d->m_mousePressNode.get();
    }
    
    if (node != 0) {
        RenderObject *r = node->renderer();
        if (r != 0) {
            return r->scroll(direction, granularity);
        }
    }
    
    return false;
}

void Frame::handleAutoscroll(RenderLayer* layer)
{
    if (d->m_autoscrollTimer.isActive())
        return;
    d->m_autoscrollLayer = layer;
    startAutoscrollTimer();
}

void Frame::autoscrollTimerFired(Timer<Frame>*)
{
    if (!d->m_bMousePressed){
        stopAutoscrollTimer();
        return;
    }
    if (d->m_autoscrollLayer) {
        d->m_autoscrollLayer->autoscroll();
    } 
}

RenderObject::NodeInfo Frame::nodeInfoAtPoint(const IntPoint& point, bool allowShadowContent)
{
    RenderObject::NodeInfo nodeInfo(true, true);
    renderer()->layer()->hitTest(nodeInfo, point);

    Node *n;
    Widget *widget = 0;
    IntPoint widgetPoint(point);
    
    while (true) {
        n = nodeInfo.innerNode();
        if (!n || !n->renderer() || !n->renderer()->isWidget())
            break;
        widget = static_cast<RenderWidget*>(n->renderer())->widget();
        if (!widget || !widget->isFrameView())
            break;
        Frame* frame = static_cast<HTMLFrameElement*>(n)->contentFrame();
        if (!frame || !frame->renderer())
            break;
        int absX, absY;
        n->renderer()->absolutePosition(absX, absY, true);
        FrameView *view = static_cast<FrameView*>(widget);
        widgetPoint.setX(widgetPoint.x() - absX + view->contentsX());
        widgetPoint.setY(widgetPoint.y() - absY + view->contentsY());

        RenderObject::NodeInfo widgetNodeInfo(true, true);
        frame->renderer()->layer()->hitTest(widgetNodeInfo, widgetPoint);
        nodeInfo = widgetNodeInfo;
    }
    
    if (!allowShadowContent) {
        Node* node = nodeInfo.innerNode();
        if (node)
            node = node->shadowAncestorNode();
        nodeInfo.setInnerNode(node);
        node = nodeInfo.innerNonSharedNode();
        if (node)
            node = node->shadowAncestorNode();
        nodeInfo.setInnerNonSharedNode(node); 
    }
    return nodeInfo;
}

bool Frame::hasSelection()
{
    if (selection().isNone())
        return false;

    // If a part has a selection, it should also have a document.        
    ASSERT(document());

    return true;
}

void Frame::startAutoscrollTimer()
{
    d->m_autoscrollTimer.startRepeating(autoscrollInterval);
}

void Frame::stopAutoscrollTimer()
{
    d->m_autoscrollLayer = 0;
    d->m_autoscrollTimer.stop();
}

// FIXME: why is this here instead of on the FrameView?
void Frame::paint(GraphicsContext* p, const IntRect& rect)
{
#ifndef NDEBUG
    bool fillWithRed;
    if (!document() || document()->printing())
        fillWithRed = false; // Printing, don't fill with red (can't remember why).
    else if (document()->ownerElement())
        fillWithRed = false; // Subframe, don't fill with red.
    else if (view() && view()->isTransparent())
        fillWithRed = false; // Transparent, don't fill with red.
    else if (d->m_drawSelectionOnly)
        fillWithRed = false; // Selections are transparent, don't fill with red.
    else if (d->m_elementToDraw)
        fillWithRed = false; // Element images are transparent, don't fill with red.
    else
        fillWithRed = true;
    
    if (fillWithRed)
        p->fillRect(rect, Color(0xFF, 0, 0));
#endif
    
    if (renderer()) {
        // d->m_elementToDraw is used to draw only one element
        RenderObject *eltRenderer = d->m_elementToDraw ? d->m_elementToDraw->renderer() : 0;
        renderer()->layer()->paint(p, rect, d->m_drawSelectionOnly, eltRenderer);

#if __APPLE__
        // Regions may have changed as a result of the visibility/z-index of element changing.
        if (renderer()->document()->dashboardRegionsDirty())
            renderer()->view()->frameView()->updateDashboardRegions();
#endif
    } else
        LOG_ERROR("called Frame::paint with nil renderer");
}

#if __APPLE__

void Frame::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float bottomLimit)
{
    RenderView *root = static_cast<RenderView*>(document()->renderer());
    if (root) {
        // Use a context with painting disabled.
        GraphicsContext context(0);
        root->setTruncatedAt((int)floorf(oldBottom));
        IntRect dirtyRect(0, (int)floorf(oldTop), root->docWidth(), (int)ceilf(oldBottom - oldTop));
        root->layer()->paint(&context, dirtyRect);
        *newBottom = root->bestTruncatedAt();
        if (*newBottom == 0)
            *newBottom = oldBottom;
    } else
        *newBottom = oldBottom;
}

#endif

PausedTimeouts *Frame::pauseTimeouts()
{
#if SVG_SUPPORT
    if (d->m_doc && d->m_doc->svgExtensions())
        d->m_doc->accessSVGExtensions()->pauseAnimations();
#endif

    if (d->m_doc && d->m_jscript) {
        if (Window* w = Window::retrieveWindow(this))
            return w->pauseTimeouts();
    }
    return 0;
}

void Frame::resumeTimeouts(PausedTimeouts* t)
{
#if SVG_SUPPORT
    if (d->m_doc && d->m_doc->svgExtensions())
        d->m_doc->accessSVGExtensions()->unpauseAnimations();
#endif

    if (d->m_doc && d->m_jscript && d->m_bJScriptEnabled) {
        if (Window* w = Window::retrieveWindow(this))
            w->resumeTimeouts(t);
    }
}

bool Frame::canCachePage()
{
    // Only save page state if:
    // 1.  We're not a frame or frameset.
    // 2.  The page has no unload handler.
    // 3.  The page has no password fields.
    // 4.  The URL for the page is not https.
    // 5.  The page has no applets.
    if (tree()->childCount() || d->m_plugins.size() ||
        tree()->parent() ||
        d->m_url.protocol().startsWith("https") || 
        (d->m_doc && (d->m_doc->applets()->length() != 0 ||
                      d->m_doc->hasWindowEventListener(unloadEvent) ||
                      d->m_doc->hasPasswordField()))) {
        return false;
    }
    return true;
}

void Frame::saveWindowProperties(KJS::SavedProperties *windowProperties)
{
    Window *window = Window::retrieveWindow(this);
    if (window)
        window->saveProperties(*windowProperties);
}

void Frame::saveLocationProperties(SavedProperties *locationProperties)
{
    Window *window = Window::retrieveWindow(this);
    if (window) {
        JSLock lock;
        Location *location = window->location();
        location->saveProperties(*locationProperties);
    }
}

void Frame::restoreWindowProperties(SavedProperties *windowProperties)
{
    Window *window = Window::retrieveWindow(this);
    if (window)
        window->restoreProperties(*windowProperties);
}

void Frame::restoreLocationProperties(SavedProperties *locationProperties)
{
    Window *window = Window::retrieveWindow(this);
    if (window) {
        JSLock lock;
        Location *location = window->location();
        location->restoreProperties(*locationProperties);
    }
}

void Frame::saveInterpreterBuiltins(SavedBuiltins& interpreterBuiltins)
{
    if (jScript())
        jScript()->interpreter()->saveBuiltins(interpreterBuiltins);
}

void Frame::restoreInterpreterBuiltins(const SavedBuiltins& interpreterBuiltins)
{
    if (jScript())
        jScript()->interpreter()->restoreBuiltins(interpreterBuiltins);
}

Frame *Frame::frameForWidget(const Widget *widget)
{
    ASSERT_ARG(widget, widget);
    
    Node *node = nodeForWidget(widget);
    if (node)
        return frameForNode(node);
    
    // Assume all widgets are either form controls, or FrameViews.
    ASSERT(widget->isFrameView());
    return static_cast<const FrameView*>(widget)->frame();
}

Frame *Frame::frameForNode(Node *node)
{
    ASSERT_ARG(node, node);
    return node->document()->frame();
}

Node* Frame::nodeForWidget(const Widget* widget)
{
    ASSERT_ARG(widget, widget);
    WidgetClient* client = widget->client();
    if (!client)
        return 0;
    return client->element(const_cast<Widget*>(widget));
}

void Frame::clearDocumentFocus(Widget *widget)
{
    Node *node = nodeForWidget(widget);
    ASSERT(node);
    node->document()->setFocusNode(0);
}

void Frame::updatePolicyBaseURL()
{
    if (tree()->parent() && tree()->parent()->document())
        setPolicyBaseURL(tree()->parent()->document()->policyBaseURL());
    else
        setPolicyBaseURL(d->m_url.url());
}

void Frame::setPolicyBaseURL(const String& s)
{
    if (document())
        document()->setPolicyBaseURL(s);
    for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
        child->setPolicyBaseURL(s);
}

void Frame::forceLayout()
{
    FrameView *v = d->m_view.get();
    if (v) {
        v->layout(false);
        // We cannot unschedule a pending relayout, since the force can be called with
        // a tiny rectangle from a drawRect update.  By unscheduling we in effect
        // "validate" and stop the necessary full repaint from occurring.  Basically any basic
        // append/remove DHTML is broken by this call.  For now, I have removed the optimization
        // until we have a better invalidation stategy. -dwh
        //v->unscheduleRelayout();
    }
}

void Frame::forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth)
{
    // Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
    // the state of things before and after the layout
    RenderView *root = static_cast<RenderView*>(document()->renderer());
    if (root) {
        // This magic is basically copied from khtmlview::print
        int pageW = (int)ceilf(minPageWidth);
        root->setWidth(pageW);
        root->setNeedsLayoutAndMinMaxRecalc();
        forceLayout();
        
        // If we don't fit in the minimum page width, we'll lay out again. If we don't fit in the
        // maximum page width, we will lay out to the maximum page width and clip extra content.
        // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
        // implementation should not do this!
        int rightmostPos = root->rightmostPosition();
        if (rightmostPos > minPageWidth) {
            pageW = min(rightmostPos, (int)ceilf(maxPageWidth));
            root->setWidth(pageW);
            root->setNeedsLayoutAndMinMaxRecalc();
            forceLayout();
        }
    }
}

void Frame::sendResizeEvent()
{
    if (Document* doc = document())
        doc->dispatchWindowEvent(EventNames::resizeEvent, false, false);
}

void Frame::sendScrollEvent()
{
    FrameView *v = d->m_view.get();
    if (v) {
        Document *doc = document();
        if (!doc)
            return;
        doc->dispatchHTMLEvent(scrollEvent, true, false);
    }
}

bool Frame::scrollbarsVisible()
{
    if (!view())
        return false;
    
    if (view()->hScrollBarMode() == ScrollBarAlwaysOff || view()->vScrollBarMode() == ScrollBarAlwaysOff)
        return false;
    
    return true;
}

void Frame::addMetaData(const String& key, const String& value)
{
    d->m_job->addMetaData(key, value);
}

// This does the same kind of work that Frame::openURL does, except it relies on the fact
// that a higher level already checked that the URLs match and the scrolling is the right thing to do.
void Frame::scrollToAnchor(const KURL& URL)
{
    d->m_url = URL;
    started();
    
    gotoAnchor();
    
    // It's important to model this as a load that starts and immediately finishes.
    // Otherwise, the parent frame may think we never finished loading.
    d->m_bComplete = false;
    checkCompleted();
}

bool Frame::closeURL()
{
    saveDocumentState();
    stopLoading(true);
    clearUndoRedoOperations();
    return true;
}

bool Frame::canMouseDownStartSelect(Node* node)
{
    if (!node || !node->renderer())
        return true;
    
    // Check to see if -webkit-user-select has been set to none
    if (!node->renderer()->canSelect())
        return false;
    
    // Some controls and images can't start a select on a mouse down.
    for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {
        if (curr->style()->userSelect() == SELECT_IGNORE)
            return false;
    }
    
    return true;
}

void Frame::handleMouseReleaseDoubleClickEvent(const MouseEventWithHitTestResults& event)
{
    passWidgetMouseDownEventToWidget(event, true);
}

bool Frame::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event, bool isDoubleClick)
{
    // Figure out which view to send the event to.
    RenderObject *target = event.targetNode() ? event.targetNode()->renderer() : 0;
    if (!target)
        return false;
    
    Widget* widget = RenderLayer::gScrollBar;
    if (!widget) {
        if (!target->isWidget())
            return false;
        widget = static_cast<RenderWidget*>(target)->widget();
    }
    
    // Doubleclick events don't exist in Cocoa.  Since passWidgetMouseDownEventToWidget will
    // just pass _currentEvent down to the widget,  we don't want to call it for events that
    // don't correspond to Cocoa events.  The mousedown/ups will have already been passed on as
    // part of the pressed/released handling.
    if (!isDoubleClick)
        return passMouseDownEventToWidget(widget);
    return true;
}

bool Frame::passWidgetMouseDownEventToWidget(RenderWidget *renderWidget)
{
    return passMouseDownEventToWidget(renderWidget->widget());
}

void Frame::clearTimers(FrameView *view)
{
    if (view) {
        view->unscheduleRelayout();
        if (view->frame()) {
            Document* document = view->frame()->document();
            if (document && document->renderer() && document->renderer()->layer())
                document->renderer()->layer()->suspendMarquees();
        }
    }
}

void Frame::clearTimers()
{
    clearTimers(d->m_view.get());
}

// FIXME: selection controller?
void Frame::centerSelectionInVisibleArea() const
{
    IntRect rect;
    
    switch (selection().state()) {
        case Selection::NONE:
            return;
            
        case Selection::CARET:
            rect = selection().caretRect();
            break;
            
        case Selection::RANGE:
            rect = selectionRect();
            break;
    }
    
    Position start = selection().start();
    Position end = selection().end();
    ASSERT(start.node());
    if (start.node() && start.node()->renderer()) {
        RenderLayer *layer = start.node()->renderer()->enclosingLayer();
        if (layer) {
            ASSERT(!end.node() || !end.node()->renderer() 
                   || (end.node()->renderer()->enclosingLayer() == layer));
            layer->scrollRectToVisible(rect, RenderLayer::gAlignCenterAlways, RenderLayer::gAlignCenterAlways);
        }
    }
}

RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
{
    nodeToRemove = 0;
    
    if (!document())
        return 0;
    if (d->m_selection.isNone())
        return 0;
    
    Position pos = VisiblePosition(d->m_selection.start(), d->m_selection.affinity()).deepEquivalent();
    if (!pos.inRenderedContent())
        return 0;
    Node *node = pos.node();
    if (!node)
        return 0;
    
    if (!d->m_typingStyle)
        return node->renderer()->style();
    
    ExceptionCode ec = 0;
    RefPtr<Element> styleElement = document()->createElementNS(xhtmlNamespaceURI, "span", ec);
    ASSERT(ec == 0);
    
    styleElement->setAttribute(styleAttr, d->m_typingStyle->cssText().impl(), ec);
    ASSERT(ec == 0);
    
    styleElement->appendChild(document()->createEditingTextNode(""), ec);
    ASSERT(ec == 0);
    
    node->parentNode()->appendChild(styleElement, ec);
    ASSERT(ec == 0);
    
    nodeToRemove = styleElement.get();    
    return styleElement->renderer()->style();
}

void Frame::setMediaType(const String& type)
{
    if (d->m_view)
        d->m_view->setMediaType(type);
}

void Frame::setSelectionFromNone()
{
    // Put a caret inside the body if the entire frame is editable (either the 
    // entire WebView is editable or designMode is on for this document).
    Document *doc = document();
    if (!doc || !selection().isNone() || !isContentEditable())
        return;
        
    Node* node = doc->documentElement();
    while (node && !node->hasTagName(bodyTag))
        node = node->traverseNextNode();
    if (node)
        setSelection(SelectionController(Position(node, 0), DOWNSTREAM));
}

bool Frame::displaysWithFocusAttributes() const
{
    return d->m_isFocused;
}

void Frame::setDisplaysWithFocusAttributes(bool flag)
{
    if (d->m_isFocused == flag)
        return;
    
    d->m_isFocused = flag;

    // This method does the job of updating the view based on whether the view is "active".
    // This involves three kinds of drawing updates:

    // 1. The background color used to draw behind selected content (active | inactive color)
    if (d->m_view)
        d->m_view->updateContents(enclosingIntRect(visibleSelectionRect()));

    // 2. Caret blinking (blinks | does not blink)
    if (flag)
        setSelectionFromNone();
    setCaretVisible(flag);
    
    // 3. The drawing of a focus ring around links in web pages.
    Document *doc = document();
    if (doc) {
        Node *node = doc->focusNode();
        if (node) {
            node->setChanged();
            if (node->renderer() && node->renderer()->style()->hasAppearance())
                theme()->stateChanged(node->renderer(), FocusState);
        }
    }
}

void Frame::setWindowHasFocus(bool flag)
{
    if (d->m_windowHasFocus == flag)
        return;
    d->m_windowHasFocus = flag;
    
    if (Document *doc = document())
        doc->dispatchWindowEvent(flag ? focusEvent : blurEvent, false, false);
}

UChar Frame::backslashAsCurrencySymbol() const
{
    Document *doc = document();
    if (!doc)
        return '\\';
    Decoder *decoder = doc->decoder();
    if (!decoder)
        return '\\';

    return decoder->encoding().backslashAsCurrencySymbol();
}

bool Frame::markedTextUsesUnderlines() const
{
    return d->m_markedTextUsesUnderlines;
}

DeprecatedValueList<MarkedTextUnderline> Frame::markedTextUnderlines() const
{
    return d->m_markedTextUnderlines;
}

unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag)
{
    if (target.isEmpty())
        return 0;
    
    RefPtr<Range> searchRange(rangeOfContents(document()));
    
    int exception = 0;
    unsigned matchCount = 0;
    do {
        RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));
        if (resultRange->collapsed(exception))
            break;
        
        // A non-collapsed result range can in some funky whitespace cases still not
        // advance the range's start position (4509328). Break to avoid infinite loop.
        VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
        if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
            break;

        ++matchCount;
        document()->addMarker(resultRange.get(), DocumentMarker::TextMatch);        
        
        setStart(searchRange.get(), newStart);
    } while (true);
    
    return matchCount;
}

bool Frame::markedTextMatchesAreHighlighted() const
{
    return d->m_highlightTextMatches;
}

void Frame::setMarkedTextMatchesAreHighlighted(bool flag)
{
    if (flag == d->m_highlightTextMatches)
        return;
    
    d->m_highlightTextMatches = flag;
    document()->repaintMarkers(DocumentMarker::TextMatch);
}

void Frame::prepareForUserAction()
{
    // Reset the multiple form submission protection code.
    // We'll let you submit the same form twice if you do two separate user actions.
    d->m_submittedFormURL = KURL();
}

Node *Frame::mousePressNode()
{
    return d->m_mousePressNode.get();
}

bool Frame::isComplete() const
{
    return d->m_bComplete;
}

bool Frame::isLoadingMainResource() const
{
    return d->m_bLoadingMainResource;
}

FrameTree* Frame::tree() const
{
    return &d->m_treeNode;
}

DOMWindow* Frame::domWindow() const
{
    if (!d->m_domWindow)
        d->m_domWindow = new DOMWindow(const_cast<Frame*>(this));

    return d->m_domWindow.get();
}

KURL Frame::url() const
{
    return d->m_url;
}

void Frame::startRedirectionTimer()
{
    d->m_redirectionTimer.startOneShot(d->m_delayRedirect);
}

void Frame::stopRedirectionTimer()
{
    d->m_redirectionTimer.stop();
}

void Frame::frameDetached()
{
}

void Frame::updateBaseURLForEmptyDocument()
{
    Element* owner = ownerElement();
    // FIXME: Should embed be included?
    if (owner && (owner->hasTagName(iframeTag) || owner->hasTagName(objectTag) || owner->hasTagName(embedTag)))
        d->m_doc->setBaseURL(tree()->parent()->d->m_doc->baseURL());
}

Page* Frame::page() const
{
    return d->m_page;
}

void Frame::completed(bool complete)
{
    ref();
    for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
        child->parentCompleted();
    if (Frame* parent = tree()->parent())
        parent->childCompleted(complete);
    submitFormAgain();
    deref();
}

void Frame::setStatusBarText(const String&)
{
}

void Frame::started()
{
    for (Frame* frame = this; frame; frame = frame->tree()->parent())
        frame->d->m_bComplete = false;
}

void Frame::disconnectOwnerRenderer()
{
    d->m_ownerRenderer = 0;
}

String Frame::documentTypeString() const
{
    if (Document *doc = document())
        if (DocumentType *doctype = doc->realDocType())
            return doctype->toString();

    return String();
}

bool Frame::containsPlugins() const 
{ 
    return d->m_plugins.size() != 0;
}

} // namespace WebCore
