summaryrefslogtreecommitdiffstats
path: root/WebCore/page/Frame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/page/Frame.cpp')
-rw-r--r--WebCore/page/Frame.cpp760
1 files changed, 367 insertions, 393 deletions
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index 6e8081e..fa1a514 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -7,7 +7,8 @@
* 2001 George Staikos <staikos@kde.org>
* Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
- * Copyright (C) 2007 Trolltech ASA
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,6 +25,9 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+#ifdef ANDROID_INSTRUMENT
+#define LOG_TAG "WebCore"
+#endif
#include "config.h"
#include "Frame.h"
@@ -45,15 +49,18 @@
#include "FrameLoader.h"
#include "FrameView.h"
#include "GraphicsContext.h"
-#include "HitTestResult.h"
#include "HTMLDocument.h"
#include "HTMLFormElement.h"
#include "HTMLFrameElementBase.h"
-#include "HTMLGenericFormElement.h"
+#include "HTMLFormControlElement.h"
#include "HTMLNames.h"
#include "HTMLTableCellElement.h"
+#include "HitTestResult.h"
+#include "JSDOMWindowShell.h"
#include "Logging.h"
+#include "markup.h"
#include "MediaFeatureNames.h"
+#include "Navigator.h"
#include "NodeList.h"
#include "Page.h"
#include "RegularExpression.h"
@@ -67,29 +74,16 @@
#include "TextIterator.h"
#include "TextResourceDecoder.h"
#include "XMLNames.h"
-#include "bindings/NP_jsobject.h"
-#include "bindings/npruntime_impl.h"
-#include "bindings/runtime_root.h"
-#include "kjs_proxy.h"
-#include "kjs_window.h"
+#include "ScriptController.h"
+#include "npruntime_impl.h"
+#include "runtime_root.h"
#include "visible_units.h"
+#include <wtf/RefCountedLeakCounter.h>
-#ifdef MANUAL_MERGE_REQUIRED
-#ifdef ANDROID_BRIDGE
- #define LOG_TAG "webcore"
- #undef LOG
- #include <utils/Log.h>
-
- #include "WebCoreViewBridge.h"
- #include "FrameAndroid.h"
-#endif
-
-#else // MANUAL_MERGE_REQUIRED
#if FRAME_LOADS_USER_STYLESHEET
#include "UserStyleSheetLoader.h"
#endif
-#endif // MANUAL_MERGE_REQUIRED
#if ENABLE(SVG)
#include "SVGDocument.h"
#include "SVGDocumentExtensions.h"
@@ -97,34 +91,23 @@
#include "XLinkNames.h"
#endif
-using namespace std;
+#if PLATFORM(ANDROID)
+#include "WebViewCore.h"
+#endif
+
+#ifdef ANDROID_INSTRUMENT
+#include "CString.h"
+#include "Cache.h"
+#endif
-using KJS::JSLock;
+using namespace std;
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
-double Frame::s_currentPaintTimeStamp = 0.0;
-
-#ifndef NDEBUG
-WTFLogChannel LogWebCoreFrameLeaks = { 0x00000000, "", WTFLogChannelOn };
-
-struct FrameCounter {
- static int count;
- ~FrameCounter()
- {
- if (count)
-#ifdef ANDROID_BRIDGE
- fprintf(stderr, "LEAK: %d Frame\n", count);
-#else
- LOG(WebCoreFrameLeaks, "LEAK: %d Frame\n", count);
-#endif
- }
-};
-int FrameCounter::count = 0;
-static FrameCounter frameCounter;
+#ifndef NDEBUG
+static WTF::RefCountedLeakCounter frameCounter("Frame");
#endif
static inline Frame* parentFromOwnerElement(HTMLFrameOwnerElement* ownerElement)
@@ -153,15 +136,14 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
if (!ownerElement)
page->setMainFrame(this);
else {
- // FIXME: Frames were originally created with a refcount of 1.
- // Leave this ref call here until we can straighten that out.
- ref();
page->incrementFrameCount();
+ // Make sure we will not end up with two frames referencing the same owner element.
+ ASSERT((!(ownerElement->m_contentFrame)) || (ownerElement->m_contentFrame->ownerElement() != ownerElement));
ownerElement->m_contentFrame = this;
}
#ifndef NDEBUG
- ++FrameCounter::count;
+ frameCounter.increment();
#endif
}
@@ -169,11 +151,6 @@ Frame::~Frame()
{
setView(0);
loader()->clearRecordedFormValues();
-
-#if PLATFORM(MAC)
- setBridge(0);
-#endif
-
loader()->cancelAndClear();
// FIXME: We should not be doing all this work inside the destructor
@@ -181,22 +158,26 @@ Frame::~Frame()
ASSERT(!d->m_lifeSupportTimer.isActive());
#ifndef NDEBUG
- --FrameCounter::count;
+ frameCounter.decrement();
#endif
- if (d->m_jscript && d->m_jscript->haveGlobalObject())
- static_cast<KJS::Window*>(d->m_jscript->globalObject())->disconnectFrame();
+ if (d->m_script.haveWindowShell())
+ d->m_script.windowShell()->disconnectFrame();
disconnectOwnerElement();
if (d->m_domWindow)
d->m_domWindow->disconnectFrame();
+
+ HashSet<DOMWindow*>::iterator end = d->m_liveFormerWindows.end();
+ for (HashSet<DOMWindow*>::iterator it = d->m_liveFormerWindows.begin(); it != end; ++it)
+ (*it)->disconnectFrame();
if (d->m_view) {
d->m_view->hide();
d->m_view->clearFrame();
}
-
+
ASSERT(!d->m_lifeSupportTimer.isActive());
#if FRAME_LOADS_USER_STYLESHEET
@@ -209,12 +190,12 @@ Frame::~Frame()
void Frame::init()
{
- d->m_loader->init();
+ d->m_loader.init();
}
FrameLoader* Frame::loader() const
{
- return d->m_loader;
+ return &d->m_loader;
}
FrameView* Frame::view() const
@@ -224,6 +205,14 @@ FrameView* Frame::view() const
void Frame::setView(FrameView* view)
{
+#if PLATFORM(ANDROID)
+ if (!view && d->m_view) {
+ // FIXME(for Cary): This is moved from FrameAndroid destructor. Do we
+ // need to call removeFrameGeneration per Frame or per FrameView?
+ android::WebViewCore::getWebViewCore(d->m_view.get())->removeFrameGeneration(this);
+ }
+#endif
+
// Detach the document now, so any onUnload handlers get run - if
// we wait until the view is destroyed, then things won't be
// hooked up enough for some JavaScript calls to work.
@@ -243,18 +232,14 @@ void Frame::setView(FrameView* view)
loader()->resetMultipleFormSubmissionProtection();
}
-KJSProxy *Frame::scriptProxy()
+ScriptController* Frame::script()
{
- if (!d->m_jscript)
- d->m_jscript = new KJSProxy(this);
- return d->m_jscript;
+ return &d->m_script;
}
-Document *Frame::document() const
+Document* Frame::document() const
{
- if (d)
- return d->m_doc.get();
- return 0;
+ return d->m_doc.get();
}
void Frame::setDocument(PassRefPtr<Document> newDoc)
@@ -265,15 +250,14 @@ void Frame::setDocument(PassRefPtr<Document> newDoc)
}
d->m_doc = newDoc;
- if (d->m_doc && selectionController()->isFocusedAndActive())
+ if (d->m_doc && selection()->isFocusedAndActive())
setUseSecureKeyboardEntry(d->m_doc->useSecureKeyboardEntryWhenActive());
if (d->m_doc && !d->m_doc->attached())
d->m_doc->attach();
-
- // Remove the cached 'document' property, which is now stale.
- if (d->m_jscript)
- d->m_jscript->clearDocumentWrapper();
+
+ // Update the cached 'document' property, which is now stale.
+ d->m_script.updateDocument();
}
Settings* Frame::settings() const
@@ -283,7 +267,7 @@ Settings* Frame::settings() const
String Frame::selectedText() const
{
- return plainText(selectionController()->toRange().get());
+ return plainText(selection()->toRange().get());
}
IntRect Frame::firstRectForRange(Range* range) const
@@ -292,11 +276,16 @@ IntRect Frame::firstRectForRange(Range* range) const
ExceptionCode ec = 0;
ASSERT(range->startContainer(ec));
ASSERT(range->endContainer(ec));
- IntRect startCaretRect = range->startContainer(ec)->renderer()->caretRect(range->startOffset(ec), DOWNSTREAM, &extraWidthToEndOfLine);
- ASSERT(!ec);
- IntRect endCaretRect = range->endContainer(ec)->renderer()->caretRect(range->endOffset(ec), UPSTREAM);
- ASSERT(!ec);
-
+ InlineBox* startInlineBox;
+ int startCaretOffset;
+ range->startPosition().getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset);
+ IntRect startCaretRect = range->startContainer(ec)->renderer()->caretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine);
+
+ InlineBox* endInlineBox;
+ int endCaretOffset;
+ range->endPosition().getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset);
+ IntRect endCaretRect = range->endContainer(ec)->renderer()->caretRect(endInlineBox, endCaretOffset);
+
if (startCaretRect.y() == endCaretRect.y()) {
// start and end are on the same line
return IntRect(min(startCaretRect.x(), endCaretRect.x()),
@@ -312,7 +301,7 @@ IntRect Frame::firstRectForRange(Range* range) const
startCaretRect.height());
}
-SelectionController* Frame::selectionController() const
+SelectionController* Frame::selection() const
{
return &d->m_selectionController;
}
@@ -338,28 +327,28 @@ SelectionController* Frame::dragCaretController() const
}
-AnimationController* Frame::animationController() const
+AnimationController* Frame::animation() const
{
return &d->m_animationController;
}
-static RegularExpression *createRegExpForLabels(const Vector<String>& labels)
+static RegularExpression* createRegExpForLabels(const Vector<String>& labels)
{
// REVIEW- version of this call in FrameMac.mm caches based on the NSArray ptrs being
// the same across calls. We can't do that.
static RegularExpression wordRegExp = RegularExpression("\\w");
- DeprecatedString pattern("(");
+ String pattern("(");
unsigned int numLabels = labels.size();
unsigned int i;
for (i = 0; i < numLabels; i++) {
- DeprecatedString label = labels[i].deprecatedString();
+ String label = labels[i];
bool startsWithWordChar = false;
bool endsWithWordChar = false;
if (label.length() != 0) {
- startsWithWordChar = wordRegExp.search(label.at(0)) >= 0;
- endsWithWordChar = wordRegExp.search(label.at(label.length() - 1)) >= 0;
+ startsWithWordChar = wordRegExp.search(label.substring(0, 1)) >= 0;
+ endsWithWordChar = wordRegExp.search(label.substring(label.length() - 1, 1)) >= 0;
}
if (i != 0)
@@ -395,10 +384,10 @@ String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellE
for (Node* n = aboveCell->firstChild(); n; n = n->traverseNextNode(aboveCell)) {
if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
// For each text chunk, run the regexp
- DeprecatedString nodeString = n->nodeValue().deprecatedString();
+ String nodeString = n->nodeValue();
int pos = regExp->searchRev(nodeString);
if (pos >= 0)
- return nodeString.mid(pos, regExp->matchedLength());
+ return nodeString.substring(pos, regExp->matchedLength());
}
}
}
@@ -442,15 +431,14 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
searchedCellAbove = true;
} else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
// For each text chunk, run the regexp
- DeprecatedString nodeString = n->nodeValue().deprecatedString();
+ String nodeString = n->nodeValue();
// add 100 for slop, to make it more likely that we'll search whole nodes
if (lengthSearched + nodeString.length() > maxCharsSearched)
nodeString = nodeString.right(charsSearchedThreshold - lengthSearched);
int pos = regExp->searchRev(nodeString);
if (pos >= 0)
- return nodeString.mid(pos, regExp->matchedLength());
- else
- lengthSearched += nodeString.length();
+ return nodeString.substring(pos, regExp->matchedLength());
+ lengthSearched += nodeString.length();
}
}
@@ -464,9 +452,12 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* element)
{
- DeprecatedString name = element->getAttribute(nameAttr).deprecatedString();
+ String name = element->getAttribute(nameAttr);
+ if (name.isEmpty())
+ return String();
+
// Make numbers and _'s in field names behave like word boundaries, e.g., "address2"
- name.replace(RegularExpression("\\d"), " ");
+ replace(name, RegularExpression("\\d"), " ");
name.replace('_', ' ');
OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
@@ -484,12 +475,12 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e
bestPos = pos;
bestLength = length;
}
- start = pos+1;
+ start = pos + 1;
}
} while (pos != -1);
if (bestPos != -1)
- return name.mid(bestPos, bestLength);
+ return name.substring(bestPos, bestLength);
return String();
}
@@ -511,8 +502,8 @@ void Frame::setMark(const Selection& s)
void Frame::notifyRendererOfSelectionChange(bool userTriggered)
{
RenderObject* renderer = 0;
- if (selectionController()->rootEditableElement())
- renderer = selectionController()->rootEditableElement()->shadowAncestorNode()->renderer();
+ if (selection()->rootEditableElement())
+ renderer = selection()->rootEditableElement()->shadowAncestorNode()->renderer();
// If the current selection is in a textfield or textarea, notify the renderer that the selection has changed
if (renderer && (renderer->isTextArea() || renderer->isTextField()))
@@ -521,7 +512,7 @@ void Frame::notifyRendererOfSelectionChange(bool userTriggered)
void Frame::invalidateSelection()
{
- selectionController()->setNeedsLayout();
+ selection()->setNeedsLayout();
selectionLayoutChanged();
}
@@ -536,10 +527,10 @@ void Frame::setCaretVisible(bool flag)
void Frame::clearCaretRectIfNeeded()
{
-#ifndef ANDROID_DRAW_OWN_CARET
+#if ENABLE(TEXT_CARET)
if (d->m_caretPaint) {
d->m_caretPaint = false;
- selectionController()->invalidateCaretRect();
+ selection()->invalidateCaretRect();
}
#endif
}
@@ -559,10 +550,10 @@ static bool isFrameElement(const Node *n)
void Frame::setFocusedNodeIfNeeded()
{
- if (!document() || selectionController()->isNone() || !selectionController()->isFocusedAndActive())
+ if (!document() || selection()->isNone() || !selection()->isFocusedAndActive())
return;
- Node* target = selectionController()->rootEditableElement();
+ Node* target = selection()->rootEditableElement();
if (target) {
RenderObject* renderer = target->renderer();
@@ -586,11 +577,11 @@ void Frame::setFocusedNodeIfNeeded()
void Frame::selectionLayoutChanged()
{
- bool caretRectChanged = selectionController()->recomputeCaretRect();
+ bool caretRectChanged = selection()->recomputeCaretRect();
-#ifndef ANDROID_DRAW_OWN_CARET
+#if ENABLE(TEXT_CARET)
bool shouldBlink = d->m_caretVisible
- && selectionController()->isCaret() && selectionController()->isContentEditable();
+ && selection()->isCaret() && selection()->isContentEditable();
shouldBlink = false;
// If the caret moved, stop the blink timer so we can restart with a
@@ -604,19 +595,19 @@ void Frame::selectionLayoutChanged()
d->m_caretBlinkTimer.startRepeating(theme()->caretBlinkFrequency());
if (!d->m_caretPaint) {
d->m_caretPaint = true;
- selectionController()->invalidateCaretRect();
+ selection()->invalidateCaretRect();
}
}
#else
- if (caretRectChanged == false)
+ if (!caretRectChanged)
return;
#endif
- if (!renderer())
+ RenderView* canvas = contentRenderer();
+ if (!canvas)
return;
- RenderView* canvas = static_cast<RenderView*>(renderer());
- Selection selection = selectionController()->selection();
+ Selection selection = this->selection()->selection();
if (!selection.isRange())
canvas->clearSelection();
@@ -625,10 +616,10 @@ void Frame::selectionLayoutChanged()
// Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', and that 'bar' is selected. If we pass [foo, 3]
// as the start of the selection, the selection painting code will think that content on the line containing 'foo' is selected
// and will fill the gap before 'bar'.
- Position startPos = selection.visibleStart().deepEquivalent();
+ Position startPos = selection.start();
if (startPos.downstream().isCandidate())
startPos = startPos.downstream();
- Position endPos = selection.visibleEnd().deepEquivalent();
+ Position endPos = selection.end();
if (endPos.upstream().isCandidate())
endPos = endPos.upstream();
@@ -644,28 +635,28 @@ void Frame::selectionLayoutChanged()
void Frame::caretBlinkTimerFired(Timer<Frame>*)
{
-#ifndef ANDROID_DRAW_OWN_CARET
+#if ENABLE(TEXT_CARET)
ASSERT(d->m_caretVisible);
- ASSERT(selectionController()->isCaret());
+ ASSERT(selection()->isCaret());
bool caretPaint = d->m_caretPaint;
- if (selectionController()->isCaretBlinkingSuspended() && caretPaint)
+ if (selection()->isCaretBlinkingSuspended() && caretPaint)
return;
d->m_caretPaint = !caretPaint;
- selectionController()->invalidateCaretRect();
+ selection()->invalidateCaretRect();
#endif
}
void Frame::paintCaret(GraphicsContext* p, const IntRect& rect) const
{
-#ifndef ANDROID_DRAW_OWN_CARET
+#if ENABLE(TEXT_CARET)
if (d->m_caretPaint && d->m_caretVisible)
- selectionController()->paintCaret(p, rect);
+ selection()->paintCaret(p, rect);
#endif
}
void Frame::paintDragCaret(GraphicsContext* p, const IntRect& rect) const
{
-#ifndef ANDROID_DRAW_OWN_CARET
+#if ENABLE(TEXT_CARET)
SelectionController* dragCaretController = d->m_page->dragCaretController();
ASSERT(dragCaretController->selection().isCaret());
if (dragCaretController->selection().start().node()->document()->frame() == this)
@@ -673,35 +664,68 @@ void Frame::paintDragCaret(GraphicsContext* p, const IntRect& rect) const
#endif
}
-int Frame::zoomFactor() const
+float Frame::zoomFactor() const
+{
+ return d->m_zoomFactor;
+}
+
+bool Frame::isZoomFactorTextOnly() const
{
- return d->m_zoomFactor;
+ return d->m_page->settings()->zoomsTextOnly();
}
-void Frame::setZoomFactor(int percent)
+bool Frame::shouldApplyTextZoom() const
+{
+ if (d->m_zoomFactor == 1.0f || !isZoomFactorTextOnly())
+ return false;
+#if ENABLE(SVG)
+ if (d->m_doc && d->m_doc->isSVGDocument())
+ return false;
+#endif
+ return true;
+}
+
+bool Frame::shouldApplyPageZoom() const
+{
+ if (d->m_zoomFactor == 1.0f || isZoomFactorTextOnly())
+ return false;
+#if ENABLE(SVG)
+ if (d->m_doc && d->m_doc->isSVGDocument())
+ return false;
+#endif
+ return true;
+}
+
+void Frame::setZoomFactor(float percent, bool isTextOnly)
{
- if (d->m_zoomFactor == percent)
- return;
+ if (d->m_zoomFactor == percent && isZoomFactorTextOnly())
+ return;
#if ENABLE(SVG)
+ // SVG doesn't care if the zoom factor is text only. It will always apply a
+ // zoom to the whole SVG.
if (d->m_doc && d->m_doc->isSVGDocument()) {
if (!static_cast<SVGDocument*>(d->m_doc.get())->zoomAndPanEnabled())
return;
d->m_zoomFactor = percent;
+ d->m_page->settings()->setZoomsTextOnly(true); // We do this to avoid doing any scaling of CSS pixels, since the SVG has its own notion of zoom.
if (d->m_doc->renderer())
d->m_doc->renderer()->repaint();
return;
}
#endif
- 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);
+ d->m_zoomFactor = percent;
+ d->m_page->settings()->setZoomsTextOnly(isTextOnly);
+
+ 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, isTextOnly);
- if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout())
- view()->layout();
+ if (d->m_doc && d->m_doc->renderer() && d->m_doc->renderer()->needsLayout() && view()->didFirstLayout())
+ view()->layout();
}
void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
@@ -751,7 +775,8 @@ void Frame::setNeedsReapplyStyles()
// Invalidate the FrameView so that FrameView::layout will get called,
// which calls reapplyStyles.
- view()->invalidate();
+ if (view())
+ view()->invalidate();
}
bool Frame::needsReapplyStyles() const
@@ -787,7 +812,7 @@ void Frame::reapplyStyles()
bool Frame::shouldChangeSelection(const Selection& newSelection) const
{
- return shouldChangeSelection(selectionController()->selection(), newSelection, newSelection.affinity(), false);
+ return shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false);
}
bool Frame::shouldChangeSelection(const Selection& oldSelection, const Selection& newSelection, EAffinity affinity, bool stillSelecting) const
@@ -820,7 +845,7 @@ void Frame::setUseSecureKeyboardEntry(bool)
void Frame::updateSecureKeyboardEntryIfActive()
{
- if (selectionController()->isFocusedAndActive())
+ if (selection()->isFocusedAndActive())
setUseSecureKeyboardEntry(d->m_doc->useSecureKeyboardEntryWhenActive());
}
@@ -853,15 +878,14 @@ void Frame::computeAndSetTypingStyle(CSSStyleDeclaration *style, EditAction edit
mutableStyle = typingStyle();
}
- Node *node = selectionController()->selection().visibleStart().deepEquivalent().node();
- CSSComputedStyleDeclaration computedStyle(node);
- computedStyle.diff(mutableStyle.get());
+ Node* node = selection()->selection().visibleStart().deepEquivalent().node();
+ computedStyle(node)->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)
- applyCommand(new ApplyStyleCommand(document(), blockStyle.get(), editingAction));
+ applyCommand(ApplyStyleCommand::create(document(), blockStyle.get(), editingAction));
// Set the remaining style as the typing style.
d->m_typingStyle = mutableStyle.release();
@@ -885,17 +909,17 @@ String Frame::selectionStartStylePropertyValue(int stylePropertyID) const
return value;
}
-CSSComputedStyleDeclaration *Frame::selectionComputedStyle(Node *&nodeToRemove) const
+PassRefPtr<CSSComputedStyleDeclaration> Frame::selectionComputedStyle(Node*& nodeToRemove) const
{
nodeToRemove = 0;
if (!document())
return 0;
- if (selectionController()->isNone())
+ if (selection()->isNone())
return 0;
- RefPtr<Range> range(selectionController()->toRange());
+ RefPtr<Range> range(selection()->toRange());
Position pos = range->editingStartPosition();
Element *elem = pos.element();
@@ -932,7 +956,7 @@ CSSComputedStyleDeclaration *Frame::selectionComputedStyle(Node *&nodeToRemove)
nodeToRemove = styleElement.get();
}
- return new CSSComputedStyleDeclaration(styleElement);
+ return computedStyle(styleElement.release());
}
void Frame::textFieldDidBeginEditing(Element* e)
@@ -1006,11 +1030,11 @@ void Frame::applyEditingStyleToElement(Element* element) const
ASSERT(style);
ExceptionCode ec = 0;
- style->setProperty(CSS_PROP_WORD_WRAP, "break-word", false, ec);
+ style->setProperty(CSSPropertyWordWrap, "break-word", false, ec);
ASSERT(ec == 0);
- style->setProperty(CSS_PROP__WEBKIT_NBSP_MODE, "space", false, ec);
+ style->setProperty(CSSPropertyWebkitNbspMode, "space", false, ec);
ASSERT(ec == 0);
- style->setProperty(CSS_PROP__WEBKIT_LINE_BREAK, "after-white-space", false, ec);
+ style->setProperty(CSSPropertyWebkitLineBreak, "after-white-space", false, ec);
ASSERT(ec == 0);
}
@@ -1058,141 +1082,88 @@ void Frame::lifeSupportTimerFired(Timer<Frame>*)
deref();
}
-KJS::Bindings::RootObject* Frame::bindingRootObject()
+void Frame::clearDOMWindow()
{
- if (!scriptProxy()->isEnabled())
- return 0;
-
- if (!d->m_bindingRootObject) {
- JSLock lock;
- d->m_bindingRootObject = KJS::Bindings::RootObject::create(0, scriptProxy()->globalObject());
+ if (d->m_domWindow) {
+ d->m_liveFormerWindows.add(d->m_domWindow.get());
+ d->m_domWindow->clear();
}
- return d->m_bindingRootObject.get();
+ d->m_domWindow = 0;
}
-PassRefPtr<KJS::Bindings::RootObject> Frame::createRootObject(void* nativeHandle, KJS::JSGlobalObject* globalObject)
-{
- RootObjectMap::iterator it = d->m_rootObjects.find(nativeHandle);
- if (it != d->m_rootObjects.end())
- return it->second;
-
- RefPtr<KJS::Bindings::RootObject> rootObject = KJS::Bindings::RootObject::create(nativeHandle, globalObject);
-
- d->m_rootObjects.set(nativeHandle, rootObject);
- return rootObject.release();
-}
-
-#if USE(NPOBJECT)
-NPObject* Frame::windowScriptNPObject()
-{
- if (!d->m_windowScriptNPObject) {
- if (scriptProxy()->isEnabled()) {
- // JavaScript is enabled, so there is a JavaScript window object. Return an NPObject bound to the window
- // object.
- KJS::JSLock lock;
- KJS::JSObject* win = KJS::Window::retrieveWindow(this);
- ASSERT(win);
- KJS::Bindings::RootObject* root = bindingRootObject();
- d->m_windowScriptNPObject = _NPN_CreateScriptObject(0, win, root);
- } else {
- // JavaScript is not enabled, so we cannot bind the NPObject to the JavaScript window object.
- // Instead, we create an NPObject of a different class, one which is not bound to a JavaScript object.
- d->m_windowScriptNPObject = _NPN_CreateNoScriptObject();
- }
- }
-
- return d->m_windowScriptNPObject;
-}
-#endif
-
-void Frame::clearScriptProxy()
+RenderView* Frame::contentRenderer() const
{
- if (d->m_jscript)
- d->m_jscript->clear();
+ Document* doc = document();
+ if (!doc)
+ return 0;
+ RenderObject* object = doc->renderer();
+ if (!object)
+ return 0;
+ ASSERT(object->isRenderView());
+ return static_cast<RenderView*>(object);
}
-void Frame::clearDOMWindow()
+HTMLFrameOwnerElement* Frame::ownerElement() const
{
- if (d->m_domWindow)
- d->m_domWindow->clear();
+ return d->m_ownerElement;
}
-void Frame::cleanupScriptObjectsForPlugin(void* nativeHandle)
+RenderPart* Frame::ownerRenderer() const
{
- RootObjectMap::iterator it = d->m_rootObjects.find(nativeHandle);
-
- if (it == d->m_rootObjects.end())
- return;
-
- it->second->invalidate();
- d->m_rootObjects.remove(it);
+ HTMLFrameOwnerElement* ownerElement = d->m_ownerElement;
+ if (!ownerElement)
+ return 0;
+ RenderObject* object = ownerElement->renderer();
+ if (!object)
+ return 0;
+ // FIXME: If <object> is ever fixed to disassociate itself from frames
+ // that it has started but canceled, then this can turn into an ASSERT
+ // since d->m_ownerElement would be 0 when the load is canceled.
+ // https://bugs.webkit.org/show_bug.cgi?id=18585
+ if (!object->isRenderPart())
+ return 0;
+ return static_cast<RenderPart*>(object);
}
-
-void Frame::clearScriptObjects()
-{
- JSLock lock;
-
- RootObjectMap::const_iterator end = d->m_rootObjects.end();
- for (RootObjectMap::const_iterator it = d->m_rootObjects.begin(); it != end; ++it)
- it->second->invalidate();
-
- d->m_rootObjects.clear();
- if (d->m_bindingRootObject) {
- d->m_bindingRootObject->invalidate();
- d->m_bindingRootObject = 0;
- }
-
-#if USE(NPOBJECT)
- if (d->m_windowScriptNPObject) {
- // Call _NPN_DeallocateObject() instead of _NPN_ReleaseObject() so that we don't leak if a plugin fails to release the window
- // script object properly.
- // This shouldn't cause any problems for plugins since they should have already been stopped and destroyed at this point.
- _NPN_DeallocateObject(d->m_windowScriptNPObject);
- d->m_windowScriptNPObject = 0;
- }
-#endif
-
- clearPlatformScriptObjects();
+bool Frame::isDisconnected() const
+{
+ return d->m_isDisconnected;
}
-RenderObject *Frame::renderer() const
+void Frame::setIsDisconnected(bool isDisconnected)
{
- Document *doc = document();
- return doc ? doc->renderer() : 0;
+ d->m_isDisconnected = isDisconnected;
}
-HTMLFrameOwnerElement* Frame::ownerElement() const
+bool Frame::excludeFromTextSearch() const
{
- return d->m_ownerElement;
+ return d->m_excludeFromTextSearch;
}
-RenderPart* Frame::ownerRenderer()
+void Frame::setExcludeFromTextSearch(bool exclude)
{
- HTMLFrameOwnerElement* ownerElement = d->m_ownerElement;
- if (!ownerElement)
- return 0;
- return static_cast<RenderPart*>(ownerElement->renderer());
+ d->m_excludeFromTextSearch = exclude;
}
// returns FloatRect because going through IntRect would truncate any floats
FloatRect Frame::selectionRect(bool clipToVisibleContent) const
{
- RenderView *root = static_cast<RenderView*>(renderer());
- if (!root)
+ RenderView* root = contentRenderer();
+ FrameView* view = d->m_view.get();
+ if (!root || !view)
return IntRect();
IntRect selectionRect = root->selectionRect(clipToVisibleContent);
- return clipToVisibleContent ? intersection(selectionRect, d->m_view->visibleContentRect()) : selectionRect;
+ return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;
}
void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleContent) const
{
- RenderView *root = static_cast<RenderView*>(renderer());
+ RenderView* root = contentRenderer();
if (!root)
return;
- RefPtr<Range> selectedRange = selectionController()->toRange();
+ RefPtr<Range> selectedRange = selection()->toRange();
Vector<IntRect> intRects;
selectedRange->addLineBoxRects(intRects, true);
@@ -1224,7 +1195,7 @@ static HTMLFormElement *scanForForm(Node *start)
if (n->hasTagName(formTag))
return static_cast<HTMLFormElement*>(n);
else if (n->isHTMLElement() && static_cast<HTMLElement*>(n)->isGenericFormElement())
- return static_cast<HTMLGenericFormElement*>(n)->form();
+ return static_cast<HTMLFormControlElement*>(n)->form();
else if (n->hasTagName(frameTag) || n->hasTagName(iframeTag)) {
Node *childDoc = static_cast<HTMLFrameElementBase*>(n)->contentDocument();
if (HTMLFormElement *frameResult = scanForForm(childDoc))
@@ -1240,7 +1211,7 @@ 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->focusedNode() : 0;
if (!start)
- start = selectionController()->start().node();
+ start = selection()->start().node();
// try walking up the node tree to find a form element
Node *n;
@@ -1249,7 +1220,7 @@ HTMLFormElement *Frame::currentForm() const
return static_cast<HTMLFormElement*>(n);
else if (n->isHTMLElement()
&& static_cast<HTMLElement*>(n)->isGenericFormElement())
- return static_cast<HTMLGenericFormElement*>(n)->form();
+ return static_cast<HTMLFormControlElement*>(n)->form();
}
// try walking forward in the node tree to find a form element
@@ -1261,12 +1232,12 @@ void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
{
IntRect rect;
- switch (selectionController()->state()) {
+ switch (selection()->state()) {
case Selection::NONE:
return;
case Selection::CARET:
- rect = selectionController()->caretRect();
+ rect = selection()->caretRect();
break;
case Selection::RANGE:
@@ -1274,7 +1245,7 @@ void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
break;
}
- Position start = selectionController()->start();
+ Position start = selection()->start();
ASSERT(start.node());
if (start.node() && start.node()->renderer()) {
@@ -1282,87 +1253,27 @@ void Frame::revealSelection(const RenderLayer::ScrollAlignment& alignment) const
// the selection rect could intersect more than just that.
// See <rdar://problem/4799899>.
if (RenderLayer *layer = start.node()->renderer()->enclosingLayer())
- layer->scrollRectToVisible(rect, alignment, alignment);
+ layer->scrollRectToVisible(rect, false, alignment, alignment);
}
}
void Frame::revealCaret(const RenderLayer::ScrollAlignment& alignment) const
{
- if (selectionController()->isNone())
+ if (selection()->isNone())
return;
- Position extent = selectionController()->extent();
+ Position extent = selection()->extent();
if (extent.node() && extent.node()->renderer()) {
IntRect extentRect = VisiblePosition(extent).caretRect();
RenderLayer* layer = extent.node()->renderer()->enclosingLayer();
if (layer)
- layer->scrollRectToVisible(extentRect, alignment, alignment);
+ layer->scrollRectToVisible(extentRect, false, alignment, alignment);
}
}
-// 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_paintRestriction == PaintRestrictionSelectionOnly || d->m_paintRestriction == PaintRestrictionSelectionOnlyBlackText)
- 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
-
- bool isTopLevelPainter = !s_currentPaintTimeStamp;
- if (isTopLevelPainter)
- s_currentPaintTimeStamp = currentTime();
-
- if (renderer()) {
- ASSERT(d->m_view && !d->m_view->needsLayout());
- ASSERT(!d->m_isPainting);
-
- d->m_isPainting = true;
-
- // d->m_elementToDraw is used to draw only one element
- RenderObject *eltRenderer = d->m_elementToDraw ? d->m_elementToDraw->renderer() : 0;
- if (d->m_paintRestriction == PaintRestrictionNone)
- renderer()->document()->invalidateRenderedRectsForMarkersInRect(rect);
- renderer()->layer()->paint(p, rect, d->m_paintRestriction, eltRenderer);
-
- d->m_isPainting = false;
-
- // Regions may have changed as a result of the visibility/z-index of element changing.
- if (renderer()->document()->dashboardRegionsDirty())
- renderer()->view()->frameView()->updateDashboardRegions();
- } else
- LOG_ERROR("called Frame::paint with nil renderer");
-
- if (isTopLevelPainter)
- s_currentPaintTimeStamp = 0;
-}
-
-void Frame::setPaintRestriction(PaintRestriction pr)
-{
- d->m_paintRestriction = pr;
-}
-
-bool Frame::isPainting() const
-{
- return d->m_isPainting;
-}
-
void Frame::adjustPageHeight(float *newBottom, float oldTop, float oldBottom, float bottomLimit)
{
- RenderView *root = static_cast<RenderView*>(document()->renderer());
+ RenderView* root = contentRenderer();
if (root) {
// Use a context with painting disabled.
GraphicsContext context((PlatformGraphicsContext*)0);
@@ -1436,7 +1347,7 @@ void Frame::forceLayoutWithPageWidthRange(float minPageWidth, float maxPageWidth
void Frame::sendResizeEvent()
{
if (Document* doc = document())
- doc->dispatchWindowEvent(EventNames::resizeEvent, false, false);
+ doc->dispatchWindowEvent(eventNames().resizeEvent, false, false);
}
void Frame::sendScrollEvent()
@@ -1448,25 +1359,25 @@ void Frame::sendScrollEvent()
Document* doc = document();
if (!doc)
return;
- doc->dispatchHTMLEvent(scrollEvent, true, false);
+ doc->dispatchEventForType(eventNames().scrollEvent, true, false);
}
-void Frame::clearTimers(FrameView *view)
+void Frame::clearTimers(FrameView *view, Document *document)
{
if (view) {
view->unscheduleRelayout();
if (view->frame()) {
- Document* document = view->frame()->document();
if (document && document->renderer() && document->renderer()->hasLayer())
document->renderer()->layer()->suspendMarquees();
- view->frame()->animationController()->suspendAnimations();
+ view->frame()->animation()->suspendAnimations(document);
+ view->frame()->eventHandler()->stopAutoscrollTimer();
}
}
}
void Frame::clearTimers()
{
- clearTimers(d->m_view.get());
+ clearTimers(d->m_view.get(), document());
}
RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
@@ -1475,10 +1386,10 @@ RenderStyle *Frame::styleForSelectionStart(Node *&nodeToRemove) const
if (!document())
return 0;
- if (selectionController()->isNone())
+ if (selection()->isNone())
return 0;
- Position pos = selectionController()->selection().visibleStart().deepEquivalent();
+ Position pos = selection()->selection().visibleStart().deepEquivalent();
if (!pos.isCandidate())
return 0;
Node *node = pos.node();
@@ -1511,14 +1422,14 @@ 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 || !selectionController()->isNone() || !isContentEditable())
+ if (!doc || !selection()->isNone() || !isContentEditable())
return;
Node* node = doc->documentElement();
while (node && !node->hasTagName(bodyTag))
node = node->traverseNextNode();
if (node)
- selectionController()->setSelection(Selection(Position(node, 0), DOWNSTREAM));
+ selection()->setSelection(Selection(Position(node, 0), DOWNSTREAM));
}
bool Frame::inViewSourceMode() const
@@ -1543,51 +1454,75 @@ UChar Frame::backslashAsCurrencySymbol() const
return decoder->encoding().backslashAsCurrencySymbol();
}
-static bool isInShadowTree(Node* node)
-{
- for (Node* n = node; n; n = n->parentNode())
- if (n->isShadowNode())
- return true;
- return false;
-}
-
// Searches from the beginning of the document if nothing is selected.
bool Frame::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection)
{
if (target.isEmpty() || !document())
return false;
+ if (excludeFromTextSearch())
+ return false;
+
// Start from an edge of the selection, if there's a selection that's not in shadow content. Which edge
// is used depends on whether we're searching forward or backward, and whether startInSelection is set.
RefPtr<Range> searchRange(rangeOfContents(document()));
- Selection selection(selectionController()->selection());
- Node* selectionBaseNode = selection.base().node();
-
- // FIXME 3099526: We don't search in the shadow trees (e.g. text fields and textareas), though we'd like to
- // someday. If we don't explicitly skip them here, we'll miss hits in the regular content.
- bool selectionIsInMainContent = selectionBaseNode && !isInShadowTree(selectionBaseNode);
+ Selection selection = this->selection()->selection();
+
+ if (forward)
+ setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());
+ else
+ setEnd(searchRange.get(), startInSelection ? selection.visibleEnd() : selection.visibleStart());
- if (selectionIsInMainContent) {
+ Node* shadowTreeRoot = selection.shadowTreeRootNode();
+ if (shadowTreeRoot) {
+ ExceptionCode ec = 0;
if (forward)
- setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());
+ searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
else
- setEnd(searchRange.get(), startInSelection ? selection.visibleEnd() : selection.visibleStart());
+ searchRange->setStart(shadowTreeRoot, 0, ec);
}
+
RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag));
// If we started in the selection and the found range exactly matches the existing selection, find again.
// Build a selection with the found range to remove collapsed whitespace.
// Compare ranges instead of selection objects to ignore the way that the current selection was made.
- if (startInSelection && selectionIsInMainContent && *Selection(resultRange.get()).toRange() == *selection.toRange()) {
+ if (startInSelection && *Selection(resultRange.get()).toRange() == *selection.toRange()) {
searchRange = rangeOfContents(document());
if (forward)
setStart(searchRange.get(), selection.visibleEnd());
else
setEnd(searchRange.get(), selection.visibleStart());
+
+ if (shadowTreeRoot) {
+ ExceptionCode ec = 0;
+ if (forward)
+ searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
+ else
+ searchRange->setStart(shadowTreeRoot, 0, ec);
+ }
+
resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
}
- int exception = 0;
+ ExceptionCode exception = 0;
+
+ // If nothing was found in the shadow tree, search in main content following the shadow tree.
+ if (resultRange->collapsed(exception) && shadowTreeRoot) {
+ searchRange = rangeOfContents(document());
+ if (forward)
+ searchRange->setStartAfter(shadowTreeRoot->shadowParentNode(), exception);
+ else
+ searchRange->setEndBefore(shadowTreeRoot->shadowParentNode(), exception);
+
+ resultRange = findPlainText(searchRange.get(), target, forward, caseFlag);
+ }
+ if (!editor()->insideVisibleArea(resultRange.get())) {
+ resultRange = editor()->nextVisibleRange(resultRange.get(), target, forward, caseFlag, wrapFlag);
+ if (!resultRange)
+ return false;
+ }
+
// If we didn't find anything and we're wrapping, search again in the entire document (this will
// redundantly re-search the area already searched in some cases).
if (resultRange->collapsed(exception) && wrapFlag) {
@@ -1601,7 +1536,7 @@ bool Frame::findString(const String& target, bool forward, bool caseFlag, bool w
if (resultRange->collapsed(exception))
return false;
- selectionController()->setSelection(Selection(resultRange.get(), DOWNSTREAM));
+ this->selection()->setSelection(Selection(resultRange.get(), DOWNSTREAM));
revealSelection();
return true;
}
@@ -1613,12 +1548,18 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig
RefPtr<Range> searchRange(rangeOfContents(document()));
- int exception = 0;
+ ExceptionCode exception = 0;
unsigned matchCount = 0;
do {
RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag));
- if (resultRange->collapsed(exception))
- break;
+ if (resultRange->collapsed(exception)) {
+ if (!resultRange->startContainer()->isInShadowTree())
+ break;
+
+ searchRange = rangeOfContents(document());
+ searchRange->setStartAfter(resultRange->startContainer()->shadowAncestorNode(), exception);
+ continue;
+ }
// 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.
@@ -1626,26 +1567,33 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig
if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
break;
- ++matchCount;
-
- document()->addMarker(resultRange.get(), DocumentMarker::TextMatch);
+ // Only treat the result as a match if it is visible
+ if (editor()->insideVisibleArea(resultRange.get())) {
+ ++matchCount;
+ document()->addMarker(resultRange.get(), DocumentMarker::TextMatch);
+ }
// Stop looking if we hit the specified limit. A limit of 0 means no limit.
if (limit > 0 && matchCount >= limit)
break;
setStart(searchRange.get(), newStart);
+ Node* shadowTreeRoot = searchRange->shadowTreeRootNode();
+ if (searchRange->collapsed(exception) && shadowTreeRoot)
+ searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), exception);
} while (true);
// Do a "fake" paint in order to execute the code that computes the rendered rect for
// each text match.
Document* doc = document();
- if (doc && d->m_view && renderer()) {
+ if (doc && d->m_view && contentRenderer()) {
doc->updateLayout(); // Ensure layout is up to date.
- IntRect visibleRect(enclosingIntRect(d->m_view->visibleContentRect()));
- GraphicsContext context((PlatformGraphicsContext*)0);
- context.setPaintingDisabled(true);
- paint(&context, visibleRect);
+ IntRect visibleRect = d->m_view->visibleContentRect();
+ if (!visibleRect.isEmpty()) {
+ GraphicsContext context((PlatformGraphicsContext*)0);
+ context.setPaintingDisabled(true);
+ d->m_view->paintContents(&context, visibleRect);
+ }
}
return matchCount;
@@ -1673,11 +1621,16 @@ FrameTree* Frame::tree() const
DOMWindow* Frame::domWindow() const
{
if (!d->m_domWindow)
- d->m_domWindow = new DOMWindow(const_cast<Frame*>(this));
+ d->m_domWindow = DOMWindow::create(const_cast<Frame*>(this));
return d->m_domWindow.get();
}
+void Frame::clearFormerDOMWindow(DOMWindow* window)
+{
+ d->m_liveFormerWindows.remove(window);
+}
+
Page* Frame::page() const
{
return d->m_page;
@@ -1693,22 +1646,27 @@ void Frame::pageDestroyed()
if (Frame* parent = tree()->parent())
parent->loader()->checkLoadComplete();
- if (d->m_page && d->m_page->focusController()->focusedFrame() == this)
- d->m_page->focusController()->setFocusedFrame(0);
+ // FIXME: It's unclear as to why this is called more than once, but it is,
+ // so page() could be NULL.
+ if (page() && page()->focusController()->focusedFrame() == this)
+ page()->focusController()->setFocusedFrame(0);
+
+ script()->clearWindowShell();
// This will stop any JS timers
- if (d->m_jscript && d->m_jscript->haveGlobalObject())
- if (KJS::Window* w = KJS::Window::retrieveWindow(this))
- w->disconnectFrame();
+ if (script()->haveWindowShell())
+ script()->windowShell()->disconnectFrame();
+
+ script()->clearScriptObjects();
- clearScriptObjects();
-
d->m_page = 0;
}
void Frame::disconnectOwnerElement()
{
if (d->m_ownerElement) {
+ if (Document* doc = document())
+ doc->clearAXObjectCache();
d->m_ownerElement->m_contentFrame = 0;
if (d->m_page)
d->m_page->decrementFrameCount();
@@ -1718,23 +1676,14 @@ void Frame::disconnectOwnerElement()
String Frame::documentTypeString() const
{
- if (Document *doc = document())
- if (DocumentType *doctype = doc->realDocType())
- return doctype->toString();
+ if (Document* doc = document()) {
+ if (DocumentType* doctype = doc->doctype())
+ return createMarkup(doctype);
+ }
return String();
}
-bool Frame::prohibitsScrolling() const
-{
- return d->m_prohibitsScrolling;
-}
-
-void Frame::setProhibitsScrolling(bool prohibit)
-{
- d->m_prohibitsScrolling = prohibit;
-}
-
void Frame::focusWindow()
{
if (!page())
@@ -1770,7 +1719,7 @@ bool Frame::shouldClose()
if (!body)
return true;
- RefPtr<BeforeUnloadEvent> beforeUnloadEvent = new BeforeUnloadEvent;
+ RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
beforeUnloadEvent->setTarget(doc);
doc->handleWindowEvent(beforeUnloadEvent.get(), false);
@@ -1803,8 +1752,8 @@ void Frame::respondToChangedSelection(const Selection& oldSelection, bool closeT
if (isContinuousSpellCheckingEnabled) {
Selection newAdjacentWords;
Selection newSelectedSentence;
- if (selectionController()->selection().isContentEditable()) {
- VisiblePosition newStart(selectionController()->selection().visibleStart());
+ if (selection()->selection().isContentEditable()) {
+ VisiblePosition newStart(selection()->selection().visibleStart());
newAdjacentWords = Selection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary));
if (isContinuousGrammarCheckingEnabled)
newSelectedSentence = Selection(startOfSentence(newStart), endOfSentence(newStart));
@@ -1867,7 +1816,7 @@ Document* Frame::documentAtPoint(const IntPoint& point)
IntPoint pt = view()->windowToContents(point);
HitTestResult result = HitTestResult(pt);
- if (renderer())
+ if (contentRenderer())
result = eventHandler()->hitTestResultAtPoint(pt, false);
return result.innerNode() ? result.innerNode()->document() : 0;
}
@@ -1876,41 +1825,66 @@ FramePrivate::FramePrivate(Page* page, Frame* parent, Frame* thisFrame, HTMLFram
FrameLoaderClient* frameLoaderClient)
: m_page(page)
, m_treeNode(thisFrame, parent)
+ , m_loader(thisFrame, frameLoaderClient)
, m_ownerElement(ownerElement)
- , m_jscript(0)
- , m_zoomFactor(parent ? parent->d->m_zoomFactor : 100)
+ , m_script(thisFrame)
+ , m_zoomFactor(parent ? parent->d->m_zoomFactor : 1.0f)
, m_selectionGranularity(CharacterGranularity)
, m_selectionController(thisFrame)
, m_caretBlinkTimer(thisFrame, &Frame::caretBlinkTimerFired)
, m_editor(thisFrame)
, m_eventHandler(thisFrame)
, m_animationController(thisFrame)
+ , m_lifeSupportTimer(thisFrame, &Frame::lifeSupportTimerFired)
, m_caretVisible(false)
, m_caretPaint(true)
- , m_isPainting(false)
- , m_lifeSupportTimer(thisFrame, &Frame::lifeSupportTimerFired)
- , m_loader(new FrameLoader(thisFrame, frameLoaderClient))
- , m_paintRestriction(PaintRestrictionNone)
, m_highlightTextMatches(false)
, m_inViewSourceMode(false)
- , frameCount(0)
- , m_prohibitsScrolling(false)
, m_needsReapplyStyles(false)
- , m_windowScriptNPObject(0)
+ , m_isDisconnected(false)
+ , m_excludeFromTextSearch(false)
#if FRAME_LOADS_USER_STYLESHEET
, m_userStyleSheetLoader(0)
#endif
-#if PLATFORM(MAC)
- , m_windowScriptObject(nil)
- , m_bridge(nil)
-#endif
{
}
FramePrivate::~FramePrivate()
{
- delete m_jscript;
- delete m_loader;
}
+#ifdef ANDROID_INSTRUMENT
+void Frame::resetTimeCounter() {
+ JSC::JSGlobalObject::resetTimeCounter();
+ resetLayoutTimeCounter();
+ resetPaintTimeCounter();
+ resetCSSTimeCounter();
+ resetParsingTimeCounter();
+ resetCalculateStyleTimeCounter();
+ resetFramebridgeTimeCounter();
+ resetSharedTimerTimeCounter();
+ resetResourceLoadTimeCounter();
+ resetWebViewCoreTimeCounter();
+ LOGD("*-* Start browser instrument\n");
+}
+
+void Frame::reportTimeCounter(String url, int total, int totalThreadTime)
+{
+ LOGD("*-* Total load time: %d ms, thread time: %d ms for %s\n",
+ total, totalThreadTime, url.utf8().data());
+ JSC::JSGlobalObject::reportTimeCounter();
+ reportLayoutTimeCounter();
+ reportPaintTimeCounter();
+ reportCSSTimeCounter();
+ reportParsingTimeCounter();
+ reportCalculateStyleTimeCounter();
+ reportFramebridgeTimeCounter();
+ reportSharedTimerTimeCounter();
+ reportResourceLoadTimeCounter();
+ reportWebViewCoreTimeCounter();
+ LOGD("Current cache has %d bytes live and %d bytes dead",
+ cache()->getLiveSize(), cache()->getDeadSize());
+}
+#endif
+
} // namespace WebCore