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 "Navigator.h"
55 #include "NetworkStateNotifier.h"
56 #include "NotificationController.h"
57 #include "NotificationPresenter.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 "RenderView.h"
65 #include "RenderWidget.h"
66 #include "RuntimeEnabledFeatures.h"
67 #include "SchemeRegistry.h"
69 #include "SharedBuffer.h"
70 #include "SpeechInput.h"
71 #include "SpeechInputClient.h"
72 #include "StorageArea.h"
73 #include "StorageNamespace.h"
74 #include "TextResourceDecoder.h"
76 #include <wtf/HashMap.h>
77 #include <wtf/RefCountedLeakCounter.h>
78 #include <wtf/StdLibExtras.h>
79 #include <wtf/text/StringHash.h>
81 #if ENABLE(CLIENT_BASED_GEOLOCATION)
82 #include "GeolocationController.h"
85 #if ENABLE(MEDIA_STREAM)
86 #include "UserMediaClient.h"
91 static HashSet<Page*>* allPages;
93 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page"));
95 static void networkStateChanged()
97 Vector<RefPtr<Frame> > frames;
99 // Get all the frames of all the pages in all the page groups
100 HashSet<Page*>::iterator end = allPages->end();
101 for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
102 for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext())
103 frames.append(frame);
104 InspectorInstrumentation::networkStateChanged(*it);
107 AtomicString eventName = networkStateNotifier().onLine() ? eventNames().onlineEvent : eventNames().offlineEvent;
108 for (unsigned i = 0; i < frames.size(); i++)
109 frames[i]->document()->dispatchWindowEvent(Event::create(eventName, false, false));
112 float deviceScaleFactor(Frame* frame)
116 Page* page = frame->page();
119 return page->deviceScaleFactor();
122 Page::Page(PageClients& pageClients)
123 : m_chrome(adoptPtr(new Chrome(this, pageClients.chromeClient)))
124 , m_dragCaretController(adoptPtr(new DragCaretController))
125 #if ENABLE(DRAG_SUPPORT)
126 , m_dragController(adoptPtr(new DragController(this, pageClients.dragClient)))
128 , m_focusController(adoptPtr(new FocusController(this)))
129 #if ENABLE(CONTEXT_MENUS)
130 , m_contextMenuController(adoptPtr(new ContextMenuController(this, pageClients.contextMenuClient)))
132 #if ENABLE(INSPECTOR)
133 , m_inspectorController(adoptPtr(new InspectorController(this, pageClients.inspectorClient)))
135 #if ENABLE(CLIENT_BASED_GEOLOCATION)
136 , m_geolocationController(adoptPtr(new GeolocationController(this, pageClients.geolocationClient)))
138 #if ENABLE(DEVICE_ORIENTATION)
139 , m_deviceMotionController(RuntimeEnabledFeatures::deviceMotionEnabled() ? adoptPtr(new DeviceMotionController(pageClients.deviceMotionClient)) : nullptr)
140 , m_deviceOrientationController(RuntimeEnabledFeatures::deviceOrientationEnabled() ? adoptPtr(new DeviceOrientationController(this, pageClients.deviceOrientationClient)) : nullptr)
142 #if ENABLE(NOTIFICATIONS)
143 , m_notificationController(adoptPtr(new NotificationController(this, pageClients.notificationClient)))
145 #if ENABLE(INPUT_SPEECH)
146 , m_speechInputClient(pageClients.speechInputClient)
148 #if ENABLE(MEDIA_STREAM)
149 , m_userMediaClient(pageClients.userMediaClient)
151 , m_settings(adoptPtr(new Settings(this)))
152 , m_progress(adoptPtr(new ProgressTracker))
153 , m_backForwardController(adoptPtr(new BackForwardController(this, pageClients.backForwardClient)))
154 , m_theme(RenderTheme::themeForPage(this))
155 , m_editorClient(pageClients.editorClient)
157 , m_openedByDOM(false)
158 , m_tabKeyCyclesThroughElements(true)
159 , m_defersLoading(false)
160 , m_inLowQualityInterpolationMode(false)
161 , m_cookieEnabled(true)
162 , m_areMemoryCacheClientCallsEnabled(true)
164 , m_pageScaleFactor(1)
165 , m_deviceScaleFactor(1)
166 , m_javaScriptURLsAreAllowed(true)
167 , m_didLoadUserStyleSheet(false)
168 , m_userStyleSheetModificationTime(0)
171 , m_customHTMLTokenizerTimeDelay(-1)
172 , m_customHTMLTokenizerChunkSize(-1)
173 , m_canStartMedia(true)
174 , m_viewMode(ViewModeWindowed)
175 , m_minimumTimerInterval(Settings::defaultMinDOMTimerInterval())
176 #if ENABLE(TIZEN_JS_PERMISSION_CHECKER)
177 , m_deferStatus(RESUMED)
180 , m_isEditable(false)
181 #if ENABLE(PAGE_VISIBILITY_API)
182 , m_visibilityState(PageVisibilityStateVisible)
187 allPages = new HashSet<Page*>;
189 networkStateNotifier().setNetworkStateChangedFunction(networkStateChanged);
192 ASSERT(!allPages->contains(this));
196 pageCounter.increment();
202 #if ENABLE(TIZEN_JS_PERMISSION_CHECKER)
203 if (m_deferStatus != SUSPENDED)
206 m_mainFrame->setView(0);
207 setGroupName(String());
208 allPages->remove(this);
210 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
211 frame->pageDestroyed();
213 if (m_scrollableAreaSet) {
214 ScrollableAreaSet::const_iterator end = m_scrollableAreaSet->end();
215 for (ScrollableAreaSet::const_iterator it = m_scrollableAreaSet->begin(); it != end; ++it)
216 (*it)->disconnectFromPage();
219 m_editorClient->pageDestroyed();
221 #if ENABLE(INSPECTOR)
222 m_inspectorController->inspectedPageDestroyed();
225 #if ENABLE(MEDIA_STREAM)
226 if (m_userMediaClient)
227 m_userMediaClient->pageDestroyed();
230 backForward()->close();
233 pageCounter.decrement();
237 struct ViewModeInfo {
241 static const int viewModeMapSize = 5;
242 static ViewModeInfo viewModeMap[viewModeMapSize] = {
243 {"windowed", Page::ViewModeWindowed},
244 {"floating", Page::ViewModeFloating},
245 {"fullscreen", Page::ViewModeFullscreen},
246 {"maximized", Page::ViewModeMaximized},
247 {"minimized", Page::ViewModeMinimized}
250 Page::ViewMode Page::stringToViewMode(const String& text)
252 for (int i = 0; i < viewModeMapSize; ++i) {
253 if (text == viewModeMap[i].name)
254 return viewModeMap[i].type;
256 return Page::ViewModeInvalid;
259 void Page::setViewMode(ViewMode viewMode)
261 if (viewMode == m_viewMode || viewMode == ViewModeInvalid)
264 m_viewMode = viewMode;
269 if (m_mainFrame->view())
270 m_mainFrame->view()->forceLayout();
272 if (m_mainFrame->document())
273 m_mainFrame->document()->styleSelectorChanged(RecalcStyleImmediately);
276 void Page::setMainFrame(PassRefPtr<Frame> mainFrame)
278 ASSERT(!m_mainFrame); // Should only be called during initialization
279 m_mainFrame = mainFrame;
282 bool Page::openedByDOM() const
284 return m_openedByDOM;
287 void Page::setOpenedByDOM()
289 m_openedByDOM = true;
292 BackForwardList* Page::backForwardList() const
294 return m_backForwardController->client();
299 HistoryItem* item = backForward()->backItem();
302 goToItem(item, FrameLoadTypeBack);
308 bool Page::goForward()
310 HistoryItem* item = backForward()->forwardItem();
313 goToItem(item, FrameLoadTypeForward);
319 bool Page::canGoBackOrForward(int distance) const
323 if (distance > 0 && distance <= backForward()->forwardCount())
325 if (distance < 0 && -distance <= backForward()->backCount())
330 void Page::goBackOrForward(int distance)
335 HistoryItem* item = backForward()->itemAtIndex(distance);
338 if (int forwardCount = backForward()->forwardCount())
339 item = backForward()->itemAtIndex(forwardCount);
341 if (int backCount = backForward()->backCount())
342 item = backForward()->itemAtIndex(-backCount);
350 goToItem(item, FrameLoadTypeIndexedBackForward);
353 void Page::goToItem(HistoryItem* item, FrameLoadType type)
355 // stopAllLoaders may end up running onload handlers, which could cause further history traversals that may lead to the passed in HistoryItem
356 // being deref()-ed. Make sure we can still use it with HistoryController::goToItem later.
357 RefPtr<HistoryItem> protector(item);
359 if (m_mainFrame->loader()->history()->shouldStopLoadingForHistoryItem(item))
360 m_mainFrame->loader()->stopAllLoaders();
362 m_mainFrame->loader()->history()->goToItem(item, type);
365 int Page::getHistoryLength()
367 return backForward()->backCount() + 1 + backForward()->forwardCount();
370 void Page::setGroupName(const String& name)
372 if (m_group && !m_group->name().isEmpty()) {
373 ASSERT(m_group != m_singlePageGroup.get());
374 ASSERT(!m_singlePageGroup);
375 m_group->removePage(this);
379 m_group = m_singlePageGroup.get();
381 m_singlePageGroup.clear();
382 m_group = PageGroup::pageGroup(name);
383 m_group->addPage(this);
387 const String& Page::groupName() const
389 DEFINE_STATIC_LOCAL(String, nullString, ());
390 return m_group ? m_group->name() : nullString;
393 void Page::initGroup()
395 ASSERT(!m_singlePageGroup);
397 m_singlePageGroup = adoptPtr(new PageGroup(this));
398 m_group = m_singlePageGroup.get();
401 void Page::scheduleForcedStyleRecalcForAllPages()
405 HashSet<Page*>::iterator end = allPages->end();
406 for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it)
407 for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext())
408 frame->document()->scheduleForcedStyleRecalc();
411 void Page::setNeedsRecalcStyleInAllFrames()
413 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
414 frame->document()->styleSelectorChanged(DeferRecalcStyle);
417 void Page::updateViewportArguments()
419 if (!mainFrame() || !mainFrame()->document())
422 m_viewportArguments = mainFrame()->document()->viewportArguments();
423 chrome()->dispatchViewportPropertiesDidChange(m_viewportArguments);
426 void Page::refreshPlugins(bool reload)
431 PluginData::refresh();
433 Vector<RefPtr<Frame> > framesNeedingReload;
435 HashSet<Page*>::iterator end = allPages->end();
436 for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
439 // Clear out the page's plug-in data.
440 if (page->m_pluginData)
441 page->m_pluginData = 0;
446 for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
447 if (frame->loader()->subframeLoader()->containsPlugins())
448 framesNeedingReload.append(frame);
452 for (size_t i = 0; i < framesNeedingReload.size(); ++i)
453 framesNeedingReload[i]->loader()->reload();
456 PluginData* Page::pluginData() const
458 if (!mainFrame()->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin))
461 m_pluginData = PluginData::create(this);
462 return m_pluginData.get();
465 inline MediaCanStartListener* Page::takeAnyMediaCanStartListener()
467 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
468 if (MediaCanStartListener* listener = frame->document()->takeAnyMediaCanStartListener())
474 void Page::setCanStartMedia(bool canStartMedia)
476 if (m_canStartMedia == canStartMedia)
479 m_canStartMedia = canStartMedia;
481 while (m_canStartMedia) {
482 MediaCanStartListener* listener = takeAnyMediaCanStartListener();
485 listener->mediaCanStart();
489 static Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag)
492 ? curr->tree()->traverseNextWithWrap(wrapFlag)
493 : curr->tree()->traversePreviousWithWrap(wrapFlag);
496 bool Page::findString(const String& target, TextCaseSensitivity caseSensitivity, FindDirection direction, bool shouldWrap)
498 return findString(target, (caseSensitivity == TextCaseInsensitive ? CaseInsensitive : 0) | (direction == FindDirectionBackward ? Backwards : 0) | (shouldWrap ? WrapAround : 0));
501 bool Page::findString(const String& target, FindOptions options)
503 if (target.isEmpty() || !mainFrame())
506 bool shouldWrap = options & WrapAround;
507 Frame* frame = focusController()->focusedOrMainFrame();
508 Frame* startFrame = frame;
510 if (frame->editor()->findString(target, (options & ~WrapAround) | StartInSelection)) {
511 if (frame != startFrame)
512 startFrame->selection()->clear();
513 focusController()->setFocusedFrame(frame);
516 frame = incrementFrame(frame, !(options & Backwards), shouldWrap);
517 } while (frame && frame != startFrame);
519 // Search contents of startFrame, on the other side of the selection that we did earlier.
520 // We cheat a bit and just research with wrap on
521 if (shouldWrap && !startFrame->selection()->isNone()) {
522 bool found = startFrame->editor()->findString(target, options | WrapAround | StartInSelection);
523 focusController()->setFocusedFrame(frame);
530 PassRefPtr<Range> Page::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
532 if (target.isEmpty() || !mainFrame())
535 if (referenceRange && referenceRange->ownerDocument()->page() != this)
538 bool shouldWrap = options & WrapAround;
539 Frame* frame = referenceRange ? referenceRange->ownerDocument()->frame() : mainFrame();
540 Frame* startFrame = frame;
542 if (RefPtr<Range> resultRange = frame->editor()->rangeOfString(target, frame == startFrame ? referenceRange : 0, options & ~WrapAround))
543 return resultRange.release();
545 frame = incrementFrame(frame, !(options & Backwards), shouldWrap);
546 } while (frame && frame != startFrame);
548 // Search contents of startFrame, on the other side of the reference range that we did earlier.
549 // We cheat a bit and just search again with wrap on.
550 if (shouldWrap && referenceRange) {
551 if (RefPtr<Range> resultRange = startFrame->editor()->rangeOfString(target, referenceRange, options | WrapAround | StartInSelection))
552 return resultRange.release();
558 unsigned int Page::markAllMatchesForText(const String& target, TextCaseSensitivity caseSensitivity, bool shouldHighlight, unsigned limit)
560 return markAllMatchesForText(target, caseSensitivity == TextCaseInsensitive ? CaseInsensitive : 0, shouldHighlight, limit);
563 unsigned int Page::markAllMatchesForText(const String& target, FindOptions options, bool shouldHighlight, unsigned limit)
565 if (target.isEmpty() || !mainFrame())
568 unsigned matches = 0;
570 Frame* frame = mainFrame();
572 frame->editor()->setMarkedTextMatchesAreHighlighted(shouldHighlight);
573 matches += frame->editor()->countMatchesForText(target, options, limit ? (limit - matches) : 0, true);
574 frame = incrementFrame(frame, true, false);
580 void Page::unmarkAllTextMatches()
585 Frame* frame = mainFrame();
587 frame->document()->markers()->removeMarkers(DocumentMarker::TextMatch);
588 frame = incrementFrame(frame, true, false);
592 const VisibleSelection& Page::selection() const
594 return focusController()->focusedOrMainFrame()->selection()->selection();
597 void Page::setDefersLoading(bool defers)
599 if (!m_settings->loadDeferringEnabled())
602 if (defers == m_defersLoading)
605 m_defersLoading = defers;
606 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
607 frame->loader()->setDefersLoading(defers);
610 void Page::clearUndoRedoOperations()
612 m_editorClient->clearUndoRedoOperations();
615 bool Page::inLowQualityImageInterpolationMode() const
617 return m_inLowQualityInterpolationMode;
620 void Page::setInLowQualityImageInterpolationMode(bool mode)
622 m_inLowQualityInterpolationMode = mode;
625 void Page::setMediaVolume(float volume)
627 if (volume < 0 || volume > 1)
630 if (m_mediaVolume == volume)
633 m_mediaVolume = volume;
634 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
635 frame->document()->mediaVolumeDidChange();
639 void Page::setPageScaleFactor(float scale, const IntPoint& origin)
641 if (scale == m_pageScaleFactor)
644 Document* document = mainFrame()->document();
646 m_pageScaleFactor = scale;
648 if (document->renderer())
649 document->renderer()->setNeedsLayout(true);
651 document->recalcStyle(Node::Force);
653 #if USE(ACCELERATED_COMPOSITING)
654 mainFrame()->deviceOrPageScaleFactorChanged();
657 if (FrameView* view = document->view()) {
658 if (view->scrollPosition() != origin) {
659 if (document->renderer() && document->renderer()->needsLayout() && view->didFirstLayout())
661 view->setScrollPosition(origin);
667 void Page::setDeviceScaleFactor(float scaleFactor)
669 if (m_deviceScaleFactor == scaleFactor)
672 m_deviceScaleFactor = scaleFactor;
673 setNeedsRecalcStyleInAllFrames();
675 #if USE(ACCELERATED_COMPOSITING)
677 mainFrame()->deviceOrPageScaleFactorChanged();
680 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
681 frame->editor()->deviceScaleFactorChanged();
683 backForward()->markPagesForFullStyleRecalc();
686 void Page::setPagination(const Pagination& pagination)
688 if (m_pagination.mode == pagination.mode && m_pagination.gap == pagination.gap)
691 m_pagination = pagination;
693 setNeedsRecalcStyleInAllFrames();
694 backForward()->markPagesForFullStyleRecalc();
697 unsigned Page::pageCount() const
699 if (m_pagination.mode == Pagination::Unpaginated)
702 FrameView* frameView = mainFrame()->view();
703 if (!frameView->didFirstLayout())
706 mainFrame()->view()->forceLayout();
708 RenderView* contentRenderer = mainFrame()->contentRenderer();
709 return contentRenderer->columnCount(contentRenderer->columnInfo());
712 void Page::didMoveOnscreen()
714 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
716 frame->view()->didMoveOnscreen();
719 resumeScriptedAnimations();
722 void Page::willMoveOffscreen()
724 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
726 frame->view()->willMoveOffscreen();
729 suspendScriptedAnimations();
732 void Page::windowScreenDidChange(PlatformDisplayID displayID)
734 m_displayID = displayID;
736 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
737 if (frame->document())
738 frame->document()->windowScreenDidChange(displayID);
742 void Page::suspendScriptedAnimations()
744 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
745 if (frame->document())
746 frame->document()->suspendScriptedAnimationControllerCallbacks();
750 void Page::resumeScriptedAnimations()
752 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
753 if (frame->document())
754 frame->document()->resumeScriptedAnimationControllerCallbacks();
758 void Page::userStyleSheetLocationChanged()
760 // FIXME: Eventually we will move to a model of just being handed the sheet
761 // text instead of loading the URL ourselves.
762 KURL url = m_settings->userStyleSheetLocation();
764 // Allow any local file URL scheme to be loaded.
765 if (SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol()))
766 m_userStyleSheetPath = url.fileSystemPath();
768 m_userStyleSheetPath = String();
770 m_didLoadUserStyleSheet = false;
771 m_userStyleSheet = String();
772 m_userStyleSheetModificationTime = 0;
774 // Data URLs with base64-encoded UTF-8 style sheets are common. We can process them
775 // synchronously and avoid using a loader.
776 if (url.protocolIsData() && url.string().startsWith("data:text/css;charset=utf-8;base64,")) {
777 m_didLoadUserStyleSheet = true;
779 Vector<char> styleSheetAsUTF8;
780 if (base64Decode(decodeURLEscapeSequences(url.string().substring(35)), styleSheetAsUTF8, IgnoreWhitespace))
781 m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data(), styleSheetAsUTF8.size());
784 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
785 if (frame->document())
786 frame->document()->updatePageUserSheet();
790 const String& Page::userStyleSheet() const
792 if (m_userStyleSheetPath.isEmpty())
793 return m_userStyleSheet;
796 if (!getFileModificationTime(m_userStyleSheetPath, modTime)) {
797 // The stylesheet either doesn't exist, was just deleted, or is
798 // otherwise unreadable. If we've read the stylesheet before, we should
799 // throw away that data now as it no longer represents what's on disk.
800 m_userStyleSheet = String();
801 return m_userStyleSheet;
804 // If the stylesheet hasn't changed since the last time we read it, we can
805 // just return the old data.
806 if (m_didLoadUserStyleSheet && modTime <= m_userStyleSheetModificationTime)
807 return m_userStyleSheet;
809 m_didLoadUserStyleSheet = true;
810 m_userStyleSheet = String();
811 m_userStyleSheetModificationTime = modTime;
813 // FIXME: It would be better to load this asynchronously to avoid blocking
814 // the process, but we will first need to create an asynchronous loading
815 // mechanism that is not tied to a particular Frame. We will also have to
816 // determine what our behavior should be before the stylesheet is loaded
817 // and what should happen when it finishes loading, especially with respect
818 // to when the load event fires, when Document::close is called, and when
819 // layout/paint are allowed to happen.
820 RefPtr<SharedBuffer> data = SharedBuffer::createWithContentsOfFile(m_userStyleSheetPath);
822 return m_userStyleSheet;
824 RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/css");
825 m_userStyleSheet = decoder->decode(data->data(), data->size());
826 m_userStyleSheet += decoder->flush();
828 return m_userStyleSheet;
831 void Page::removeAllVisitedLinks()
835 HashSet<PageGroup*> groups;
836 HashSet<Page*>::iterator pagesEnd = allPages->end();
837 for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
838 if (PageGroup* group = (*it)->groupPtr())
841 HashSet<PageGroup*>::iterator groupsEnd = groups.end();
842 for (HashSet<PageGroup*>::iterator it = groups.begin(); it != groupsEnd; ++it)
843 (*it)->removeVisitedLinks();
846 void Page::allVisitedStateChanged(PageGroup* group)
852 HashSet<Page*>::iterator pagesEnd = allPages->end();
853 for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
855 if (page->m_group != group)
857 for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
858 if (CSSStyleSelector* styleSelector = frame->document()->styleSelector())
859 styleSelector->allVisitedStateChanged();
864 void Page::visitedStateChanged(PageGroup* group, LinkHash visitedLinkHash)
870 HashSet<Page*>::iterator pagesEnd = allPages->end();
871 for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
873 if (page->m_group != group)
875 for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) {
876 if (CSSStyleSelector* styleSelector = frame->document()->styleSelector())
877 styleSelector->visitedStateChanged(visitedLinkHash);
882 void Page::setDebuggerForAllPages(JSC::Debugger* debugger)
886 HashSet<Page*>::iterator end = allPages->end();
887 for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it)
888 (*it)->setDebugger(debugger);
891 void Page::setDebugger(JSC::Debugger* debugger)
893 if (m_debugger == debugger)
896 m_debugger = debugger;
898 for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree()->traverseNext())
899 frame->script()->attachDebugger(m_debugger);
902 StorageNamespace* Page::sessionStorage(bool optionalCreate)
904 if (!m_sessionStorage && optionalCreate)
905 m_sessionStorage = StorageNamespace::sessionStorageNamespace(this, m_settings->sessionStorageQuota());
907 return m_sessionStorage.get();
910 void Page::setSessionStorage(PassRefPtr<StorageNamespace> newStorage)
912 m_sessionStorage = newStorage;
915 void Page::setCustomHTMLTokenizerTimeDelay(double customHTMLTokenizerTimeDelay)
917 if (customHTMLTokenizerTimeDelay < 0) {
918 m_customHTMLTokenizerTimeDelay = -1;
921 m_customHTMLTokenizerTimeDelay = customHTMLTokenizerTimeDelay;
924 void Page::setCustomHTMLTokenizerChunkSize(int customHTMLTokenizerChunkSize)
926 if (customHTMLTokenizerChunkSize < 0) {
927 m_customHTMLTokenizerChunkSize = -1;
930 m_customHTMLTokenizerChunkSize = customHTMLTokenizerChunkSize;
933 void Page::setMemoryCacheClientCallsEnabled(bool enabled)
935 if (m_areMemoryCacheClientCallsEnabled == enabled)
938 m_areMemoryCacheClientCallsEnabled = enabled;
942 for (RefPtr<Frame> frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
943 frame->loader()->tellClientAboutPastMemoryCacheLoads();
946 void Page::setJavaScriptURLsAreAllowed(bool areAllowed)
948 m_javaScriptURLsAreAllowed = areAllowed;
951 bool Page::javaScriptURLsAreAllowed() const
953 return m_javaScriptURLsAreAllowed;
956 void Page::setMinimumTimerInterval(double minimumTimerInterval)
958 double oldTimerInterval = m_minimumTimerInterval;
959 m_minimumTimerInterval = minimumTimerInterval;
960 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNextWithWrap(false)) {
961 if (frame->document())
962 frame->document()->adjustMinimumTimerInterval(oldTimerInterval);
966 double Page::minimumTimerInterval() const
968 return m_minimumTimerInterval;
971 #if ENABLE(INPUT_SPEECH)
972 SpeechInput* Page::speechInput()
974 ASSERT(m_speechInputClient);
975 if (!m_speechInput.get())
976 m_speechInput = adoptPtr(new SpeechInput(m_speechInputClient));
977 return m_speechInput.get();
981 void Page::dnsPrefetchingStateChanged()
983 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
984 frame->document()->initDNSPrefetch();
987 void Page::privateBrowsingStateChanged()
989 bool privateBrowsingEnabled = m_settings->privateBrowsingEnabled();
991 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
992 frame->document()->privateBrowsingStateDidChange();
994 // Collect the PluginViews in to a vector to ensure that action the plug-in takes
995 // from below privateBrowsingStateChanged does not affect their lifetime.
996 Vector<RefPtr<PluginViewBase>, 32> pluginViewBases;
997 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
998 FrameView* view = frame->view();
1002 const HashSet<RefPtr<Widget> >* children = view->children();
1005 HashSet<RefPtr<Widget> >::const_iterator end = children->end();
1006 for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
1007 Widget* widget = (*it).get();
1008 if (widget->isPluginViewBase())
1009 pluginViewBases.append(static_cast<PluginViewBase*>(widget));
1013 for (size_t i = 0; i < pluginViewBases.size(); ++i)
1014 pluginViewBases[i]->privateBrowsingStateChanged(privateBrowsingEnabled);
1017 void Page::addScrollableArea(ScrollableArea* scrollableArea)
1019 if (!m_scrollableAreaSet)
1020 m_scrollableAreaSet = adoptPtr(new ScrollableAreaSet);
1021 m_scrollableAreaSet->add(scrollableArea);
1024 void Page::removeScrollableArea(ScrollableArea* scrollableArea)
1026 if (!m_scrollableAreaSet)
1028 m_scrollableAreaSet->remove(scrollableArea);
1031 bool Page::containsScrollableArea(ScrollableArea* scrollableArea) const
1033 if (!m_scrollableAreaSet)
1035 return m_scrollableAreaSet->contains(scrollableArea);
1038 #if !ASSERT_DISABLED
1039 void Page::checkFrameCountConsistency() const
1041 ASSERT(m_frameCount >= 0);
1044 for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
1047 ASSERT(m_frameCount + 1 == frameCount);
1051 #if ENABLE(PAGE_VISIBILITY_API)
1052 void Page::setVisibilityState(PageVisibilityState visibilityState, bool isInitialState)
1054 if (m_visibilityState == visibilityState)
1056 m_visibilityState = visibilityState;
1058 if (!isInitialState && m_mainFrame)
1059 m_mainFrame->dispatchVisibilityStateChangeEvent();
1062 PageVisibilityState Page::visibilityState() const
1064 return m_visibilityState;
1068 Page::PageClients::PageClients()
1070 , contextMenuClient(0)
1073 , inspectorClient(0)
1074 , geolocationClient(0)
1075 , deviceMotionClient(0)
1076 , deviceOrientationClient(0)
1077 , speechInputClient(0)
1078 , notificationClient(0)
1079 , userMediaClient(0)
1083 Page::PageClients::~PageClients()
1087 #if ENABLE(TIZEN_JS_PERMISSION_CHECKER)
1088 void Page::suspendJavaScript()
1090 // Old deferrer could block different object then new one.
1091 // We need to "reblock" all active object once again.
1092 m_deferStatus = SUSPENDING;
1094 m_deferrer = new PageGroupLoadDeferrer(this, true);
1095 m_deferStatus = SUSPENDED;
1098 void Page::resumeJavaScript()
1100 if (m_deferStatus != SUSPENDED)
1103 m_deferStatus = RESUMING;
1106 m_deferStatus = RESUMED;
1110 } // namespace WebCore