Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / page / Page.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All Rights Reserved.
3  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21 #include "core/page/Page.h"
22
23 #include "core/dom/ClientRectList.h"
24 #include "core/dom/DocumentMarkerController.h"
25 #include "core/dom/StyleEngine.h"
26 #include "core/dom/VisitedLinkState.h"
27 #include "core/editing/Caret.h"
28 #include "core/editing/UndoStack.h"
29 #include "core/events/Event.h"
30 #include "core/fetch/ResourceFetcher.h"
31 #include "core/frame/DOMTimer.h"
32 #include "core/frame/DOMWindow.h"
33 #include "core/frame/EventHandlerRegistry.h"
34 #include "core/frame/FrameHost.h"
35 #include "core/frame/FrameView.h"
36 #include "core/frame/LocalFrame.h"
37 #include "core/frame/Settings.h"
38 #include "core/inspector/InspectorController.h"
39 #include "core/inspector/InspectorInstrumentation.h"
40 #include "core/loader/FrameLoader.h"
41 #include "core/loader/HistoryItem.h"
42 #include "core/page/AutoscrollController.h"
43 #include "core/page/Chrome.h"
44 #include "core/page/ChromeClient.h"
45 #include "core/page/ContextMenuController.h"
46 #include "core/page/DragController.h"
47 #include "core/page/FocusController.h"
48 #include "core/page/FrameTree.h"
49 #include "core/page/PageLifecycleNotifier.h"
50 #include "core/page/PointerLockController.h"
51 #include "core/page/StorageClient.h"
52 #include "core/page/ValidationMessageClient.h"
53 #include "core/page/scrolling/ScrollingCoordinator.h"
54 #include "core/rendering/FastTextAutosizer.h"
55 #include "core/rendering/RenderView.h"
56 #include "core/rendering/TextAutosizer.h"
57 #include "core/storage/StorageNamespace.h"
58 #include "platform/plugins/PluginData.h"
59 #include "wtf/HashMap.h"
60 #include "wtf/RefCountedLeakCounter.h"
61 #include "wtf/StdLibExtras.h"
62 #include "wtf/text/Base64.h"
63
64 namespace WebCore {
65
66 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page"));
67
68 // static
69 HashSet<Page*>& Page::allPages()
70 {
71     DEFINE_STATIC_LOCAL(HashSet<Page*>, allPages, ());
72     return allPages;
73 }
74
75 // static
76 HashSet<Page*>& Page::ordinaryPages()
77 {
78     DEFINE_STATIC_LOCAL(HashSet<Page*>, ordinaryPages, ());
79     return ordinaryPages;
80 }
81
82
83 void Page::networkStateChanged(bool online)
84 {
85     Vector<RefPtr<LocalFrame> > frames;
86
87     // Get all the frames of all the pages in all the page groups
88     HashSet<Page*>::iterator end = allPages().end();
89     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
90         for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
91             frames.append(frame);
92         InspectorInstrumentation::networkStateChanged(*it, online);
93     }
94
95     AtomicString eventName = online ? EventTypeNames::online : EventTypeNames::offline;
96     for (unsigned i = 0; i < frames.size(); i++)
97         frames[i]->domWindow()->dispatchEvent(Event::create(eventName));
98 }
99
100 float deviceScaleFactor(LocalFrame* frame)
101 {
102     if (!frame)
103         return 1;
104     Page* page = frame->page();
105     if (!page)
106         return 1;
107     return page->deviceScaleFactor();
108 }
109
110 Page::Page(PageClients& pageClients)
111     : SettingsDelegate(Settings::create())
112     , m_animator(this)
113     , m_autoscrollController(AutoscrollController::create(*this))
114     , m_chrome(Chrome::create(this, pageClients.chromeClient))
115     , m_dragCaretController(DragCaretController::create())
116     , m_dragController(DragController::create(this, pageClients.dragClient))
117     , m_focusController(FocusController::create(this))
118     , m_contextMenuController(ContextMenuController::create(this, pageClients.contextMenuClient))
119     , m_inspectorController(InspectorController::create(this, pageClients.inspectorClient))
120     , m_pointerLockController(PointerLockController::create(this))
121     , m_undoStack(UndoStack::create())
122     , m_backForwardClient(pageClients.backForwardClient)
123     , m_editorClient(pageClients.editorClient)
124     , m_spellCheckerClient(pageClients.spellCheckerClient)
125     , m_storageClient(pageClients.storageClient)
126     , m_subframeCount(0)
127     , m_openedByDOM(false)
128     , m_tabKeyCyclesThroughElements(true)
129     , m_defersLoading(false)
130     , m_deviceScaleFactor(1)
131     , m_timerAlignmentInterval(DOMTimer::visiblePageAlignmentInterval())
132     , m_visibilityState(PageVisibilityStateVisible)
133     , m_isCursorVisible(true)
134 #ifndef NDEBUG
135     , m_isPainting(false)
136 #endif
137     , m_frameHost(FrameHost::create(*this))
138 {
139     ASSERT(m_editorClient);
140
141     ASSERT(!allPages().contains(this));
142     allPages().add(this);
143
144 #ifndef NDEBUG
145     pageCounter.increment();
146 #endif
147 }
148
149 Page::~Page()
150 {
151 }
152
153 void Page::makeOrdinary()
154 {
155     ASSERT(!ordinaryPages().contains(this));
156     ordinaryPages().add(this);
157 }
158
159 ViewportDescription Page::viewportDescription() const
160 {
161     return mainFrame() && mainFrame()->document() ? mainFrame()->document()->viewportDescription() : ViewportDescription();
162 }
163
164 ScrollingCoordinator* Page::scrollingCoordinator()
165 {
166     if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled())
167         m_scrollingCoordinator = ScrollingCoordinator::create(this);
168
169     return m_scrollingCoordinator.get();
170 }
171
172 String Page::mainThreadScrollingReasonsAsText()
173 {
174     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
175         return scrollingCoordinator->mainThreadScrollingReasonsAsText();
176
177     return String();
178 }
179
180 PassRefPtrWillBeRawPtr<ClientRectList> Page::nonFastScrollableRects(const LocalFrame* frame)
181 {
182     if (Document* document = m_mainFrame->document())
183         document->updateLayout();
184
185     Vector<IntRect> rects;
186     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
187         rects = scrollingCoordinator->computeShouldHandleScrollGestureOnMainThreadRegion(frame, IntPoint()).rects();
188
189     Vector<FloatQuad> quads(rects.size());
190     for (size_t i = 0; i < rects.size(); ++i)
191         quads[i] = FloatRect(rects[i]);
192     return ClientRectList::create(quads);
193 }
194
195 void Page::setMainFrame(PassRefPtr<LocalFrame> mainFrame)
196 {
197     ASSERT(!m_mainFrame); // Should only be called during initialization
198     m_mainFrame = mainFrame;
199 }
200
201 void Page::documentDetached(Document* document)
202 {
203     m_multisamplingChangedObservers.clear();
204     m_pointerLockController->documentDetached(document);
205     m_contextMenuController->documentDetached(document);
206     if (m_validationMessageClient)
207         m_validationMessageClient->documentDetached(*document);
208     m_frameHost->eventHandlerRegistry().documentDetached(*document);
209 }
210
211 bool Page::openedByDOM() const
212 {
213     return m_openedByDOM;
214 }
215
216 void Page::setOpenedByDOM()
217 {
218     m_openedByDOM = true;
219 }
220
221 void Page::scheduleForcedStyleRecalcForAllPages()
222 {
223     HashSet<Page*>::iterator end = allPages().end();
224     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it)
225         for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
226             frame->document()->setNeedsStyleRecalc(SubtreeStyleChange);
227 }
228
229 void Page::setNeedsRecalcStyleInAllFrames()
230 {
231     for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
232         frame->document()->styleResolverChanged(RecalcStyleDeferred);
233 }
234
235 void Page::setNeedsLayoutInAllFrames()
236 {
237     for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
238         if (FrameView* view = frame->view()) {
239             view->setNeedsLayout();
240             view->scheduleRelayout();
241         }
242     }
243 }
244
245 void Page::refreshPlugins(bool reload)
246 {
247     if (allPages().isEmpty())
248         return;
249
250     PluginData::refresh();
251
252     Vector<RefPtr<LocalFrame> > framesNeedingReload;
253
254     HashSet<Page*>::iterator end = allPages().end();
255     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
256         Page* page = *it;
257
258         // Clear out the page's plug-in data.
259         if (page->m_pluginData)
260             page->m_pluginData = nullptr;
261
262         if (!reload)
263             continue;
264
265         for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
266             if (frame->document()->containsPlugins())
267                 framesNeedingReload.append(frame);
268         }
269     }
270
271     for (size_t i = 0; i < framesNeedingReload.size(); ++i)
272         framesNeedingReload[i]->loader().reload();
273 }
274
275 PluginData* Page::pluginData() const
276 {
277     if (!mainFrame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
278         return 0;
279     if (!m_pluginData)
280         m_pluginData = PluginData::create(this);
281     return m_pluginData.get();
282 }
283
284 static LocalFrame* incrementFrame(LocalFrame* curr, bool forward, bool wrapFlag)
285 {
286     return forward
287         ? curr->tree().traverseNextWithWrap(wrapFlag)
288         : curr->tree().traversePreviousWithWrap(wrapFlag);
289 }
290
291 void Page::unmarkAllTextMatches()
292 {
293     if (!mainFrame())
294         return;
295
296     LocalFrame* frame = mainFrame();
297     do {
298         frame->document()->markers().removeMarkers(DocumentMarker::TextMatch);
299         frame = incrementFrame(frame, true, false);
300     } while (frame);
301 }
302
303 void Page::setValidationMessageClient(PassOwnPtr<ValidationMessageClient> client)
304 {
305     m_validationMessageClient = client;
306 }
307
308 void Page::setDefersLoading(bool defers)
309 {
310     if (defers == m_defersLoading)
311         return;
312
313     m_defersLoading = defers;
314     for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
315         frame->loader().setDefersLoading(defers);
316 }
317
318 void Page::setPageScaleFactor(float scale, const IntPoint& origin)
319 {
320     FrameView* view = mainFrame()->view();
321     PinchViewport& viewport = frameHost().pinchViewport();
322
323     if (scale != viewport.scale()) {
324         viewport.setScale(scale);
325
326         if (view && !settings().pinchVirtualViewportEnabled())
327             view->setVisibleContentScaleFactor(scale);
328
329         mainFrame()->deviceOrPageScaleFactorChanged();
330         m_chrome->client().deviceOrPageScaleFactorChanged();
331
332         if (view)
333             view->viewportConstrainedVisibleContentSizeChanged(true, true);
334
335         mainFrame()->loader().saveScrollState();
336     }
337
338     if (view && view->scrollPosition() != origin)
339         view->notifyScrollPositionChanged(origin);
340 }
341
342 float Page::pageScaleFactor() const
343 {
344     return frameHost().pinchViewport().scale();
345 }
346
347 void Page::setDeviceScaleFactor(float scaleFactor)
348 {
349     if (m_deviceScaleFactor == scaleFactor)
350         return;
351
352     m_deviceScaleFactor = scaleFactor;
353     setNeedsRecalcStyleInAllFrames();
354
355     if (mainFrame()) {
356         mainFrame()->deviceOrPageScaleFactorChanged();
357         m_chrome->client().deviceOrPageScaleFactorChanged();
358     }
359 }
360
361 void Page::allVisitedStateChanged()
362 {
363     HashSet<Page*>::iterator pagesEnd = ordinaryPages().end();
364     for (HashSet<Page*>::iterator it = ordinaryPages().begin(); it != pagesEnd; ++it) {
365         Page* page = *it;
366         for (LocalFrame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
367             frame->document()->visitedLinkState().invalidateStyleForAllLinks();
368     }
369 }
370
371 void Page::visitedStateChanged(LinkHash linkHash)
372 {
373     HashSet<Page*>::iterator pagesEnd = ordinaryPages().end();
374     for (HashSet<Page*>::iterator it = ordinaryPages().begin(); it != pagesEnd; ++it) {
375         Page* page = *it;
376         for (LocalFrame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
377             frame->document()->visitedLinkState().invalidateStyleForLink(linkHash);
378     }
379 }
380
381 StorageNamespace* Page::sessionStorage(bool optionalCreate)
382 {
383     if (!m_sessionStorage && optionalCreate)
384         m_sessionStorage = m_storageClient->createSessionStorageNamespace();
385     return m_sessionStorage.get();
386 }
387
388 void Page::setTimerAlignmentInterval(double interval)
389 {
390     if (interval == m_timerAlignmentInterval)
391         return;
392
393     m_timerAlignmentInterval = interval;
394     for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) {
395         if (frame->document())
396             frame->document()->didChangeTimerAlignmentInterval();
397     }
398 }
399
400 double Page::timerAlignmentInterval() const
401 {
402     return m_timerAlignmentInterval;
403 }
404
405 #if !ASSERT_DISABLED
406 void Page::checkSubframeCountConsistency() const
407 {
408     ASSERT(m_subframeCount >= 0);
409
410     int subframeCount = 0;
411     for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
412         ++subframeCount;
413
414     ASSERT(m_subframeCount + 1 == subframeCount);
415 }
416 #endif
417
418 void Page::setVisibilityState(PageVisibilityState visibilityState, bool isInitialState)
419 {
420     if (m_visibilityState == visibilityState)
421         return;
422     m_visibilityState = visibilityState;
423
424     if (visibilityState == WebCore::PageVisibilityStateHidden)
425         setTimerAlignmentInterval(DOMTimer::hiddenPageAlignmentInterval());
426     else
427         setTimerAlignmentInterval(DOMTimer::visiblePageAlignmentInterval());
428
429     if (!isInitialState)
430         lifecycleNotifier().notifyPageVisibilityChanged();
431
432     if (!isInitialState && m_mainFrame)
433         m_mainFrame->didChangeVisibilityState();
434 }
435
436 PageVisibilityState Page::visibilityState() const
437 {
438     return m_visibilityState;
439 }
440
441 bool Page::isCursorVisible() const
442 {
443     return m_isCursorVisible && settings().deviceSupportsMouse();
444 }
445
446 void Page::addMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
447 {
448     m_multisamplingChangedObservers.add(observer);
449 }
450
451 void Page::removeMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
452 {
453     m_multisamplingChangedObservers.remove(observer);
454 }
455
456 void Page::settingsChanged(SettingsDelegate::ChangeType changeType)
457 {
458     switch (changeType) {
459     case SettingsDelegate::StyleChange:
460         setNeedsRecalcStyleInAllFrames();
461         break;
462     case SettingsDelegate::ViewportDescriptionChange:
463         if (mainFrame())
464             mainFrame()->document()->updateViewportDescription();
465         break;
466     case SettingsDelegate::MediaTypeChange:
467         m_mainFrame->view()->setMediaType(AtomicString(settings().mediaTypeOverride()));
468         setNeedsRecalcStyleInAllFrames();
469         break;
470     case SettingsDelegate::DNSPrefetchingChange:
471         for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
472             frame->document()->initDNSPrefetch();
473         break;
474     case SettingsDelegate::MultisamplingChange: {
475         WillBeHeapHashSet<RawPtrWillBeWeakMember<MultisamplingChangedObserver> >::iterator stop = m_multisamplingChangedObservers.end();
476         for (WillBeHeapHashSet<RawPtrWillBeWeakMember<MultisamplingChangedObserver> >::iterator it = m_multisamplingChangedObservers.begin(); it != stop; ++it)
477             (*it)->multisamplingChanged(m_settings->openGLMultisamplingEnabled());
478         break;
479     }
480     case SettingsDelegate::ImageLoadingChange:
481         for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
482             frame->document()->fetcher()->setImagesEnabled(settings().imagesEnabled());
483             frame->document()->fetcher()->setAutoLoadImages(settings().loadsImagesAutomatically());
484         }
485         break;
486     case SettingsDelegate::TextAutosizingChange:
487         if (!mainFrame())
488             break;
489         if (FastTextAutosizer* textAutosizer = mainFrame()->document()->fastTextAutosizer()) {
490             textAutosizer->updatePageInfoInAllFrames();
491         } else {
492             for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
493                 if (TextAutosizer* textAutosizer = frame->document()->textAutosizer())
494                     textAutosizer->recalculateMultipliers();
495             }
496             // TextAutosizing updates RenderStyle during layout phase (via TextAutosizer::processSubtree).
497             // We should invoke setNeedsLayout here.
498             setNeedsLayoutInAllFrames();
499         }
500         break;
501     case SettingsDelegate::ScriptEnableChange:
502         m_inspectorController->scriptsEnabled(settings().scriptEnabled());
503         break;
504     case SettingsDelegate::FontFamilyChange:
505         for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
506             frame->document()->styleEngine()->updateGenericFontFamilySettings();
507         setNeedsRecalcStyleInAllFrames();
508         break;
509     case SettingsDelegate::AcceleratedCompositingChange:
510         updateAcceleratedCompositingSettings();
511         break;
512     }
513 }
514
515 void Page::updateAcceleratedCompositingSettings()
516 {
517     for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
518         if (FrameView* view = frame->view())
519             view->updateAcceleratedCompositingSettings();
520     }
521 }
522
523 void Page::didCommitLoad(LocalFrame* frame)
524 {
525     lifecycleNotifier().notifyDidCommitLoad(frame);
526     if (m_mainFrame == frame) {
527         useCounter().didCommitLoad();
528         m_inspectorController->didCommitLoadForMainFrame();
529     }
530 }
531
532 PageLifecycleNotifier& Page::lifecycleNotifier()
533 {
534     return static_cast<PageLifecycleNotifier&>(LifecycleContext<Page>::lifecycleNotifier());
535 }
536
537 PassOwnPtr<LifecycleNotifier<Page> > Page::createLifecycleNotifier()
538 {
539     return PageLifecycleNotifier::create(this);
540 }
541
542 void Page::trace(Visitor* visitor)
543 {
544     visitor->trace(m_multisamplingChangedObservers);
545     visitor->trace(m_frameHost);
546     WillBeHeapSupplementable<Page>::trace(visitor);
547 }
548
549 void Page::willBeDestroyed()
550 {
551     // Disable all agents prior to resetting the frame view.
552     m_inspectorController->willBeDestroyed();
553
554     m_mainFrame->setView(nullptr);
555
556     allPages().remove(this);
557     if (ordinaryPages().contains(this))
558         ordinaryPages().remove(this);
559
560     for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
561         frame->loader().frameDetached();
562
563     if (m_scrollingCoordinator)
564         m_scrollingCoordinator->willBeDestroyed();
565
566 #ifndef NDEBUG
567     pageCounter.decrement();
568 #endif
569
570     m_chrome->willBeDestroyed();
571     m_mainFrame.clear();
572     if (m_validationMessageClient)
573         m_validationMessageClient->willBeDestroyed();
574     WillBeHeapSupplementable<Page>::willBeDestroyed();
575 }
576
577 Page::PageClients::PageClients()
578     : chromeClient(0)
579     , contextMenuClient(0)
580     , editorClient(0)
581     , dragClient(0)
582     , inspectorClient(0)
583     , backForwardClient(0)
584     , spellCheckerClient(0)
585     , storageClient(0)
586 {
587 }
588
589 Page::PageClients::~PageClients()
590 {
591 }
592
593 } // namespace WebCore