1/*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 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 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#ifndef Page_h
22#define Page_h
23
24#include "FrameLoaderTypes.h"
25#include "FindOptions.h"
26#include "PlatformString.h"
27#include "ViewportArguments.h"
28#include <wtf/Forward.h>
29#include <wtf/HashSet.h>
30#include <wtf/Noncopyable.h>
31
32#if OS(SOLARIS)
33#include <sys/time.h> // For time_t structure.
34#endif
35
36#if PLATFORM(MAC)
37#include "SchedulePair.h"
38#endif
39
40namespace JSC {
41    class Debugger;
42}
43
44namespace WebCore {
45
46    class BackForwardController;
47    class BackForwardList;
48    class Chrome;
49    class ChromeClient;
50    class ContextMenuClient;
51    class ContextMenuController;
52    class DeviceMotionClient;
53    class DeviceMotionController;
54    class DeviceOrientationClient;
55    class DeviceOrientationController;
56    class Document;
57    class DragClient;
58    class DragController;
59    class EditorClient;
60    class FocusController;
61    class Frame;
62    class GeolocationClient;
63    class GeolocationController;
64    class HaltablePlugin;
65    class HistoryItem;
66    class InspectorClient;
67    class InspectorController;
68    class MediaCanStartListener;
69    class Node;
70    class PageGroup;
71    class PluginData;
72    class PluginHalter;
73    class PluginHalterClient;
74    class ProgressTracker;
75    class RenderTheme;
76    class VisibleSelection;
77    class ScrollableArea;
78    class SelectionController;
79    class Settings;
80    class SharedGraphicsContext3D;
81    class SpeechInput;
82    class SpeechInputClient;
83#if ENABLE(DOM_STORAGE)
84    class StorageNamespace;
85#endif
86#if ENABLE(NOTIFICATIONS)
87    class NotificationPresenter;
88#endif
89#if ENABLE(WML)
90    class WMLPageState;
91#endif
92
93    typedef uint64_t LinkHash;
94
95    enum FindDirection { FindDirectionForward, FindDirectionBackward };
96
97    class Page {
98        WTF_MAKE_NONCOPYABLE(Page);
99        friend class Settings;
100    public:
101        static void scheduleForcedStyleRecalcForAllPages();
102
103        // It is up to the platform to ensure that non-null clients are provided where required.
104        struct PageClients {
105            WTF_MAKE_NONCOPYABLE(PageClients); WTF_MAKE_FAST_ALLOCATED;
106        public:
107            PageClients();
108            ~PageClients();
109
110            ChromeClient* chromeClient;
111            ContextMenuClient* contextMenuClient;
112            EditorClient* editorClient;
113            DragClient* dragClient;
114            InspectorClient* inspectorClient;
115            PluginHalterClient* pluginHalterClient;
116            GeolocationClient* geolocationClient;
117            DeviceMotionClient* deviceMotionClient;
118            DeviceOrientationClient* deviceOrientationClient;
119            RefPtr<BackForwardList> backForwardClient;
120            SpeechInputClient* speechInputClient;
121        };
122
123        Page(const PageClients&);
124        ~Page();
125
126        void setNeedsRecalcStyleInAllFrames();
127
128        RenderTheme* theme() const { return m_theme.get(); };
129
130        ViewportArguments viewportArguments() const { return m_viewportArguments; }
131        void updateViewportArguments();
132
133        static void refreshPlugins(bool reload);
134        PluginData* pluginData() const;
135
136        void setCanStartMedia(bool);
137        bool canStartMedia() const { return m_canStartMedia; }
138
139        EditorClient* editorClient() const { return m_editorClient; }
140
141        void setMainFrame(PassRefPtr<Frame>);
142        Frame* mainFrame() const { return m_mainFrame.get(); }
143
144        bool openedByDOM() const;
145        void setOpenedByDOM();
146
147        // DEPRECATED. Use backForward() instead of the following 6 functions.
148        BackForwardList* backForwardList() const;
149        bool goBack();
150        bool goForward();
151        bool canGoBackOrForward(int distance) const;
152        void goBackOrForward(int distance);
153        int getHistoryLength();
154
155        void goToItem(HistoryItem*, FrameLoadType);
156
157        void setGroupName(const String&);
158        const String& groupName() const;
159
160        PageGroup& group() { if (!m_group) initGroup(); return *m_group; }
161        PageGroup* groupPtr() { return m_group; } // can return 0
162
163        void incrementFrameCount() { ++m_frameCount; }
164        void decrementFrameCount() { ASSERT(m_frameCount); --m_frameCount; }
165        int frameCount() const { checkFrameCountConsistency(); return m_frameCount; }
166
167        Chrome* chrome() const { return m_chrome.get(); }
168        SelectionController* dragCaretController() const { return m_dragCaretController.get(); }
169#if ENABLE(DRAG_SUPPORT)
170        DragController* dragController() const { return m_dragController.get(); }
171#endif
172        FocusController* focusController() const { return m_focusController.get(); }
173#if ENABLE(CONTEXT_MENUS)
174        ContextMenuController* contextMenuController() const { return m_contextMenuController.get(); }
175#endif
176#if ENABLE(INSPECTOR)
177        InspectorController* inspectorController() const { return m_inspectorController.get(); }
178#endif
179#if ENABLE(CLIENT_BASED_GEOLOCATION)
180        GeolocationController* geolocationController() const { return m_geolocationController.get(); }
181#endif
182#if ENABLE(DEVICE_ORIENTATION)
183        DeviceMotionController* deviceMotionController() const { return m_deviceMotionController.get(); }
184        DeviceOrientationController* deviceOrientationController() const { return m_deviceOrientationController.get(); }
185#endif
186#if ENABLE(INPUT_SPEECH)
187        SpeechInput* speechInput();
188#endif
189        Settings* settings() const { return m_settings.get(); }
190        ProgressTracker* progress() const { return m_progress.get(); }
191        BackForwardController* backForward() const { return m_backForwardController.get(); }
192
193        enum ViewMode {
194            ViewModeInvalid,
195            ViewModeWindowed,
196            ViewModeFloating,
197            ViewModeFullscreen,
198            ViewModeMaximized,
199            ViewModeMinimized
200        };
201        static ViewMode stringToViewMode(const String&);
202
203        ViewMode viewMode() const { return m_viewMode; }
204        void setViewMode(ViewMode);
205
206        void setTabKeyCyclesThroughElements(bool b) { m_tabKeyCyclesThroughElements = b; }
207        bool tabKeyCyclesThroughElements() const { return m_tabKeyCyclesThroughElements; }
208
209        bool findString(const String&, FindOptions);
210        // FIXME: Switch callers over to the FindOptions version and retire this one.
211        bool findString(const String&, TextCaseSensitivity, FindDirection, bool shouldWrap);
212        unsigned markAllMatchesForText(const String&, FindOptions, bool shouldHighlight, unsigned);
213        // FIXME: Switch callers over to the FindOptions version and retire this one.
214        unsigned markAllMatchesForText(const String&, TextCaseSensitivity, bool shouldHighlight, unsigned);
215        void unmarkAllTextMatches();
216
217#if PLATFORM(MAC)
218        void addSchedulePair(PassRefPtr<SchedulePair>);
219        void removeSchedulePair(PassRefPtr<SchedulePair>);
220        SchedulePairHashSet* scheduledRunLoopPairs() { return m_scheduledRunLoopPairs.get(); }
221
222        OwnPtr<SchedulePairHashSet> m_scheduledRunLoopPairs;
223#endif
224
225        const VisibleSelection& selection() const;
226
227        void setDefersLoading(bool);
228        bool defersLoading() const { return m_defersLoading; }
229
230        void clearUndoRedoOperations();
231
232        bool inLowQualityImageInterpolationMode() const;
233        void setInLowQualityImageInterpolationMode(bool = true);
234
235        bool cookieEnabled() const { return m_cookieEnabled; }
236        void setCookieEnabled(bool enabled) { m_cookieEnabled = enabled; }
237
238        float mediaVolume() const { return m_mediaVolume; }
239        void setMediaVolume(float volume);
240
241        // Notifications when the Page starts and stops being presented via a native window.
242        void didMoveOnscreen();
243        void willMoveOffscreen();
244
245        void userStyleSheetLocationChanged();
246        const String& userStyleSheet() const;
247
248        void dnsPrefetchingStateChanged();
249        void privateBrowsingStateChanged();
250
251        void didStartPlugin(HaltablePlugin*);
252        void didStopPlugin(HaltablePlugin*);
253        void pluginAllowedRunTimeChanged();
254
255        static void setDebuggerForAllPages(JSC::Debugger*);
256        void setDebugger(JSC::Debugger*);
257        JSC::Debugger* debugger() const { return m_debugger; }
258
259        static void removeAllVisitedLinks();
260
261        static void allVisitedStateChanged(PageGroup*);
262        static void visitedStateChanged(PageGroup*, LinkHash visitedHash);
263
264        SharedGraphicsContext3D* sharedGraphicsContext3D();
265
266#if ENABLE(DOM_STORAGE)
267        StorageNamespace* sessionStorage(bool optionalCreate = true);
268        void setSessionStorage(PassRefPtr<StorageNamespace>);
269#endif
270
271#if ENABLE(WML)
272        WMLPageState* wmlPageState();
273#endif
274
275        void setCustomHTMLTokenizerTimeDelay(double);
276        bool hasCustomHTMLTokenizerTimeDelay() const { return m_customHTMLTokenizerTimeDelay != -1; }
277        double customHTMLTokenizerTimeDelay() const { ASSERT(m_customHTMLTokenizerTimeDelay != -1); return m_customHTMLTokenizerTimeDelay; }
278
279        void setCustomHTMLTokenizerChunkSize(int);
280        bool hasCustomHTMLTokenizerChunkSize() const { return m_customHTMLTokenizerChunkSize != -1; }
281        int customHTMLTokenizerChunkSize() const { ASSERT(m_customHTMLTokenizerChunkSize != -1); return m_customHTMLTokenizerChunkSize; }
282
283        void setMemoryCacheClientCallsEnabled(bool);
284        bool areMemoryCacheClientCallsEnabled() const { return m_areMemoryCacheClientCallsEnabled; }
285
286        void setJavaScriptURLsAreAllowed(bool);
287        bool javaScriptURLsAreAllowed() const;
288
289        typedef HashSet<ScrollableArea*> ScrollableAreaSet;
290        void addScrollableArea(ScrollableArea*);
291        void removeScrollableArea(ScrollableArea*);
292        bool containsScrollableArea(ScrollableArea*) const;
293        const ScrollableAreaSet* scrollableAreaSet() const { return m_scrollableAreaSet.get(); }
294
295        // Don't allow more than a certain number of frames in a page.
296        // This seems like a reasonable upper bound, and otherwise mutually
297        // recursive frameset pages can quickly bring the program to its knees
298        // with exponential growth in the number of frames.
299        static const int maxNumberOfFrames = 1000;
300
301        void setEditable(bool isEditable) { m_isEditable = isEditable; }
302        bool isEditable() { return m_isEditable; }
303
304    private:
305        void initGroup();
306
307#if ASSERT_DISABLED
308        void checkFrameCountConsistency() const { }
309#else
310        void checkFrameCountConsistency() const;
311#endif
312
313        MediaCanStartListener* takeAnyMediaCanStartListener();
314
315        void setMinimumTimerInterval(double);
316        double minimumTimerInterval() const;
317
318        OwnPtr<Chrome> m_chrome;
319        OwnPtr<SelectionController> m_dragCaretController;
320
321#if ENABLE(ACCELERATED_2D_CANVAS)
322        RefPtr<SharedGraphicsContext3D> m_sharedGraphicsContext3D;
323#endif
324
325#if ENABLE(DRAG_SUPPORT)
326        OwnPtr<DragController> m_dragController;
327#endif
328        OwnPtr<FocusController> m_focusController;
329#if ENABLE(CONTEXT_MENUS)
330        OwnPtr<ContextMenuController> m_contextMenuController;
331#endif
332#if ENABLE(INSPECTOR)
333        OwnPtr<InspectorController> m_inspectorController;
334#endif
335#if ENABLE(CLIENT_BASED_GEOLOCATION)
336        OwnPtr<GeolocationController> m_geolocationController;
337#endif
338#if ENABLE(DEVICE_ORIENTATION)
339        OwnPtr<DeviceMotionController> m_deviceMotionController;
340        OwnPtr<DeviceOrientationController> m_deviceOrientationController;
341#endif
342#if ENABLE(INPUT_SPEECH)
343        SpeechInputClient* m_speechInputClient;
344        OwnPtr<SpeechInput> m_speechInput;
345#endif
346        OwnPtr<Settings> m_settings;
347        OwnPtr<ProgressTracker> m_progress;
348
349        OwnPtr<BackForwardController> m_backForwardController;
350        RefPtr<Frame> m_mainFrame;
351
352        mutable RefPtr<PluginData> m_pluginData;
353
354        RefPtr<RenderTheme> m_theme;
355
356        EditorClient* m_editorClient;
357
358        int m_frameCount;
359        String m_groupName;
360        bool m_openedByDOM;
361
362        bool m_tabKeyCyclesThroughElements;
363        bool m_defersLoading;
364
365        bool m_inLowQualityInterpolationMode;
366        bool m_cookieEnabled;
367        bool m_areMemoryCacheClientCallsEnabled;
368        float m_mediaVolume;
369
370        bool m_javaScriptURLsAreAllowed;
371
372        String m_userStyleSheetPath;
373        mutable String m_userStyleSheet;
374        mutable bool m_didLoadUserStyleSheet;
375        mutable time_t m_userStyleSheetModificationTime;
376
377        OwnPtr<PageGroup> m_singlePageGroup;
378        PageGroup* m_group;
379
380        JSC::Debugger* m_debugger;
381
382        double m_customHTMLTokenizerTimeDelay;
383        int m_customHTMLTokenizerChunkSize;
384
385        bool m_canStartMedia;
386
387        OwnPtr<PluginHalter> m_pluginHalter;
388
389#if ENABLE(DOM_STORAGE)
390        RefPtr<StorageNamespace> m_sessionStorage;
391#endif
392
393#if ENABLE(WML)
394        OwnPtr<WMLPageState> m_wmlPageState;
395#endif
396
397#if ENABLE(NOTIFICATIONS)
398        NotificationPresenter* m_notificationPresenter;
399#endif
400
401        ViewMode m_viewMode;
402
403        ViewportArguments m_viewportArguments;
404
405        double m_minimumTimerInterval;
406
407        OwnPtr<ScrollableAreaSet> m_scrollableAreaSet;
408
409        bool m_isEditable;
410    };
411
412} // namespace WebCore
413
414#endif // Page_h
415