#include "core/frame/Frame.h"
#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
+#include "core/frame/Settings.h"
#include "core/inspector/InspectorController.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/loader/FrameLoader.h"
#include "core/page/PageGroup.h"
#include "core/page/PageLifecycleNotifier.h"
#include "core/page/PointerLockController.h"
-#include "core/frame/Settings.h"
+#include "core/page/StorageClient.h"
#include "core/page/ValidationMessageClient.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
#include "core/rendering/RenderView.h"
namespace WebCore {
-static HashSet<Page*>* allPages;
-
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page"));
-void Page::networkStateChanged(bool online)
+// static
+HashSet<Page*>& Page::allPages()
{
- if (!allPages)
- return;
+ DEFINE_STATIC_LOCAL(HashSet<Page*>, allPages, ());
+ return allPages;
+}
+void Page::networkStateChanged(bool online)
+{
Vector<RefPtr<Frame> > frames;
// Get all the frames of all the pages in all the page groups
- HashSet<Page*>::iterator end = allPages->end();
- for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
+ HashSet<Page*>::iterator end = allPages().end();
+ for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
frames.append(frame);
InspectorInstrumentation::networkStateChanged(*it, online);
, m_editorClient(pageClients.editorClient)
, m_validationMessageClient(0)
, m_spellCheckerClient(pageClients.spellCheckerClient)
+ , m_storageClient(pageClients.storageClient)
, m_subframeCount(0)
, m_openedByDOM(false)
, m_tabKeyCyclesThroughElements(true)
{
ASSERT(m_editorClient);
- if (!allPages)
- allPages = new HashSet<Page*>;
-
- ASSERT(!allPages->contains(this));
- allPages->add(this);
+ ASSERT(!allPages().contains(this));
+ allPages().add(this);
#ifndef NDEBUG
pageCounter.increment();
{
m_mainFrame->setView(0);
clearPageGroup();
- allPages->remove(this);
+ allPages().remove(this);
for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
frame->willDetachFrameHost();
void Page::scheduleForcedStyleRecalcForAllPages()
{
- if (!allPages)
- return;
- HashSet<Page*>::iterator end = allPages->end();
- for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it)
+ HashSet<Page*>::iterator end = allPages().end();
+ for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it)
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
- frame->document()->setNeedsStyleRecalc();
+ frame->document()->setNeedsStyleRecalc(SubtreeStyleChange);
}
void Page::setNeedsRecalcStyleInAllFrames()
frame->document()->styleResolverChanged(RecalcStyleDeferred);
}
+void Page::setNeedsLayoutInAllFrames()
+{
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (FrameView* view = frame->view()) {
+ view->setNeedsLayout();
+ view->scheduleRelayout();
+ }
+ }
+}
+
void Page::refreshPlugins(bool reload)
{
- if (!allPages)
+ if (allPages().isEmpty())
return;
PluginData::refresh();
Vector<RefPtr<Frame> > framesNeedingReload;
- HashSet<Page*>::iterator end = allPages->end();
- for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
+ HashSet<Page*>::iterator end = allPages().end();
+ for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
Page* page = *it;
// Clear out the page's plug-in data.
m_chrome->client().deviceOrPageScaleFactorChanged();
if (view)
- view->setViewportConstrainedObjectsNeedLayout();
+ view->viewportConstrainedVisibleContentSizeChanged(true, true);
}
if (view && view->scrollPosition() != origin)
}
}
-void Page::setPagination(const Pagination& pagination)
+void Page::allVisitedStateChanged()
{
- if (m_pagination == pagination)
- return;
-
- m_pagination = pagination;
-
- setNeedsRecalcStyleInAllFrames();
-}
-
-void Page::allVisitedStateChanged(PageGroup* group)
-{
- ASSERT(group);
- if (!allPages)
- return;
-
- HashSet<Page*>::iterator pagesEnd = allPages->end();
- for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
+ HashSet<Page*>::iterator pagesEnd = allPages().end();
+ for (HashSet<Page*>::iterator it = allPages().begin(); it != pagesEnd; ++it) {
Page* page = *it;
- if (page->m_group != group)
+ if (page->m_group != PageGroup::sharedGroup())
continue;
for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
frame->document()->visitedLinkState().invalidateStyleForAllLinks();
}
}
-void Page::visitedStateChanged(PageGroup* group, LinkHash linkHash)
+void Page::visitedStateChanged(LinkHash linkHash)
{
- ASSERT(group);
- if (!allPages)
- return;
-
- HashSet<Page*>::iterator pagesEnd = allPages->end();
- for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
+ HashSet<Page*>::iterator pagesEnd = allPages().end();
+ for (HashSet<Page*>::iterator it = allPages().begin(); it != pagesEnd; ++it) {
Page* page = *it;
- if (page->m_group != group)
+ if (page->m_group != PageGroup::sharedGroup())
continue;
for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
frame->document()->visitedLinkState().invalidateStyleForLink(linkHash);
StorageNamespace* Page::sessionStorage(bool optionalCreate)
{
if (!m_sessionStorage && optionalCreate)
- m_sessionStorage = StorageNamespace::sessionStorageNamespace(this);
+ m_sessionStorage = m_storageClient->createSessionStorageNamespace();
return m_sessionStorage.get();
}
lifecycleNotifier().notifyPageVisibilityChanged();
if (!isInitialState && m_mainFrame)
- m_mainFrame->dispatchVisibilityStateChangeEvent();
+ m_mainFrame->didChangeVisibilityState();
}
PageVisibilityState Page::visibilityState() const
}
break;
case SettingsDelegate::TextAutosizingChange:
- // FIXME: I wonder if this needs to traverse frames like in WebViewImpl::resize, or whether there is only one document per Settings instance?
- for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
- TextAutosizer* textAutosizer = frame->document()->textAutosizer();
- if (textAutosizer)
- textAutosizer->recalculateMultipliers();
+ // FTA needs both setNeedsRecalcStyle and setNeedsLayout after a setting change.
+ if (RuntimeEnabledFeatures::fastTextAutosizingEnabled()) {
+ setNeedsRecalcStyleInAllFrames();
+ } else {
+ // FIXME: I wonder if this needs to traverse frames like in WebViewImpl::resize, or whether there is only one document per Settings instance?
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ TextAutosizer* textAutosizer = frame->document()->textAutosizer();
+ if (textAutosizer)
+ textAutosizer->recalculateMultipliers();
+ }
}
+ // TextAutosizing updates RenderStyle during layout phase (via TextAutosizer::processSubtree).
+ // We should invoke setNeedsLayout here.
+ setNeedsLayoutInAllFrames();
+ break;
+ case SettingsDelegate::ScriptEnableChange:
+ m_inspectorController->scriptsEnabled(settings().scriptEnabled());
+ break;
+ case SettingsDelegate::FontFamilyChange:
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
+ frame->document()->styleEngine()->updateGenericFontFamilySettings();
setNeedsRecalcStyleInAllFrames();
break;
}
void Page::didCommitLoad(Frame* frame)
{
lifecycleNotifier().notifyDidCommitLoad(frame);
- if (m_mainFrame == frame)
+ if (m_mainFrame == frame) {
useCounter().didCommitLoad();
+ m_inspectorController->didCommitLoadForMainFrame();
+ }
}
PageLifecycleNotifier& Page::lifecycleNotifier()
, inspectorClient(0)
, backForwardClient(0)
, spellCheckerClient(0)
+ , storageClient(0)
{
}