2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
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.
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.
23 #include "BackForwardController.h"
24 #include "BackForwardList.h"
26 #include "CSSStyleSelector.h"
28 #include "ChromeClient.h"
29 #include "ContextMenuClient.h"
30 #include "ContextMenuController.h"
31 #include "DOMWindow.h"
32 #include "DeviceMotionController.h"
33 #include "DeviceOrientationController.h"
34 #include "DocumentMarkerController.h"
35 #include "DragController.h"
36 #include "EditorClient.h"
38 #include "EventNames.h"
39 #include "ExceptionCode.h"
40 #include "FileSystem.h"
41 #include "FocusController.h"
43 #include "FrameLoader.h"
44 #include "FrameLoaderClient.h"
45 #include "FrameSelection.h"
46 #include "FrameTree.h"
47 #include "FrameView.h"
48 #include "HTMLElement.h"
49 #include "HistoryItem.h"
50 #include "InspectorController.h"
51 #include "InspectorInstrumentation.h"
53 #include "MediaCanStartListener.h"
54 #include "MediaStreamClient.h"
55 #include "MediaStreamController.h"
56 #include "Navigator.h"
57 #include "NetworkStateNotifier.h"
58 #include "PageGroup.h"
59 #include "PluginData.h"
60 #include "PluginView.h"
61 #include "PluginViewBase.h"
62 #include "ProgressTracker.h"
63 #include "RenderTheme.h"
64 #include "RenderWidget.h"
65 #include "RuntimeEnabledFeatures.h"
67 #include "SharedBuffer.h"
68 #include "SpeechInput.h"
69 #include "SpeechInputClient.h"
70 #include "TextResourceDecoder.h"
72 #include <wtf/HashMap.h>
73 #include <wtf/RefCountedLeakCounter.h>
74 #include <wtf/StdLibExtras.h>
75 #include <wtf/text/StringHash.h>
77 #if ENABLE(DOM_STORAGE)
78 #include "StorageArea.h"
79 #include "StorageNamespace.h"
82 #if ENABLE(CLIENT_BASED_GEOLOCATION)
83 #include "GeolocationController.h"
88 static HashSet<Page*>* allPages;
91 static WTF::RefCountedLeakCounter pageCounter("Page");
94 static void networkStateChanged()
96 Vector<RefPtr<Frame> > frames;
98 // Get all the frames of all the pages in all the page groups
99 HashSet<Page*>::iterator end = allPages->end();
100 for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
101 for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext())
102 frames.append(frame);
103 InspectorInstrumentation::networkStateChanged(*it);
106 AtomicString eventName = networkStateNotifier().onLine() ? eventNames().onlineEvent : eventNames().offlineEvent;
107 for (unsigned i = 0; i < frames.size(); i++)
108 frames[i]->document()->dispatchWindowEvent(Event::create(eventName, false, false));
111 Page::Page(PageClients& pageClients)
112 : m_chrome(adoptPtr(new Chrome(this, pageClients.chromeClient)))
113 , m_dragCaretController(adoptPtr(new DragCaretController))
114 #if ENABLE(DRAG_SUPPORT)
115 , m_dragController(adoptPtr(new DragController(this, pageClients.dragClient)))
117 , m_focusController(adoptPtr(new FocusController(this)))
118 #if ENABLE(CONTEXT_MENUS)
119 , m_contextMenuController(adoptPtr(new ContextMenuController(this, pageClients.contextMenuClient)))
121 #if ENABLE(INSPECTOR)
122 , m_inspectorController(adoptPtr(new InspectorController(this, pageClients.inspectorClient)))
124 #if ENABLE(CLIENT_BASED_GEOLOCATION)
125 , m_geolocationController(adoptPtr(new GeolocationController(this, pageClients.geolocationClient)))
127 #if ENABLE(DEVICE_ORIENTATION)
128 , m_deviceMotionController(RuntimeEnabledFeatures::deviceMotionEnabled() ? adoptPtr(new DeviceMotionController(pageClients.deviceMotionClient)) : nullptr)
129 , m_deviceOrientationController(RuntimeEnabledFeatures::deviceOrientationEnabled() ? adoptPtr(new DeviceOrientationController(this, pageClients.deviceOrientationClient)) : nullptr)
131 #if ENABLE(MEDIA_STREAM)
132 , m_mediaStreamController(RuntimeEnabledFeatures::mediaStreamEnabled() ? adoptPtr(new MediaStreamController(pageClients.mediaStreamClient)) : PassOwnPtr<MediaStreamController>())
134 #if ENABLE(INPUT_SPEECH)
135 , m_speechInputClient(pageClients.speechInputClient)
137 , m_settings(adoptPtr(new Settings(this)))
138 , m_progress(adoptPtr(new ProgressTracker))
139 , m_backForwardController(adoptPtr(new BackForwardController(this, pageClients.backForwardClient)))
140 , m_theme(RenderTheme::themeForPage(this))
141 , m_editorClient(pageClients.editorClient)
143 , m_openedByDOM(false)
144 , m_tabKeyCyclesThroughElements(true)
145 , m_defersLoading(false)
146 , m_inLowQualityInterpolationMode(false)
147 , m_cookieEnabled(true)
148 , m_areMemoryCacheClientCallsEnabled(true)
150 , m_pageScaleFactor(1)
151 , m_deviceScaleFactor(1)
152 , m_javaScriptURLsAreAllowed(true)
153 , m_didLoadUserStyleSheet(false)
154 , m_userStyleSheetModificationTime(0)
157 , m_customHTMLTokenizerTimeDelay(-1)
158 , m_customHTMLTokenizerChunkSize(-1)
159 , m_canStartMedia(true)
160 , m_viewMode(ViewModeWindowed)
161 , m_minimumTimerInterval(Settings::defaultMinDOMTimerInterval())
162 , m_isEditable(false)
163 #if ENABLE(PAGE_VISIBILITY_API)
164 , m_visibilityState(PageVisibilityStateVisible)
168 allPages = new HashSet<Page*>;
170 networkStateNotifier().setNetworkStateChangedFunction(networkStateChanged);
173 ASSERT(!allPages->contains(this));
177 pageCounter.increment();
183 m_mainFrame->setView(0);
184 setGroupName(String());
185 allPages->remove(this);
187 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
188 frame->pageDestroyed();
190 if (m_scrollableAreaSet) {
191 ScrollableAreaSet::const_iterator end = m_scrollableAreaSet->end();
192 for (ScrollableAreaSet::const_iterator it = m_scrollableAreaSet->begin(); it != end; ++it)
193 (*it)->disconnectFromPage();
196 m_editorClient->pageDestroyed();
198 InspectorInstrumentation::inspectedPageDestroyed(this);
199 #if ENABLE(INSPECTOR)
200 m_inspectorController->inspectedPageDestroyed();
203 backForward()->close();
206 pageCounter.decrement();
210 struct ViewModeInfo {
214 static const int viewModeMapSize = 5;
215 static ViewModeInfo viewModeMap[viewModeMapSize] = {
216 {"windowed", Page::ViewModeWindowed},
217 {"floating", Page::ViewModeFloating},
218 {"fullscreen", Page::ViewModeFullscreen},
219 {"maximized", Page::ViewModeMaximized},
220 {"minimized", Page::ViewModeMinimized}
223 Page::ViewMode Page::stringToViewMode(const String& text)
225 for (int i = 0; i < viewModeMapSize; ++i) {
226 if (text == viewModeMap[i].name)
227 return viewModeMap[i].type;
229 return Page::ViewModeInvalid;
232 void Page::setViewMode(ViewMode viewMode)
234 if (viewMode == m_viewMode || viewMode == ViewModeInvalid)
237 m_viewMode = viewMode;
242 if (m_mainFrame->view())
243 m_mainFrame->view()->forceLayout();
245 if (m_mainFrame->document())
246 m_mainFrame->document()->styleSelectorChanged(RecalcStyleImmediately);
249 void Page::setMainFrame(PassRefPtr<Frame> mainFrame)
251 ASSERT(!m_mainFrame); // Should only be called during initialization
252 m_mainFrame = mainFrame;
255 bool Page::openedByDOM() const
257 return m_openedByDOM;
260 void Page::setOpenedByDOM()
262 m_openedByDOM = true;
265 BackForwardList* Page::backForwardList() const
267 return m_backForwardController->client();
272 HistoryItem* item = backForward()->backItem();
275 goToItem(item, FrameLoadTypeBack);
281 bool Page::goForward()
283 HistoryItem* item = backForward()->forwardItem();
286 goToItem(item, FrameLoadTypeForward);
292 bool Page::canGoBackOrForward(int distance) const
296 if (distance > 0 && distance <= backForward()->forwardCount())
298 if (distance < 0 && -distance <= backForward()->backCount())
303 void Page::goBackOrForward(int distance)
308 HistoryItem* item = backForward()->itemAtIndex(distance);
311 if (int forwardCount = backForward()->forwardCount())
312 item = backForward()->itemAtIndex(forwardCount);
314 if (int backCount = backForward()->backCount())
315 item = backForward()->itemAtIndex(-backCount);
323 goToItem(item, FrameLoadTypeIndexedBackForward);
326 void Page::goToItem(HistoryItem* item, FrameLoadType type)
328 // stopAllLoaders may end up running onload handlers, which could cause further history traversals that may lead to the passed in HistoryItem
329 // being deref()-ed. Make sure we can still use it with HistoryController::goToItem later.
330 RefPtr<HistoryItem> protector(item);
332 if (m_mainFrame->loader()->history()->shouldStopLoadingForHistoryItem(item))
333 m_mainFrame->loader()->stopAllLoaders();
335 m_mainFrame->loader()->history()->goToItem(item, type);
338 int Page::getHistoryLength()
340 return backForward()->backCount() + 1 + backForward()->forwardCount();
343 void Page::setGroupName(const String& name)
345 if (m_group && !m_group->name().isEmpty()) {
346 ASSERT(m_group != m_singlePageGroup.get());
347 ASSERT(!m_singlePageGroup);
348 m_group->removePage(this);
352 m_group = m_singlePageGroup.get();
354 m_singlePageGroup.clear();
355 m_group = PageGroup::pageGroup(name);
356 m_group->addPage(this);
360 const String& Page::groupName() const
362 DEFINE_STATIC_LOCAL(String, nullString, ());
363 return m_group ? m_group->name() : nullString;
366 void Page::initGroup()
368 ASSERT(!m_singlePageGroup);
370 m_singlePageGroup = adoptPtr(new PageGroup(this));
371 m_group = m_singlePageGroup.get();
374 void Page::scheduleForcedStyleRecalcForAllPages()
378 HashSet<Page*>::iterator end = allPages->end();
379 for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it)
380 for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext())
381 frame->document()->scheduleForcedStyleRecalc();
384 void Page::setNeedsRecalcStyleInAllFrames()
386 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
387 frame->document()->styleSelectorChanged(DeferRecalcStyle);
390 void Page::updateViewportArguments()
392 if (!mainFrame() || !mainFrame()->document() || mainFrame()->document()->viewportArguments() == m_viewportArguments)
395 m_viewportArguments = mainFrame()->document()->viewportArguments();
396 chrome()->dispatchViewportDataDidChange(m_viewportArguments);
399 void Page::refreshPlugins(bool reload)
404 PluginData::refresh();
406 Vector<RefPtr<Frame> > framesNeedingReload;
408 HashSet<Page*>::iterator end = allPages->end();
409 for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
412 // Clear out the page's plug-in data.
413 if (page->m_pluginData)
414 page->m_pluginData = 0;
419 for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
420 if (frame->loader()->subframeLoader()->containsPlugins())
421 framesNeedingReload.append(frame);
425 for (size_t i = 0; i < framesNeedingReload.size(); ++i)
426 framesNeedingReload[i]->loader()->reload();
429 PluginData* Page::pluginData() const
431 if (!mainFrame()->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin))
434 m_pluginData = PluginData::create(this);
435 return m_pluginData.get();
438 inline MediaCanStartListener* Page::takeAnyMediaCanStartListener()
440 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
441 if (MediaCanStartListener* listener = frame->document()->takeAnyMediaCanStartListener())
447 void Page::setCanStartMedia(bool canStartMedia)
449 if (m_canStartMedia == canStartMedia)
452 m_canStartMedia = canStartMedia;
454 while (m_canStartMedia) {
455 MediaCanStartListener* listener = takeAnyMediaCanStartListener();
458 listener->mediaCanStart();
462 static Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag)
465 ? curr->tree()->traverseNextWithWrap(wrapFlag)
466 : curr->tree()->traversePreviousWithWrap(wrapFlag);
469 bool Page::findString(const String& target, TextCaseSensitivity caseSensitivity, FindDirection direction, bool shouldWrap)
471 return findString(target, (caseSensitivity == TextCaseInsensitive ? CaseInsensitive : 0) | (direction == FindDirectionBackward ? Backwards : 0) | (shouldWrap ? WrapAround : 0));
474 bool Page::findString(const String& target, FindOptions options)
476 if (target.isEmpty() || !mainFrame())
479 bool shouldWrap = options & WrapAround;
480 Frame* frame = focusController()->focusedOrMainFrame();
481 Frame* startFrame = frame;
483 if (frame->editor()->findString(target, (options & ~WrapAround) | StartInSelection)) {
484 if (frame != startFrame)
485 startFrame->selection()->clear();
486 focusController()->setFocusedFrame(frame);
489 frame = incrementFrame(frame, !(options & Backwards), shouldWrap);
490 } while (frame && frame != startFrame);
492 // Search contents of startFrame, on the other side of the selection that we did earlier.
493 // We cheat a bit and just research with wrap on
494 if (shouldWrap && !startFrame->selection()->isNone()) {
495 bool found = startFrame->editor()->findString(target, options | WrapAround | StartInSelection);
496 focusController()->setFocusedFrame(frame);
503 PassRefPtr<Range> Page::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
505 if (target.isEmpty() || !mainFrame())
508 if (referenceRange && referenceRange->ownerDocument()->page() != this)
511 bool shouldWrap = options & WrapAround;
512 Frame* frame = referenceRange ? referenceRange->ownerDocument()->frame() : mainFrame();
513 Frame* startFrame = frame;
515 if (RefPtr<Range> resultRange = frame->editor()->rangeOfString(target, frame == startFrame ? referenceRange : 0, (options & ~WrapAround) | StartInSelection))
516 return resultRange.release();
518 frame = incrementFrame(frame, !(options & Backwards), shouldWrap);
519 } while (frame && frame != startFrame);
521 // Search contents of startFrame, on the other side of the reference range that we did earlier.
522 // We cheat a bit and just search again with wrap on.
523 if (shouldWrap && referenceRange) {
524 if (RefPtr<Range> resultRange = startFrame->editor()->rangeOfString(target, referenceRange, options | WrapAround | StartInSelection))
525 return resultRange.release();
531 unsigned int Page::markAllMatchesForText(const String& target, TextCaseSensitivity caseSensitivity, bool shouldHighlight, unsigned limit)
533 return markAllMatchesForText(target, caseSensitivity == TextCaseInsensitive ? CaseInsensitive : 0, shouldHighlight, limit);
536 unsigned int Page::markAllMatchesForText(const String& target, FindOptions options, bool shouldHighlight, unsigned limit)
538 if (target.isEmpty() || !mainFrame())
541 unsigned matches = 0;
543 Frame* frame = mainFrame();
545 frame->editor()->setMarkedTextMatchesAreHighlighted(shouldHighlight);
546 matches += frame->editor()->countMatchesForText(target, options, limit ? (limit - matches) : 0, true);
547 frame = incrementFrame(frame, true, false);
553 void Page::unmarkAllTextMatches()
558 Frame* frame = mainFrame();
560 frame->document()->markers()->removeMarkers(DocumentMarker::TextMatch);
561 frame = incrementFrame(frame, true, false);
565 const VisibleSelection& Page::selection() const
567 return focusController()->focusedOrMainFrame()->selection()->selection();
570 void Page::setDefersLoading(bool defers)
572 if (!m_settings->loadDeferringEnabled())
575 if (defers == m_defersLoading)
578 m_defersLoading = defers;
579 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
580 frame->loader()->setDefersLoading(defers);
583 void Page::clearUndoRedoOperations()
585 m_editorClient->clearUndoRedoOperations();
588 bool Page::inLowQualityImageInterpolationMode() const
590 return m_inLowQualityInterpolationMode;
593 void Page::setInLowQualityImageInterpolationMode(bool mode)
595 m_inLowQualityInterpolationMode = mode;
598 void Page::setMediaVolume(float volume)
600 if (volume < 0 || volume > 1)
603 if (m_mediaVolume == volume)
606 m_mediaVolume = volume;
607 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
608 frame->document()->mediaVolumeDidChange();
612 void Page::setPageScaleFactor(float scale, const LayoutPoint& origin)
614 if (scale == m_pageScaleFactor)
617 Document* document = mainFrame()->document();
619 m_pageScaleFactor = scale;
621 if (document->renderer())
622 document->renderer()->setNeedsLayout(true);
624 document->recalcStyle(Node::Force);
626 #if USE(ACCELERATED_COMPOSITING)
627 mainFrame()->deviceOrPageScaleFactorChanged();
630 if (FrameView* view = document->view()) {
631 if (view->scrollPosition() != origin) {
632 if (document->renderer() && document->renderer()->needsLayout() && view->didFirstLayout())
634 view->setScrollPosition(origin);
640 void Page::setDeviceScaleFactor(float scaleFactor)
642 if (m_deviceScaleFactor == scaleFactor)
645 m_deviceScaleFactor = scaleFactor;
646 setNeedsRecalcStyleInAllFrames();
648 #if USE(ACCELERATED_COMPOSITING)
649 m_mainFrame->deviceOrPageScaleFactorChanged();
652 backForward()->markPagesForFullStyleRecalc();
655 float Page::deviceScaleFactor(Frame* frame)
659 Page* page = frame->page();
662 return page->deviceScaleFactor();
665 void Page::didMoveOnscreen()
667 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
669 frame->view()->didMoveOnscreen();
673 void Page::willMoveOffscreen()
675 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
677 frame->view()->willMoveOffscreen();
681 void Page::userStyleSheetLocationChanged()
683 // FIXME: Eventually we will move to a model of just being handed the sheet
684 // text instead of loading the URL ourselves.
685 KURL url = m_settings->userStyleSheetLocation();
686 if (url.isLocalFile())
687 m_userStyleSheetPath = url.fileSystemPath();
689 m_userStyleSheetPath = String();
691 m_didLoadUserStyleSheet = false;
692 m_userStyleSheet = String();
693 m_userStyleSheetModificationTime = 0;
695 // Data URLs with base64-encoded UTF-8 style sheets are common. We can process them
696 // synchronously and avoid using a loader.
697 if (url.protocolIsData() && url.string().startsWith("data:text/css;charset=utf-8;base64,")) {
698 m_didLoadUserStyleSheet = true;
700 Vector<char> styleSheetAsUTF8;
701 if (base64Decode(decodeURLEscapeSequences(url.string().substring(35)), styleSheetAsUTF8, IgnoreWhitespace))
702 m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data(), styleSheetAsUTF8.size());
705 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
706 if (frame->document())
707 frame->document()->updatePageUserSheet();
711 const String& Page::userStyleSheet() const
713 if (m_userStyleSheetPath.isEmpty())
714 return m_userStyleSheet;
717 if (!getFileModificationTime(m_userStyleSheetPath, modTime)) {
718 // The stylesheet either doesn't exist, was just deleted, or is
719 // otherwise unreadable. If we've read the stylesheet before, we should
720 // throw away that data now as it no longer represents what's on disk.
721 m_userStyleSheet = String();
722 return m_userStyleSheet;
725 // If the stylesheet hasn't changed since the last time we read it, we can
726 // just return the old data.
727 if (m_didLoadUserStyleSheet && modTime <= m_userStyleSheetModificationTime)
728 return m_userStyleSheet;
730 m_didLoadUserStyleSheet = true;
731 m_userStyleSheet = String();
732 m_userStyleSheetModificationTime = modTime;
734 // FIXME: It would be better to load this asynchronously to avoid blocking
735 // the process, but we will first need to create an asynchronous loading
736 // mechanism that is not tied to a particular Frame. We will also have to
737 // determine what our behavior should be before the stylesheet is loaded
738 // and what should happen when it finishes loading, especially with respect
739 // to when the load event fires, when Document::close is called, and when
740 // layout/paint are allowed to happen.
741 RefPtr<SharedBuffer> data = SharedBuffer::createWithContentsOfFile(m_userStyleSheetPath);
743 return m_userStyleSheet;
745 RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/css");
746 m_userStyleSheet = decoder->decode(data->data(), data->size());
747 m_userStyleSheet += decoder->flush();
749 return m_userStyleSheet;
752 void Page::removeAllVisitedLinks()
756 HashSet<PageGroup*> groups;
757 HashSet<Page*>::iterator pagesEnd = allPages->end();
758 for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
759 if (PageGroup* group = (*it)->groupPtr())
762 HashSet<PageGroup*>::iterator groupsEnd = groups.end();
763 for (HashSet<PageGroup*>::iterator it = groups.begin(); it != groupsEnd; ++it)
764 (*it)->removeVisitedLinks();
767 void Page::allVisitedStateChanged(PageGroup* group)
773 HashSet<Page*>::iterator pagesEnd = allPages->end();
774 for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
776 if (page->m_group != group)
778 for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
779 if (CSSStyleSelector* styleSelector = frame->document()->styleSelector())
780 styleSelector->allVisitedStateChanged();
785 void Page::visitedStateChanged(PageGroup* group, LinkHash visitedLinkHash)
791 HashSet<Page*>::iterator pagesEnd = allPages->end();
792 for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
794 if (page->m_group != group)
796 for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
797 if (CSSStyleSelector* styleSelector = frame->document()->styleSelector())
798 styleSelector->visitedStateChanged(visitedLinkHash);
803 void Page::setDebuggerForAllPages(JSC::Debugger* debugger)
807 HashSet<Page*>::iterator end = allPages->end();
808 for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it)
809 (*it)->setDebugger(debugger);
812 void Page::setDebugger(JSC::Debugger* debugger)
814 if (m_debugger == debugger)
817 m_debugger = debugger;
819 for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree()->traverseNext())
820 frame->script()->attachDebugger(m_debugger);
823 #if ENABLE(DOM_STORAGE)
824 StorageNamespace* Page::sessionStorage(bool optionalCreate)
826 if (!m_sessionStorage && optionalCreate)
827 m_sessionStorage = StorageNamespace::sessionStorageNamespace(this, m_settings->sessionStorageQuota());
829 return m_sessionStorage.get();
832 void Page::setSessionStorage(PassRefPtr<StorageNamespace> newStorage)
834 m_sessionStorage = newStorage;
838 void Page::setCustomHTMLTokenizerTimeDelay(double customHTMLTokenizerTimeDelay)
840 if (customHTMLTokenizerTimeDelay < 0) {
841 m_customHTMLTokenizerTimeDelay = -1;
844 m_customHTMLTokenizerTimeDelay = customHTMLTokenizerTimeDelay;
847 void Page::setCustomHTMLTokenizerChunkSize(int customHTMLTokenizerChunkSize)
849 if (customHTMLTokenizerChunkSize < 0) {
850 m_customHTMLTokenizerChunkSize = -1;
853 m_customHTMLTokenizerChunkSize = customHTMLTokenizerChunkSize;
856 void Page::setMemoryCacheClientCallsEnabled(bool enabled)
858 if (m_areMemoryCacheClientCallsEnabled == enabled)
861 m_areMemoryCacheClientCallsEnabled = enabled;
865 for (RefPtr<Frame> frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
866 frame->loader()->tellClientAboutPastMemoryCacheLoads();
869 void Page::setJavaScriptURLsAreAllowed(bool areAllowed)
871 m_javaScriptURLsAreAllowed = areAllowed;
874 bool Page::javaScriptURLsAreAllowed() const
876 return m_javaScriptURLsAreAllowed;
879 void Page::setMinimumTimerInterval(double minimumTimerInterval)
881 double oldTimerInterval = m_minimumTimerInterval;
882 m_minimumTimerInterval = minimumTimerInterval;
883 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNextWithWrap(false)) {
884 if (frame->document())
885 frame->document()->adjustMinimumTimerInterval(oldTimerInterval);
889 double Page::minimumTimerInterval() const
891 return m_minimumTimerInterval;
894 #if ENABLE(INPUT_SPEECH)
895 SpeechInput* Page::speechInput()
897 ASSERT(m_speechInputClient);
898 if (!m_speechInput.get())
899 m_speechInput = adoptPtr(new SpeechInput(m_speechInputClient));
900 return m_speechInput.get();
904 void Page::dnsPrefetchingStateChanged()
906 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
907 frame->document()->initDNSPrefetch();
910 void Page::privateBrowsingStateChanged()
912 bool privateBrowsingEnabled = m_settings->privateBrowsingEnabled();
914 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
915 frame->document()->privateBrowsingStateDidChange();
917 // Collect the PluginViews in to a vector to ensure that action the plug-in takes
918 // from below privateBrowsingStateChanged does not affect their lifetime.
919 Vector<RefPtr<PluginViewBase>, 32> pluginViewBases;
920 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
921 FrameView* view = frame->view();
925 const HashSet<RefPtr<Widget> >* children = view->children();
928 HashSet<RefPtr<Widget> >::const_iterator end = children->end();
929 for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
930 Widget* widget = (*it).get();
931 if (widget->isPluginViewBase())
932 pluginViewBases.append(static_cast<PluginViewBase*>(widget));
936 for (size_t i = 0; i < pluginViewBases.size(); ++i)
937 pluginViewBases[i]->privateBrowsingStateChanged(privateBrowsingEnabled);
940 void Page::addScrollableArea(ScrollableArea* scrollableArea)
942 if (!m_scrollableAreaSet)
943 m_scrollableAreaSet = adoptPtr(new ScrollableAreaSet);
944 m_scrollableAreaSet->add(scrollableArea);
947 void Page::removeScrollableArea(ScrollableArea* scrollableArea)
949 if (!m_scrollableAreaSet)
951 m_scrollableAreaSet->remove(scrollableArea);
954 bool Page::containsScrollableArea(ScrollableArea* scrollableArea) const
956 if (!m_scrollableAreaSet)
958 return m_scrollableAreaSet->contains(scrollableArea);
962 void Page::checkFrameCountConsistency() const
964 ASSERT(m_frameCount >= 0);
967 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
970 ASSERT(m_frameCount + 1 == frameCount);
974 #if ENABLE(PAGE_VISIBILITY_API)
975 void Page::setVisibilityState(PageVisibilityState visibilityState, bool isInitialState)
977 if (m_visibilityState == visibilityState)
979 m_visibilityState = visibilityState;
981 if (!isInitialState && m_mainFrame)
982 m_mainFrame->dispatchVisibilityStateChangeEvent();
985 PageVisibilityState Page::visibilityState() const
987 return m_visibilityState;
991 Page::PageClients::PageClients()
993 , contextMenuClient(0)
997 , geolocationClient(0)
998 , deviceMotionClient(0)
999 , deviceOrientationClient(0)
1000 , speechInputClient(0)
1001 , mediaStreamClient(0)
1005 Page::PageClients::~PageClients()
1009 } // namespace WebCore