summaryrefslogtreecommitdiff
path: root/Source/WebCore/page/Frame.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/page/Frame.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/page/Frame.cpp')
-rw-r--r--Source/WebCore/page/Frame.cpp468
1 files changed, 193 insertions, 275 deletions
diff --git a/Source/WebCore/page/Frame.cpp b/Source/WebCore/page/Frame.cpp
index 4456c0d5a..990885027 100644
--- a/Source/WebCore/page/Frame.cpp
+++ b/Source/WebCore/page/Frame.cpp
@@ -5,7 +5,7 @@
* 2000 Simon Hausmann <hausmann@kde.org>
* 2000 Stefan Schimanski <1Stein@gmx.de>
* 2001 George Staikos <staikos@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2016 Apple Inc. All rights reserved.
* Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
@@ -30,9 +30,9 @@
#include "config.h"
#include "Frame.h"
-#include "AnimationController.h"
#include "ApplyStyleCommand.h"
#include "BackForwardController.h"
+#include "CSSAnimationController.h"
#include "CSSComputedStyleDeclaration.h"
#include "CSSPropertyNames.h"
#include "CachedCSSStyleSheet.h"
@@ -61,6 +61,7 @@
#include "HTMLFrameElementBase.h"
#include "HTMLNames.h"
#include "HTMLTableCellElement.h"
+#include "HTMLTableRowElement.h"
#include "HitTestResult.h"
#include "ImageBuffer.h"
#include "InspectorInstrumentation.h"
@@ -74,7 +75,7 @@
#include "NodeTraversal.h"
#include "Page.h"
#include "PageCache.h"
-#include "PageGroup.h"
+#include "RenderLayerCompositor.h"
#include "RenderTableCell.h"
#include "RenderText.h"
#include "RenderTextControl.h"
@@ -82,17 +83,20 @@
#include "RenderView.h"
#include "RenderWidget.h"
#include "RuntimeEnabledFeatures.h"
+#include "SVGDocument.h"
+#include "SVGDocumentExtensions.h"
#include "SVGNames.h"
#include "ScriptController.h"
#include "ScriptSourceCode.h"
#include "ScrollingCoordinator.h"
#include "Settings.h"
#include "StyleProperties.h"
-#include "TextIterator.h"
+#include "StyleScope.h"
#include "TextNodeTraversal.h"
#include "TextResourceDecoder.h"
#include "UserContentController.h"
#include "UserContentURLPattern.h"
+#include "UserScript.h"
#include "UserTypingGestureIndicator.h"
#include "VisibleUnits.h"
#include "WebKitFontFamilyNames.h"
@@ -103,25 +107,11 @@
#include "markup.h"
#include "npruntime_impl.h"
#include "runtime_root.h"
-#include <bindings/ScriptValue.h>
-#include <wtf/PassOwnPtr.h>
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/StdLibExtras.h>
+#include <wtf/text/StringBuilder.h>
#include <yarr/RegularExpression.h>
-#if USE(ACCELERATED_COMPOSITING)
-#include "RenderLayerCompositor.h"
-#endif
-
-#if ENABLE(SVG)
-#include "SVGDocument.h"
-#include "SVGDocumentExtensions.h"
-#endif
-
-#if USE(TILED_BACKING_STORE)
-#include "TiledBackingStore.h"
-#endif
-
#if PLATFORM(IOS)
#include "WKContentObservation.h"
#endif
@@ -168,22 +158,17 @@ Frame::Frame(Page& page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient&
, m_navigationScheduler(*this)
, m_ownerElement(ownerElement)
, m_script(std::make_unique<ScriptController>(*this))
- , m_editor(Editor::create(*this))
- , m_selection(adoptPtr(new FrameSelection(this)))
- , m_eventHandler(adoptPtr(new EventHandler(*this)))
- , m_animationController(std::make_unique<AnimationController>(*this))
+ , m_editor(std::make_unique<Editor>(*this))
+ , m_selection(std::make_unique<FrameSelection>(this))
+ , m_animationController(std::make_unique<CSSAnimationController>(*this))
#if PLATFORM(IOS)
- , m_overflowAutoScrollTimer(this, &Frame::overflowAutoScrollTimerFired)
+ , m_overflowAutoScrollTimer(*this, &Frame::overflowAutoScrollTimerFired)
, m_selectionChangeCallbacksDisabled(false)
- , m_timersPausedCount(0)
#endif
, m_pageZoomFactor(parentPageZoomFactor(this))
, m_textZoomFactor(parentTextZoomFactor(this))
-#if ENABLE(ORIENTATION_EVENTS)
- , m_orientation(0)
-#endif
- , m_inViewSourceMode(false)
, m_activeDOMObjectsAndAnimationsSuspendedCount(0)
+ , m_eventHandler(std::make_unique<EventHandler>(*this))
{
AtomicString::init();
HTMLNames::init();
@@ -196,12 +181,7 @@ Frame::Frame(Page& page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient&
XMLNames::init();
WebKitFontFamilyNames::init();
- if (!ownerElement) {
-#if USE(TILED_BACKING_STORE)
- // Top level frame only for now.
- setTiledBackingStoreEnabled(settings().tiledBackingStoreEnabled());
-#endif
- } else {
+ if (ownerElement) {
m_mainFrame.selfOnlyRef();
page.incrementSubframeCount();
ownerElement->setContentFrame(this);
@@ -211,29 +191,22 @@ Frame::Frame(Page& page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient&
frameCounter.increment();
#endif
- // FIXME: We should reconcile the iOS and OpenSource code below.
- Frame* parent = parentFromOwnerElement(ownerElement);
-#if PLATFORM(IOS)
- // Pause future timers if this frame is created when page is in pending state.
- if (parent && parent->timersPaused())
- setTimersPaused(true);
-#else
// Pause future ActiveDOMObjects if this frame is being created while the page is in a paused state.
+ Frame* parent = parentFromOwnerElement(ownerElement);
if (parent && parent->activeDOMObjectsAndAnimationsSuspended())
suspendActiveDOMObjectsAndAnimations();
-#endif
}
-PassRefPtr<Frame> Frame::create(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* client)
+Ref<Frame> Frame::create(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* client)
{
ASSERT(page);
ASSERT(client);
- return adoptRef(new Frame(*page, ownerElement, *client));
+ return adoptRef(*new Frame(*page, ownerElement, *client));
}
Frame::~Frame()
{
- setView(0);
+ setView(nullptr);
loader().cancelAndClear();
// FIXME: We should not be doing all this work inside the destructor
@@ -244,8 +217,8 @@ Frame::~Frame()
disconnectOwnerElement();
- for (auto& observer : m_destructionObservers)
- observer->frameDestroyed();
+ while (auto* destructionObserver = m_destructionObservers.takeAny())
+ destructionObserver->frameDestroyed();
if (!isMainFrame())
m_mainFrame.selfOnlyDeref();
@@ -261,7 +234,7 @@ void Frame::removeDestructionObserver(FrameDestructionObserver* observer)
m_destructionObservers.remove(observer);
}
-void Frame::setView(PassRefPtr<FrameView> view)
+void Frame::setView(RefPtr<FrameView>&& view)
{
// We the custom scroll bars as early as possible to prevent m_doc->detach()
// from messing with the view such that its scroll bars won't be torn down.
@@ -272,35 +245,44 @@ void Frame::setView(PassRefPtr<FrameView> view)
// Prepare for destruction now, so any unload event handlers get run and the DOMWindow is
// notified. If we wait until the view is destroyed, then things won't be hooked up enough for
// these calls to work.
- if (!view && m_doc && m_doc->hasLivingRenderTree() && !m_doc->inPageCache())
+ if (!view && m_doc && m_doc->pageCacheState() != Document::InPageCache)
m_doc->prepareForDestruction();
if (m_view)
m_view->unscheduleRelayout();
- eventHandler().clear();
+ // This may be called during destruction, so need to do a null check.
+ if (m_eventHandler)
+ m_eventHandler->clear();
+
+ bool hadLivingRenderTree = m_doc ? m_doc->hasLivingRenderTree() : false;
+ if (hadLivingRenderTree)
+ m_doc->destroyRenderTree();
- m_view = view;
+ m_view = WTFMove(view);
+ if (hadLivingRenderTree && m_view)
+ m_doc->didBecomeCurrentDocumentInView();
+
// Only one form submission is allowed per view of a part.
// Since this part may be getting reused as a result of being
// pulled from the back/forward cache, reset this flag.
loader().resetMultipleFormSubmissionProtection();
-
-#if USE(TILED_BACKING_STORE)
- if (m_view && tiledBackingStore())
- m_view->setPaintsEntireContents(true);
-#endif
}
-void Frame::setDocument(PassRefPtr<Document> newDocument)
+void Frame::setDocument(RefPtr<Document>&& newDocument)
{
ASSERT(!newDocument || newDocument->frame() == this);
- if (m_doc && m_doc->hasLivingRenderTree() && !m_doc->inPageCache())
+ if (m_documentIsBeingReplaced)
+ return;
+
+ m_documentIsBeingReplaced = true;
+
+ if (m_doc && m_doc->pageCacheState() != Document::InPageCache)
m_doc->prepareForDestruction();
- m_doc = newDocument.get();
+ m_doc = newDocument.copyRef();
ASSERT(!m_doc || m_doc->domWindow());
ASSERT(!m_doc || m_doc->domWindow()->frame() == this);
@@ -308,24 +290,41 @@ void Frame::setDocument(PassRefPtr<Document> newDocument)
// that the document is not destroyed during this function call.
if (newDocument)
newDocument->didBecomeCurrentDocumentInFrame();
+
+ InspectorInstrumentation::frameDocumentUpdated(*this);
+
+ m_documentIsBeingReplaced = false;
}
#if ENABLE(ORIENTATION_EVENTS)
-void Frame::sendOrientationChangeEvent(int orientation)
+void Frame::orientationChanged()
+{
+ Vector<Ref<Frame>> frames;
+ for (Frame* frame = this; frame; frame = frame->tree().traverseNext())
+ frames.append(*frame);
+
+ for (auto& frame : frames) {
+ if (Document* document = frame->document())
+ document->dispatchWindowEvent(Event::create(eventNames().orientationchangeEvent, false, false));
+ }
+}
+
+int Frame::orientation() const
{
- m_orientation = orientation;
- if (Document* doc = document())
- doc->dispatchWindowEvent(Event::create(eventNames().orientationchangeEvent, false, false));
+ if (m_page)
+ return m_page->chrome().client().deviceOrientation();
+ return 0;
}
#endif // ENABLE(ORIENTATION_EVENTS)
-static PassOwnPtr<JSC::Yarr::RegularExpression> createRegExpForLabels(const Vector<String>& labels)
+static JSC::Yarr::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.
- DEFINE_STATIC_LOCAL(JSC::Yarr::RegularExpression, wordRegExp, ("\\w", TextCaseSensitive));
- String pattern("(");
+ static NeverDestroyed<JSC::Yarr::RegularExpression> wordRegExp("\\w", TextCaseSensitive);
+ StringBuilder pattern;
+ pattern.append('(');
unsigned int numLabels = labels.size();
unsigned int i;
for (i = 0; i < numLabels; i++) {
@@ -334,41 +333,41 @@ static PassOwnPtr<JSC::Yarr::RegularExpression> createRegExpForLabels(const Vect
bool startsWithWordChar = false;
bool endsWithWordChar = false;
if (label.length()) {
- startsWithWordChar = wordRegExp.match(label.substring(0, 1)) >= 0;
- endsWithWordChar = wordRegExp.match(label.substring(label.length() - 1, 1)) >= 0;
+ startsWithWordChar = wordRegExp.get().match(label.substring(0, 1)) >= 0;
+ endsWithWordChar = wordRegExp.get().match(label.substring(label.length() - 1, 1)) >= 0;
}
if (i)
- pattern.append("|");
+ pattern.append('|');
// Search for word boundaries only if label starts/ends with "word characters".
// If we always searched for word boundaries, this wouldn't work for languages
// such as Japanese.
if (startsWithWordChar)
- pattern.append("\\b");
+ pattern.appendLiteral("\\b");
pattern.append(label);
if (endsWithWordChar)
- pattern.append("\\b");
+ pattern.appendLiteral("\\b");
}
- pattern.append(")");
- return adoptPtr(new JSC::Yarr::RegularExpression(pattern, TextCaseInsensitive));
+ pattern.append(')');
+ return JSC::Yarr::RegularExpression(pattern.toString(), TextCaseInsensitive);
}
-String Frame::searchForLabelsAboveCell(JSC::Yarr::RegularExpression* regExp, HTMLTableCellElement* cell, size_t* resultDistanceFromStartOfCell)
+String Frame::searchForLabelsAboveCell(const JSC::Yarr::RegularExpression& regExp, HTMLTableCellElement* cell, size_t* resultDistanceFromStartOfCell)
{
HTMLTableCellElement* aboveCell = cell->cellAbove();
if (aboveCell) {
// search within the above cell we found for a match
size_t lengthSearched = 0;
- for (Text* textNode = TextNodeTraversal::firstWithin(aboveCell); textNode; textNode = TextNodeTraversal::next(textNode, aboveCell)) {
+ for (Text* textNode = TextNodeTraversal::firstWithin(*aboveCell); textNode; textNode = TextNodeTraversal::next(*textNode, aboveCell)) {
if (!textNode->renderer() || textNode->renderer()->style().visibility() != VISIBLE)
continue;
// For each text chunk, run the regexp
String nodeString = textNode->data();
- int pos = regExp->searchRev(nodeString);
+ int pos = regExp.searchRev(nodeString);
if (pos >= 0) {
if (resultDistanceFromStartOfCell)
*resultDistanceFromStartOfCell = lengthSearched;
- return nodeString.substring(pos, regExp->matchedLength());
+ return nodeString.substring(pos, regExp.matchedLength());
}
lengthSearched += nodeString.length();
}
@@ -380,16 +379,18 @@ String Frame::searchForLabelsAboveCell(JSC::Yarr::RegularExpression* regExp, HTM
return String();
}
+// FIXME: This should take an Element&.
String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element* element, size_t* resultDistance, bool* resultIsInCellAbove)
{
- OwnPtr<JSC::Yarr::RegularExpression> regExp(createRegExpForLabels(labels));
+ ASSERT(element);
+ JSC::Yarr::RegularExpression regExp = createRegExpForLabels(labels);
// We stop searching after we've seen this many chars
const unsigned int charsSearchedThreshold = 500;
// This is the absolute max we search. We allow a little more slop than
// charsSearchedThreshold, to make it more likely that we'll search whole nodes.
const unsigned int maxCharsSearched = 600;
// If the starting element is within a table, the cell that contains it
- HTMLTableCellElement* startingTableCell = 0;
+ HTMLTableCellElement* startingTableCell = nullptr;
bool searchedCellAbove = false;
if (resultDistance)
@@ -400,15 +401,15 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
// walk backwards in the node tree, until another element, or form, or end of tree
int unsigned lengthSearched = 0;
Node* n;
- for (n = NodeTraversal::previous(element); n && lengthSearched < charsSearchedThreshold; n = NodeTraversal::previous(n)) {
+ for (n = NodeTraversal::previous(*element); n && lengthSearched < charsSearchedThreshold; n = NodeTraversal::previous(*n)) {
// We hit another form element or the start of the form - bail out
- if (isHTMLFormElement(n) || (n->isHTMLElement() && toElement(n)->isFormControlElement()))
+ if (is<HTMLFormElement>(*n) || is<HTMLFormControlElement>(*n))
break;
- if (n->hasTagName(tdTag) && !startingTableCell) {
- startingTableCell = toHTMLTableCellElement(n);
- } else if (n->hasTagName(trTag) && startingTableCell) {
- String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance);
+ if (n->hasTagName(tdTag) && !startingTableCell)
+ startingTableCell = downcast<HTMLTableCellElement>(n);
+ else if (is<HTMLTableRowElement>(*n) && startingTableCell) {
+ String result = searchForLabelsAboveCell(regExp, startingTableCell, resultDistance);
if (!result.isEmpty()) {
if (resultIsInCellAbove)
*resultIsInCellAbove = true;
@@ -421,11 +422,11 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
// 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);
+ int pos = regExp.searchRev(nodeString);
if (pos >= 0) {
if (resultDistance)
*resultDistance = lengthSearched;
- return nodeString.substring(pos, regExp->matchedLength());
+ return nodeString.substring(pos, regExp.matchedLength());
}
lengthSearched += nodeString.length();
}
@@ -434,7 +435,7 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
// If we started in a cell, but bailed because we found the start of the form or the
// previous element, we still might need to search the row above us for a label.
if (startingTableCell && !searchedCellAbove) {
- String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance);
+ String result = searchForLabelsAboveCell(regExp, startingTableCell, resultDistance);
if (!result.isEmpty()) {
if (resultIsInCellAbove)
*resultIsInCellAbove = true;
@@ -455,7 +456,7 @@ static String matchLabelsAgainstString(const Vector<String>& labels, const Strin
replace(mutableStringToMatch, JSC::Yarr::RegularExpression("\\d", TextCaseSensitive), " ");
mutableStringToMatch.replace('_', ' ');
- OwnPtr<JSC::Yarr::RegularExpression> regExp(createRegExpForLabels(labels));
+ JSC::Yarr::RegularExpression regExp = createRegExpForLabels(labels);
// Use the largest match we can find in the whole string
int pos;
int length;
@@ -463,9 +464,9 @@ static String matchLabelsAgainstString(const Vector<String>& labels, const Strin
int bestLength = -1;
int start = 0;
do {
- pos = regExp->match(mutableStringToMatch, start);
+ pos = regExp.match(mutableStringToMatch, start);
if (pos != -1) {
- length = regExp->matchedLength();
+ length = regExp.matchedLength();
if (length >= bestLength) {
bestPos = pos;
bestLength = length;
@@ -489,7 +490,7 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e
if (!resultFromNameAttribute.isEmpty())
return resultFromNameAttribute;
- return matchLabelsAgainstString(labels, element->getAttribute(idAttr));
+ return matchLabelsAgainstString(labels, element->attributeWithoutSynchronization(idAttr));
}
#if PLATFORM(IOS)
@@ -505,30 +506,30 @@ void Frame::scrollOverflowLayer(RenderLayer* layer, const IntRect& visibleRect,
if (visibleRect.intersects(exposeRect))
return;
- int x = layer->scrollXOffset();
+ // FIXME: Why isn't this just calling RenderLayer::scrollRectToVisible()?
+ ScrollOffset scrollOffset = layer->scrollOffset();
int exposeLeft = exposeRect.x();
int exposeRight = exposeLeft + exposeRect.width();
- int clientWidth = box->clientWidth();
+ int clientWidth = roundToInt(box->clientWidth());
if (exposeLeft <= 0)
- x = std::max(0, x + exposeLeft - clientWidth / 2);
+ scrollOffset.setX(std::max(0, scrollOffset.x() + exposeLeft - clientWidth / 2));
else if (exposeRight >= clientWidth)
- x = std::min(box->scrollWidth() - clientWidth, x + clientWidth / 2);
+ scrollOffset.setX(std::min(box->scrollWidth() - clientWidth, scrollOffset.x() + clientWidth / 2));
- int y = layer->scrollYOffset();
int exposeTop = exposeRect.y();
int exposeBottom = exposeTop + exposeRect.height();
- int clientHeight = box->clientHeight();
+ int clientHeight = roundToInt(box->clientHeight());
if (exposeTop <= 0)
- y = std::max(0, y + exposeTop - clientHeight / 2);
+ scrollOffset.setY(std::max(0, scrollOffset.y() + exposeTop - clientHeight / 2));
else if (exposeBottom >= clientHeight)
- y = std::min(box->scrollHeight() - clientHeight, y + clientHeight / 2);
+ scrollOffset.setY(std::min(box->scrollHeight() - clientHeight, scrollOffset.y() + clientHeight / 2));
- layer->scrollToOffset(IntSize(x, y));
+ layer->scrollToOffset(scrollOffset);
selection().setCaretRectNeedsUpdate();
selection().updateAppearance();
}
-void Frame::overflowAutoScrollTimerFired(Timer<Frame>*)
+void Frame::overflowAutoScrollTimerFired()
{
if (!eventHandler().mousePressed() || checkOverflowScroll(PerformOverflowScroll) == OverflowScrollNone) {
if (m_overflowAutoScrollTimer.isActive())
@@ -616,11 +617,13 @@ int Frame::checkOverflowScroll(OverflowScrollAction action)
}
}
+ Ref<Frame> protectedThis(*this);
+
if (action == PerformOverflowScroll && (deltaX || deltaY)) {
- layer->scrollToOffset(IntSize(layer->scrollXOffset() + deltaX, layer->scrollYOffset() + deltaY));
+ layer->scrollToOffset(layer->scrollOffset() + IntSize(deltaX, deltaY));
// Handle making selection.
- VisiblePosition visiblePosition(renderer->positionForPoint(selectionPosition));
+ VisiblePosition visiblePosition(renderer->positionForPoint(selectionPosition, nullptr));
if (visiblePosition.isNotNull()) {
VisibleSelection visibleSelection = selection().selection();
visibleSelection.setExtent(visiblePosition);
@@ -653,15 +656,17 @@ void Frame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSiz
ResourceCacheValidationSuppressor validationSuppressor(m_doc->cachedResourceLoader());
m_doc->setPrinting(printing);
- view()->adjustMediaTypeForPrinting(printing);
-
- m_doc->styleResolverChanged(RecalcStyleImmediately);
- if (shouldUsePrintingLayout()) {
- view()->forceLayoutForPagination(pageSize, originalPageSize, maximumShrinkRatio, shouldAdjustViewSize);
- } else {
- view()->forceLayout();
- if (shouldAdjustViewSize == AdjustViewSize)
- view()->adjustViewSize();
+ if (auto* frameView = view()) {
+ frameView->adjustMediaTypeForPrinting(printing);
+
+ m_doc->styleScope().didChangeStyleSheetEnvironment();
+ if (shouldUsePrintingLayout())
+ frameView->forceLayoutForPagination(pageSize, originalPageSize, maximumShrinkRatio, shouldAdjustViewSize);
+ else {
+ frameView->forceLayout();
+ if (shouldAdjustViewSize == AdjustViewSize)
+ frameView->adjustViewSize();
+ }
}
// Subframes of the one we're printing don't lay out to the page size.
@@ -701,76 +706,52 @@ void Frame::injectUserScripts(UserScriptInjectionTime injectionTime)
if (!m_page)
return;
- if (loader().stateMachine()->creatingInitialEmptyDocument() && !settings().shouldInjectUserScriptsInInitialEmptyDocument())
- return;
-
- const auto* userContentController = m_page->userContentController();
- if (!userContentController)
- return;
-
- // Walk the hashtable. Inject by world.
- const UserScriptMap* userScripts = userContentController->userScripts();
- if (!userScripts)
+ if (loader().stateMachine().creatingInitialEmptyDocument() && !settings().shouldInjectUserScriptsInInitialEmptyDocument())
return;
- for (const auto& worldAndUserScript : *userScripts)
- injectUserScriptsForWorld(*worldAndUserScript.key, *worldAndUserScript.value, injectionTime);
-}
-
-void Frame::injectUserScriptsForWorld(DOMWrapperWorld& world, const UserScriptVector& userScripts, UserScriptInjectionTime injectionTime)
-{
- if (userScripts.isEmpty())
- return;
-
- Document* doc = document();
- if (!doc)
+ Document* document = this->document();
+ if (!document)
return;
- Vector<ScriptSourceCode> sourceCode;
- unsigned count = userScripts.size();
- for (unsigned i = 0; i < count; ++i) {
- UserScript* script = userScripts[i].get();
- if (script->injectedFrames() == InjectInTopFrameOnly && ownerElement())
- continue;
+ m_page->userContentProvider().forEachUserScript([&](DOMWrapperWorld& world, const UserScript& script) {
+ if (script.injectedFrames() == InjectInTopFrameOnly && ownerElement())
+ return;
- if (script->injectionTime() == injectionTime && UserContentURLPattern::matchesPatterns(doc->url(), script->whitelist(), script->blacklist()))
- m_script->evaluateInWorld(ScriptSourceCode(script->source(), script->url()), world);
- }
+ if (script.injectionTime() == injectionTime && UserContentURLPattern::matchesPatterns(document->url(), script.whitelist(), script.blacklist())) {
+ m_page->setAsRunningUserScripts();
+ m_script->evaluateInWorld(ScriptSourceCode(script.source(), script.url()), world);
+ }
+ });
}
RenderView* Frame::contentRenderer() const
{
- return document() ? document()->renderView() : 0;
+ return document() ? document()->renderView() : nullptr;
}
RenderWidget* Frame::ownerRenderer() const
{
- HTMLFrameOwnerElement* ownerElement = m_ownerElement;
+ auto* ownerElement = m_ownerElement;
if (!ownerElement)
- return 0;
- auto object = ownerElement->renderer();
- if (!object)
- return 0;
+ return nullptr;
+ auto* object = ownerElement->renderer();
// 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 m_ownerElement would be 0 when the load is canceled.
+ // since m_ownerElement would be nullptr when the load is canceled.
// https://bugs.webkit.org/show_bug.cgi?id=18585
- if (!object->isWidget())
- return 0;
- return toRenderWidget(object);
+ if (!is<RenderWidget>(object))
+ return nullptr;
+ return downcast<RenderWidget>(object);
}
-Frame* Frame::frameForWidget(const Widget* widget)
+Frame* Frame::frameForWidget(const Widget& widget)
{
- ASSERT_ARG(widget, widget);
-
- if (RenderWidget* renderer = RenderWidget::find(widget))
+ if (auto* renderer = RenderWidget::find(widget))
return renderer->frameOwnerElement().document().frame();
// Assume all widgets are either a FrameView or owned by a RenderWidget.
// FIXME: That assumption is not right for scroll bars!
- ASSERT_WITH_SECURITY_IMPLICATION(widget->isFrameView());
- return &toFrameView(widget)->frame();
+ return &downcast<FrameView>(widget).frame();
}
void Frame::clearTimers(FrameView *view, Document *document)
@@ -798,35 +779,34 @@ void Frame::willDetachPage()
// 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);
+ page()->focusController().setFocusedFrame(nullptr);
if (page() && page()->scrollingCoordinator() && m_view)
- page()->scrollingCoordinator()->willDestroyScrollableArea(m_view.get());
+ page()->scrollingCoordinator()->willDestroyScrollableArea(*m_view);
#if PLATFORM(IOS)
if (WebThreadCountOfObservedContentModifiers() > 0 && m_page)
- m_page->chrome().client().clearContentChangeObservers(this);
+ m_page->chrome().client().clearContentChangeObservers(*this);
#endif
script().clearScriptObjects();
script().updatePlatformScriptObjects();
+
+ // We promise that the Frame is always connected to a Page while the render tree is live.
+ //
+ // The render tree can be torn down in a few different ways, but the two important ones are:
+ //
+ // - When calling Frame::setView() with a null FrameView*. This is always done before calling
+ // Frame::willDetachPage (this function.) Hence the assertion below.
+ //
+ // - When adding a document to the page cache, the tree is torn down before instantiating
+ // the CachedPage+CachedFrame object tree.
+ ASSERT(!document() || !document()->renderView());
}
void Frame::disconnectOwnerElement()
{
if (m_ownerElement) {
- // We use the ownerElement's document to retrieve the cache, because the contentDocument for this
- // frame is already detached (and can't access the top level AX cache).
- // However, we pass in the current document to clearTextMarkerNodesInUse so we can identify the
- // nodes inside this document that need to be removed from the cache.
-
- // We don't clear the AXObjectCache here because we don't want to clear the top level cache
- // when a sub-frame is removed.
-#if HAVE(ACCESSIBILITY)
- if (AXObjectCache* cache = m_ownerElement->document().existingAXObjectCache())
- cache->clearTextMarkerNodesInUse(document());
-#endif
-
m_ownerElement->clearContentFrame();
if (m_page)
m_page->decrementSubframeCount();
@@ -839,7 +819,7 @@ String Frame::displayStringModifiedByEncoding(const String& str) const
return document() ? document()->displayStringModifiedByEncoding(str) : str;
}
-VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
+VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint) const
{
HitTestResult result = eventHandler().hitTestResultAtPoint(framePoint, HitTestRequest::ReadOnly | HitTestRequest::Active);
Node* node = result.innerNonSharedNode();
@@ -848,7 +828,7 @@ VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
auto renderer = node->renderer();
if (!renderer)
return VisiblePosition();
- VisiblePosition visiblePos = renderer->positionForPoint(result.localPoint());
+ VisiblePosition visiblePos = renderer->positionForPoint(result.localPoint(), nullptr);
if (visiblePos.isNull())
visiblePos = firstPositionInOrBeforeNode(node);
return visiblePos;
@@ -857,7 +837,7 @@ VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
Document* Frame::documentAtPoint(const IntPoint& point)
{
if (!view())
- return 0;
+ return nullptr;
IntPoint pt = view()->windowToContents(point);
HitTestResult result = HitTestResult(pt);
@@ -867,28 +847,33 @@ Document* Frame::documentAtPoint(const IntPoint& point)
return result.innerNode() ? &result.innerNode()->document() : 0;
}
-PassRefPtr<Range> Frame::rangeForPoint(const IntPoint& framePoint)
+RefPtr<Range> Frame::rangeForPoint(const IntPoint& framePoint)
{
VisiblePosition position = visiblePositionForPoint(framePoint);
if (position.isNull())
- return 0;
+ return nullptr;
+
+ Position deepPosition = position.deepEquivalent();
+ Text* containerText = deepPosition.containerText();
+ if (!containerText || !containerText->renderer() || containerText->renderer()->style().userSelect() == SELECT_NONE)
+ return nullptr;
VisiblePosition previous = position.previous();
if (previous.isNotNull()) {
RefPtr<Range> previousCharacterRange = makeRange(previous, position);
LayoutRect rect = editor().firstRectForRange(previousCharacterRange.get());
if (rect.contains(framePoint))
- return previousCharacterRange.release();
+ return previousCharacterRange;
}
VisiblePosition next = position.next();
if (RefPtr<Range> nextCharacterRange = makeRange(position, next)) {
LayoutRect rect = editor().firstRectForRange(nextCharacterRange.get());
if (rect.contains(framePoint))
- return nextCharacterRange.release();
+ return nextCharacterRange;
}
- return 0;
+ return nullptr;
}
void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor, bool transparent,
@@ -896,7 +881,6 @@ void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor
bool useFixedLayout, ScrollbarMode horizontalScrollbarMode, bool horizontalLock,
ScrollbarMode verticalScrollbarMode, bool verticalLock)
{
- ASSERT(this);
ASSERT(m_page);
bool isMainFrame = this->isMainFrame();
@@ -904,13 +888,13 @@ void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor
if (isMainFrame && view())
view()->setParentVisible(false);
- setView(0);
+ setView(nullptr);
RefPtr<FrameView> frameView;
if (isMainFrame) {
frameView = FrameView::create(*this, viewportSize);
frameView->setFixedLayoutSize(fixedLayoutSize);
-#if USE(TILED_BACKING_STORE)
+#if USE(COORDINATED_GRAPHICS)
frameView->setFixedVisibleContentRect(fixedVisibleContentRect);
#else
UNUSED_PARAM(fixedVisibleContentRect);
@@ -921,7 +905,7 @@ void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor
frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode, horizontalLock, verticalLock);
- setView(frameView);
+ setView(frameView.copyRef());
if (backgroundColor.isValid())
frameView->updateBackgroundRecursively(backgroundColor, transparent);
@@ -936,80 +920,14 @@ void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor
view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
}
-#if USE(TILED_BACKING_STORE)
-void Frame::setTiledBackingStoreEnabled(bool enabled)
-{
- if (!enabled) {
- m_tiledBackingStore.clear();
- return;
- }
- if (m_tiledBackingStore)
- return;
- m_tiledBackingStore = adoptPtr(new TiledBackingStore(this));
- m_tiledBackingStore->setCommitTileUpdatesOnIdleEventLoop(true);
- if (m_view)
- m_view->setPaintsEntireContents(true);
-}
-
-void Frame::tiledBackingStorePaintBegin()
-{
- if (!m_view)
- return;
- m_view->updateLayoutAndStyleIfNeededRecursive();
-}
-
-void Frame::tiledBackingStorePaint(GraphicsContext* context, const IntRect& rect)
-{
- if (!m_view)
- return;
- m_view->paintContents(context, rect);
-}
-
-void Frame::tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea)
-{
- if (!m_page || !m_view)
- return;
- unsigned size = paintedArea.size();
- // Request repaint from the system
- for (unsigned n = 0; n < size; ++n)
- m_page->chrome().invalidateContentsAndRootView(m_view->contentsToRootView(paintedArea[n]), false);
-}
-
-IntRect Frame::tiledBackingStoreContentsRect()
-{
- if (!m_view)
- return IntRect();
- return IntRect(IntPoint(), m_view->contentsSize());
-}
-
-IntRect Frame::tiledBackingStoreVisibleRect()
-{
- if (!m_page)
- return IntRect();
- return m_page->chrome().client().visibleRectForTiledBackingStore();
-}
-
-Color Frame::tiledBackingStoreBackgroundColor() const
-{
- if (!m_view)
- return Color();
- return m_view->baseBackgroundColor();
-}
-#endif
-
String Frame::layerTreeAsText(LayerTreeFlags flags) const
{
-#if USE(ACCELERATED_COMPOSITING)
document()->updateLayout();
if (!contentRenderer())
return String();
return contentRenderer()->compositor().layerTreeAsText(flags);
-#else
- UNUSED_PARAM(flags);
- return String();
-#endif
}
String Frame::trackedRepaintRectsAsText() const
@@ -1044,14 +962,10 @@ void Frame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor
m_editor->dismissCorrectionPanelAsIgnored();
-#if ENABLE(SVG)
// Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
// FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
- if (document->isSVGDocument()) {
- if (!toSVGDocument(document)->zoomAndPanEnabled())
- return;
- }
-#endif
+ if (is<SVGDocument>(*document) && !downcast<SVGDocument>(*document).zoomAndPanEnabled())
+ return;
if (m_pageZoomFactor != pageZoomFactor) {
if (FrameView* view = this->view()) {
@@ -1074,9 +988,6 @@ void Frame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor
if (document->renderView() && document->renderView()->needsLayout() && view->didFirstLayout())
view->layout();
}
-
- if (isMainFrame())
- pageCache()->markPagesForFullStyleRecalc(page);
}
float Frame::frameScaleFactor() const
@@ -1100,30 +1011,33 @@ void Frame::suspendActiveDOMObjectsAndAnimations()
return;
// FIXME: Suspend/resume calls will not match if the frame is navigated, and gets a new document.
- if (document()) {
- document()->suspendScriptedAnimationControllerCallbacks();
- animation().suspendAnimationsForDocument(document());
- document()->suspendActiveDOMObjects(ActiveDOMObject::PageWillBeSuspended);
- }
+ clearTimers(); // Suspends animations and pending relayouts.
+ if (m_doc)
+ m_doc->suspendScheduledTasks(ActiveDOMObject::PageWillBeSuspended);
}
void Frame::resumeActiveDOMObjectsAndAnimations()
{
- ASSERT(activeDOMObjectsAndAnimationsSuspended());
+ if (!activeDOMObjectsAndAnimationsSuspended())
+ return;
m_activeDOMObjectsAndAnimationsSuspendedCount--;
if (activeDOMObjectsAndAnimationsSuspended())
return;
- if (document()) {
- document()->resumeActiveDOMObjects(ActiveDOMObject::PageWillBeSuspended);
- animation().resumeAnimationsForDocument(document());
- document()->resumeScriptedAnimationControllerCallbacks();
- }
+ if (!m_doc)
+ return;
+
+ // FIXME: Suspend/resume calls will not match if the frame is navigated, and gets a new document.
+ m_doc->resumeScheduledTasks(ActiveDOMObject::PageWillBeSuspended);
+
+ // Frame::clearTimers() suspended animations and pending relayouts.
+ animation().resumeAnimationsForDocument(m_doc.get());
+ if (m_view)
+ m_view->scheduleRelayout();
}
-#if USE(ACCELERATED_COMPOSITING)
void Frame::deviceOrPageScaleFactorChanged()
{
for (RefPtr<Frame> child = tree().firstChild(); child; child = child->tree().nextSibling())
@@ -1132,7 +1046,6 @@ void Frame::deviceOrPageScaleFactorChanged()
if (RenderView* root = contentRenderer())
root->compositor().deviceOrPageScaleFactorChanged();
}
-#endif
bool Frame::isURLAllowed(const URL& url) const
{
@@ -1151,4 +1064,9 @@ bool Frame::isURLAllowed(const URL& url) const
return true;
}
+bool Frame::isAlwaysOnLoggingAllowed() const
+{
+ return page() && page()->isAlwaysOnLoggingAllowed();
+}
+
} // namespace WebCore