Merge lp:~timo-jyrinki/ubuntu/raring/qtwebkit-source/raring_231 into lp:ubuntu/saucy/qtwebkit-source
- Raring (13.04)
- raring_231
- Merge into saucy
Status: | Merged |
---|---|
Merge reported by: | Sebastien Bacher |
Merged at revision: | not available |
Proposed branch: | lp:~timo-jyrinki/ubuntu/raring/qtwebkit-source/raring_231 |
Merge into: | lp:ubuntu/saucy/qtwebkit-source |
Diff against target: |
16806 lines (+1220/-14071) 85 files modified
.pc/05_sparc_unaligned_access.diff/Source/WTF/wtf/ListHashSet.h (+0/-872) .pc/applied-patches (+0/-9) .pc/devicePixelResolution.patch/Source/WebCore/page/Page.cpp (+0/-1346) .pc/disable_geolocation_501.diff/Source/WebKit/qt/Api/qwebpage.cpp (+0/-4103) .pc/hurd.diff/Source/WTF/wtf/FastMalloc.cpp (+0/-4734) .pc/kubuntu_fix_for_powerpc.diff/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp (+0/-545) .pc/kubuntu_fix_for_powerpc.diff/Source/JavaScriptCore/offlineasm/cloop.rb (+0/-1131) .pc/no_gc_sections.diff/Source/WebCore/WebCore.pri (+0/-361) .pc/save_memory.diff/Source/WebCore/WebCore.pri (+0/-361) .pc/stabs_format_debug_info.diff/Source/WebKit/WebKit1.pri (+0/-60) .pc/stabs_format_debug_info.diff/Source/WebKit2/WebKit2.pri (+0/-81) .pc/webkit_qt_hide_symbols.diff/Source/QtWebKit.pro (+0/-38) ChangeLog (+16/-0) Source/JavaScriptCore/ChangeLog (+403/-0) Source/JavaScriptCore/JSCTypedArrayStubs.h (+4/-1) Source/JavaScriptCore/assembler/ARMv7Assembler.h (+42/-3) Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h (+6/-1) Source/JavaScriptCore/bytecode/CodeBlock.cpp (+2/-2) Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (+30/-2) Source/JavaScriptCore/bytecompiler/Label.h (+6/-0) Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp (+9/-8) Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp (+8/-3) Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (+11/-3) Source/JavaScriptCore/dfg/DFGGraph.h (+19/-8) Source/JavaScriptCore/dfg/DFGNodeFlags.h (+1/-1) Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (+29/-4) Source/JavaScriptCore/dfg/DFGRepatch.cpp (+6/-6) Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (+3/-4) Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (+1/-1) Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp (+1/-1) Source/JavaScriptCore/heap/MarkStack.cpp (+4/-8) Source/JavaScriptCore/heap/MarkStack.h (+5/-11) Source/JavaScriptCore/heap/MarkStackInlines.h (+5/-5) Source/JavaScriptCore/heap/WeakSet.cpp (+1/-1) Source/JavaScriptCore/interpreter/Interpreter.cpp (+6/-3) Source/JavaScriptCore/jit/JIT.h (+1/-1) Source/JavaScriptCore/jit/JITStubs.cpp (+18/-2) Source/JavaScriptCore/llint/LLIntExceptions.cpp (+3/-3) Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (+3/-4) Source/JavaScriptCore/offlineasm/ast.rb (+1/-1) Source/JavaScriptCore/runtime/Executable.cpp (+2/-2) Source/JavaScriptCore/runtime/JSArray.h (+4/-0) Source/JavaScriptCore/runtime/JSTypeInfo.h (+2/-1) Source/JavaScriptCore/runtime/Operations.h (+6/-3) Source/JavaScriptCore/runtime/Options.h (+0/-1) Source/JavaScriptCore/yarr/YarrJIT.cpp (+12/-0) Source/QtWebKit.pro (+1/-6) Source/WTF/ChangeLog (+75/-0) Source/WTF/wtf/Compiler.h (+3/-0) Source/WTF/wtf/FastMalloc.cpp (+0/-4) Source/WTF/wtf/HashMap.h (+30/-24) Source/WTF/wtf/ListHashSet.h (+6/-3) Source/WTF/wtf/Platform.h (+2/-2) Source/WebCore/ChangeLog (+193/-11) Source/WebCore/Target.pri (+10/-7) Source/WebCore/WebCore.pri (+1/-3) Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (+10/-3) Source/WebCore/css/mediaControlsQt.css (+98/-197) Source/WebCore/page/EventHandler.cpp (+1/-1) Source/WebCore/page/Page.cpp (+2/-2) Source/WebCore/platform/graphics/GraphicsContext.cpp (+1/-1) Source/WebCore/platform/graphics/ShadowBlur.cpp (+2/-2) Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp (+6/-3) Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp (+31/-0) Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp (+2/-0) Source/WebCore/platform/text/TextEncodingRegistry.cpp (+9/-0) Source/WebCore/rendering/RenderBox.cpp (+1/-0) Source/WebCore/rendering/RenderFrameSet.cpp (+4/-4) Source/WebCore/rendering/RenderLayer.cpp (+1/-2) Source/WebCore/rendering/RenderLayer.h (+0/-4) Source/WebCore/rendering/RenderTableSection.cpp (+6/-1) Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp (+1/-1) Source/WebKit/WebKit1.pri (+0/-6) Source/WebKit/qt/Api/qwebkitglobal.h (+2/-2) Source/WebKit/qt/Api/qwebpage.cpp (+10/-1) Source/WebKit/qt/Api/qwebpage.h (+1/-0) Source/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp (+2/-1) Source/WebKit2/WebKit2.pri (+0/-6) Source/api.pri (+13/-0) Tools/Scripts/webkitdirs.pm (+3/-0) Tools/qmake/qt_webkit.pri (+2/-2) debian/changelog (+18/-0) debian/patches/kubuntu_fix_for_powerpc.diff (+0/-35) debian/patches/series (+0/-1) debian/rules (+3/-1) |
To merge this branch: | bzr merge lp:~timo-jyrinki/ubuntu/raring/qtwebkit-source/raring_231 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu branches | Pending | ||
Review via email: mp+165031@code.launchpad.net |
This proposal supersedes a proposal from 2013-04-22.
Commit message
This new 2.3.1 release with the correct build parameter (http://
It does not however fix the Skype issue NVIDIA users have (bug #1155327).
Description of the change
This new 2.3.1 release with the correct build parameter (http://
It does not however fix the Skype issue NVIDIA users have (bug #1155327).
Timo Jyrinki (timo-jyrinki) wrote : Posted in a previous version of this proposal | # |
Dmitry Shachnev (mitya57) wrote : Posted in a previous version of this proposal | # |
Thanks Timo for working on it, I have a couple of comments:
- I've unlinked bugs that are not fixed by your update;
- Now this should go to Saucy, the diff looks to big for a SRU.
- We may want to cherry-pick some fixes to Raring, but I would like to wait for fix for https:/
Timo Jyrinki (timo-jyrinki) wrote : Posted in a previous version of this proposal | # |
Yeah certainly this is for saucy at this point.
Sebastien Bacher (seb128) wrote : Posted in a previous version of this proposal | # |
Timo, could you retarget that one for saucy?
Timo Jyrinki (timo-jyrinki) wrote : | # |
Resubmitted to saucy, thanks.
Dmitry Shachnev (mitya57) wrote : | # |
Note that it is not rebased on top of 2.3.0-0ubuntu3 in Saucy, so one will need to at least merge changelog entries before uploading.
Timo Jyrinki (timo-jyrinki) wrote : | # |
Right, it does not show up in any bzr, so merging manually the changelog entry and checking if the patch still applies.
- 35. By Timo Jyrinki
-
Manual merge of 2.3.0-0ubuntu3 in saucy. Changelog only, patch is included in 2.3.1.
* debian/
patches/ 108991- jsval-32bit- fix.patch:
- Drop, merged upstream
* Add patch 108991-jsval-32bit- fix.patch fixes
QtWebKit JS crash on 32-bit systems LP: #1180731
Sebastien Bacher (seb128) wrote : | # |
Thanks, I'm sponsoring that one
Preview Diff
1 | === renamed file '.dir-locals.el' => '.dir-locals.el' | |||
2 | === renamed directory '.pc' => '.pc' | |||
3 | === removed directory '.pc/05_sparc_unaligned_access.diff' | |||
4 | === removed directory '.pc/05_sparc_unaligned_access.diff/Source' | |||
5 | === removed directory '.pc/05_sparc_unaligned_access.diff/Source/WTF' | |||
6 | === removed directory '.pc/05_sparc_unaligned_access.diff/Source/WTF/wtf' | |||
7 | === removed file '.pc/05_sparc_unaligned_access.diff/Source/WTF/wtf/ListHashSet.h' | |||
8 | --- .pc/05_sparc_unaligned_access.diff/Source/WTF/wtf/ListHashSet.h 2013-02-18 14:24:18 +0000 | |||
9 | +++ .pc/05_sparc_unaligned_access.diff/Source/WTF/wtf/ListHashSet.h 1970-01-01 00:00:00 +0000 | |||
10 | @@ -1,872 +0,0 @@ | |||
11 | 1 | /* | ||
12 | 2 | * Copyright (C) 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. | ||
13 | 3 | * Copyright (C) 2011, Benjamin Poulain <ikipou@gmail.com> | ||
14 | 4 | * | ||
15 | 5 | * This library is free software; you can redistribute it and/or | ||
16 | 6 | * modify it under the terms of the GNU Library General Public | ||
17 | 7 | * License as published by the Free Software Foundation; either | ||
18 | 8 | * version 2 of the License, or (at your option) any later version. | ||
19 | 9 | * | ||
20 | 10 | * This library is distributed in the hope that it will be useful, | ||
21 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
23 | 13 | * Library General Public License for more details. | ||
24 | 14 | * | ||
25 | 15 | * You should have received a copy of the GNU Library General Public License | ||
26 | 16 | * along with this library; see the file COPYING.LIB. If not, write to | ||
27 | 17 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
28 | 18 | * Boston, MA 02110-1301, USA. | ||
29 | 19 | * | ||
30 | 20 | */ | ||
31 | 21 | |||
32 | 22 | #ifndef WTF_ListHashSet_h | ||
33 | 23 | #define WTF_ListHashSet_h | ||
34 | 24 | |||
35 | 25 | #include <wtf/HashSet.h> | ||
36 | 26 | #include <wtf/OwnPtr.h> | ||
37 | 27 | #include <wtf/PassOwnPtr.h> | ||
38 | 28 | |||
39 | 29 | namespace WTF { | ||
40 | 30 | |||
41 | 31 | // ListHashSet: Just like HashSet, this class provides a Set | ||
42 | 32 | // interface - a collection of unique objects with O(1) insertion, | ||
43 | 33 | // removal and test for containership. However, it also has an | ||
44 | 34 | // order - iterating it will always give back values in the order | ||
45 | 35 | // in which they are added. | ||
46 | 36 | |||
47 | 37 | // Unlike iteration of most WTF Hash data structures, iteration is | ||
48 | 38 | // guaranteed safe against mutation of the ListHashSet, except for | ||
49 | 39 | // removal of the item currently pointed to by a given iterator. | ||
50 | 40 | |||
51 | 41 | // In theory it would be possible to add prepend, insertAfter | ||
52 | 42 | // and an append that moves the element to the end even if already present, | ||
53 | 43 | // but unclear yet if these are needed. | ||
54 | 44 | |||
55 | 45 | template<typename Value, size_t inlineCapacity, typename HashFunctions> class ListHashSet; | ||
56 | 46 | |||
57 | 47 | template<typename Value, size_t inlineCapacity, typename HashFunctions> | ||
58 | 48 | void deleteAllValues(const ListHashSet<Value, inlineCapacity, HashFunctions>&); | ||
59 | 49 | |||
60 | 50 | template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetIterator; | ||
61 | 51 | template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstIterator; | ||
62 | 52 | template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetReverseIterator; | ||
63 | 53 | template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstReverseIterator; | ||
64 | 54 | |||
65 | 55 | template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNode; | ||
66 | 56 | template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNodeAllocator; | ||
67 | 57 | |||
68 | 58 | template<typename HashArg> struct ListHashSetNodeHashFunctions; | ||
69 | 59 | template<typename HashArg> struct ListHashSetTranslator; | ||
70 | 60 | |||
71 | 61 | template<typename ValueArg, size_t inlineCapacity = 256, typename HashArg = typename DefaultHash<ValueArg>::Hash> class ListHashSet { | ||
72 | 62 | WTF_MAKE_FAST_ALLOCATED; | ||
73 | 63 | private: | ||
74 | 64 | typedef ListHashSetNode<ValueArg, inlineCapacity> Node; | ||
75 | 65 | typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator; | ||
76 | 66 | |||
77 | 67 | typedef HashTraits<Node*> NodeTraits; | ||
78 | 68 | typedef ListHashSetNodeHashFunctions<HashArg> NodeHash; | ||
79 | 69 | typedef ListHashSetTranslator<HashArg> BaseTranslator; | ||
80 | 70 | |||
81 | 71 | typedef HashTable<Node*, Node*, IdentityExtractor, NodeHash, NodeTraits, NodeTraits> ImplType; | ||
82 | 72 | typedef HashTableIterator<Node*, Node*, IdentityExtractor, NodeHash, NodeTraits, NodeTraits> ImplTypeIterator; | ||
83 | 73 | typedef HashTableConstIterator<Node*, Node*, IdentityExtractor, NodeHash, NodeTraits, NodeTraits> ImplTypeConstIterator; | ||
84 | 74 | |||
85 | 75 | typedef HashArg HashFunctions; | ||
86 | 76 | |||
87 | 77 | public: | ||
88 | 78 | typedef ValueArg ValueType; | ||
89 | 79 | |||
90 | 80 | typedef ListHashSetIterator<ValueType, inlineCapacity, HashArg> iterator; | ||
91 | 81 | typedef ListHashSetConstIterator<ValueType, inlineCapacity, HashArg> const_iterator; | ||
92 | 82 | friend class ListHashSetConstIterator<ValueType, inlineCapacity, HashArg>; | ||
93 | 83 | |||
94 | 84 | typedef ListHashSetReverseIterator<ValueType, inlineCapacity, HashArg> reverse_iterator; | ||
95 | 85 | typedef ListHashSetConstReverseIterator<ValueType, inlineCapacity, HashArg> const_reverse_iterator; | ||
96 | 86 | friend class ListHashSetConstReverseIterator<ValueType, inlineCapacity, HashArg>; | ||
97 | 87 | |||
98 | 88 | typedef HashTableAddResult<iterator> AddResult; | ||
99 | 89 | |||
100 | 90 | ListHashSet(); | ||
101 | 91 | ListHashSet(const ListHashSet&); | ||
102 | 92 | ListHashSet& operator=(const ListHashSet&); | ||
103 | 93 | ~ListHashSet(); | ||
104 | 94 | |||
105 | 95 | void swap(ListHashSet&); | ||
106 | 96 | |||
107 | 97 | int size() const; | ||
108 | 98 | int capacity() const; | ||
109 | 99 | bool isEmpty() const; | ||
110 | 100 | |||
111 | 101 | size_t sizeInBytes() const; | ||
112 | 102 | |||
113 | 103 | iterator begin(); | ||
114 | 104 | iterator end(); | ||
115 | 105 | const_iterator begin() const; | ||
116 | 106 | const_iterator end() const; | ||
117 | 107 | |||
118 | 108 | reverse_iterator rbegin(); | ||
119 | 109 | reverse_iterator rend(); | ||
120 | 110 | const_reverse_iterator rbegin() const; | ||
121 | 111 | const_reverse_iterator rend() const; | ||
122 | 112 | |||
123 | 113 | ValueType& first(); | ||
124 | 114 | const ValueType& first() const; | ||
125 | 115 | |||
126 | 116 | ValueType& last(); | ||
127 | 117 | const ValueType& last() const; | ||
128 | 118 | void removeLast(); | ||
129 | 119 | |||
130 | 120 | iterator find(const ValueType&); | ||
131 | 121 | const_iterator find(const ValueType&) const; | ||
132 | 122 | bool contains(const ValueType&) const; | ||
133 | 123 | |||
134 | 124 | // An alternate version of find() that finds the object by hashing and comparing | ||
135 | 125 | // with some other type, to avoid the cost of type conversion. | ||
136 | 126 | // The HashTranslator interface is defined in HashSet. | ||
137 | 127 | // FIXME: We should reverse the order of the template arguments so that callers | ||
138 | 128 | // can just pass the translator let the compiler deduce T. | ||
139 | 129 | template<typename T, typename HashTranslator> iterator find(const T&); | ||
140 | 130 | template<typename T, typename HashTranslator> const_iterator find(const T&) const; | ||
141 | 131 | template<typename T, typename HashTranslator> bool contains(const T&) const; | ||
142 | 132 | |||
143 | 133 | // The return value of add is a pair of an iterator to the new value's location, | ||
144 | 134 | // and a bool that is true if an new entry was added. | ||
145 | 135 | AddResult add(const ValueType&); | ||
146 | 136 | |||
147 | 137 | AddResult insertBefore(const ValueType& beforeValue, const ValueType& newValue); | ||
148 | 138 | AddResult insertBefore(iterator, const ValueType&); | ||
149 | 139 | |||
150 | 140 | void remove(const ValueType&); | ||
151 | 141 | void remove(iterator); | ||
152 | 142 | void clear(); | ||
153 | 143 | |||
154 | 144 | private: | ||
155 | 145 | void unlinkAndDelete(Node*); | ||
156 | 146 | void appendNode(Node*); | ||
157 | 147 | void insertNodeBefore(Node* beforeNode, Node* newNode); | ||
158 | 148 | void deleteAllNodes(); | ||
159 | 149 | |||
160 | 150 | iterator makeIterator(Node*); | ||
161 | 151 | const_iterator makeConstIterator(Node*) const; | ||
162 | 152 | reverse_iterator makeReverseIterator(Node*); | ||
163 | 153 | const_reverse_iterator makeConstReverseIterator(Node*) const; | ||
164 | 154 | |||
165 | 155 | friend void deleteAllValues<>(const ListHashSet&); | ||
166 | 156 | |||
167 | 157 | ImplType m_impl; | ||
168 | 158 | Node* m_head; | ||
169 | 159 | Node* m_tail; | ||
170 | 160 | OwnPtr<NodeAllocator> m_allocator; | ||
171 | 161 | }; | ||
172 | 162 | |||
173 | 163 | template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNodeAllocator { | ||
174 | 164 | typedef ListHashSetNode<ValueArg, inlineCapacity> Node; | ||
175 | 165 | typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator; | ||
176 | 166 | |||
177 | 167 | ListHashSetNodeAllocator() | ||
178 | 168 | : m_freeList(pool()) | ||
179 | 169 | , m_isDoneWithInitialFreeList(false) | ||
180 | 170 | { | ||
181 | 171 | memset(m_pool.pool, 0, sizeof(m_pool.pool)); | ||
182 | 172 | } | ||
183 | 173 | |||
184 | 174 | Node* allocate() | ||
185 | 175 | { | ||
186 | 176 | Node* result = m_freeList; | ||
187 | 177 | |||
188 | 178 | if (!result) | ||
189 | 179 | return static_cast<Node*>(fastMalloc(sizeof(Node))); | ||
190 | 180 | |||
191 | 181 | ASSERT(!result->m_isAllocated); | ||
192 | 182 | |||
193 | 183 | Node* next = result->m_next; | ||
194 | 184 | ASSERT(!next || !next->m_isAllocated); | ||
195 | 185 | if (!next && !m_isDoneWithInitialFreeList) { | ||
196 | 186 | next = result + 1; | ||
197 | 187 | if (next == pastPool()) { | ||
198 | 188 | m_isDoneWithInitialFreeList = true; | ||
199 | 189 | next = 0; | ||
200 | 190 | } else { | ||
201 | 191 | ASSERT(inPool(next)); | ||
202 | 192 | ASSERT(!next->m_isAllocated); | ||
203 | 193 | } | ||
204 | 194 | } | ||
205 | 195 | m_freeList = next; | ||
206 | 196 | |||
207 | 197 | return result; | ||
208 | 198 | } | ||
209 | 199 | |||
210 | 200 | void deallocate(Node* node) | ||
211 | 201 | { | ||
212 | 202 | if (inPool(node)) { | ||
213 | 203 | #ifndef NDEBUG | ||
214 | 204 | node->m_isAllocated = false; | ||
215 | 205 | #endif | ||
216 | 206 | node->m_next = m_freeList; | ||
217 | 207 | m_freeList = node; | ||
218 | 208 | return; | ||
219 | 209 | } | ||
220 | 210 | |||
221 | 211 | fastFree(node); | ||
222 | 212 | } | ||
223 | 213 | |||
224 | 214 | bool inPool(Node* node) | ||
225 | 215 | { | ||
226 | 216 | return node >= pool() && node < pastPool(); | ||
227 | 217 | } | ||
228 | 218 | |||
229 | 219 | private: | ||
230 | 220 | Node* pool() { return reinterpret_cast_ptr<Node*>(m_pool.pool); } | ||
231 | 221 | Node* pastPool() { return pool() + m_poolSize; } | ||
232 | 222 | |||
233 | 223 | Node* m_freeList; | ||
234 | 224 | bool m_isDoneWithInitialFreeList; | ||
235 | 225 | static const size_t m_poolSize = inlineCapacity; | ||
236 | 226 | union { | ||
237 | 227 | char pool[sizeof(Node) * m_poolSize]; | ||
238 | 228 | double forAlignment; | ||
239 | 229 | } m_pool; | ||
240 | 230 | }; | ||
241 | 231 | |||
242 | 232 | template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNode { | ||
243 | 233 | typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator; | ||
244 | 234 | |||
245 | 235 | ListHashSetNode(ValueArg value) | ||
246 | 236 | : m_value(value) | ||
247 | 237 | , m_prev(0) | ||
248 | 238 | , m_next(0) | ||
249 | 239 | #ifndef NDEBUG | ||
250 | 240 | , m_isAllocated(true) | ||
251 | 241 | #endif | ||
252 | 242 | { | ||
253 | 243 | } | ||
254 | 244 | |||
255 | 245 | void* operator new(size_t, NodeAllocator* allocator) | ||
256 | 246 | { | ||
257 | 247 | return allocator->allocate(); | ||
258 | 248 | } | ||
259 | 249 | void destroy(NodeAllocator* allocator) | ||
260 | 250 | { | ||
261 | 251 | this->~ListHashSetNode(); | ||
262 | 252 | allocator->deallocate(this); | ||
263 | 253 | } | ||
264 | 254 | |||
265 | 255 | ValueArg m_value; | ||
266 | 256 | ListHashSetNode* m_prev; | ||
267 | 257 | ListHashSetNode* m_next; | ||
268 | 258 | |||
269 | 259 | #ifndef NDEBUG | ||
270 | 260 | bool m_isAllocated; | ||
271 | 261 | #endif | ||
272 | 262 | }; | ||
273 | 263 | |||
274 | 264 | template<typename HashArg> struct ListHashSetNodeHashFunctions { | ||
275 | 265 | template<typename T> static unsigned hash(const T& key) { return HashArg::hash(key->m_value); } | ||
276 | 266 | template<typename T> static bool equal(const T& a, const T& b) { return HashArg::equal(a->m_value, b->m_value); } | ||
277 | 267 | static const bool safeToCompareToEmptyOrDeleted = false; | ||
278 | 268 | }; | ||
279 | 269 | |||
280 | 270 | template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetIterator { | ||
281 | 271 | private: | ||
282 | 272 | typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType; | ||
283 | 273 | typedef ListHashSetIterator<ValueArg, inlineCapacity, HashArg> iterator; | ||
284 | 274 | typedef ListHashSetConstIterator<ValueArg, inlineCapacity, HashArg> const_iterator; | ||
285 | 275 | typedef ListHashSetNode<ValueArg, inlineCapacity> Node; | ||
286 | 276 | typedef ValueArg ValueType; | ||
287 | 277 | typedef ValueType& ReferenceType; | ||
288 | 278 | typedef ValueType* PointerType; | ||
289 | 279 | |||
290 | 280 | friend class ListHashSet<ValueArg, inlineCapacity, HashArg>; | ||
291 | 281 | |||
292 | 282 | ListHashSetIterator(const ListHashSetType* set, Node* position) : m_iterator(set, position) { } | ||
293 | 283 | |||
294 | 284 | public: | ||
295 | 285 | ListHashSetIterator() { } | ||
296 | 286 | |||
297 | 287 | // default copy, assignment and destructor are OK | ||
298 | 288 | |||
299 | 289 | PointerType get() const { return const_cast<PointerType>(m_iterator.get()); } | ||
300 | 290 | ReferenceType operator*() const { return *get(); } | ||
301 | 291 | PointerType operator->() const { return get(); } | ||
302 | 292 | |||
303 | 293 | iterator& operator++() { ++m_iterator; return *this; } | ||
304 | 294 | |||
305 | 295 | // postfix ++ intentionally omitted | ||
306 | 296 | |||
307 | 297 | iterator& operator--() { --m_iterator; return *this; } | ||
308 | 298 | |||
309 | 299 | // postfix -- intentionally omitted | ||
310 | 300 | |||
311 | 301 | // Comparison. | ||
312 | 302 | bool operator==(const iterator& other) const { return m_iterator == other.m_iterator; } | ||
313 | 303 | bool operator!=(const iterator& other) const { return m_iterator != other.m_iterator; } | ||
314 | 304 | |||
315 | 305 | operator const_iterator() const { return m_iterator; } | ||
316 | 306 | |||
317 | 307 | private: | ||
318 | 308 | Node* node() { return m_iterator.node(); } | ||
319 | 309 | |||
320 | 310 | const_iterator m_iterator; | ||
321 | 311 | }; | ||
322 | 312 | |||
323 | 313 | template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstIterator { | ||
324 | 314 | private: | ||
325 | 315 | typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType; | ||
326 | 316 | typedef ListHashSetIterator<ValueArg, inlineCapacity, HashArg> iterator; | ||
327 | 317 | typedef ListHashSetConstIterator<ValueArg, inlineCapacity, HashArg> const_iterator; | ||
328 | 318 | typedef ListHashSetNode<ValueArg, inlineCapacity> Node; | ||
329 | 319 | typedef ValueArg ValueType; | ||
330 | 320 | typedef const ValueType& ReferenceType; | ||
331 | 321 | typedef const ValueType* PointerType; | ||
332 | 322 | |||
333 | 323 | friend class ListHashSet<ValueArg, inlineCapacity, HashArg>; | ||
334 | 324 | friend class ListHashSetIterator<ValueArg, inlineCapacity, HashArg>; | ||
335 | 325 | |||
336 | 326 | ListHashSetConstIterator(const ListHashSetType* set, Node* position) | ||
337 | 327 | : m_set(set) | ||
338 | 328 | , m_position(position) | ||
339 | 329 | { | ||
340 | 330 | } | ||
341 | 331 | |||
342 | 332 | public: | ||
343 | 333 | ListHashSetConstIterator() | ||
344 | 334 | { | ||
345 | 335 | } | ||
346 | 336 | |||
347 | 337 | PointerType get() const | ||
348 | 338 | { | ||
349 | 339 | return &m_position->m_value; | ||
350 | 340 | } | ||
351 | 341 | ReferenceType operator*() const { return *get(); } | ||
352 | 342 | PointerType operator->() const { return get(); } | ||
353 | 343 | |||
354 | 344 | const_iterator& operator++() | ||
355 | 345 | { | ||
356 | 346 | ASSERT(m_position != 0); | ||
357 | 347 | m_position = m_position->m_next; | ||
358 | 348 | return *this; | ||
359 | 349 | } | ||
360 | 350 | |||
361 | 351 | // postfix ++ intentionally omitted | ||
362 | 352 | |||
363 | 353 | const_iterator& operator--() | ||
364 | 354 | { | ||
365 | 355 | ASSERT(m_position != m_set->m_head); | ||
366 | 356 | if (!m_position) | ||
367 | 357 | m_position = m_set->m_tail; | ||
368 | 358 | else | ||
369 | 359 | m_position = m_position->m_prev; | ||
370 | 360 | return *this; | ||
371 | 361 | } | ||
372 | 362 | |||
373 | 363 | // postfix -- intentionally omitted | ||
374 | 364 | |||
375 | 365 | // Comparison. | ||
376 | 366 | bool operator==(const const_iterator& other) const | ||
377 | 367 | { | ||
378 | 368 | return m_position == other.m_position; | ||
379 | 369 | } | ||
380 | 370 | bool operator!=(const const_iterator& other) const | ||
381 | 371 | { | ||
382 | 372 | return m_position != other.m_position; | ||
383 | 373 | } | ||
384 | 374 | |||
385 | 375 | private: | ||
386 | 376 | Node* node() { return m_position; } | ||
387 | 377 | |||
388 | 378 | const ListHashSetType* m_set; | ||
389 | 379 | Node* m_position; | ||
390 | 380 | }; | ||
391 | 381 | |||
392 | 382 | template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetReverseIterator { | ||
393 | 383 | private: | ||
394 | 384 | typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType; | ||
395 | 385 | typedef ListHashSetReverseIterator<ValueArg, inlineCapacity, HashArg> reverse_iterator; | ||
396 | 386 | typedef ListHashSetConstReverseIterator<ValueArg, inlineCapacity, HashArg> const_reverse_iterator; | ||
397 | 387 | typedef ListHashSetNode<ValueArg, inlineCapacity> Node; | ||
398 | 388 | typedef ValueArg ValueType; | ||
399 | 389 | typedef ValueType& ReferenceType; | ||
400 | 390 | typedef ValueType* PointerType; | ||
401 | 391 | |||
402 | 392 | friend class ListHashSet<ValueArg, inlineCapacity, HashArg>; | ||
403 | 393 | |||
404 | 394 | ListHashSetReverseIterator(const ListHashSetType* set, Node* position) : m_iterator(set, position) { } | ||
405 | 395 | |||
406 | 396 | public: | ||
407 | 397 | ListHashSetReverseIterator() { } | ||
408 | 398 | |||
409 | 399 | // default copy, assignment and destructor are OK | ||
410 | 400 | |||
411 | 401 | PointerType get() const { return const_cast<PointerType>(m_iterator.get()); } | ||
412 | 402 | ReferenceType operator*() const { return *get(); } | ||
413 | 403 | PointerType operator->() const { return get(); } | ||
414 | 404 | |||
415 | 405 | reverse_iterator& operator++() { ++m_iterator; return *this; } | ||
416 | 406 | |||
417 | 407 | // postfix ++ intentionally omitted | ||
418 | 408 | |||
419 | 409 | reverse_iterator& operator--() { --m_iterator; return *this; } | ||
420 | 410 | |||
421 | 411 | // postfix -- intentionally omitted | ||
422 | 412 | |||
423 | 413 | // Comparison. | ||
424 | 414 | bool operator==(const reverse_iterator& other) const { return m_iterator == other.m_iterator; } | ||
425 | 415 | bool operator!=(const reverse_iterator& other) const { return m_iterator != other.m_iterator; } | ||
426 | 416 | |||
427 | 417 | operator const_reverse_iterator() const { return m_iterator; } | ||
428 | 418 | |||
429 | 419 | private: | ||
430 | 420 | Node* node() { return m_iterator.node(); } | ||
431 | 421 | |||
432 | 422 | const_reverse_iterator m_iterator; | ||
433 | 423 | }; | ||
434 | 424 | |||
435 | 425 | template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstReverseIterator { | ||
436 | 426 | private: | ||
437 | 427 | typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType; | ||
438 | 428 | typedef ListHashSetReverseIterator<ValueArg, inlineCapacity, HashArg> reverse_iterator; | ||
439 | 429 | typedef ListHashSetConstReverseIterator<ValueArg, inlineCapacity, HashArg> const_reverse_iterator; | ||
440 | 430 | typedef ListHashSetNode<ValueArg, inlineCapacity> Node; | ||
441 | 431 | typedef ValueArg ValueType; | ||
442 | 432 | typedef const ValueType& ReferenceType; | ||
443 | 433 | typedef const ValueType* PointerType; | ||
444 | 434 | |||
445 | 435 | friend class ListHashSet<ValueArg, inlineCapacity, HashArg>; | ||
446 | 436 | friend class ListHashSetReverseIterator<ValueArg, inlineCapacity, HashArg>; | ||
447 | 437 | |||
448 | 438 | ListHashSetConstReverseIterator(const ListHashSetType* set, Node* position) | ||
449 | 439 | : m_set(set) | ||
450 | 440 | , m_position(position) | ||
451 | 441 | { | ||
452 | 442 | } | ||
453 | 443 | |||
454 | 444 | public: | ||
455 | 445 | ListHashSetConstReverseIterator() | ||
456 | 446 | { | ||
457 | 447 | } | ||
458 | 448 | |||
459 | 449 | PointerType get() const | ||
460 | 450 | { | ||
461 | 451 | return &m_position->m_value; | ||
462 | 452 | } | ||
463 | 453 | ReferenceType operator*() const { return *get(); } | ||
464 | 454 | PointerType operator->() const { return get(); } | ||
465 | 455 | |||
466 | 456 | const_reverse_iterator& operator++() | ||
467 | 457 | { | ||
468 | 458 | ASSERT(m_position != 0); | ||
469 | 459 | m_position = m_position->m_prev; | ||
470 | 460 | return *this; | ||
471 | 461 | } | ||
472 | 462 | |||
473 | 463 | // postfix ++ intentionally omitted | ||
474 | 464 | |||
475 | 465 | const_reverse_iterator& operator--() | ||
476 | 466 | { | ||
477 | 467 | ASSERT(m_position != m_set->m_tail); | ||
478 | 468 | if (!m_position) | ||
479 | 469 | m_position = m_set->m_head; | ||
480 | 470 | else | ||
481 | 471 | m_position = m_position->m_next; | ||
482 | 472 | return *this; | ||
483 | 473 | } | ||
484 | 474 | |||
485 | 475 | // postfix -- intentionally omitted | ||
486 | 476 | |||
487 | 477 | // Comparison. | ||
488 | 478 | bool operator==(const const_reverse_iterator& other) const | ||
489 | 479 | { | ||
490 | 480 | return m_position == other.m_position; | ||
491 | 481 | } | ||
492 | 482 | bool operator!=(const const_reverse_iterator& other) const | ||
493 | 483 | { | ||
494 | 484 | return m_position != other.m_position; | ||
495 | 485 | } | ||
496 | 486 | |||
497 | 487 | private: | ||
498 | 488 | Node* node() { return m_position; } | ||
499 | 489 | |||
500 | 490 | const ListHashSetType* m_set; | ||
501 | 491 | Node* m_position; | ||
502 | 492 | }; | ||
503 | 493 | |||
504 | 494 | template<typename HashFunctions> | ||
505 | 495 | struct ListHashSetTranslator { | ||
506 | 496 | template<typename T> static unsigned hash(const T& key) { return HashFunctions::hash(key); } | ||
507 | 497 | template<typename T, typename U> static bool equal(const T& a, const U& b) { return HashFunctions::equal(a->m_value, b); } | ||
508 | 498 | template<typename T, typename U, typename V> static void translate(T*& location, const U& key, const V& allocator) | ||
509 | 499 | { | ||
510 | 500 | location = new (allocator) T(key); | ||
511 | 501 | } | ||
512 | 502 | }; | ||
513 | 503 | |||
514 | 504 | template<typename T, size_t inlineCapacity, typename U> | ||
515 | 505 | inline ListHashSet<T, inlineCapacity, U>::ListHashSet() | ||
516 | 506 | : m_head(0) | ||
517 | 507 | , m_tail(0) | ||
518 | 508 | , m_allocator(adoptPtr(new NodeAllocator)) | ||
519 | 509 | { | ||
520 | 510 | } | ||
521 | 511 | |||
522 | 512 | template<typename T, size_t inlineCapacity, typename U> | ||
523 | 513 | inline ListHashSet<T, inlineCapacity, U>::ListHashSet(const ListHashSet& other) | ||
524 | 514 | : m_head(0) | ||
525 | 515 | , m_tail(0) | ||
526 | 516 | , m_allocator(adoptPtr(new NodeAllocator)) | ||
527 | 517 | { | ||
528 | 518 | const_iterator end = other.end(); | ||
529 | 519 | for (const_iterator it = other.begin(); it != end; ++it) | ||
530 | 520 | add(*it); | ||
531 | 521 | } | ||
532 | 522 | |||
533 | 523 | template<typename T, size_t inlineCapacity, typename U> | ||
534 | 524 | inline ListHashSet<T, inlineCapacity, U>& ListHashSet<T, inlineCapacity, U>::operator=(const ListHashSet& other) | ||
535 | 525 | { | ||
536 | 526 | ListHashSet tmp(other); | ||
537 | 527 | swap(tmp); | ||
538 | 528 | return *this; | ||
539 | 529 | } | ||
540 | 530 | |||
541 | 531 | template<typename T, size_t inlineCapacity, typename U> | ||
542 | 532 | inline void ListHashSet<T, inlineCapacity, U>::swap(ListHashSet& other) | ||
543 | 533 | { | ||
544 | 534 | m_impl.swap(other.m_impl); | ||
545 | 535 | std::swap(m_head, other.m_head); | ||
546 | 536 | std::swap(m_tail, other.m_tail); | ||
547 | 537 | m_allocator.swap(other.m_allocator); | ||
548 | 538 | } | ||
549 | 539 | |||
550 | 540 | template<typename T, size_t inlineCapacity, typename U> | ||
551 | 541 | inline ListHashSet<T, inlineCapacity, U>::~ListHashSet() | ||
552 | 542 | { | ||
553 | 543 | deleteAllNodes(); | ||
554 | 544 | } | ||
555 | 545 | |||
556 | 546 | template<typename T, size_t inlineCapacity, typename U> | ||
557 | 547 | inline int ListHashSet<T, inlineCapacity, U>::size() const | ||
558 | 548 | { | ||
559 | 549 | return m_impl.size(); | ||
560 | 550 | } | ||
561 | 551 | |||
562 | 552 | template<typename T, size_t inlineCapacity, typename U> | ||
563 | 553 | inline int ListHashSet<T, inlineCapacity, U>::capacity() const | ||
564 | 554 | { | ||
565 | 555 | return m_impl.capacity(); | ||
566 | 556 | } | ||
567 | 557 | |||
568 | 558 | template<typename T, size_t inlineCapacity, typename U> | ||
569 | 559 | inline bool ListHashSet<T, inlineCapacity, U>::isEmpty() const | ||
570 | 560 | { | ||
571 | 561 | return m_impl.isEmpty(); | ||
572 | 562 | } | ||
573 | 563 | |||
574 | 564 | template<typename T, size_t inlineCapacity, typename U> | ||
575 | 565 | size_t ListHashSet<T, inlineCapacity, U>::sizeInBytes() const | ||
576 | 566 | { | ||
577 | 567 | size_t result = sizeof(*this) + sizeof(*m_allocator); | ||
578 | 568 | result += sizeof(typename ImplType::ValueType) * m_impl.capacity(); | ||
579 | 569 | for (Node* node = m_head; node; node = node->m_next) { | ||
580 | 570 | if (!m_allocator->inPool(node)) | ||
581 | 571 | result += sizeof(Node); | ||
582 | 572 | } | ||
583 | 573 | return result; | ||
584 | 574 | } | ||
585 | 575 | |||
586 | 576 | template<typename T, size_t inlineCapacity, typename U> | ||
587 | 577 | inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::begin() | ||
588 | 578 | { | ||
589 | 579 | return makeIterator(m_head); | ||
590 | 580 | } | ||
591 | 581 | |||
592 | 582 | template<typename T, size_t inlineCapacity, typename U> | ||
593 | 583 | inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::end() | ||
594 | 584 | { | ||
595 | 585 | return makeIterator(0); | ||
596 | 586 | } | ||
597 | 587 | |||
598 | 588 | template<typename T, size_t inlineCapacity, typename U> | ||
599 | 589 | inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::begin() const | ||
600 | 590 | { | ||
601 | 591 | return makeConstIterator(m_head); | ||
602 | 592 | } | ||
603 | 593 | |||
604 | 594 | template<typename T, size_t inlineCapacity, typename U> | ||
605 | 595 | inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::end() const | ||
606 | 596 | { | ||
607 | 597 | return makeConstIterator(0); | ||
608 | 598 | } | ||
609 | 599 | |||
610 | 600 | template<typename T, size_t inlineCapacity, typename U> | ||
611 | 601 | inline typename ListHashSet<T, inlineCapacity, U>::reverse_iterator ListHashSet<T, inlineCapacity, U>::rbegin() | ||
612 | 602 | { | ||
613 | 603 | return makeReverseIterator(m_tail); | ||
614 | 604 | } | ||
615 | 605 | |||
616 | 606 | template<typename T, size_t inlineCapacity, typename U> | ||
617 | 607 | inline typename ListHashSet<T, inlineCapacity, U>::reverse_iterator ListHashSet<T, inlineCapacity, U>::rend() | ||
618 | 608 | { | ||
619 | 609 | return makeReverseIterator(0); | ||
620 | 610 | } | ||
621 | 611 | |||
622 | 612 | template<typename T, size_t inlineCapacity, typename U> | ||
623 | 613 | inline typename ListHashSet<T, inlineCapacity, U>::const_reverse_iterator ListHashSet<T, inlineCapacity, U>::rbegin() const | ||
624 | 614 | { | ||
625 | 615 | return makeConstReverseIterator(m_tail); | ||
626 | 616 | } | ||
627 | 617 | |||
628 | 618 | template<typename T, size_t inlineCapacity, typename U> | ||
629 | 619 | inline typename ListHashSet<T, inlineCapacity, U>::const_reverse_iterator ListHashSet<T, inlineCapacity, U>::rend() const | ||
630 | 620 | { | ||
631 | 621 | return makeConstReverseIterator(0); | ||
632 | 622 | } | ||
633 | 623 | |||
634 | 624 | template<typename T, size_t inlineCapacity, typename U> | ||
635 | 625 | inline T& ListHashSet<T, inlineCapacity, U>::first() | ||
636 | 626 | { | ||
637 | 627 | ASSERT(!isEmpty()); | ||
638 | 628 | return m_head->m_value; | ||
639 | 629 | } | ||
640 | 630 | |||
641 | 631 | template<typename T, size_t inlineCapacity, typename U> | ||
642 | 632 | inline const T& ListHashSet<T, inlineCapacity, U>::first() const | ||
643 | 633 | { | ||
644 | 634 | ASSERT(!isEmpty()); | ||
645 | 635 | return m_head->m_value; | ||
646 | 636 | } | ||
647 | 637 | |||
648 | 638 | template<typename T, size_t inlineCapacity, typename U> | ||
649 | 639 | inline T& ListHashSet<T, inlineCapacity, U>::last() | ||
650 | 640 | { | ||
651 | 641 | ASSERT(!isEmpty()); | ||
652 | 642 | return m_tail->m_value; | ||
653 | 643 | } | ||
654 | 644 | |||
655 | 645 | template<typename T, size_t inlineCapacity, typename U> | ||
656 | 646 | inline const T& ListHashSet<T, inlineCapacity, U>::last() const | ||
657 | 647 | { | ||
658 | 648 | ASSERT(!isEmpty()); | ||
659 | 649 | return m_tail->m_value; | ||
660 | 650 | } | ||
661 | 651 | |||
662 | 652 | template<typename T, size_t inlineCapacity, typename U> | ||
663 | 653 | inline void ListHashSet<T, inlineCapacity, U>::removeLast() | ||
664 | 654 | { | ||
665 | 655 | ASSERT(!isEmpty()); | ||
666 | 656 | m_impl.remove(m_tail); | ||
667 | 657 | unlinkAndDelete(m_tail); | ||
668 | 658 | } | ||
669 | 659 | |||
670 | 660 | template<typename T, size_t inlineCapacity, typename U> | ||
671 | 661 | inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::find(const ValueType& value) | ||
672 | 662 | { | ||
673 | 663 | ImplTypeIterator it = m_impl.template find<BaseTranslator>(value); | ||
674 | 664 | if (it == m_impl.end()) | ||
675 | 665 | return end(); | ||
676 | 666 | return makeIterator(*it); | ||
677 | 667 | } | ||
678 | 668 | |||
679 | 669 | template<typename T, size_t inlineCapacity, typename U> | ||
680 | 670 | inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::find(const ValueType& value) const | ||
681 | 671 | { | ||
682 | 672 | ImplTypeConstIterator it = m_impl.template find<BaseTranslator>(value); | ||
683 | 673 | if (it == m_impl.end()) | ||
684 | 674 | return end(); | ||
685 | 675 | return makeConstIterator(*it); | ||
686 | 676 | } | ||
687 | 677 | |||
688 | 678 | template<typename Translator> | ||
689 | 679 | struct ListHashSetTranslatorAdapter { | ||
690 | 680 | template<typename T> static unsigned hash(const T& key) { return Translator::hash(key); } | ||
691 | 681 | template<typename T, typename U> static bool equal(const T& a, const U& b) { return Translator::equal(a->m_value, b); } | ||
692 | 682 | }; | ||
693 | 683 | |||
694 | 684 | template<typename ValueType, size_t inlineCapacity, typename U> | ||
695 | 685 | template<typename T, typename HashTranslator> | ||
696 | 686 | inline typename ListHashSet<ValueType, inlineCapacity, U>::iterator ListHashSet<ValueType, inlineCapacity, U>::find(const T& value) | ||
697 | 687 | { | ||
698 | 688 | ImplTypeConstIterator it = m_impl.template find<ListHashSetTranslatorAdapter<HashTranslator> >(value); | ||
699 | 689 | if (it == m_impl.end()) | ||
700 | 690 | return end(); | ||
701 | 691 | return makeIterator(*it); | ||
702 | 692 | } | ||
703 | 693 | |||
704 | 694 | template<typename ValueType, size_t inlineCapacity, typename U> | ||
705 | 695 | template<typename T, typename HashTranslator> | ||
706 | 696 | inline typename ListHashSet<ValueType, inlineCapacity, U>::const_iterator ListHashSet<ValueType, inlineCapacity, U>::find(const T& value) const | ||
707 | 697 | { | ||
708 | 698 | ImplTypeConstIterator it = m_impl.template find<ListHashSetTranslatorAdapter<HashTranslator> >(value); | ||
709 | 699 | if (it == m_impl.end()) | ||
710 | 700 | return end(); | ||
711 | 701 | return makeConstIterator(*it); | ||
712 | 702 | } | ||
713 | 703 | |||
714 | 704 | template<typename ValueType, size_t inlineCapacity, typename U> | ||
715 | 705 | template<typename T, typename HashTranslator> | ||
716 | 706 | inline bool ListHashSet<ValueType, inlineCapacity, U>::contains(const T& value) const | ||
717 | 707 | { | ||
718 | 708 | return m_impl.template contains<ListHashSetTranslatorAdapter<HashTranslator> >(value); | ||
719 | 709 | } | ||
720 | 710 | |||
721 | 711 | template<typename T, size_t inlineCapacity, typename U> | ||
722 | 712 | inline bool ListHashSet<T, inlineCapacity, U>::contains(const ValueType& value) const | ||
723 | 713 | { | ||
724 | 714 | return m_impl.template contains<BaseTranslator>(value); | ||
725 | 715 | } | ||
726 | 716 | |||
727 | 717 | template<typename T, size_t inlineCapacity, typename U> | ||
728 | 718 | typename ListHashSet<T, inlineCapacity, U>::AddResult ListHashSet<T, inlineCapacity, U>::add(const ValueType &value) | ||
729 | 719 | { | ||
730 | 720 | typename ImplType::AddResult result = m_impl.template add<BaseTranslator>(value, m_allocator.get()); | ||
731 | 721 | if (result.isNewEntry) | ||
732 | 722 | appendNode(*result.iterator); | ||
733 | 723 | return AddResult(makeIterator(*result.iterator), result.isNewEntry); | ||
734 | 724 | } | ||
735 | 725 | |||
736 | 726 | template<typename T, size_t inlineCapacity, typename U> | ||
737 | 727 | typename ListHashSet<T, inlineCapacity, U>::AddResult ListHashSet<T, inlineCapacity, U>::insertBefore(iterator it, const ValueType& newValue) | ||
738 | 728 | { | ||
739 | 729 | typename ImplType::AddResult result = m_impl.template add<BaseTranslator>(newValue, m_allocator.get()); | ||
740 | 730 | if (result.isNewEntry) | ||
741 | 731 | insertNodeBefore(it.node(), *result.iterator); | ||
742 | 732 | return AddResult(makeIterator(*result.iterator), result.isNewEntry); | ||
743 | 733 | } | ||
744 | 734 | |||
745 | 735 | template<typename T, size_t inlineCapacity, typename U> | ||
746 | 736 | typename ListHashSet<T, inlineCapacity, U>::AddResult ListHashSet<T, inlineCapacity, U>::insertBefore(const ValueType& beforeValue, const ValueType& newValue) | ||
747 | 737 | { | ||
748 | 738 | return insertBefore(find(beforeValue), newValue); | ||
749 | 739 | } | ||
750 | 740 | |||
751 | 741 | template<typename T, size_t inlineCapacity, typename U> | ||
752 | 742 | inline void ListHashSet<T, inlineCapacity, U>::remove(iterator it) | ||
753 | 743 | { | ||
754 | 744 | if (it == end()) | ||
755 | 745 | return; | ||
756 | 746 | m_impl.remove(it.node()); | ||
757 | 747 | unlinkAndDelete(it.node()); | ||
758 | 748 | } | ||
759 | 749 | |||
760 | 750 | template<typename T, size_t inlineCapacity, typename U> | ||
761 | 751 | inline void ListHashSet<T, inlineCapacity, U>::remove(const ValueType& value) | ||
762 | 752 | { | ||
763 | 753 | remove(find(value)); | ||
764 | 754 | } | ||
765 | 755 | |||
766 | 756 | template<typename T, size_t inlineCapacity, typename U> | ||
767 | 757 | inline void ListHashSet<T, inlineCapacity, U>::clear() | ||
768 | 758 | { | ||
769 | 759 | deleteAllNodes(); | ||
770 | 760 | m_impl.clear(); | ||
771 | 761 | m_head = 0; | ||
772 | 762 | m_tail = 0; | ||
773 | 763 | } | ||
774 | 764 | |||
775 | 765 | template<typename T, size_t inlineCapacity, typename U> | ||
776 | 766 | void ListHashSet<T, inlineCapacity, U>::unlinkAndDelete(Node* node) | ||
777 | 767 | { | ||
778 | 768 | if (!node->m_prev) { | ||
779 | 769 | ASSERT(node == m_head); | ||
780 | 770 | m_head = node->m_next; | ||
781 | 771 | } else { | ||
782 | 772 | ASSERT(node != m_head); | ||
783 | 773 | node->m_prev->m_next = node->m_next; | ||
784 | 774 | } | ||
785 | 775 | |||
786 | 776 | if (!node->m_next) { | ||
787 | 777 | ASSERT(node == m_tail); | ||
788 | 778 | m_tail = node->m_prev; | ||
789 | 779 | } else { | ||
790 | 780 | ASSERT(node != m_tail); | ||
791 | 781 | node->m_next->m_prev = node->m_prev; | ||
792 | 782 | } | ||
793 | 783 | |||
794 | 784 | node->destroy(m_allocator.get()); | ||
795 | 785 | } | ||
796 | 786 | |||
797 | 787 | template<typename T, size_t inlineCapacity, typename U> | ||
798 | 788 | void ListHashSet<T, inlineCapacity, U>::appendNode(Node* node) | ||
799 | 789 | { | ||
800 | 790 | node->m_prev = m_tail; | ||
801 | 791 | node->m_next = 0; | ||
802 | 792 | |||
803 | 793 | if (m_tail) { | ||
804 | 794 | ASSERT(m_head); | ||
805 | 795 | m_tail->m_next = node; | ||
806 | 796 | } else { | ||
807 | 797 | ASSERT(!m_head); | ||
808 | 798 | m_head = node; | ||
809 | 799 | } | ||
810 | 800 | |||
811 | 801 | m_tail = node; | ||
812 | 802 | } | ||
813 | 803 | |||
814 | 804 | template<typename T, size_t inlineCapacity, typename U> | ||
815 | 805 | void ListHashSet<T, inlineCapacity, U>::insertNodeBefore(Node* beforeNode, Node* newNode) | ||
816 | 806 | { | ||
817 | 807 | if (!beforeNode) | ||
818 | 808 | return appendNode(newNode); | ||
819 | 809 | |||
820 | 810 | newNode->m_next = beforeNode; | ||
821 | 811 | newNode->m_prev = beforeNode->m_prev; | ||
822 | 812 | if (beforeNode->m_prev) | ||
823 | 813 | beforeNode->m_prev->m_next = newNode; | ||
824 | 814 | beforeNode->m_prev = newNode; | ||
825 | 815 | |||
826 | 816 | if (!newNode->m_prev) | ||
827 | 817 | m_head = newNode; | ||
828 | 818 | } | ||
829 | 819 | |||
830 | 820 | template<typename T, size_t inlineCapacity, typename U> | ||
831 | 821 | void ListHashSet<T, inlineCapacity, U>::deleteAllNodes() | ||
832 | 822 | { | ||
833 | 823 | if (!m_head) | ||
834 | 824 | return; | ||
835 | 825 | |||
836 | 826 | for (Node* node = m_head, *next = m_head->m_next; node; node = next, next = node ? node->m_next : 0) | ||
837 | 827 | node->destroy(m_allocator.get()); | ||
838 | 828 | } | ||
839 | 829 | |||
840 | 830 | template<typename T, size_t inlineCapacity, typename U> | ||
841 | 831 | inline ListHashSetReverseIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeReverseIterator(Node* position) | ||
842 | 832 | { | ||
843 | 833 | return ListHashSetReverseIterator<T, inlineCapacity, U>(this, position); | ||
844 | 834 | } | ||
845 | 835 | |||
846 | 836 | template<typename T, size_t inlineCapacity, typename U> | ||
847 | 837 | inline ListHashSetConstReverseIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeConstReverseIterator(Node* position) const | ||
848 | 838 | { | ||
849 | 839 | return ListHashSetConstReverseIterator<T, inlineCapacity, U>(this, position); | ||
850 | 840 | } | ||
851 | 841 | |||
852 | 842 | template<typename T, size_t inlineCapacity, typename U> | ||
853 | 843 | inline ListHashSetIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeIterator(Node* position) | ||
854 | 844 | { | ||
855 | 845 | return ListHashSetIterator<T, inlineCapacity, U>(this, position); | ||
856 | 846 | } | ||
857 | 847 | |||
858 | 848 | template<typename T, size_t inlineCapacity, typename U> | ||
859 | 849 | inline ListHashSetConstIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeConstIterator(Node* position) const | ||
860 | 850 | { | ||
861 | 851 | return ListHashSetConstIterator<T, inlineCapacity, U>(this, position); | ||
862 | 852 | } | ||
863 | 853 | template<bool, typename ValueType, typename HashTableType> | ||
864 | 854 | void deleteAllValues(HashTableType& collection) | ||
865 | 855 | { | ||
866 | 856 | typedef typename HashTableType::const_iterator iterator; | ||
867 | 857 | iterator end = collection.end(); | ||
868 | 858 | for (iterator it = collection.begin(); it != end; ++it) | ||
869 | 859 | delete (*it)->m_value; | ||
870 | 860 | } | ||
871 | 861 | |||
872 | 862 | template<typename T, size_t inlineCapacity, typename U> | ||
873 | 863 | inline void deleteAllValues(const ListHashSet<T, inlineCapacity, U>& collection) | ||
874 | 864 | { | ||
875 | 865 | deleteAllValues<true, typename ListHashSet<T, inlineCapacity, U>::ValueType>(collection.m_impl); | ||
876 | 866 | } | ||
877 | 867 | |||
878 | 868 | } // namespace WTF | ||
879 | 869 | |||
880 | 870 | using WTF::ListHashSet; | ||
881 | 871 | |||
882 | 872 | #endif /* WTF_ListHashSet_h */ | ||
883 | 873 | 0 | ||
884 | === removed file '.pc/applied-patches' | |||
885 | --- .pc/applied-patches 2013-03-28 15:37:15 +0000 | |||
886 | +++ .pc/applied-patches 1970-01-01 00:00:00 +0000 | |||
887 | @@ -1,9 +0,0 @@ | |||
888 | 1 | 05_sparc_unaligned_access.diff | ||
889 | 2 | stabs_format_debug_info.diff | ||
890 | 3 | no_gc_sections.diff | ||
891 | 4 | hurd.diff | ||
892 | 5 | webkit_qt_hide_symbols.diff | ||
893 | 6 | save_memory.diff | ||
894 | 7 | devicePixelResolution.patch | ||
895 | 8 | disable_geolocation_501.diff | ||
896 | 9 | kubuntu_fix_for_powerpc.diff | ||
897 | 10 | 0 | ||
898 | === removed directory '.pc/devicePixelResolution.patch' | |||
899 | === removed directory '.pc/devicePixelResolution.patch/Source' | |||
900 | === removed directory '.pc/devicePixelResolution.patch/Source/WebCore' | |||
901 | === removed directory '.pc/devicePixelResolution.patch/Source/WebCore/page' | |||
902 | === removed file '.pc/devicePixelResolution.patch/Source/WebCore/page/Page.cpp' | |||
903 | --- .pc/devicePixelResolution.patch/Source/WebCore/page/Page.cpp 2013-02-18 14:24:18 +0000 | |||
904 | +++ .pc/devicePixelResolution.patch/Source/WebCore/page/Page.cpp 1970-01-01 00:00:00 +0000 | |||
905 | @@ -1,1346 +0,0 @@ | |||
906 | 1 | /* | ||
907 | 2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All Rights Reserved. | ||
908 | 3 | * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) | ||
909 | 4 | * | ||
910 | 5 | * This library is free software; you can redistribute it and/or | ||
911 | 6 | * modify it under the terms of the GNU Library General Public | ||
912 | 7 | * License as published by the Free Software Foundation; either | ||
913 | 8 | * version 2 of the License, or (at your option) any later version. | ||
914 | 9 | * This library is distributed in the hope that it will be useful, | ||
915 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
916 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
917 | 12 | * Library General Public License for more details. | ||
918 | 13 | * | ||
919 | 14 | * You should have received a copy of the GNU Library General Public License | ||
920 | 15 | * along with this library; see the file COPYING.LIB. If not, write to | ||
921 | 16 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
922 | 17 | * Boston, MA 02110-1301, USA. | ||
923 | 18 | */ | ||
924 | 19 | |||
925 | 20 | #include "config.h" | ||
926 | 21 | #include "Page.h" | ||
927 | 22 | |||
928 | 23 | #include "AlternativeTextClient.h" | ||
929 | 24 | #include "BackForwardController.h" | ||
930 | 25 | #include "BackForwardList.h" | ||
931 | 26 | #include "Chrome.h" | ||
932 | 27 | #include "ChromeClient.h" | ||
933 | 28 | #include "ContextMenuClient.h" | ||
934 | 29 | #include "ContextMenuController.h" | ||
935 | 30 | #include "DOMWindow.h" | ||
936 | 31 | #include "DocumentMarkerController.h" | ||
937 | 32 | #include "DocumentStyleSheetCollection.h" | ||
938 | 33 | #include "DragController.h" | ||
939 | 34 | #include "EditorClient.h" | ||
940 | 35 | #include "Event.h" | ||
941 | 36 | #include "EventNames.h" | ||
942 | 37 | #include "ExceptionCode.h" | ||
943 | 38 | #include "FileSystem.h" | ||
944 | 39 | #include "FocusController.h" | ||
945 | 40 | #include "Frame.h" | ||
946 | 41 | #include "FrameLoader.h" | ||
947 | 42 | #include "FrameLoaderClient.h" | ||
948 | 43 | #include "FrameSelection.h" | ||
949 | 44 | #include "FrameTree.h" | ||
950 | 45 | #include "FrameView.h" | ||
951 | 46 | #include "HTMLElement.h" | ||
952 | 47 | #include "HistoryItem.h" | ||
953 | 48 | #include "InspectorController.h" | ||
954 | 49 | #include "InspectorInstrumentation.h" | ||
955 | 50 | #include "Logging.h" | ||
956 | 51 | #include "MediaCanStartListener.h" | ||
957 | 52 | #include "Navigator.h" | ||
958 | 53 | #include "NetworkStateNotifier.h" | ||
959 | 54 | #include "PageCache.h" | ||
960 | 55 | #include "PageGroup.h" | ||
961 | 56 | #include "PluginData.h" | ||
962 | 57 | #include "PluginView.h" | ||
963 | 58 | #include "PointerLockController.h" | ||
964 | 59 | #include "ProgressTracker.h" | ||
965 | 60 | #include "RenderArena.h" | ||
966 | 61 | #include "RenderTheme.h" | ||
967 | 62 | #include "RenderView.h" | ||
968 | 63 | #include "RenderWidget.h" | ||
969 | 64 | #include "RuntimeEnabledFeatures.h" | ||
970 | 65 | #include "SchemeRegistry.h" | ||
971 | 66 | #include "ScrollingCoordinator.h" | ||
972 | 67 | #include "Settings.h" | ||
973 | 68 | #include "SharedBuffer.h" | ||
974 | 69 | #include "StorageArea.h" | ||
975 | 70 | #include "StorageNamespace.h" | ||
976 | 71 | #include "StyleResolver.h" | ||
977 | 72 | #include "TextResourceDecoder.h" | ||
978 | 73 | #include "VoidCallback.h" | ||
979 | 74 | #include "WebCoreMemoryInstrumentation.h" | ||
980 | 75 | #include "Widget.h" | ||
981 | 76 | #include <wtf/HashMap.h> | ||
982 | 77 | #include <wtf/RefCountedLeakCounter.h> | ||
983 | 78 | #include <wtf/StdLibExtras.h> | ||
984 | 79 | #include <wtf/text/Base64.h> | ||
985 | 80 | #include <wtf/text/StringHash.h> | ||
986 | 81 | |||
987 | 82 | namespace WebCore { | ||
988 | 83 | |||
989 | 84 | static HashSet<Page*>* allPages; | ||
990 | 85 | static const double hiddenPageTimerAlignmentInterval = 1.0; // once a second | ||
991 | 86 | |||
992 | 87 | DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page")); | ||
993 | 88 | |||
994 | 89 | static void networkStateChanged() | ||
995 | 90 | { | ||
996 | 91 | Vector<RefPtr<Frame> > frames; | ||
997 | 92 | |||
998 | 93 | // Get all the frames of all the pages in all the page groups | ||
999 | 94 | HashSet<Page*>::iterator end = allPages->end(); | ||
1000 | 95 | for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) { | ||
1001 | 96 | for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
1002 | 97 | frames.append(frame); | ||
1003 | 98 | InspectorInstrumentation::networkStateChanged(*it); | ||
1004 | 99 | } | ||
1005 | 100 | |||
1006 | 101 | AtomicString eventName = networkStateNotifier().onLine() ? eventNames().onlineEvent : eventNames().offlineEvent; | ||
1007 | 102 | for (unsigned i = 0; i < frames.size(); i++) | ||
1008 | 103 | frames[i]->document()->dispatchWindowEvent(Event::create(eventName, false, false)); | ||
1009 | 104 | } | ||
1010 | 105 | |||
1011 | 106 | float deviceScaleFactor(Frame* frame) | ||
1012 | 107 | { | ||
1013 | 108 | if (!frame) | ||
1014 | 109 | return 1; | ||
1015 | 110 | Page* page = frame->page(); | ||
1016 | 111 | if (!page) | ||
1017 | 112 | return 1; | ||
1018 | 113 | return page->deviceScaleFactor(); | ||
1019 | 114 | } | ||
1020 | 115 | |||
1021 | 116 | Page::Page(PageClients& pageClients) | ||
1022 | 117 | : m_chrome(Chrome::create(this, pageClients.chromeClient)) | ||
1023 | 118 | , m_dragCaretController(DragCaretController::create()) | ||
1024 | 119 | #if ENABLE(DRAG_SUPPORT) | ||
1025 | 120 | , m_dragController(DragController::create(this, pageClients.dragClient)) | ||
1026 | 121 | #endif | ||
1027 | 122 | , m_focusController(FocusController::create(this)) | ||
1028 | 123 | #if ENABLE(CONTEXT_MENUS) | ||
1029 | 124 | , m_contextMenuController(ContextMenuController::create(this, pageClients.contextMenuClient)) | ||
1030 | 125 | #endif | ||
1031 | 126 | #if ENABLE(INSPECTOR) | ||
1032 | 127 | , m_inspectorController(InspectorController::create(this, pageClients.inspectorClient)) | ||
1033 | 128 | #endif | ||
1034 | 129 | #if ENABLE(POINTER_LOCK) | ||
1035 | 130 | , m_pointerLockController(PointerLockController::create(this)) | ||
1036 | 131 | #endif | ||
1037 | 132 | , m_settings(Settings::create(this)) | ||
1038 | 133 | , m_progress(ProgressTracker::create()) | ||
1039 | 134 | , m_backForwardController(BackForwardController::create(this, pageClients.backForwardClient)) | ||
1040 | 135 | , m_theme(RenderTheme::themeForPage(this)) | ||
1041 | 136 | , m_editorClient(pageClients.editorClient) | ||
1042 | 137 | , m_validationMessageClient(pageClients.validationMessageClient) | ||
1043 | 138 | , m_subframeCount(0) | ||
1044 | 139 | , m_openedByDOM(false) | ||
1045 | 140 | , m_tabKeyCyclesThroughElements(true) | ||
1046 | 141 | , m_defersLoading(false) | ||
1047 | 142 | , m_defersLoadingCallCount(0) | ||
1048 | 143 | , m_inLowQualityInterpolationMode(false) | ||
1049 | 144 | , m_cookieEnabled(true) | ||
1050 | 145 | , m_areMemoryCacheClientCallsEnabled(true) | ||
1051 | 146 | , m_mediaVolume(1) | ||
1052 | 147 | , m_pageScaleFactor(1) | ||
1053 | 148 | , m_deviceScaleFactor(1) | ||
1054 | 149 | , m_suppressScrollbarAnimations(false) | ||
1055 | 150 | , m_didLoadUserStyleSheet(false) | ||
1056 | 151 | , m_userStyleSheetModificationTime(0) | ||
1057 | 152 | , m_group(0) | ||
1058 | 153 | , m_debugger(0) | ||
1059 | 154 | , m_customHTMLTokenizerTimeDelay(-1) | ||
1060 | 155 | , m_customHTMLTokenizerChunkSize(-1) | ||
1061 | 156 | , m_canStartMedia(true) | ||
1062 | 157 | , m_viewMode(ViewModeWindowed) | ||
1063 | 158 | , m_minimumTimerInterval(Settings::defaultMinDOMTimerInterval()) | ||
1064 | 159 | , m_timerAlignmentInterval(Settings::defaultDOMTimerAlignmentInterval()) | ||
1065 | 160 | , m_isEditable(false) | ||
1066 | 161 | , m_isOnscreen(true) | ||
1067 | 162 | #if ENABLE(PAGE_VISIBILITY_API) | ||
1068 | 163 | , m_visibilityState(PageVisibilityStateVisible) | ||
1069 | 164 | #endif | ||
1070 | 165 | , m_displayID(0) | ||
1071 | 166 | , m_layoutMilestones(0) | ||
1072 | 167 | , m_isCountingRelevantRepaintedObjects(false) | ||
1073 | 168 | #ifndef NDEBUG | ||
1074 | 169 | , m_isPainting(false) | ||
1075 | 170 | #endif | ||
1076 | 171 | , m_alternativeTextClient(pageClients.alternativeTextClient) | ||
1077 | 172 | , m_scriptedAnimationsSuspended(false) | ||
1078 | 173 | { | ||
1079 | 174 | ASSERT(m_editorClient); | ||
1080 | 175 | |||
1081 | 176 | if (!allPages) { | ||
1082 | 177 | allPages = new HashSet<Page*>; | ||
1083 | 178 | |||
1084 | 179 | networkStateNotifier().setNetworkStateChangedFunction(networkStateChanged); | ||
1085 | 180 | } | ||
1086 | 181 | |||
1087 | 182 | ASSERT(!allPages->contains(this)); | ||
1088 | 183 | allPages->add(this); | ||
1089 | 184 | |||
1090 | 185 | #ifndef NDEBUG | ||
1091 | 186 | pageCounter.increment(); | ||
1092 | 187 | #endif | ||
1093 | 188 | } | ||
1094 | 189 | |||
1095 | 190 | Page::~Page() | ||
1096 | 191 | { | ||
1097 | 192 | m_mainFrame->setView(0); | ||
1098 | 193 | setGroupName(String()); | ||
1099 | 194 | allPages->remove(this); | ||
1100 | 195 | |||
1101 | 196 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1102 | 197 | frame->willDetachPage(); | ||
1103 | 198 | frame->detachFromPage(); | ||
1104 | 199 | } | ||
1105 | 200 | |||
1106 | 201 | m_editorClient->pageDestroyed(); | ||
1107 | 202 | if (m_alternativeTextClient) | ||
1108 | 203 | m_alternativeTextClient->pageDestroyed(); | ||
1109 | 204 | |||
1110 | 205 | #if ENABLE(INSPECTOR) | ||
1111 | 206 | m_inspectorController->inspectedPageDestroyed(); | ||
1112 | 207 | #endif | ||
1113 | 208 | |||
1114 | 209 | if (m_scrollingCoordinator) | ||
1115 | 210 | m_scrollingCoordinator->pageDestroyed(); | ||
1116 | 211 | |||
1117 | 212 | backForward()->close(); | ||
1118 | 213 | |||
1119 | 214 | #ifndef NDEBUG | ||
1120 | 215 | pageCounter.decrement(); | ||
1121 | 216 | #endif | ||
1122 | 217 | |||
1123 | 218 | } | ||
1124 | 219 | |||
1125 | 220 | ArenaSize Page::renderTreeSize() const | ||
1126 | 221 | { | ||
1127 | 222 | ArenaSize total(0, 0); | ||
1128 | 223 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1129 | 224 | if (!frame->document()) | ||
1130 | 225 | continue; | ||
1131 | 226 | if (RenderArena* arena = frame->document()->renderArena()) { | ||
1132 | 227 | total.treeSize += arena->totalRenderArenaSize(); | ||
1133 | 228 | total.allocated += arena->totalRenderArenaAllocatedBytes(); | ||
1134 | 229 | } | ||
1135 | 230 | } | ||
1136 | 231 | return total; | ||
1137 | 232 | } | ||
1138 | 233 | |||
1139 | 234 | ViewportArguments Page::viewportArguments() const | ||
1140 | 235 | { | ||
1141 | 236 | return mainFrame() && mainFrame()->document() ? mainFrame()->document()->viewportArguments() : ViewportArguments(); | ||
1142 | 237 | } | ||
1143 | 238 | |||
1144 | 239 | ScrollingCoordinator* Page::scrollingCoordinator() | ||
1145 | 240 | { | ||
1146 | 241 | if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled()) | ||
1147 | 242 | m_scrollingCoordinator = ScrollingCoordinator::create(this); | ||
1148 | 243 | |||
1149 | 244 | return m_scrollingCoordinator.get(); | ||
1150 | 245 | } | ||
1151 | 246 | |||
1152 | 247 | String Page::scrollingStateTreeAsText() | ||
1153 | 248 | { | ||
1154 | 249 | if (Document* document = m_mainFrame->document()) | ||
1155 | 250 | document->updateLayout(); | ||
1156 | 251 | |||
1157 | 252 | if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) | ||
1158 | 253 | return scrollingCoordinator->scrollingStateTreeAsText(); | ||
1159 | 254 | |||
1160 | 255 | return String(); | ||
1161 | 256 | } | ||
1162 | 257 | |||
1163 | 258 | struct ViewModeInfo { | ||
1164 | 259 | const char* name; | ||
1165 | 260 | Page::ViewMode type; | ||
1166 | 261 | }; | ||
1167 | 262 | static const int viewModeMapSize = 5; | ||
1168 | 263 | static ViewModeInfo viewModeMap[viewModeMapSize] = { | ||
1169 | 264 | {"windowed", Page::ViewModeWindowed}, | ||
1170 | 265 | {"floating", Page::ViewModeFloating}, | ||
1171 | 266 | {"fullscreen", Page::ViewModeFullscreen}, | ||
1172 | 267 | {"maximized", Page::ViewModeMaximized}, | ||
1173 | 268 | {"minimized", Page::ViewModeMinimized} | ||
1174 | 269 | }; | ||
1175 | 270 | |||
1176 | 271 | Page::ViewMode Page::stringToViewMode(const String& text) | ||
1177 | 272 | { | ||
1178 | 273 | for (int i = 0; i < viewModeMapSize; ++i) { | ||
1179 | 274 | if (text == viewModeMap[i].name) | ||
1180 | 275 | return viewModeMap[i].type; | ||
1181 | 276 | } | ||
1182 | 277 | return Page::ViewModeInvalid; | ||
1183 | 278 | } | ||
1184 | 279 | |||
1185 | 280 | void Page::setViewMode(ViewMode viewMode) | ||
1186 | 281 | { | ||
1187 | 282 | if (viewMode == m_viewMode || viewMode == ViewModeInvalid) | ||
1188 | 283 | return; | ||
1189 | 284 | |||
1190 | 285 | m_viewMode = viewMode; | ||
1191 | 286 | |||
1192 | 287 | if (!m_mainFrame) | ||
1193 | 288 | return; | ||
1194 | 289 | |||
1195 | 290 | if (m_mainFrame->view()) | ||
1196 | 291 | m_mainFrame->view()->forceLayout(); | ||
1197 | 292 | |||
1198 | 293 | if (m_mainFrame->document()) | ||
1199 | 294 | m_mainFrame->document()->styleResolverChanged(RecalcStyleImmediately); | ||
1200 | 295 | } | ||
1201 | 296 | |||
1202 | 297 | void Page::setMainFrame(PassRefPtr<Frame> mainFrame) | ||
1203 | 298 | { | ||
1204 | 299 | ASSERT(!m_mainFrame); // Should only be called during initialization | ||
1205 | 300 | m_mainFrame = mainFrame; | ||
1206 | 301 | } | ||
1207 | 302 | |||
1208 | 303 | bool Page::openedByDOM() const | ||
1209 | 304 | { | ||
1210 | 305 | return m_openedByDOM; | ||
1211 | 306 | } | ||
1212 | 307 | |||
1213 | 308 | void Page::setOpenedByDOM() | ||
1214 | 309 | { | ||
1215 | 310 | m_openedByDOM = true; | ||
1216 | 311 | } | ||
1217 | 312 | |||
1218 | 313 | BackForwardList* Page::backForwardList() const | ||
1219 | 314 | { | ||
1220 | 315 | return m_backForwardController->client(); | ||
1221 | 316 | } | ||
1222 | 317 | |||
1223 | 318 | bool Page::goBack() | ||
1224 | 319 | { | ||
1225 | 320 | HistoryItem* item = backForward()->backItem(); | ||
1226 | 321 | |||
1227 | 322 | if (item) { | ||
1228 | 323 | goToItem(item, FrameLoadTypeBack); | ||
1229 | 324 | return true; | ||
1230 | 325 | } | ||
1231 | 326 | return false; | ||
1232 | 327 | } | ||
1233 | 328 | |||
1234 | 329 | bool Page::goForward() | ||
1235 | 330 | { | ||
1236 | 331 | HistoryItem* item = backForward()->forwardItem(); | ||
1237 | 332 | |||
1238 | 333 | if (item) { | ||
1239 | 334 | goToItem(item, FrameLoadTypeForward); | ||
1240 | 335 | return true; | ||
1241 | 336 | } | ||
1242 | 337 | return false; | ||
1243 | 338 | } | ||
1244 | 339 | |||
1245 | 340 | bool Page::canGoBackOrForward(int distance) const | ||
1246 | 341 | { | ||
1247 | 342 | if (distance == 0) | ||
1248 | 343 | return true; | ||
1249 | 344 | if (distance > 0 && distance <= backForward()->forwardCount()) | ||
1250 | 345 | return true; | ||
1251 | 346 | if (distance < 0 && -distance <= backForward()->backCount()) | ||
1252 | 347 | return true; | ||
1253 | 348 | return false; | ||
1254 | 349 | } | ||
1255 | 350 | |||
1256 | 351 | void Page::goBackOrForward(int distance) | ||
1257 | 352 | { | ||
1258 | 353 | if (distance == 0) | ||
1259 | 354 | return; | ||
1260 | 355 | |||
1261 | 356 | HistoryItem* item = backForward()->itemAtIndex(distance); | ||
1262 | 357 | if (!item) { | ||
1263 | 358 | if (distance > 0) { | ||
1264 | 359 | if (int forwardCount = backForward()->forwardCount()) | ||
1265 | 360 | item = backForward()->itemAtIndex(forwardCount); | ||
1266 | 361 | } else { | ||
1267 | 362 | if (int backCount = backForward()->backCount()) | ||
1268 | 363 | item = backForward()->itemAtIndex(-backCount); | ||
1269 | 364 | } | ||
1270 | 365 | } | ||
1271 | 366 | |||
1272 | 367 | if (!item) | ||
1273 | 368 | return; | ||
1274 | 369 | |||
1275 | 370 | goToItem(item, FrameLoadTypeIndexedBackForward); | ||
1276 | 371 | } | ||
1277 | 372 | |||
1278 | 373 | void Page::goToItem(HistoryItem* item, FrameLoadType type) | ||
1279 | 374 | { | ||
1280 | 375 | // stopAllLoaders may end up running onload handlers, which could cause further history traversals that may lead to the passed in HistoryItem | ||
1281 | 376 | // being deref()-ed. Make sure we can still use it with HistoryController::goToItem later. | ||
1282 | 377 | RefPtr<HistoryItem> protector(item); | ||
1283 | 378 | |||
1284 | 379 | if (m_mainFrame->loader()->history()->shouldStopLoadingForHistoryItem(item)) | ||
1285 | 380 | m_mainFrame->loader()->stopAllLoaders(); | ||
1286 | 381 | |||
1287 | 382 | m_mainFrame->loader()->history()->goToItem(item, type); | ||
1288 | 383 | } | ||
1289 | 384 | |||
1290 | 385 | int Page::getHistoryLength() | ||
1291 | 386 | { | ||
1292 | 387 | return backForward()->backCount() + 1 + backForward()->forwardCount(); | ||
1293 | 388 | } | ||
1294 | 389 | |||
1295 | 390 | void Page::setGroupName(const String& name) | ||
1296 | 391 | { | ||
1297 | 392 | if (m_group && !m_group->name().isEmpty()) { | ||
1298 | 393 | ASSERT(m_group != m_singlePageGroup.get()); | ||
1299 | 394 | ASSERT(!m_singlePageGroup); | ||
1300 | 395 | m_group->removePage(this); | ||
1301 | 396 | } | ||
1302 | 397 | |||
1303 | 398 | if (name.isEmpty()) | ||
1304 | 399 | m_group = m_singlePageGroup.get(); | ||
1305 | 400 | else { | ||
1306 | 401 | m_singlePageGroup.clear(); | ||
1307 | 402 | m_group = PageGroup::pageGroup(name); | ||
1308 | 403 | m_group->addPage(this); | ||
1309 | 404 | } | ||
1310 | 405 | } | ||
1311 | 406 | |||
1312 | 407 | const String& Page::groupName() const | ||
1313 | 408 | { | ||
1314 | 409 | DEFINE_STATIC_LOCAL(String, nullString, ()); | ||
1315 | 410 | // FIXME: Why not just return String()? | ||
1316 | 411 | return m_group ? m_group->name() : nullString; | ||
1317 | 412 | } | ||
1318 | 413 | |||
1319 | 414 | void Page::initGroup() | ||
1320 | 415 | { | ||
1321 | 416 | ASSERT(!m_singlePageGroup); | ||
1322 | 417 | ASSERT(!m_group); | ||
1323 | 418 | m_singlePageGroup = PageGroup::create(this); | ||
1324 | 419 | m_group = m_singlePageGroup.get(); | ||
1325 | 420 | } | ||
1326 | 421 | |||
1327 | 422 | void Page::scheduleForcedStyleRecalcForAllPages() | ||
1328 | 423 | { | ||
1329 | 424 | if (!allPages) | ||
1330 | 425 | return; | ||
1331 | 426 | HashSet<Page*>::iterator end = allPages->end(); | ||
1332 | 427 | for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) | ||
1333 | 428 | for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
1334 | 429 | frame->document()->scheduleForcedStyleRecalc(); | ||
1335 | 430 | } | ||
1336 | 431 | |||
1337 | 432 | void Page::setNeedsRecalcStyleInAllFrames() | ||
1338 | 433 | { | ||
1339 | 434 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
1340 | 435 | frame->document()->styleResolverChanged(DeferRecalcStyle); | ||
1341 | 436 | } | ||
1342 | 437 | |||
1343 | 438 | void Page::refreshPlugins(bool reload) | ||
1344 | 439 | { | ||
1345 | 440 | if (!allPages) | ||
1346 | 441 | return; | ||
1347 | 442 | |||
1348 | 443 | PluginData::refresh(); | ||
1349 | 444 | |||
1350 | 445 | Vector<RefPtr<Frame> > framesNeedingReload; | ||
1351 | 446 | |||
1352 | 447 | HashSet<Page*>::iterator end = allPages->end(); | ||
1353 | 448 | for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) { | ||
1354 | 449 | Page* page = *it; | ||
1355 | 450 | |||
1356 | 451 | // Clear out the page's plug-in data. | ||
1357 | 452 | if (page->m_pluginData) | ||
1358 | 453 | page->m_pluginData = 0; | ||
1359 | 454 | |||
1360 | 455 | if (!reload) | ||
1361 | 456 | continue; | ||
1362 | 457 | |||
1363 | 458 | for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1364 | 459 | if (frame->loader()->subframeLoader()->containsPlugins()) | ||
1365 | 460 | framesNeedingReload.append(frame); | ||
1366 | 461 | } | ||
1367 | 462 | } | ||
1368 | 463 | |||
1369 | 464 | for (size_t i = 0; i < framesNeedingReload.size(); ++i) | ||
1370 | 465 | framesNeedingReload[i]->loader()->reload(); | ||
1371 | 466 | } | ||
1372 | 467 | |||
1373 | 468 | PluginData* Page::pluginData() const | ||
1374 | 469 | { | ||
1375 | 470 | if (!mainFrame()->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin)) | ||
1376 | 471 | return 0; | ||
1377 | 472 | if (!m_pluginData) | ||
1378 | 473 | m_pluginData = PluginData::create(this); | ||
1379 | 474 | return m_pluginData.get(); | ||
1380 | 475 | } | ||
1381 | 476 | |||
1382 | 477 | inline MediaCanStartListener* Page::takeAnyMediaCanStartListener() | ||
1383 | 478 | { | ||
1384 | 479 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1385 | 480 | if (MediaCanStartListener* listener = frame->document()->takeAnyMediaCanStartListener()) | ||
1386 | 481 | return listener; | ||
1387 | 482 | } | ||
1388 | 483 | return 0; | ||
1389 | 484 | } | ||
1390 | 485 | |||
1391 | 486 | void Page::setCanStartMedia(bool canStartMedia) | ||
1392 | 487 | { | ||
1393 | 488 | if (m_canStartMedia == canStartMedia) | ||
1394 | 489 | return; | ||
1395 | 490 | |||
1396 | 491 | m_canStartMedia = canStartMedia; | ||
1397 | 492 | |||
1398 | 493 | while (m_canStartMedia) { | ||
1399 | 494 | MediaCanStartListener* listener = takeAnyMediaCanStartListener(); | ||
1400 | 495 | if (!listener) | ||
1401 | 496 | break; | ||
1402 | 497 | listener->mediaCanStart(); | ||
1403 | 498 | } | ||
1404 | 499 | } | ||
1405 | 500 | |||
1406 | 501 | static Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag) | ||
1407 | 502 | { | ||
1408 | 503 | return forward | ||
1409 | 504 | ? curr->tree()->traverseNextWithWrap(wrapFlag) | ||
1410 | 505 | : curr->tree()->traversePreviousWithWrap(wrapFlag); | ||
1411 | 506 | } | ||
1412 | 507 | |||
1413 | 508 | bool Page::findString(const String& target, TextCaseSensitivity caseSensitivity, FindDirection direction, bool shouldWrap) | ||
1414 | 509 | { | ||
1415 | 510 | return findString(target, (caseSensitivity == TextCaseInsensitive ? CaseInsensitive : 0) | (direction == FindDirectionBackward ? Backwards : 0) | (shouldWrap ? WrapAround : 0)); | ||
1416 | 511 | } | ||
1417 | 512 | |||
1418 | 513 | bool Page::findString(const String& target, FindOptions options) | ||
1419 | 514 | { | ||
1420 | 515 | if (target.isEmpty() || !mainFrame()) | ||
1421 | 516 | return false; | ||
1422 | 517 | |||
1423 | 518 | bool shouldWrap = options & WrapAround; | ||
1424 | 519 | Frame* frame = focusController()->focusedOrMainFrame(); | ||
1425 | 520 | Frame* startFrame = frame; | ||
1426 | 521 | do { | ||
1427 | 522 | if (frame->editor()->findString(target, (options & ~WrapAround) | StartInSelection)) { | ||
1428 | 523 | if (frame != startFrame) | ||
1429 | 524 | startFrame->selection()->clear(); | ||
1430 | 525 | focusController()->setFocusedFrame(frame); | ||
1431 | 526 | return true; | ||
1432 | 527 | } | ||
1433 | 528 | frame = incrementFrame(frame, !(options & Backwards), shouldWrap); | ||
1434 | 529 | } while (frame && frame != startFrame); | ||
1435 | 530 | |||
1436 | 531 | // Search contents of startFrame, on the other side of the selection that we did earlier. | ||
1437 | 532 | // We cheat a bit and just research with wrap on | ||
1438 | 533 | if (shouldWrap && !startFrame->selection()->isNone()) { | ||
1439 | 534 | bool found = startFrame->editor()->findString(target, options | WrapAround | StartInSelection); | ||
1440 | 535 | focusController()->setFocusedFrame(frame); | ||
1441 | 536 | return found; | ||
1442 | 537 | } | ||
1443 | 538 | |||
1444 | 539 | return false; | ||
1445 | 540 | } | ||
1446 | 541 | |||
1447 | 542 | PassRefPtr<Range> Page::rangeOfString(const String& target, Range* referenceRange, FindOptions options) | ||
1448 | 543 | { | ||
1449 | 544 | if (target.isEmpty() || !mainFrame()) | ||
1450 | 545 | return 0; | ||
1451 | 546 | |||
1452 | 547 | if (referenceRange && referenceRange->ownerDocument()->page() != this) | ||
1453 | 548 | return 0; | ||
1454 | 549 | |||
1455 | 550 | bool shouldWrap = options & WrapAround; | ||
1456 | 551 | Frame* frame = referenceRange ? referenceRange->ownerDocument()->frame() : mainFrame(); | ||
1457 | 552 | Frame* startFrame = frame; | ||
1458 | 553 | do { | ||
1459 | 554 | if (RefPtr<Range> resultRange = frame->editor()->rangeOfString(target, frame == startFrame ? referenceRange : 0, options & ~WrapAround)) | ||
1460 | 555 | return resultRange.release(); | ||
1461 | 556 | |||
1462 | 557 | frame = incrementFrame(frame, !(options & Backwards), shouldWrap); | ||
1463 | 558 | } while (frame && frame != startFrame); | ||
1464 | 559 | |||
1465 | 560 | // Search contents of startFrame, on the other side of the reference range that we did earlier. | ||
1466 | 561 | // We cheat a bit and just search again with wrap on. | ||
1467 | 562 | if (shouldWrap && referenceRange) { | ||
1468 | 563 | if (RefPtr<Range> resultRange = startFrame->editor()->rangeOfString(target, referenceRange, options | WrapAround | StartInSelection)) | ||
1469 | 564 | return resultRange.release(); | ||
1470 | 565 | } | ||
1471 | 566 | |||
1472 | 567 | return 0; | ||
1473 | 568 | } | ||
1474 | 569 | |||
1475 | 570 | unsigned int Page::markAllMatchesForText(const String& target, TextCaseSensitivity caseSensitivity, bool shouldHighlight, unsigned limit) | ||
1476 | 571 | { | ||
1477 | 572 | return markAllMatchesForText(target, caseSensitivity == TextCaseInsensitive ? CaseInsensitive : 0, shouldHighlight, limit); | ||
1478 | 573 | } | ||
1479 | 574 | |||
1480 | 575 | unsigned int Page::markAllMatchesForText(const String& target, FindOptions options, bool shouldHighlight, unsigned limit) | ||
1481 | 576 | { | ||
1482 | 577 | if (target.isEmpty() || !mainFrame()) | ||
1483 | 578 | return 0; | ||
1484 | 579 | |||
1485 | 580 | unsigned matches = 0; | ||
1486 | 581 | |||
1487 | 582 | Frame* frame = mainFrame(); | ||
1488 | 583 | do { | ||
1489 | 584 | frame->editor()->setMarkedTextMatchesAreHighlighted(shouldHighlight); | ||
1490 | 585 | matches += frame->editor()->countMatchesForText(target, options, limit ? (limit - matches) : 0, true); | ||
1491 | 586 | frame = incrementFrame(frame, true, false); | ||
1492 | 587 | } while (frame); | ||
1493 | 588 | |||
1494 | 589 | return matches; | ||
1495 | 590 | } | ||
1496 | 591 | |||
1497 | 592 | void Page::unmarkAllTextMatches() | ||
1498 | 593 | { | ||
1499 | 594 | if (!mainFrame()) | ||
1500 | 595 | return; | ||
1501 | 596 | |||
1502 | 597 | Frame* frame = mainFrame(); | ||
1503 | 598 | do { | ||
1504 | 599 | frame->document()->markers()->removeMarkers(DocumentMarker::TextMatch); | ||
1505 | 600 | frame = incrementFrame(frame, true, false); | ||
1506 | 601 | } while (frame); | ||
1507 | 602 | } | ||
1508 | 603 | |||
1509 | 604 | const VisibleSelection& Page::selection() const | ||
1510 | 605 | { | ||
1511 | 606 | return focusController()->focusedOrMainFrame()->selection()->selection(); | ||
1512 | 607 | } | ||
1513 | 608 | |||
1514 | 609 | void Page::setDefersLoading(bool defers) | ||
1515 | 610 | { | ||
1516 | 611 | if (!m_settings->loadDeferringEnabled()) | ||
1517 | 612 | return; | ||
1518 | 613 | |||
1519 | 614 | if (m_settings->wantsBalancedSetDefersLoadingBehavior()) { | ||
1520 | 615 | ASSERT(defers || m_defersLoadingCallCount); | ||
1521 | 616 | if (defers && ++m_defersLoadingCallCount > 1) | ||
1522 | 617 | return; | ||
1523 | 618 | if (!defers && --m_defersLoadingCallCount) | ||
1524 | 619 | return; | ||
1525 | 620 | } else { | ||
1526 | 621 | ASSERT(!m_defersLoadingCallCount); | ||
1527 | 622 | if (defers == m_defersLoading) | ||
1528 | 623 | return; | ||
1529 | 624 | } | ||
1530 | 625 | |||
1531 | 626 | m_defersLoading = defers; | ||
1532 | 627 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
1533 | 628 | frame->loader()->setDefersLoading(defers); | ||
1534 | 629 | } | ||
1535 | 630 | |||
1536 | 631 | void Page::clearUndoRedoOperations() | ||
1537 | 632 | { | ||
1538 | 633 | m_editorClient->clearUndoRedoOperations(); | ||
1539 | 634 | } | ||
1540 | 635 | |||
1541 | 636 | bool Page::inLowQualityImageInterpolationMode() const | ||
1542 | 637 | { | ||
1543 | 638 | return m_inLowQualityInterpolationMode; | ||
1544 | 639 | } | ||
1545 | 640 | |||
1546 | 641 | void Page::setInLowQualityImageInterpolationMode(bool mode) | ||
1547 | 642 | { | ||
1548 | 643 | m_inLowQualityInterpolationMode = mode; | ||
1549 | 644 | } | ||
1550 | 645 | |||
1551 | 646 | void Page::setMediaVolume(float volume) | ||
1552 | 647 | { | ||
1553 | 648 | if (volume < 0 || volume > 1) | ||
1554 | 649 | return; | ||
1555 | 650 | |||
1556 | 651 | if (m_mediaVolume == volume) | ||
1557 | 652 | return; | ||
1558 | 653 | |||
1559 | 654 | m_mediaVolume = volume; | ||
1560 | 655 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1561 | 656 | frame->document()->mediaVolumeDidChange(); | ||
1562 | 657 | } | ||
1563 | 658 | } | ||
1564 | 659 | |||
1565 | 660 | void Page::setPageScaleFactor(float scale, const IntPoint& origin) | ||
1566 | 661 | { | ||
1567 | 662 | Document* document = mainFrame()->document(); | ||
1568 | 663 | FrameView* view = document->view(); | ||
1569 | 664 | |||
1570 | 665 | if (scale == m_pageScaleFactor) { | ||
1571 | 666 | if (view && (view->scrollPosition() != origin || view->delegatesScrolling())) { | ||
1572 | 667 | document->updateLayoutIgnorePendingStylesheets(); | ||
1573 | 668 | view->setScrollPosition(origin); | ||
1574 | 669 | } | ||
1575 | 670 | return; | ||
1576 | 671 | } | ||
1577 | 672 | |||
1578 | 673 | m_pageScaleFactor = scale; | ||
1579 | 674 | |||
1580 | 675 | if (document->renderer()) | ||
1581 | 676 | document->renderer()->setNeedsLayout(true); | ||
1582 | 677 | |||
1583 | 678 | document->recalcStyle(Node::Force); | ||
1584 | 679 | |||
1585 | 680 | // Transform change on RenderView doesn't trigger repaint on non-composited contents. | ||
1586 | 681 | mainFrame()->view()->invalidateRect(IntRect(LayoutRect::infiniteRect())); | ||
1587 | 682 | |||
1588 | 683 | #if USE(ACCELERATED_COMPOSITING) | ||
1589 | 684 | mainFrame()->deviceOrPageScaleFactorChanged(); | ||
1590 | 685 | #endif | ||
1591 | 686 | |||
1592 | 687 | if (view && view->scrollPosition() != origin) { | ||
1593 | 688 | if (document->renderer() && document->renderer()->needsLayout() && view->didFirstLayout()) | ||
1594 | 689 | view->layout(); | ||
1595 | 690 | view->setScrollPosition(origin); | ||
1596 | 691 | } | ||
1597 | 692 | } | ||
1598 | 693 | |||
1599 | 694 | |||
1600 | 695 | void Page::setDeviceScaleFactor(float scaleFactor) | ||
1601 | 696 | { | ||
1602 | 697 | if (m_deviceScaleFactor == scaleFactor) | ||
1603 | 698 | return; | ||
1604 | 699 | |||
1605 | 700 | m_deviceScaleFactor = scaleFactor; | ||
1606 | 701 | setNeedsRecalcStyleInAllFrames(); | ||
1607 | 702 | |||
1608 | 703 | #if USE(ACCELERATED_COMPOSITING) | ||
1609 | 704 | if (mainFrame()) | ||
1610 | 705 | mainFrame()->deviceOrPageScaleFactorChanged(); | ||
1611 | 706 | #endif | ||
1612 | 707 | |||
1613 | 708 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
1614 | 709 | frame->editor()->deviceScaleFactorChanged(); | ||
1615 | 710 | |||
1616 | 711 | pageCache()->markPagesForFullStyleRecalc(this); | ||
1617 | 712 | } | ||
1618 | 713 | |||
1619 | 714 | void Page::setShouldSuppressScrollbarAnimations(bool suppressAnimations) | ||
1620 | 715 | { | ||
1621 | 716 | if (suppressAnimations == m_suppressScrollbarAnimations) | ||
1622 | 717 | return; | ||
1623 | 718 | |||
1624 | 719 | if (!suppressAnimations) { | ||
1625 | 720 | // If animations are not going to be suppressed anymore, then there is nothing to do here but | ||
1626 | 721 | // change the cached value. | ||
1627 | 722 | m_suppressScrollbarAnimations = suppressAnimations; | ||
1628 | 723 | return; | ||
1629 | 724 | } | ||
1630 | 725 | |||
1631 | 726 | // On the other hand, if we are going to start suppressing animations, then we need to make sure we | ||
1632 | 727 | // finish any current scroll animations first. | ||
1633 | 728 | FrameView* view = mainFrame()->view(); | ||
1634 | 729 | if (!view) | ||
1635 | 730 | return; | ||
1636 | 731 | |||
1637 | 732 | view->finishCurrentScrollAnimations(); | ||
1638 | 733 | |||
1639 | 734 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1640 | 735 | FrameView* frameView = frame->view(); | ||
1641 | 736 | if (!frameView) | ||
1642 | 737 | continue; | ||
1643 | 738 | |||
1644 | 739 | const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas(); | ||
1645 | 740 | if (!scrollableAreas) | ||
1646 | 741 | continue; | ||
1647 | 742 | |||
1648 | 743 | for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) { | ||
1649 | 744 | ScrollableArea* scrollableArea = *it; | ||
1650 | 745 | ASSERT(scrollableArea->scrollbarsCanBeActive()); | ||
1651 | 746 | |||
1652 | 747 | scrollableArea->finishCurrentScrollAnimations(); | ||
1653 | 748 | } | ||
1654 | 749 | } | ||
1655 | 750 | |||
1656 | 751 | m_suppressScrollbarAnimations = suppressAnimations; | ||
1657 | 752 | } | ||
1658 | 753 | |||
1659 | 754 | void Page::setPagination(const Pagination& pagination) | ||
1660 | 755 | { | ||
1661 | 756 | if (m_pagination == pagination) | ||
1662 | 757 | return; | ||
1663 | 758 | |||
1664 | 759 | m_pagination = pagination; | ||
1665 | 760 | |||
1666 | 761 | setNeedsRecalcStyleInAllFrames(); | ||
1667 | 762 | pageCache()->markPagesForFullStyleRecalc(this); | ||
1668 | 763 | } | ||
1669 | 764 | |||
1670 | 765 | unsigned Page::pageCount() const | ||
1671 | 766 | { | ||
1672 | 767 | if (m_pagination.mode == Pagination::Unpaginated) | ||
1673 | 768 | return 0; | ||
1674 | 769 | |||
1675 | 770 | FrameView* frameView = mainFrame()->view(); | ||
1676 | 771 | if (frameView->needsLayout()) | ||
1677 | 772 | frameView->layout(); | ||
1678 | 773 | |||
1679 | 774 | RenderView* contentRenderer = mainFrame()->contentRenderer(); | ||
1680 | 775 | return contentRenderer ? contentRenderer->columnCount(contentRenderer->columnInfo()) : 0; | ||
1681 | 776 | } | ||
1682 | 777 | |||
1683 | 778 | void Page::didMoveOnscreen() | ||
1684 | 779 | { | ||
1685 | 780 | m_isOnscreen = true; | ||
1686 | 781 | |||
1687 | 782 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1688 | 783 | if (FrameView* frameView = frame->view()) | ||
1689 | 784 | frameView->didMoveOnscreen(); | ||
1690 | 785 | } | ||
1691 | 786 | |||
1692 | 787 | resumeScriptedAnimations(); | ||
1693 | 788 | } | ||
1694 | 789 | |||
1695 | 790 | void Page::willMoveOffscreen() | ||
1696 | 791 | { | ||
1697 | 792 | m_isOnscreen = false; | ||
1698 | 793 | |||
1699 | 794 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1700 | 795 | if (FrameView* frameView = frame->view()) | ||
1701 | 796 | frameView->willMoveOffscreen(); | ||
1702 | 797 | } | ||
1703 | 798 | |||
1704 | 799 | suspendScriptedAnimations(); | ||
1705 | 800 | } | ||
1706 | 801 | |||
1707 | 802 | void Page::windowScreenDidChange(PlatformDisplayID displayID) | ||
1708 | 803 | { | ||
1709 | 804 | m_displayID = displayID; | ||
1710 | 805 | |||
1711 | 806 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1712 | 807 | if (frame->document()) | ||
1713 | 808 | frame->document()->windowScreenDidChange(displayID); | ||
1714 | 809 | } | ||
1715 | 810 | } | ||
1716 | 811 | |||
1717 | 812 | void Page::suspendScriptedAnimations() | ||
1718 | 813 | { | ||
1719 | 814 | m_scriptedAnimationsSuspended = true; | ||
1720 | 815 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1721 | 816 | if (frame->document()) | ||
1722 | 817 | frame->document()->suspendScriptedAnimationControllerCallbacks(); | ||
1723 | 818 | } | ||
1724 | 819 | } | ||
1725 | 820 | |||
1726 | 821 | void Page::resumeScriptedAnimations() | ||
1727 | 822 | { | ||
1728 | 823 | m_scriptedAnimationsSuspended = false; | ||
1729 | 824 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1730 | 825 | if (frame->document()) | ||
1731 | 826 | frame->document()->resumeScriptedAnimationControllerCallbacks(); | ||
1732 | 827 | } | ||
1733 | 828 | } | ||
1734 | 829 | |||
1735 | 830 | void Page::userStyleSheetLocationChanged() | ||
1736 | 831 | { | ||
1737 | 832 | // FIXME: Eventually we will move to a model of just being handed the sheet | ||
1738 | 833 | // text instead of loading the URL ourselves. | ||
1739 | 834 | KURL url = m_settings->userStyleSheetLocation(); | ||
1740 | 835 | |||
1741 | 836 | // Allow any local file URL scheme to be loaded. | ||
1742 | 837 | if (SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol())) | ||
1743 | 838 | m_userStyleSheetPath = url.fileSystemPath(); | ||
1744 | 839 | else | ||
1745 | 840 | m_userStyleSheetPath = String(); | ||
1746 | 841 | |||
1747 | 842 | m_didLoadUserStyleSheet = false; | ||
1748 | 843 | m_userStyleSheet = String(); | ||
1749 | 844 | m_userStyleSheetModificationTime = 0; | ||
1750 | 845 | |||
1751 | 846 | // Data URLs with base64-encoded UTF-8 style sheets are common. We can process them | ||
1752 | 847 | // synchronously and avoid using a loader. | ||
1753 | 848 | if (url.protocolIsData() && url.string().startsWith("data:text/css;charset=utf-8;base64,")) { | ||
1754 | 849 | m_didLoadUserStyleSheet = true; | ||
1755 | 850 | |||
1756 | 851 | Vector<char> styleSheetAsUTF8; | ||
1757 | 852 | if (base64Decode(decodeURLEscapeSequences(url.string().substring(35)), styleSheetAsUTF8, Base64IgnoreWhitespace)) | ||
1758 | 853 | m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data(), styleSheetAsUTF8.size()); | ||
1759 | 854 | } | ||
1760 | 855 | |||
1761 | 856 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1762 | 857 | if (frame->document()) | ||
1763 | 858 | frame->document()->styleSheetCollection()->updatePageUserStyleSheet(); | ||
1764 | 859 | } | ||
1765 | 860 | } | ||
1766 | 861 | |||
1767 | 862 | const String& Page::userStyleSheet() const | ||
1768 | 863 | { | ||
1769 | 864 | if (m_userStyleSheetPath.isEmpty()) | ||
1770 | 865 | return m_userStyleSheet; | ||
1771 | 866 | |||
1772 | 867 | time_t modTime; | ||
1773 | 868 | if (!getFileModificationTime(m_userStyleSheetPath, modTime)) { | ||
1774 | 869 | // The stylesheet either doesn't exist, was just deleted, or is | ||
1775 | 870 | // otherwise unreadable. If we've read the stylesheet before, we should | ||
1776 | 871 | // throw away that data now as it no longer represents what's on disk. | ||
1777 | 872 | m_userStyleSheet = String(); | ||
1778 | 873 | return m_userStyleSheet; | ||
1779 | 874 | } | ||
1780 | 875 | |||
1781 | 876 | // If the stylesheet hasn't changed since the last time we read it, we can | ||
1782 | 877 | // just return the old data. | ||
1783 | 878 | if (m_didLoadUserStyleSheet && modTime <= m_userStyleSheetModificationTime) | ||
1784 | 879 | return m_userStyleSheet; | ||
1785 | 880 | |||
1786 | 881 | m_didLoadUserStyleSheet = true; | ||
1787 | 882 | m_userStyleSheet = String(); | ||
1788 | 883 | m_userStyleSheetModificationTime = modTime; | ||
1789 | 884 | |||
1790 | 885 | // FIXME: It would be better to load this asynchronously to avoid blocking | ||
1791 | 886 | // the process, but we will first need to create an asynchronous loading | ||
1792 | 887 | // mechanism that is not tied to a particular Frame. We will also have to | ||
1793 | 888 | // determine what our behavior should be before the stylesheet is loaded | ||
1794 | 889 | // and what should happen when it finishes loading, especially with respect | ||
1795 | 890 | // to when the load event fires, when Document::close is called, and when | ||
1796 | 891 | // layout/paint are allowed to happen. | ||
1797 | 892 | RefPtr<SharedBuffer> data = SharedBuffer::createWithContentsOfFile(m_userStyleSheetPath); | ||
1798 | 893 | if (!data) | ||
1799 | 894 | return m_userStyleSheet; | ||
1800 | 895 | |||
1801 | 896 | RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/css"); | ||
1802 | 897 | m_userStyleSheet = decoder->decode(data->data(), data->size()); | ||
1803 | 898 | m_userStyleSheet.append(decoder->flush()); | ||
1804 | 899 | |||
1805 | 900 | return m_userStyleSheet; | ||
1806 | 901 | } | ||
1807 | 902 | |||
1808 | 903 | void Page::removeAllVisitedLinks() | ||
1809 | 904 | { | ||
1810 | 905 | if (!allPages) | ||
1811 | 906 | return; | ||
1812 | 907 | HashSet<PageGroup*> groups; | ||
1813 | 908 | HashSet<Page*>::iterator pagesEnd = allPages->end(); | ||
1814 | 909 | for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) { | ||
1815 | 910 | if (PageGroup* group = (*it)->groupPtr()) | ||
1816 | 911 | groups.add(group); | ||
1817 | 912 | } | ||
1818 | 913 | HashSet<PageGroup*>::iterator groupsEnd = groups.end(); | ||
1819 | 914 | for (HashSet<PageGroup*>::iterator it = groups.begin(); it != groupsEnd; ++it) | ||
1820 | 915 | (*it)->removeVisitedLinks(); | ||
1821 | 916 | } | ||
1822 | 917 | |||
1823 | 918 | void Page::allVisitedStateChanged(PageGroup* group) | ||
1824 | 919 | { | ||
1825 | 920 | ASSERT(group); | ||
1826 | 921 | if (!allPages) | ||
1827 | 922 | return; | ||
1828 | 923 | |||
1829 | 924 | HashSet<Page*>::iterator pagesEnd = allPages->end(); | ||
1830 | 925 | for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) { | ||
1831 | 926 | Page* page = *it; | ||
1832 | 927 | if (page->m_group != group) | ||
1833 | 928 | continue; | ||
1834 | 929 | for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) { | ||
1835 | 930 | if (StyleResolver* styleResolver = frame->document()->styleResolver()) | ||
1836 | 931 | styleResolver->allVisitedStateChanged(); | ||
1837 | 932 | } | ||
1838 | 933 | } | ||
1839 | 934 | } | ||
1840 | 935 | |||
1841 | 936 | void Page::visitedStateChanged(PageGroup* group, LinkHash visitedLinkHash) | ||
1842 | 937 | { | ||
1843 | 938 | ASSERT(group); | ||
1844 | 939 | if (!allPages) | ||
1845 | 940 | return; | ||
1846 | 941 | |||
1847 | 942 | HashSet<Page*>::iterator pagesEnd = allPages->end(); | ||
1848 | 943 | for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) { | ||
1849 | 944 | Page* page = *it; | ||
1850 | 945 | if (page->m_group != group) | ||
1851 | 946 | continue; | ||
1852 | 947 | for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) { | ||
1853 | 948 | if (StyleResolver* styleResolver = frame->document()->styleResolver()) | ||
1854 | 949 | styleResolver->visitedStateChanged(visitedLinkHash); | ||
1855 | 950 | } | ||
1856 | 951 | } | ||
1857 | 952 | } | ||
1858 | 953 | |||
1859 | 954 | void Page::setDebuggerForAllPages(JSC::Debugger* debugger) | ||
1860 | 955 | { | ||
1861 | 956 | ASSERT(allPages); | ||
1862 | 957 | |||
1863 | 958 | HashSet<Page*>::iterator end = allPages->end(); | ||
1864 | 959 | for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) | ||
1865 | 960 | (*it)->setDebugger(debugger); | ||
1866 | 961 | } | ||
1867 | 962 | |||
1868 | 963 | void Page::setDebugger(JSC::Debugger* debugger) | ||
1869 | 964 | { | ||
1870 | 965 | if (m_debugger == debugger) | ||
1871 | 966 | return; | ||
1872 | 967 | |||
1873 | 968 | m_debugger = debugger; | ||
1874 | 969 | |||
1875 | 970 | for (Frame* frame = m_mainFrame.get(); frame; frame = frame->tree()->traverseNext()) | ||
1876 | 971 | frame->script()->attachDebugger(m_debugger); | ||
1877 | 972 | } | ||
1878 | 973 | |||
1879 | 974 | StorageNamespace* Page::sessionStorage(bool optionalCreate) | ||
1880 | 975 | { | ||
1881 | 976 | if (!m_sessionStorage && optionalCreate) | ||
1882 | 977 | m_sessionStorage = StorageNamespace::sessionStorageNamespace(this, m_settings->sessionStorageQuota()); | ||
1883 | 978 | |||
1884 | 979 | return m_sessionStorage.get(); | ||
1885 | 980 | } | ||
1886 | 981 | |||
1887 | 982 | void Page::setSessionStorage(PassRefPtr<StorageNamespace> newStorage) | ||
1888 | 983 | { | ||
1889 | 984 | m_sessionStorage = newStorage; | ||
1890 | 985 | } | ||
1891 | 986 | |||
1892 | 987 | void Page::setCustomHTMLTokenizerTimeDelay(double customHTMLTokenizerTimeDelay) | ||
1893 | 988 | { | ||
1894 | 989 | if (customHTMLTokenizerTimeDelay < 0) { | ||
1895 | 990 | m_customHTMLTokenizerTimeDelay = -1; | ||
1896 | 991 | return; | ||
1897 | 992 | } | ||
1898 | 993 | m_customHTMLTokenizerTimeDelay = customHTMLTokenizerTimeDelay; | ||
1899 | 994 | } | ||
1900 | 995 | |||
1901 | 996 | void Page::setCustomHTMLTokenizerChunkSize(int customHTMLTokenizerChunkSize) | ||
1902 | 997 | { | ||
1903 | 998 | if (customHTMLTokenizerChunkSize < 0) { | ||
1904 | 999 | m_customHTMLTokenizerChunkSize = -1; | ||
1905 | 1000 | return; | ||
1906 | 1001 | } | ||
1907 | 1002 | m_customHTMLTokenizerChunkSize = customHTMLTokenizerChunkSize; | ||
1908 | 1003 | } | ||
1909 | 1004 | |||
1910 | 1005 | void Page::setMemoryCacheClientCallsEnabled(bool enabled) | ||
1911 | 1006 | { | ||
1912 | 1007 | if (m_areMemoryCacheClientCallsEnabled == enabled) | ||
1913 | 1008 | return; | ||
1914 | 1009 | |||
1915 | 1010 | m_areMemoryCacheClientCallsEnabled = enabled; | ||
1916 | 1011 | if (!enabled) | ||
1917 | 1012 | return; | ||
1918 | 1013 | |||
1919 | 1014 | for (RefPtr<Frame> frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
1920 | 1015 | frame->loader()->tellClientAboutPastMemoryCacheLoads(); | ||
1921 | 1016 | } | ||
1922 | 1017 | |||
1923 | 1018 | void Page::setMinimumTimerInterval(double minimumTimerInterval) | ||
1924 | 1019 | { | ||
1925 | 1020 | double oldTimerInterval = m_minimumTimerInterval; | ||
1926 | 1021 | m_minimumTimerInterval = minimumTimerInterval; | ||
1927 | 1022 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNextWithWrap(false)) { | ||
1928 | 1023 | if (frame->document()) | ||
1929 | 1024 | frame->document()->adjustMinimumTimerInterval(oldTimerInterval); | ||
1930 | 1025 | } | ||
1931 | 1026 | } | ||
1932 | 1027 | |||
1933 | 1028 | double Page::minimumTimerInterval() const | ||
1934 | 1029 | { | ||
1935 | 1030 | return m_minimumTimerInterval; | ||
1936 | 1031 | } | ||
1937 | 1032 | |||
1938 | 1033 | void Page::setTimerAlignmentInterval(double interval) | ||
1939 | 1034 | { | ||
1940 | 1035 | if (interval == m_timerAlignmentInterval) | ||
1941 | 1036 | return; | ||
1942 | 1037 | |||
1943 | 1038 | m_timerAlignmentInterval = interval; | ||
1944 | 1039 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNextWithWrap(false)) { | ||
1945 | 1040 | if (frame->document()) | ||
1946 | 1041 | frame->document()->didChangeTimerAlignmentInterval(); | ||
1947 | 1042 | } | ||
1948 | 1043 | } | ||
1949 | 1044 | |||
1950 | 1045 | double Page::timerAlignmentInterval() const | ||
1951 | 1046 | { | ||
1952 | 1047 | return m_timerAlignmentInterval; | ||
1953 | 1048 | } | ||
1954 | 1049 | |||
1955 | 1050 | void Page::dnsPrefetchingStateChanged() | ||
1956 | 1051 | { | ||
1957 | 1052 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
1958 | 1053 | frame->document()->initDNSPrefetch(); | ||
1959 | 1054 | } | ||
1960 | 1055 | |||
1961 | 1056 | void Page::collectPluginViews(Vector<RefPtr<PluginViewBase>, 32>& pluginViewBases) | ||
1962 | 1057 | { | ||
1963 | 1058 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { | ||
1964 | 1059 | FrameView* view = frame->view(); | ||
1965 | 1060 | if (!view) | ||
1966 | 1061 | return; | ||
1967 | 1062 | |||
1968 | 1063 | const HashSet<RefPtr<Widget> >* children = view->children(); | ||
1969 | 1064 | ASSERT(children); | ||
1970 | 1065 | |||
1971 | 1066 | HashSet<RefPtr<Widget> >::const_iterator end = children->end(); | ||
1972 | 1067 | for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) { | ||
1973 | 1068 | Widget* widget = (*it).get(); | ||
1974 | 1069 | if (widget->isPluginViewBase()) | ||
1975 | 1070 | pluginViewBases.append(static_cast<PluginViewBase*>(widget)); | ||
1976 | 1071 | } | ||
1977 | 1072 | } | ||
1978 | 1073 | } | ||
1979 | 1074 | |||
1980 | 1075 | void Page::storageBlockingStateChanged() | ||
1981 | 1076 | { | ||
1982 | 1077 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
1983 | 1078 | frame->document()->storageBlockingStateDidChange(); | ||
1984 | 1079 | |||
1985 | 1080 | // Collect the PluginViews in to a vector to ensure that action the plug-in takes | ||
1986 | 1081 | // from below storageBlockingStateChanged does not affect their lifetime. | ||
1987 | 1082 | Vector<RefPtr<PluginViewBase>, 32> pluginViewBases; | ||
1988 | 1083 | collectPluginViews(pluginViewBases); | ||
1989 | 1084 | |||
1990 | 1085 | for (size_t i = 0; i < pluginViewBases.size(); ++i) | ||
1991 | 1086 | pluginViewBases[i]->storageBlockingStateChanged(); | ||
1992 | 1087 | } | ||
1993 | 1088 | |||
1994 | 1089 | void Page::privateBrowsingStateChanged() | ||
1995 | 1090 | { | ||
1996 | 1091 | bool privateBrowsingEnabled = m_settings->privateBrowsingEnabled(); | ||
1997 | 1092 | |||
1998 | 1093 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
1999 | 1094 | frame->document()->privateBrowsingStateDidChange(); | ||
2000 | 1095 | |||
2001 | 1096 | // Collect the PluginViews in to a vector to ensure that action the plug-in takes | ||
2002 | 1097 | // from below privateBrowsingStateChanged does not affect their lifetime. | ||
2003 | 1098 | Vector<RefPtr<PluginViewBase>, 32> pluginViewBases; | ||
2004 | 1099 | collectPluginViews(pluginViewBases); | ||
2005 | 1100 | |||
2006 | 1101 | for (size_t i = 0; i < pluginViewBases.size(); ++i) | ||
2007 | 1102 | pluginViewBases[i]->privateBrowsingStateChanged(privateBrowsingEnabled); | ||
2008 | 1103 | } | ||
2009 | 1104 | |||
2010 | 1105 | #if !ASSERT_DISABLED | ||
2011 | 1106 | void Page::checkSubframeCountConsistency() const | ||
2012 | 1107 | { | ||
2013 | 1108 | ASSERT(m_subframeCount >= 0); | ||
2014 | 1109 | |||
2015 | 1110 | int subframeCount = 0; | ||
2016 | 1111 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
2017 | 1112 | ++subframeCount; | ||
2018 | 1113 | |||
2019 | 1114 | ASSERT(m_subframeCount + 1 == subframeCount); | ||
2020 | 1115 | } | ||
2021 | 1116 | #endif | ||
2022 | 1117 | |||
2023 | 1118 | #if ENABLE(PAGE_VISIBILITY_API) || ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) | ||
2024 | 1119 | void Page::setVisibilityState(PageVisibilityState visibilityState, bool isInitialState) | ||
2025 | 1120 | { | ||
2026 | 1121 | #if ENABLE(PAGE_VISIBILITY_API) | ||
2027 | 1122 | if (m_visibilityState == visibilityState) | ||
2028 | 1123 | return; | ||
2029 | 1124 | m_visibilityState = visibilityState; | ||
2030 | 1125 | |||
2031 | 1126 | if (!isInitialState && m_mainFrame) | ||
2032 | 1127 | m_mainFrame->dispatchVisibilityStateChangeEvent(); | ||
2033 | 1128 | #endif | ||
2034 | 1129 | |||
2035 | 1130 | #if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) | ||
2036 | 1131 | if (visibilityState == WebCore::PageVisibilityStateHidden) | ||
2037 | 1132 | setTimerAlignmentInterval(hiddenPageTimerAlignmentInterval); | ||
2038 | 1133 | else | ||
2039 | 1134 | setTimerAlignmentInterval(Settings::defaultDOMTimerAlignmentInterval()); | ||
2040 | 1135 | #if !ENABLE(PAGE_VISIBILITY_API) | ||
2041 | 1136 | UNUSED_PARAM(isInitialState); | ||
2042 | 1137 | #endif | ||
2043 | 1138 | #endif | ||
2044 | 1139 | } | ||
2045 | 1140 | #endif // ENABLE(PAGE_VISIBILITY_API) || ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) | ||
2046 | 1141 | |||
2047 | 1142 | #if ENABLE(PAGE_VISIBILITY_API) | ||
2048 | 1143 | PageVisibilityState Page::visibilityState() const | ||
2049 | 1144 | { | ||
2050 | 1145 | return m_visibilityState; | ||
2051 | 1146 | } | ||
2052 | 1147 | #endif | ||
2053 | 1148 | |||
2054 | 1149 | void Page::addLayoutMilestones(LayoutMilestones milestones) | ||
2055 | 1150 | { | ||
2056 | 1151 | // In the future, we may want a function that replaces m_layoutMilestones instead of just adding to it. | ||
2057 | 1152 | m_layoutMilestones |= milestones; | ||
2058 | 1153 | } | ||
2059 | 1154 | |||
2060 | 1155 | // These are magical constants that might be tweaked over time. | ||
2061 | 1156 | static double gMinimumPaintedAreaRatio = 0.1; | ||
2062 | 1157 | static double gMaximumUnpaintedAreaRatio = 0.04; | ||
2063 | 1158 | |||
2064 | 1159 | bool Page::isCountingRelevantRepaintedObjects() const | ||
2065 | 1160 | { | ||
2066 | 1161 | return m_isCountingRelevantRepaintedObjects && (m_layoutMilestones & DidHitRelevantRepaintedObjectsAreaThreshold); | ||
2067 | 1162 | } | ||
2068 | 1163 | |||
2069 | 1164 | void Page::startCountingRelevantRepaintedObjects() | ||
2070 | 1165 | { | ||
2071 | 1166 | // Reset everything in case we didn't hit the threshold last time. | ||
2072 | 1167 | resetRelevantPaintedObjectCounter(); | ||
2073 | 1168 | |||
2074 | 1169 | m_isCountingRelevantRepaintedObjects = true; | ||
2075 | 1170 | } | ||
2076 | 1171 | |||
2077 | 1172 | void Page::resetRelevantPaintedObjectCounter() | ||
2078 | 1173 | { | ||
2079 | 1174 | m_isCountingRelevantRepaintedObjects = false; | ||
2080 | 1175 | m_relevantUnpaintedRenderObjects.clear(); | ||
2081 | 1176 | m_relevantPaintedRegion = Region(); | ||
2082 | 1177 | m_relevantUnpaintedRegion = Region(); | ||
2083 | 1178 | } | ||
2084 | 1179 | |||
2085 | 1180 | void Page::addRelevantRepaintedObject(RenderObject* object, const LayoutRect& objectPaintRect) | ||
2086 | 1181 | { | ||
2087 | 1182 | if (!isCountingRelevantRepaintedObjects()) | ||
2088 | 1183 | return; | ||
2089 | 1184 | |||
2090 | 1185 | // The objects are only relevant if they are being painted within the viewRect(). | ||
2091 | 1186 | if (RenderView* view = object->view()) { | ||
2092 | 1187 | if (!objectPaintRect.intersects(pixelSnappedIntRect(view->viewRect()))) | ||
2093 | 1188 | return; | ||
2094 | 1189 | } | ||
2095 | 1190 | |||
2096 | 1191 | IntRect snappedPaintRect = pixelSnappedIntRect(objectPaintRect); | ||
2097 | 1192 | |||
2098 | 1193 | // If this object was previously counted as an unpainted object, remove it from that HashSet | ||
2099 | 1194 | // and corresponding Region. FIXME: This doesn't do the right thing if the objects overlap. | ||
2100 | 1195 | HashSet<RenderObject*>::iterator it = m_relevantUnpaintedRenderObjects.find(object); | ||
2101 | 1196 | if (it != m_relevantUnpaintedRenderObjects.end()) { | ||
2102 | 1197 | m_relevantUnpaintedRenderObjects.remove(it); | ||
2103 | 1198 | m_relevantUnpaintedRegion.subtract(snappedPaintRect); | ||
2104 | 1199 | } | ||
2105 | 1200 | |||
2106 | 1201 | m_relevantPaintedRegion.unite(snappedPaintRect); | ||
2107 | 1202 | |||
2108 | 1203 | RenderView* view = object->view(); | ||
2109 | 1204 | if (!view) | ||
2110 | 1205 | return; | ||
2111 | 1206 | |||
2112 | 1207 | float viewArea = view->viewRect().width() * view->viewRect().height(); | ||
2113 | 1208 | float ratioOfViewThatIsPainted = m_relevantPaintedRegion.totalArea() / viewArea; | ||
2114 | 1209 | float ratioOfViewThatIsUnpainted = m_relevantUnpaintedRegion.totalArea() / viewArea; | ||
2115 | 1210 | |||
2116 | 1211 | if (ratioOfViewThatIsPainted > gMinimumPaintedAreaRatio && ratioOfViewThatIsUnpainted < gMaximumUnpaintedAreaRatio) { | ||
2117 | 1212 | m_isCountingRelevantRepaintedObjects = false; | ||
2118 | 1213 | resetRelevantPaintedObjectCounter(); | ||
2119 | 1214 | if (Frame* frame = mainFrame()) | ||
2120 | 1215 | frame->loader()->didLayout(DidHitRelevantRepaintedObjectsAreaThreshold); | ||
2121 | 1216 | } | ||
2122 | 1217 | } | ||
2123 | 1218 | |||
2124 | 1219 | void Page::addRelevantUnpaintedObject(RenderObject* object, const LayoutRect& objectPaintRect) | ||
2125 | 1220 | { | ||
2126 | 1221 | if (!isCountingRelevantRepaintedObjects()) | ||
2127 | 1222 | return; | ||
2128 | 1223 | |||
2129 | 1224 | // The objects are only relevant if they are being painted within the viewRect(). | ||
2130 | 1225 | if (RenderView* view = object->view()) { | ||
2131 | 1226 | if (!objectPaintRect.intersects(pixelSnappedIntRect(view->viewRect()))) | ||
2132 | 1227 | return; | ||
2133 | 1228 | } | ||
2134 | 1229 | |||
2135 | 1230 | m_relevantUnpaintedRenderObjects.add(object); | ||
2136 | 1231 | m_relevantUnpaintedRegion.unite(pixelSnappedIntRect(objectPaintRect)); | ||
2137 | 1232 | } | ||
2138 | 1233 | |||
2139 | 1234 | void Page::suspendActiveDOMObjectsAndAnimations() | ||
2140 | 1235 | { | ||
2141 | 1236 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
2142 | 1237 | frame->suspendActiveDOMObjectsAndAnimations(); | ||
2143 | 1238 | } | ||
2144 | 1239 | |||
2145 | 1240 | void Page::resumeActiveDOMObjectsAndAnimations() | ||
2146 | 1241 | { | ||
2147 | 1242 | for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) | ||
2148 | 1243 | frame->resumeActiveDOMObjectsAndAnimations(); | ||
2149 | 1244 | } | ||
2150 | 1245 | |||
2151 | 1246 | bool Page::hasSeenAnyPlugin() const | ||
2152 | 1247 | { | ||
2153 | 1248 | return !m_seenPlugins.isEmpty(); | ||
2154 | 1249 | } | ||
2155 | 1250 | |||
2156 | 1251 | bool Page::hasSeenPlugin(const String& serviceType) const | ||
2157 | 1252 | { | ||
2158 | 1253 | return m_seenPlugins.contains(serviceType); | ||
2159 | 1254 | } | ||
2160 | 1255 | |||
2161 | 1256 | void Page::sawPlugin(const String& serviceType) | ||
2162 | 1257 | { | ||
2163 | 1258 | m_seenPlugins.add(serviceType); | ||
2164 | 1259 | } | ||
2165 | 1260 | |||
2166 | 1261 | void Page::resetSeenPlugins() | ||
2167 | 1262 | { | ||
2168 | 1263 | m_seenPlugins.clear(); | ||
2169 | 1264 | } | ||
2170 | 1265 | |||
2171 | 1266 | bool Page::hasSeenAnyMediaEngine() const | ||
2172 | 1267 | { | ||
2173 | 1268 | return !m_seenMediaEngines.isEmpty(); | ||
2174 | 1269 | } | ||
2175 | 1270 | |||
2176 | 1271 | bool Page::hasSeenMediaEngine(const String& engineDescription) const | ||
2177 | 1272 | { | ||
2178 | 1273 | return m_seenMediaEngines.contains(engineDescription); | ||
2179 | 1274 | } | ||
2180 | 1275 | |||
2181 | 1276 | void Page::sawMediaEngine(const String& engineDescription) | ||
2182 | 1277 | { | ||
2183 | 1278 | m_seenMediaEngines.add(engineDescription); | ||
2184 | 1279 | } | ||
2185 | 1280 | |||
2186 | 1281 | void Page::resetSeenMediaEngines() | ||
2187 | 1282 | { | ||
2188 | 1283 | m_seenMediaEngines.clear(); | ||
2189 | 1284 | } | ||
2190 | 1285 | |||
2191 | 1286 | void Page::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const | ||
2192 | 1287 | { | ||
2193 | 1288 | MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Page); | ||
2194 | 1289 | info.addMember(m_chrome); | ||
2195 | 1290 | info.addMember(m_dragCaretController); | ||
2196 | 1291 | |||
2197 | 1292 | #if ENABLE(DRAG_SUPPORT) | ||
2198 | 1293 | info.addMember(m_dragController); | ||
2199 | 1294 | #endif | ||
2200 | 1295 | info.addMember(m_focusController); | ||
2201 | 1296 | #if ENABLE(CONTEXT_MENUS) | ||
2202 | 1297 | info.addMember(m_contextMenuController); | ||
2203 | 1298 | #endif | ||
2204 | 1299 | #if ENABLE(INSPECTOR) | ||
2205 | 1300 | info.addMember(m_inspectorController); | ||
2206 | 1301 | #endif | ||
2207 | 1302 | #if ENABLE(POINTER_LOCK) | ||
2208 | 1303 | info.addMember(m_pointerLockController); | ||
2209 | 1304 | #endif | ||
2210 | 1305 | info.addMember(m_scrollingCoordinator); | ||
2211 | 1306 | info.addMember(m_settings); | ||
2212 | 1307 | info.addMember(m_progress); | ||
2213 | 1308 | info.addMember(m_backForwardController); | ||
2214 | 1309 | info.addMember(m_mainFrame); | ||
2215 | 1310 | info.addMember(m_pluginData); | ||
2216 | 1311 | info.addMember(m_theme); | ||
2217 | 1312 | info.addWeakPointer(m_editorClient); | ||
2218 | 1313 | info.addMember(m_featureObserver); | ||
2219 | 1314 | info.addMember(m_groupName); | ||
2220 | 1315 | info.addMember(m_pagination); | ||
2221 | 1316 | info.addMember(m_userStyleSheetPath); | ||
2222 | 1317 | info.addMember(m_userStyleSheet); | ||
2223 | 1318 | info.addMember(m_singlePageGroup); | ||
2224 | 1319 | info.addMember(m_group); | ||
2225 | 1320 | info.addWeakPointer(m_debugger); | ||
2226 | 1321 | info.addMember(m_sessionStorage); | ||
2227 | 1322 | info.addMember(m_relevantUnpaintedRenderObjects); | ||
2228 | 1323 | info.addMember(m_relevantPaintedRegion); | ||
2229 | 1324 | info.addMember(m_relevantUnpaintedRegion); | ||
2230 | 1325 | info.addWeakPointer(m_alternativeTextClient); | ||
2231 | 1326 | info.addMember(m_seenPlugins); | ||
2232 | 1327 | } | ||
2233 | 1328 | |||
2234 | 1329 | Page::PageClients::PageClients() | ||
2235 | 1330 | : alternativeTextClient(0) | ||
2236 | 1331 | , chromeClient(0) | ||
2237 | 1332 | #if ENABLE(CONTEXT_MENUS) | ||
2238 | 1333 | , contextMenuClient(0) | ||
2239 | 1334 | #endif | ||
2240 | 1335 | , editorClient(0) | ||
2241 | 1336 | , dragClient(0) | ||
2242 | 1337 | , inspectorClient(0) | ||
2243 | 1338 | , validationMessageClient(0) | ||
2244 | 1339 | { | ||
2245 | 1340 | } | ||
2246 | 1341 | |||
2247 | 1342 | Page::PageClients::~PageClients() | ||
2248 | 1343 | { | ||
2249 | 1344 | } | ||
2250 | 1345 | |||
2251 | 1346 | } // namespace WebCore | ||
2252 | 1347 | 0 | ||
2253 | === removed directory '.pc/disable_geolocation_501.diff' | |||
2254 | === removed directory '.pc/disable_geolocation_501.diff/Source' | |||
2255 | === removed directory '.pc/disable_geolocation_501.diff/Source/WebKit' | |||
2256 | === removed directory '.pc/disable_geolocation_501.diff/Source/WebKit/qt' | |||
2257 | === removed directory '.pc/disable_geolocation_501.diff/Source/WebKit/qt/Api' | |||
2258 | === removed file '.pc/disable_geolocation_501.diff/Source/WebKit/qt/Api/qwebpage.cpp' | |||
2259 | --- .pc/disable_geolocation_501.diff/Source/WebKit/qt/Api/qwebpage.cpp 2013-02-18 14:24:18 +0000 | |||
2260 | +++ .pc/disable_geolocation_501.diff/Source/WebKit/qt/Api/qwebpage.cpp 1970-01-01 00:00:00 +0000 | |||
2261 | @@ -1,4103 +0,0 @@ | |||
2262 | 1 | /* | ||
2263 | 2 | Copyright (C) 2008, 2009, 2012 Nokia Corporation and/or its subsidiary(-ies) | ||
2264 | 3 | Copyright (C) 2007 Staikos Computing Services Inc. | ||
2265 | 4 | Copyright (C) 2007 Apple Inc. | ||
2266 | 5 | |||
2267 | 6 | This library is free software; you can redistribute it and/or | ||
2268 | 7 | modify it under the terms of the GNU Library General Public | ||
2269 | 8 | License as published by the Free Software Foundation; either | ||
2270 | 9 | version 2 of the License, or (at your option) any later version. | ||
2271 | 10 | |||
2272 | 11 | This library is distributed in the hope that it will be useful, | ||
2273 | 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2274 | 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
2275 | 14 | Library General Public License for more details. | ||
2276 | 15 | |||
2277 | 16 | You should have received a copy of the GNU Library General Public License | ||
2278 | 17 | along with this library; see the file COPYING.LIB. If not, write to | ||
2279 | 18 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
2280 | 19 | Boston, MA 02110-1301, USA. | ||
2281 | 20 | */ | ||
2282 | 21 | |||
2283 | 22 | #include "config.h" | ||
2284 | 23 | #include "qwebpage.h" | ||
2285 | 24 | |||
2286 | 25 | #include "qwebview.h" | ||
2287 | 26 | #include "qwebframe.h" | ||
2288 | 27 | #include "qwebpage_p.h" | ||
2289 | 28 | #include "qwebframe_p.h" | ||
2290 | 29 | #include "qwebhistory.h" | ||
2291 | 30 | #include "qwebhistory_p.h" | ||
2292 | 31 | #include "qwebinspector.h" | ||
2293 | 32 | #include "qwebinspector_p.h" | ||
2294 | 33 | #include "qwebsettings.h" | ||
2295 | 34 | #include "qwebkitplatformplugin.h" | ||
2296 | 35 | #include "qwebkitversion.h" | ||
2297 | 36 | |||
2298 | 37 | #include "CSSComputedStyleDeclaration.h" | ||
2299 | 38 | #include "CSSParser.h" | ||
2300 | 39 | #include "ApplicationCacheStorage.h" | ||
2301 | 40 | #include "BackForwardListImpl.h" | ||
2302 | 41 | #include "MemoryCache.h" | ||
2303 | 42 | #include "Chrome.h" | ||
2304 | 43 | #include "ChromeClientQt.h" | ||
2305 | 44 | #include "ClientRect.h" | ||
2306 | 45 | #include "ContextMenu.h" | ||
2307 | 46 | #include "ContextMenuClientQt.h" | ||
2308 | 47 | #include "ContextMenuController.h" | ||
2309 | 48 | #if ENABLE(DEVICE_ORIENTATION) | ||
2310 | 49 | #include "DeviceMotionClientQt.h" | ||
2311 | 50 | #include "DeviceOrientationClientMock.h" | ||
2312 | 51 | #include "DeviceOrientationClientQt.h" | ||
2313 | 52 | #endif | ||
2314 | 53 | #include "DocumentLoader.h" | ||
2315 | 54 | #include "DragClientQt.h" | ||
2316 | 55 | #include "DragController.h" | ||
2317 | 56 | #include "DragData.h" | ||
2318 | 57 | #include "DragSession.h" | ||
2319 | 58 | #include "Editor.h" | ||
2320 | 59 | #include "EditorClientQt.h" | ||
2321 | 60 | #include "FocusController.h" | ||
2322 | 61 | #include "FormState.h" | ||
2323 | 62 | #include "Frame.h" | ||
2324 | 63 | #include "FrameLoadRequest.h" | ||
2325 | 64 | #include "FrameLoader.h" | ||
2326 | 65 | #include "FrameLoader.h" | ||
2327 | 66 | #include "FrameLoaderClientQt.h" | ||
2328 | 67 | #include "FrameTree.h" | ||
2329 | 68 | #include "FrameView.h" | ||
2330 | 69 | #if ENABLE(GEOLOCATION) | ||
2331 | 70 | #include "GeolocationClientMock.h" | ||
2332 | 71 | #include "GeolocationClientQt.h" | ||
2333 | 72 | #include "GeolocationController.h" | ||
2334 | 73 | #endif | ||
2335 | 74 | #include "GeolocationPermissionClientQt.h" | ||
2336 | 75 | #include "HTMLFormElement.h" | ||
2337 | 76 | #include "HTMLFrameOwnerElement.h" | ||
2338 | 77 | #include "HTMLInputElement.h" | ||
2339 | 78 | #include "HTMLNames.h" | ||
2340 | 79 | #include "HitTestResult.h" | ||
2341 | 80 | #include "Image.h" | ||
2342 | 81 | #include "InitWebCoreQt.h" | ||
2343 | 82 | #include "InspectorClientQt.h" | ||
2344 | 83 | #include "InspectorController.h" | ||
2345 | 84 | #include "InspectorServerQt.h" | ||
2346 | 85 | #include "KURL.h" | ||
2347 | 86 | #include "LocalizedStrings.h" | ||
2348 | 87 | #include "MIMETypeRegistry.h" | ||
2349 | 88 | #include "NavigationAction.h" | ||
2350 | 89 | #include "NetworkingContext.h" | ||
2351 | 90 | #include "NodeList.h" | ||
2352 | 91 | #include "NotificationPresenterClientQt.h" | ||
2353 | 92 | #include "NotImplemented.h" | ||
2354 | 93 | #include "Page.h" | ||
2355 | 94 | #include "PageClientQt.h" | ||
2356 | 95 | #include "PageGroup.h" | ||
2357 | 96 | #include "Pasteboard.h" | ||
2358 | 97 | #include "PlatformGestureEvent.h" | ||
2359 | 98 | #include "PlatformKeyboardEvent.h" | ||
2360 | 99 | #include "PlatformTouchEvent.h" | ||
2361 | 100 | #include "PlatformWheelEvent.h" | ||
2362 | 101 | #include "PluginDatabase.h" | ||
2363 | 102 | #include "PluginDatabase.h" | ||
2364 | 103 | #include "PluginPackage.h" | ||
2365 | 104 | #include "ProgressTracker.h" | ||
2366 | 105 | #include "QtPlatformPlugin.h" | ||
2367 | 106 | #include "RenderTextControl.h" | ||
2368 | 107 | #include "RenderThemeQt.h" | ||
2369 | 108 | #include "SchemeRegistry.h" | ||
2370 | 109 | #include "Scrollbar.h" | ||
2371 | 110 | #include "ScrollbarTheme.h" | ||
2372 | 111 | #include "SecurityOrigin.h" | ||
2373 | 112 | #include "Settings.h" | ||
2374 | 113 | #if defined Q_OS_WIN32 | ||
2375 | 114 | #include "SystemInfo.h" | ||
2376 | 115 | #endif // Q_OS_WIN32 | ||
2377 | 116 | #include "TextIterator.h" | ||
2378 | 117 | #include "UtilsQt.h" | ||
2379 | 118 | #include "UserAgentQt.h" | ||
2380 | 119 | #include "WebEventConversion.h" | ||
2381 | 120 | #include "WebKitVersion.h" | ||
2382 | 121 | #include "WindowFeatures.h" | ||
2383 | 122 | #include "WorkerThread.h" | ||
2384 | 123 | |||
2385 | 124 | #include <QAction> | ||
2386 | 125 | #include <QApplication> | ||
2387 | 126 | #include <QBasicTimer> | ||
2388 | 127 | #include <QBitArray> | ||
2389 | 128 | #include <QColorDialog> | ||
2390 | 129 | #include <QDebug> | ||
2391 | 130 | #include <QDesktopWidget> | ||
2392 | 131 | #include <QDragEnterEvent> | ||
2393 | 132 | #include <QDragLeaveEvent> | ||
2394 | 133 | #include <QDragMoveEvent> | ||
2395 | 134 | #include <QDropEvent> | ||
2396 | 135 | #include <QFileDialog> | ||
2397 | 136 | #include <QGestureEvent> | ||
2398 | 137 | #include <QInputDialog> | ||
2399 | 138 | #include <QLabel> | ||
2400 | 139 | #include <QMenu> | ||
2401 | 140 | #include <QMessageBox> | ||
2402 | 141 | #include <QNetworkProxy> | ||
2403 | 142 | #include <QUndoStack> | ||
2404 | 143 | #include <QUrl> | ||
2405 | 144 | #include <QPainter> | ||
2406 | 145 | #include <QClipboard> | ||
2407 | 146 | #include <QSslSocket> | ||
2408 | 147 | #include <QStyle> | ||
2409 | 148 | #include <QSysInfo> | ||
2410 | 149 | #include <QTextCharFormat> | ||
2411 | 150 | #include <QTouchEvent> | ||
2412 | 151 | #include <QNetworkAccessManager> | ||
2413 | 152 | #include <QNetworkRequest> | ||
2414 | 153 | #if defined(Q_WS_X11) | ||
2415 | 154 | #include <QX11Info> | ||
2416 | 155 | #endif | ||
2417 | 156 | #if USE(QT_MOBILITY_SYSTEMINFO) | ||
2418 | 157 | #include <qsysteminfo.h> | ||
2419 | 158 | #endif | ||
2420 | 159 | |||
2421 | 160 | using namespace WebCore; | ||
2422 | 161 | |||
2423 | 162 | // from text/qfont.cpp | ||
2424 | 163 | QT_BEGIN_NAMESPACE | ||
2425 | 164 | extern Q_GUI_EXPORT int qt_defaultDpi(); | ||
2426 | 165 | QT_END_NAMESPACE | ||
2427 | 166 | |||
2428 | 167 | bool QWebPagePrivate::drtRun = false; | ||
2429 | 168 | |||
2430 | 169 | // Lookup table mapping QWebPage::WebActions to the associated Editor commands | ||
2431 | 170 | static const char* editorCommandWebActions[] = | ||
2432 | 171 | { | ||
2433 | 172 | 0, // OpenLink, | ||
2434 | 173 | |||
2435 | 174 | 0, // OpenLinkInNewWindow, | ||
2436 | 175 | 0, // OpenFrameInNewWindow, | ||
2437 | 176 | |||
2438 | 177 | 0, // DownloadLinkToDisk, | ||
2439 | 178 | 0, // CopyLinkToClipboard, | ||
2440 | 179 | |||
2441 | 180 | 0, // OpenImageInNewWindow, | ||
2442 | 181 | 0, // DownloadImageToDisk, | ||
2443 | 182 | 0, // CopyImageToClipboard, | ||
2444 | 183 | |||
2445 | 184 | 0, // Back, | ||
2446 | 185 | 0, // Forward, | ||
2447 | 186 | 0, // Stop, | ||
2448 | 187 | 0, // Reload, | ||
2449 | 188 | |||
2450 | 189 | "Cut", // Cut, | ||
2451 | 190 | "Copy", // Copy, | ||
2452 | 191 | "Paste", // Paste, | ||
2453 | 192 | |||
2454 | 193 | "Undo", // Undo, | ||
2455 | 194 | "Redo", // Redo, | ||
2456 | 195 | "MoveForward", // MoveToNextChar, | ||
2457 | 196 | "MoveBackward", // MoveToPreviousChar, | ||
2458 | 197 | "MoveWordForward", // MoveToNextWord, | ||
2459 | 198 | "MoveWordBackward", // MoveToPreviousWord, | ||
2460 | 199 | "MoveDown", // MoveToNextLine, | ||
2461 | 200 | "MoveUp", // MoveToPreviousLine, | ||
2462 | 201 | "MoveToBeginningOfLine", // MoveToStartOfLine, | ||
2463 | 202 | "MoveToEndOfLine", // MoveToEndOfLine, | ||
2464 | 203 | "MoveToBeginningOfParagraph", // MoveToStartOfBlock, | ||
2465 | 204 | "MoveToEndOfParagraph", // MoveToEndOfBlock, | ||
2466 | 205 | "MoveToBeginningOfDocument", // MoveToStartOfDocument, | ||
2467 | 206 | "MoveToEndOfDocument", // MoveToEndOfDocument, | ||
2468 | 207 | "MoveForwardAndModifySelection", // SelectNextChar, | ||
2469 | 208 | "MoveBackwardAndModifySelection", // SelectPreviousChar, | ||
2470 | 209 | "MoveWordForwardAndModifySelection", // SelectNextWord, | ||
2471 | 210 | "MoveWordBackwardAndModifySelection", // SelectPreviousWord, | ||
2472 | 211 | "MoveDownAndModifySelection", // SelectNextLine, | ||
2473 | 212 | "MoveUpAndModifySelection", // SelectPreviousLine, | ||
2474 | 213 | "MoveToBeginningOfLineAndModifySelection", // SelectStartOfLine, | ||
2475 | 214 | "MoveToEndOfLineAndModifySelection", // SelectEndOfLine, | ||
2476 | 215 | "MoveToBeginningOfParagraphAndModifySelection", // SelectStartOfBlock, | ||
2477 | 216 | "MoveToEndOfParagraphAndModifySelection", // SelectEndOfBlock, | ||
2478 | 217 | "MoveToBeginningOfDocumentAndModifySelection", //SelectStartOfDocument, | ||
2479 | 218 | "MoveToEndOfDocumentAndModifySelection", // SelectEndOfDocument, | ||
2480 | 219 | "DeleteWordBackward", // DeleteStartOfWord, | ||
2481 | 220 | "DeleteWordForward", // DeleteEndOfWord, | ||
2482 | 221 | |||
2483 | 222 | 0, // SetTextDirectionDefault, | ||
2484 | 223 | 0, // SetTextDirectionLeftToRight, | ||
2485 | 224 | 0, // SetTextDirectionRightToLeft, | ||
2486 | 225 | |||
2487 | 226 | "ToggleBold", // ToggleBold, | ||
2488 | 227 | "ToggleItalic", // ToggleItalic, | ||
2489 | 228 | "ToggleUnderline", // ToggleUnderline, | ||
2490 | 229 | |||
2491 | 230 | 0, // InspectElement, | ||
2492 | 231 | |||
2493 | 232 | "InsertNewline", // InsertParagraphSeparator | ||
2494 | 233 | "InsertLineBreak", // InsertLineSeparator | ||
2495 | 234 | |||
2496 | 235 | "SelectAll", // SelectAll | ||
2497 | 236 | 0, // ReloadAndBypassCache, | ||
2498 | 237 | |||
2499 | 238 | "PasteAndMatchStyle", // PasteAndMatchStyle | ||
2500 | 239 | "RemoveFormat", // RemoveFormat | ||
2501 | 240 | "Strikethrough", // ToggleStrikethrough, | ||
2502 | 241 | "Subscript", // ToggleSubscript | ||
2503 | 242 | "Superscript", // ToggleSuperscript | ||
2504 | 243 | "InsertUnorderedList", // InsertUnorderedList | ||
2505 | 244 | "InsertOrderedList", // InsertOrderedList | ||
2506 | 245 | "Indent", // Indent | ||
2507 | 246 | "Outdent", // Outdent, | ||
2508 | 247 | |||
2509 | 248 | "AlignCenter", // AlignCenter, | ||
2510 | 249 | "AlignJustified", // AlignJustified, | ||
2511 | 250 | "AlignLeft", // AlignLeft, | ||
2512 | 251 | "AlignRight", // AlignRight, | ||
2513 | 252 | |||
2514 | 253 | 0, // StopScheduledPageRefresh, | ||
2515 | 254 | |||
2516 | 255 | 0, // CopyImageUrlToClipboard, | ||
2517 | 256 | |||
2518 | 257 | 0, // OpenLinkInThisWindow, | ||
2519 | 258 | |||
2520 | 259 | 0 // WebActionCount | ||
2521 | 260 | }; | ||
2522 | 261 | |||
2523 | 262 | // Lookup the appropriate editor command to use for WebAction \a action | ||
2524 | 263 | const char* QWebPagePrivate::editorCommandForWebActions(QWebPage::WebAction action) | ||
2525 | 264 | { | ||
2526 | 265 | if ((action > QWebPage::NoWebAction) && (action < int(sizeof(editorCommandWebActions) / sizeof(const char*)))) | ||
2527 | 266 | return editorCommandWebActions[action]; | ||
2528 | 267 | return 0; | ||
2529 | 268 | } | ||
2530 | 269 | |||
2531 | 270 | static inline DragOperation dropActionToDragOp(Qt::DropActions actions) | ||
2532 | 271 | { | ||
2533 | 272 | unsigned result = 0; | ||
2534 | 273 | if (actions & Qt::CopyAction) | ||
2535 | 274 | result |= DragOperationCopy; | ||
2536 | 275 | // DragOperationgeneric represents InternetExplorer's equivalent of Move operation, | ||
2537 | 276 | // hence it should be considered as "move" | ||
2538 | 277 | if (actions & Qt::MoveAction) | ||
2539 | 278 | result |= (DragOperationMove | DragOperationGeneric); | ||
2540 | 279 | if (actions & Qt::LinkAction) | ||
2541 | 280 | result |= DragOperationLink; | ||
2542 | 281 | if (result == (DragOperationCopy | DragOperationMove | DragOperationGeneric | DragOperationLink)) | ||
2543 | 282 | result = DragOperationEvery; | ||
2544 | 283 | return (DragOperation)result; | ||
2545 | 284 | } | ||
2546 | 285 | |||
2547 | 286 | static inline Qt::DropAction dragOpToDropAction(unsigned actions) | ||
2548 | 287 | { | ||
2549 | 288 | Qt::DropAction result = Qt::IgnoreAction; | ||
2550 | 289 | if (actions & DragOperationCopy) | ||
2551 | 290 | result = Qt::CopyAction; | ||
2552 | 291 | else if (actions & DragOperationMove) | ||
2553 | 292 | result = Qt::MoveAction; | ||
2554 | 293 | // DragOperationgeneric represents InternetExplorer's equivalent of Move operation, | ||
2555 | 294 | // hence it should be considered as "move" | ||
2556 | 295 | else if (actions & DragOperationGeneric) | ||
2557 | 296 | result = Qt::MoveAction; | ||
2558 | 297 | else if (actions & DragOperationLink) | ||
2559 | 298 | result = Qt::LinkAction; | ||
2560 | 299 | return result; | ||
2561 | 300 | } | ||
2562 | 301 | |||
2563 | 302 | QWebPagePrivate::QWebPagePrivate(QWebPage *qq) | ||
2564 | 303 | : q(qq) | ||
2565 | 304 | , page(0) | ||
2566 | 305 | #ifndef QT_NO_UNDOSTACK | ||
2567 | 306 | , undoStack(0) | ||
2568 | 307 | #endif | ||
2569 | 308 | , insideOpenCall(false) | ||
2570 | 309 | , m_totalBytes(0) | ||
2571 | 310 | , m_bytesReceived() | ||
2572 | 311 | , clickCausedFocus(false) | ||
2573 | 312 | , networkManager(0) | ||
2574 | 313 | , forwardUnsupportedContent(false) | ||
2575 | 314 | , smartInsertDeleteEnabled(true) | ||
2576 | 315 | , selectTrailingWhitespaceEnabled(false) | ||
2577 | 316 | , linkPolicy(QWebPage::DontDelegateLinks) | ||
2578 | 317 | , viewportSize(QSize(0, 0)) | ||
2579 | 318 | , settings(0) | ||
2580 | 319 | , useFixedLayout(false) | ||
2581 | 320 | , pluginFactory(0) | ||
2582 | 321 | , inspectorFrontend(0) | ||
2583 | 322 | , inspector(0) | ||
2584 | 323 | , inspectorIsInternalOnly(false) | ||
2585 | 324 | , m_lastDropAction(Qt::IgnoreAction) | ||
2586 | 325 | { | ||
2587 | 326 | #if ENABLE(GEOLOCATION) || ENABLE(DEVICE_ORIENTATION) | ||
2588 | 327 | bool useMock = QWebPagePrivate::drtRun; | ||
2589 | 328 | #endif | ||
2590 | 329 | |||
2591 | 330 | WebCore::initializeWebCoreQt(); | ||
2592 | 331 | |||
2593 | 332 | Page::PageClients pageClients; | ||
2594 | 333 | pageClients.chromeClient = new ChromeClientQt(q); | ||
2595 | 334 | pageClients.contextMenuClient = new ContextMenuClientQt(); | ||
2596 | 335 | pageClients.editorClient = new EditorClientQt(q); | ||
2597 | 336 | pageClients.dragClient = new DragClientQt(q); | ||
2598 | 337 | pageClients.inspectorClient = new InspectorClientQt(q); | ||
2599 | 338 | page = new Page(pageClients); | ||
2600 | 339 | #if ENABLE(GEOLOCATION) | ||
2601 | 340 | if (useMock) { | ||
2602 | 341 | // In case running in DumpRenderTree mode set the controller to mock provider. | ||
2603 | 342 | GeolocationClientMock* mock = new GeolocationClientMock; | ||
2604 | 343 | WebCore::provideGeolocationTo(page, mock); | ||
2605 | 344 | mock->setController(WebCore::GeolocationController::from(page)); | ||
2606 | 345 | } else | ||
2607 | 346 | WebCore::provideGeolocationTo(page, new GeolocationClientQt(q)); | ||
2608 | 347 | #endif | ||
2609 | 348 | #if ENABLE(DEVICE_ORIENTATION) | ||
2610 | 349 | if (useMock) | ||
2611 | 350 | WebCore::provideDeviceOrientationTo(page, new DeviceOrientationClientMock); | ||
2612 | 351 | else | ||
2613 | 352 | WebCore::provideDeviceOrientationTo(page, new DeviceOrientationClientQt); | ||
2614 | 353 | WebCore::provideDeviceMotionTo(page, new DeviceMotionClientQt); | ||
2615 | 354 | #endif | ||
2616 | 355 | #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) | ||
2617 | 356 | WebCore::provideNotification(page, NotificationPresenterClientQt::notificationPresenter()); | ||
2618 | 357 | #endif | ||
2619 | 358 | |||
2620 | 359 | // By default each page is put into their own unique page group, which affects popup windows | ||
2621 | 360 | // and visited links. Page groups (per process only) is a feature making it possible to use | ||
2622 | 361 | // separate settings for each group, so that for instance an integrated browser/email reader | ||
2623 | 362 | // can use different settings for displaying HTML pages and HTML email. To make QtWebKit work | ||
2624 | 363 | // as expected out of the box, we use a default group similar to what other ports are doing. | ||
2625 | 364 | page->setGroupName("Default Group"); | ||
2626 | 365 | |||
2627 | 366 | page->addLayoutMilestones(DidFirstVisuallyNonEmptyLayout); | ||
2628 | 367 | |||
2629 | 368 | settings = new QWebSettings(page->settings()); | ||
2630 | 369 | |||
2631 | 370 | history.d = new QWebHistoryPrivate(static_cast<WebCore::BackForwardListImpl*>(page->backForwardList())); | ||
2632 | 371 | memset(actions, 0, sizeof(actions)); | ||
2633 | 372 | |||
2634 | 373 | PageGroup::setShouldTrackVisitedLinks(true); | ||
2635 | 374 | |||
2636 | 375 | #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) | ||
2637 | 376 | NotificationPresenterClientQt::notificationPresenter()->addClient(); | ||
2638 | 377 | #endif | ||
2639 | 378 | } | ||
2640 | 379 | |||
2641 | 380 | QWebPagePrivate::~QWebPagePrivate() | ||
2642 | 381 | { | ||
2643 | 382 | #ifndef QT_NO_CONTEXTMENU | ||
2644 | 383 | delete currentContextMenu.data(); | ||
2645 | 384 | #endif | ||
2646 | 385 | #ifndef QT_NO_UNDOSTACK | ||
2647 | 386 | delete undoStack; | ||
2648 | 387 | #endif | ||
2649 | 388 | delete settings; | ||
2650 | 389 | delete page; | ||
2651 | 390 | |||
2652 | 391 | if (inspector) { | ||
2653 | 392 | // If the inspector is ours, delete it, otherwise just detach from it. | ||
2654 | 393 | if (inspectorIsInternalOnly) | ||
2655 | 394 | delete inspector; | ||
2656 | 395 | else | ||
2657 | 396 | inspector->setPage(0); | ||
2658 | 397 | } | ||
2659 | 398 | |||
2660 | 399 | #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) | ||
2661 | 400 | NotificationPresenterClientQt::notificationPresenter()->removeClient(); | ||
2662 | 401 | #endif | ||
2663 | 402 | } | ||
2664 | 403 | |||
2665 | 404 | WebCore::ViewportArguments QWebPagePrivate::viewportArguments() | ||
2666 | 405 | { | ||
2667 | 406 | return page ? page->viewportArguments() : WebCore::ViewportArguments(); | ||
2668 | 407 | } | ||
2669 | 408 | |||
2670 | 409 | WebCore::Page* QWebPagePrivate::core(const QWebPage* page) | ||
2671 | 410 | { | ||
2672 | 411 | return page->d->page; | ||
2673 | 412 | } | ||
2674 | 413 | |||
2675 | 414 | QWebPagePrivate* QWebPagePrivate::priv(QWebPage* page) | ||
2676 | 415 | { | ||
2677 | 416 | return page->d; | ||
2678 | 417 | } | ||
2679 | 418 | |||
2680 | 419 | bool QWebPagePrivate::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) | ||
2681 | 420 | { | ||
2682 | 421 | if (insideOpenCall | ||
2683 | 422 | && frame == mainFrame.data()) | ||
2684 | 423 | return true; | ||
2685 | 424 | return q->acceptNavigationRequest(frame, request, type); | ||
2686 | 425 | } | ||
2687 | 426 | |||
2688 | 427 | void QWebPagePrivate::createMainFrame() | ||
2689 | 428 | { | ||
2690 | 429 | if (!mainFrame) { | ||
2691 | 430 | QWebFrameData frameData(page); | ||
2692 | 431 | mainFrame = new QWebFrame(q, &frameData); | ||
2693 | 432 | |||
2694 | 433 | emit q->frameCreated(mainFrame.data()); | ||
2695 | 434 | } | ||
2696 | 435 | } | ||
2697 | 436 | |||
2698 | 437 | static QWebPage::WebAction webActionForContextMenuAction(WebCore::ContextMenuAction action) | ||
2699 | 438 | { | ||
2700 | 439 | switch (action) { | ||
2701 | 440 | case WebCore::ContextMenuItemTagOpenLink: return QWebPage::OpenLink; | ||
2702 | 441 | case WebCore::ContextMenuItemTagOpenLinkInNewWindow: return QWebPage::OpenLinkInNewWindow; | ||
2703 | 442 | case WebCore::ContextMenuItemTagOpenLinkInThisWindow: return QWebPage::OpenLinkInThisWindow; | ||
2704 | 443 | case WebCore::ContextMenuItemTagDownloadLinkToDisk: return QWebPage::DownloadLinkToDisk; | ||
2705 | 444 | case WebCore::ContextMenuItemTagCopyLinkToClipboard: return QWebPage::CopyLinkToClipboard; | ||
2706 | 445 | case WebCore::ContextMenuItemTagOpenImageInNewWindow: return QWebPage::OpenImageInNewWindow; | ||
2707 | 446 | case WebCore::ContextMenuItemTagDownloadImageToDisk: return QWebPage::DownloadImageToDisk; | ||
2708 | 447 | case WebCore::ContextMenuItemTagCopyImageToClipboard: return QWebPage::CopyImageToClipboard; | ||
2709 | 448 | case WebCore::ContextMenuItemTagCopyImageUrlToClipboard: return QWebPage::CopyImageUrlToClipboard; | ||
2710 | 449 | case WebCore::ContextMenuItemTagOpenFrameInNewWindow: return QWebPage::OpenFrameInNewWindow; | ||
2711 | 450 | case WebCore::ContextMenuItemTagCopy: return QWebPage::Copy; | ||
2712 | 451 | case WebCore::ContextMenuItemTagGoBack: return QWebPage::Back; | ||
2713 | 452 | case WebCore::ContextMenuItemTagGoForward: return QWebPage::Forward; | ||
2714 | 453 | case WebCore::ContextMenuItemTagStop: return QWebPage::Stop; | ||
2715 | 454 | case WebCore::ContextMenuItemTagReload: return QWebPage::Reload; | ||
2716 | 455 | case WebCore::ContextMenuItemTagCut: return QWebPage::Cut; | ||
2717 | 456 | case WebCore::ContextMenuItemTagPaste: return QWebPage::Paste; | ||
2718 | 457 | case WebCore::ContextMenuItemTagDefaultDirection: return QWebPage::SetTextDirectionDefault; | ||
2719 | 458 | case WebCore::ContextMenuItemTagLeftToRight: return QWebPage::SetTextDirectionLeftToRight; | ||
2720 | 459 | case WebCore::ContextMenuItemTagRightToLeft: return QWebPage::SetTextDirectionRightToLeft; | ||
2721 | 460 | case WebCore::ContextMenuItemTagBold: return QWebPage::ToggleBold; | ||
2722 | 461 | case WebCore::ContextMenuItemTagItalic: return QWebPage::ToggleItalic; | ||
2723 | 462 | case WebCore::ContextMenuItemTagUnderline: return QWebPage::ToggleUnderline; | ||
2724 | 463 | case WebCore::ContextMenuItemTagSelectAll: return QWebPage::SelectAll; | ||
2725 | 464 | #if ENABLE(INSPECTOR) | ||
2726 | 465 | case WebCore::ContextMenuItemTagInspectElement: return QWebPage::InspectElement; | ||
2727 | 466 | #endif | ||
2728 | 467 | default: break; | ||
2729 | 468 | } | ||
2730 | 469 | return QWebPage::NoWebAction; | ||
2731 | 470 | } | ||
2732 | 471 | |||
2733 | 472 | #ifndef QT_NO_CONTEXTMENU | ||
2734 | 473 | QMenu *QWebPagePrivate::createContextMenu(const WebCore::ContextMenu *webcoreMenu, | ||
2735 | 474 | const QList<WebCore::ContextMenuItem> *items, QBitArray *visitedWebActions) | ||
2736 | 475 | { | ||
2737 | 476 | if (!client || !webcoreMenu) | ||
2738 | 477 | return 0; | ||
2739 | 478 | |||
2740 | 479 | QMenu* menu = new QMenu(client->ownerWidget()); | ||
2741 | 480 | for (int i = 0; i < items->count(); ++i) { | ||
2742 | 481 | const ContextMenuItem &item = items->at(i); | ||
2743 | 482 | switch (item.type()) { | ||
2744 | 483 | case WebCore::CheckableActionType: /* fall through */ | ||
2745 | 484 | case WebCore::ActionType: { | ||
2746 | 485 | QWebPage::WebAction action = webActionForContextMenuAction(item.action()); | ||
2747 | 486 | QAction *a = q->action(action); | ||
2748 | 487 | if (a) { | ||
2749 | 488 | ContextMenuItem it(item); | ||
2750 | 489 | page->contextMenuController()->checkOrEnableIfNeeded(it); | ||
2751 | 490 | PlatformMenuItemDescription desc = it.releasePlatformDescription(); | ||
2752 | 491 | a->setEnabled(desc.enabled); | ||
2753 | 492 | a->setChecked(desc.checked); | ||
2754 | 493 | a->setCheckable(item.type() == WebCore::CheckableActionType); | ||
2755 | 494 | |||
2756 | 495 | menu->addAction(a); | ||
2757 | 496 | visitedWebActions->setBit(action); | ||
2758 | 497 | } | ||
2759 | 498 | break; | ||
2760 | 499 | } | ||
2761 | 500 | case WebCore::SeparatorType: | ||
2762 | 501 | menu->addSeparator(); | ||
2763 | 502 | break; | ||
2764 | 503 | case WebCore::SubmenuType: { | ||
2765 | 504 | QMenu *subMenu = createContextMenu(webcoreMenu, item.platformSubMenu(), visitedWebActions); | ||
2766 | 505 | |||
2767 | 506 | bool anyEnabledAction = false; | ||
2768 | 507 | |||
2769 | 508 | QList<QAction *> actions = subMenu->actions(); | ||
2770 | 509 | for (int i = 0; i < actions.count(); ++i) { | ||
2771 | 510 | if (actions.at(i)->isVisible()) | ||
2772 | 511 | anyEnabledAction |= actions.at(i)->isEnabled(); | ||
2773 | 512 | } | ||
2774 | 513 | |||
2775 | 514 | // don't show sub-menus with just disabled actions | ||
2776 | 515 | if (anyEnabledAction) { | ||
2777 | 516 | subMenu->setTitle(item.title()); | ||
2778 | 517 | menu->addAction(subMenu->menuAction()); | ||
2779 | 518 | } else | ||
2780 | 519 | delete subMenu; | ||
2781 | 520 | break; | ||
2782 | 521 | } | ||
2783 | 522 | } | ||
2784 | 523 | } | ||
2785 | 524 | return menu; | ||
2786 | 525 | } | ||
2787 | 526 | #endif // QT_NO_CONTEXTMENU | ||
2788 | 527 | |||
2789 | 528 | #ifndef QT_NO_ACTION | ||
2790 | 529 | void QWebPagePrivate::_q_webActionTriggered(bool checked) | ||
2791 | 530 | { | ||
2792 | 531 | QAction *a = qobject_cast<QAction *>(q->sender()); | ||
2793 | 532 | if (!a) | ||
2794 | 533 | return; | ||
2795 | 534 | QWebPage::WebAction action = static_cast<QWebPage::WebAction>(a->data().toInt()); | ||
2796 | 535 | q->triggerAction(action, checked); | ||
2797 | 536 | } | ||
2798 | 537 | #endif // QT_NO_ACTION | ||
2799 | 538 | |||
2800 | 539 | void QWebPagePrivate::_q_cleanupLeakMessages() | ||
2801 | 540 | { | ||
2802 | 541 | #ifndef NDEBUG | ||
2803 | 542 | // Need this to make leak messages accurate. | ||
2804 | 543 | memoryCache()->setCapacities(0, 0, 0); | ||
2805 | 544 | #endif | ||
2806 | 545 | } | ||
2807 | 546 | |||
2808 | 547 | void QWebPagePrivate::updateAction(QWebPage::WebAction action) | ||
2809 | 548 | { | ||
2810 | 549 | #ifdef QT_NO_ACTION | ||
2811 | 550 | Q_UNUSED(action) | ||
2812 | 551 | #else | ||
2813 | 552 | QAction *a = actions[action]; | ||
2814 | 553 | if (!a || !mainFrame) | ||
2815 | 554 | return; | ||
2816 | 555 | |||
2817 | 556 | WebCore::FrameLoader *loader = mainFrame.data()->d->frame->loader(); | ||
2818 | 557 | WebCore::Editor *editor = page->focusController()->focusedOrMainFrame()->editor(); | ||
2819 | 558 | |||
2820 | 559 | bool enabled = a->isEnabled(); | ||
2821 | 560 | bool checked = a->isChecked(); | ||
2822 | 561 | |||
2823 | 562 | switch (action) { | ||
2824 | 563 | case QWebPage::Back: | ||
2825 | 564 | enabled = page->canGoBackOrForward(-1); | ||
2826 | 565 | break; | ||
2827 | 566 | case QWebPage::Forward: | ||
2828 | 567 | enabled = page->canGoBackOrForward(1); | ||
2829 | 568 | break; | ||
2830 | 569 | case QWebPage::Stop: | ||
2831 | 570 | enabled = loader->isLoading(); | ||
2832 | 571 | break; | ||
2833 | 572 | case QWebPage::Reload: | ||
2834 | 573 | case QWebPage::ReloadAndBypassCache: | ||
2835 | 574 | enabled = !loader->isLoading(); | ||
2836 | 575 | break; | ||
2837 | 576 | #ifndef QT_NO_UNDOSTACK | ||
2838 | 577 | case QWebPage::Undo: | ||
2839 | 578 | case QWebPage::Redo: | ||
2840 | 579 | // those two are handled by QUndoStack | ||
2841 | 580 | break; | ||
2842 | 581 | #endif // QT_NO_UNDOSTACK | ||
2843 | 582 | case QWebPage::SelectAll: // editor command is always enabled | ||
2844 | 583 | break; | ||
2845 | 584 | case QWebPage::SetTextDirectionDefault: | ||
2846 | 585 | case QWebPage::SetTextDirectionLeftToRight: | ||
2847 | 586 | case QWebPage::SetTextDirectionRightToLeft: | ||
2848 | 587 | enabled = editor->canEdit(); | ||
2849 | 588 | checked = false; | ||
2850 | 589 | break; | ||
2851 | 590 | default: { | ||
2852 | 591 | // see if it's an editor command | ||
2853 | 592 | const char* commandName = editorCommandForWebActions(action); | ||
2854 | 593 | |||
2855 | 594 | // if it's an editor command, let it's logic determine state | ||
2856 | 595 | if (commandName) { | ||
2857 | 596 | Editor::Command command = editor->command(commandName); | ||
2858 | 597 | enabled = command.isEnabled(); | ||
2859 | 598 | if (enabled) | ||
2860 | 599 | checked = command.state() != FalseTriState; | ||
2861 | 600 | else | ||
2862 | 601 | checked = false; | ||
2863 | 602 | } | ||
2864 | 603 | break; | ||
2865 | 604 | } | ||
2866 | 605 | } | ||
2867 | 606 | |||
2868 | 607 | a->setEnabled(enabled); | ||
2869 | 608 | |||
2870 | 609 | if (a->isCheckable()) | ||
2871 | 610 | a->setChecked(checked); | ||
2872 | 611 | #endif // QT_NO_ACTION | ||
2873 | 612 | } | ||
2874 | 613 | |||
2875 | 614 | void QWebPagePrivate::updateNavigationActions() | ||
2876 | 615 | { | ||
2877 | 616 | updateAction(QWebPage::Back); | ||
2878 | 617 | updateAction(QWebPage::Forward); | ||
2879 | 618 | updateAction(QWebPage::Stop); | ||
2880 | 619 | updateAction(QWebPage::Reload); | ||
2881 | 620 | updateAction(QWebPage::ReloadAndBypassCache); | ||
2882 | 621 | } | ||
2883 | 622 | |||
2884 | 623 | void QWebPagePrivate::updateEditorActions() | ||
2885 | 624 | { | ||
2886 | 625 | updateAction(QWebPage::Cut); | ||
2887 | 626 | updateAction(QWebPage::Copy); | ||
2888 | 627 | updateAction(QWebPage::Paste); | ||
2889 | 628 | updateAction(QWebPage::MoveToNextChar); | ||
2890 | 629 | updateAction(QWebPage::MoveToPreviousChar); | ||
2891 | 630 | updateAction(QWebPage::MoveToNextWord); | ||
2892 | 631 | updateAction(QWebPage::MoveToPreviousWord); | ||
2893 | 632 | updateAction(QWebPage::MoveToNextLine); | ||
2894 | 633 | updateAction(QWebPage::MoveToPreviousLine); | ||
2895 | 634 | updateAction(QWebPage::MoveToStartOfLine); | ||
2896 | 635 | updateAction(QWebPage::MoveToEndOfLine); | ||
2897 | 636 | updateAction(QWebPage::MoveToStartOfBlock); | ||
2898 | 637 | updateAction(QWebPage::MoveToEndOfBlock); | ||
2899 | 638 | updateAction(QWebPage::MoveToStartOfDocument); | ||
2900 | 639 | updateAction(QWebPage::MoveToEndOfDocument); | ||
2901 | 640 | updateAction(QWebPage::SelectNextChar); | ||
2902 | 641 | updateAction(QWebPage::SelectPreviousChar); | ||
2903 | 642 | updateAction(QWebPage::SelectNextWord); | ||
2904 | 643 | updateAction(QWebPage::SelectPreviousWord); | ||
2905 | 644 | updateAction(QWebPage::SelectNextLine); | ||
2906 | 645 | updateAction(QWebPage::SelectPreviousLine); | ||
2907 | 646 | updateAction(QWebPage::SelectStartOfLine); | ||
2908 | 647 | updateAction(QWebPage::SelectEndOfLine); | ||
2909 | 648 | updateAction(QWebPage::SelectStartOfBlock); | ||
2910 | 649 | updateAction(QWebPage::SelectEndOfBlock); | ||
2911 | 650 | updateAction(QWebPage::SelectStartOfDocument); | ||
2912 | 651 | updateAction(QWebPage::SelectEndOfDocument); | ||
2913 | 652 | updateAction(QWebPage::DeleteStartOfWord); | ||
2914 | 653 | updateAction(QWebPage::DeleteEndOfWord); | ||
2915 | 654 | updateAction(QWebPage::SetTextDirectionDefault); | ||
2916 | 655 | updateAction(QWebPage::SetTextDirectionLeftToRight); | ||
2917 | 656 | updateAction(QWebPage::SetTextDirectionRightToLeft); | ||
2918 | 657 | updateAction(QWebPage::ToggleBold); | ||
2919 | 658 | updateAction(QWebPage::ToggleItalic); | ||
2920 | 659 | updateAction(QWebPage::ToggleUnderline); | ||
2921 | 660 | updateAction(QWebPage::InsertParagraphSeparator); | ||
2922 | 661 | updateAction(QWebPage::InsertLineSeparator); | ||
2923 | 662 | updateAction(QWebPage::PasteAndMatchStyle); | ||
2924 | 663 | updateAction(QWebPage::RemoveFormat); | ||
2925 | 664 | updateAction(QWebPage::ToggleStrikethrough); | ||
2926 | 665 | updateAction(QWebPage::ToggleSubscript); | ||
2927 | 666 | updateAction(QWebPage::ToggleSuperscript); | ||
2928 | 667 | updateAction(QWebPage::InsertUnorderedList); | ||
2929 | 668 | updateAction(QWebPage::InsertOrderedList); | ||
2930 | 669 | updateAction(QWebPage::Indent); | ||
2931 | 670 | updateAction(QWebPage::Outdent); | ||
2932 | 671 | updateAction(QWebPage::AlignCenter); | ||
2933 | 672 | updateAction(QWebPage::AlignJustified); | ||
2934 | 673 | updateAction(QWebPage::AlignLeft); | ||
2935 | 674 | updateAction(QWebPage::AlignRight); | ||
2936 | 675 | } | ||
2937 | 676 | |||
2938 | 677 | void QWebPagePrivate::timerEvent(QTimerEvent *ev) | ||
2939 | 678 | { | ||
2940 | 679 | int timerId = ev->timerId(); | ||
2941 | 680 | if (timerId == tripleClickTimer.timerId()) | ||
2942 | 681 | tripleClickTimer.stop(); | ||
2943 | 682 | else | ||
2944 | 683 | q->timerEvent(ev); | ||
2945 | 684 | } | ||
2946 | 685 | |||
2947 | 686 | template<class T> | ||
2948 | 687 | void QWebPagePrivate::mouseMoveEvent(T* ev) | ||
2949 | 688 | { | ||
2950 | 689 | WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data()); | ||
2951 | 690 | if (!frame->view()) | ||
2952 | 691 | return; | ||
2953 | 692 | |||
2954 | 693 | bool accepted = frame->eventHandler()->mouseMoved(convertMouseEvent(ev, 0)); | ||
2955 | 694 | ev->setAccepted(accepted); | ||
2956 | 695 | } | ||
2957 | 696 | |||
2958 | 697 | template<class T> | ||
2959 | 698 | void QWebPagePrivate::mousePressEvent(T* ev) | ||
2960 | 699 | { | ||
2961 | 700 | WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data()); | ||
2962 | 701 | if (!frame->view()) | ||
2963 | 702 | return; | ||
2964 | 703 | |||
2965 | 704 | RefPtr<WebCore::Node> oldNode; | ||
2966 | 705 | Frame* focusedFrame = page->focusController()->focusedFrame(); | ||
2967 | 706 | if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0) | ||
2968 | 707 | oldNode = focusedDocument->focusedNode(); | ||
2969 | 708 | |||
2970 | 709 | if (tripleClickTimer.isActive() | ||
2971 | 710 | && (ev->pos() - tripleClick).manhattanLength() | ||
2972 | 711 | < QApplication::startDragDistance()) { | ||
2973 | 712 | mouseTripleClickEvent(ev); | ||
2974 | 713 | return; | ||
2975 | 714 | } | ||
2976 | 715 | |||
2977 | 716 | bool accepted = false; | ||
2978 | 717 | adjustPointForClicking(ev); | ||
2979 | 718 | PlatformMouseEvent mev = convertMouseEvent(ev, 1); | ||
2980 | 719 | // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton | ||
2981 | 720 | if (mev.button() != NoButton) | ||
2982 | 721 | accepted = frame->eventHandler()->handleMousePressEvent(mev); | ||
2983 | 722 | ev->setAccepted(accepted); | ||
2984 | 723 | |||
2985 | 724 | RefPtr<WebCore::Node> newNode; | ||
2986 | 725 | focusedFrame = page->focusController()->focusedFrame(); | ||
2987 | 726 | if (Document* focusedDocument = focusedFrame ? focusedFrame->document() : 0) | ||
2988 | 727 | newNode = focusedDocument->focusedNode(); | ||
2989 | 728 | |||
2990 | 729 | if (newNode && oldNode != newNode) | ||
2991 | 730 | clickCausedFocus = true; | ||
2992 | 731 | } | ||
2993 | 732 | |||
2994 | 733 | template<class T> | ||
2995 | 734 | void QWebPagePrivate::mouseDoubleClickEvent(T *ev) | ||
2996 | 735 | { | ||
2997 | 736 | WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data()); | ||
2998 | 737 | if (!frame->view()) | ||
2999 | 738 | return; | ||
3000 | 739 | |||
3001 | 740 | bool accepted = false; | ||
3002 | 741 | PlatformMouseEvent mev = convertMouseEvent(ev, 2); | ||
3003 | 742 | // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton | ||
3004 | 743 | if (mev.button() != NoButton) | ||
3005 | 744 | accepted = frame->eventHandler()->handleMousePressEvent(mev); | ||
3006 | 745 | ev->setAccepted(accepted); | ||
3007 | 746 | |||
3008 | 747 | tripleClickTimer.start(QApplication::doubleClickInterval(), q); | ||
3009 | 748 | tripleClick = QPointF(ev->pos()).toPoint(); | ||
3010 | 749 | } | ||
3011 | 750 | |||
3012 | 751 | template<class T> | ||
3013 | 752 | void QWebPagePrivate::mouseTripleClickEvent(T *ev) | ||
3014 | 753 | { | ||
3015 | 754 | WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data()); | ||
3016 | 755 | if (!frame->view()) | ||
3017 | 756 | return; | ||
3018 | 757 | |||
3019 | 758 | bool accepted = false; | ||
3020 | 759 | PlatformMouseEvent mev = convertMouseEvent(ev, 3); | ||
3021 | 760 | // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton | ||
3022 | 761 | if (mev.button() != NoButton) | ||
3023 | 762 | accepted = frame->eventHandler()->handleMousePressEvent(mev); | ||
3024 | 763 | ev->setAccepted(accepted); | ||
3025 | 764 | } | ||
3026 | 765 | |||
3027 | 766 | template<class T> | ||
3028 | 767 | void QWebPagePrivate::mouseReleaseEvent(T *ev) | ||
3029 | 768 | { | ||
3030 | 769 | WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data()); | ||
3031 | 770 | if (!frame->view()) | ||
3032 | 771 | return; | ||
3033 | 772 | |||
3034 | 773 | bool accepted = false; | ||
3035 | 774 | adjustPointForClicking(ev); | ||
3036 | 775 | PlatformMouseEvent mev = convertMouseEvent(ev, 0); | ||
3037 | 776 | // ignore the event if we can't map Qt's mouse buttons to WebCore::MouseButton | ||
3038 | 777 | if (mev.button() != NoButton) | ||
3039 | 778 | accepted = frame->eventHandler()->handleMouseReleaseEvent(mev); | ||
3040 | 779 | ev->setAccepted(accepted); | ||
3041 | 780 | |||
3042 | 781 | handleSoftwareInputPanel(ev->button(), QPointF(ev->pos()).toPoint()); | ||
3043 | 782 | } | ||
3044 | 783 | |||
3045 | 784 | void QWebPagePrivate::handleSoftwareInputPanel(Qt::MouseButton button, const QPoint& pos) | ||
3046 | 785 | { | ||
3047 | 786 | Frame* frame = page->focusController()->focusedFrame(); | ||
3048 | 787 | if (!frame) | ||
3049 | 788 | return; | ||
3050 | 789 | |||
3051 | 790 | if (client && client->inputMethodEnabled() | ||
3052 | 791 | && frame->document()->focusedNode() | ||
3053 | 792 | && button == Qt::LeftButton && qApp->autoSipEnabled()) { | ||
3054 | 793 | QStyle::RequestSoftwareInputPanel behavior = QStyle::RequestSoftwareInputPanel( | ||
3055 | 794 | client->ownerWidget()->style()->styleHint(QStyle::SH_RequestSoftwareInputPanel)); | ||
3056 | 795 | if (!clickCausedFocus || behavior == QStyle::RSIP_OnMouseClick) { | ||
3057 | 796 | HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(frame->view()->windowToContents(pos), false); | ||
3058 | 797 | if (result.isContentEditable()) { | ||
3059 | 798 | QEvent event(QEvent::RequestSoftwareInputPanel); | ||
3060 | 799 | QApplication::sendEvent(client->ownerWidget(), &event); | ||
3061 | 800 | } | ||
3062 | 801 | } | ||
3063 | 802 | } | ||
3064 | 803 | |||
3065 | 804 | clickCausedFocus = false; | ||
3066 | 805 | } | ||
3067 | 806 | |||
3068 | 807 | #ifndef QT_NO_CONTEXTMENU | ||
3069 | 808 | void QWebPagePrivate::contextMenuEvent(const QPoint& globalPos) | ||
3070 | 809 | { | ||
3071 | 810 | QMenu *menu = q->createStandardContextMenu(); | ||
3072 | 811 | if (menu) { | ||
3073 | 812 | menu->exec(globalPos); | ||
3074 | 813 | delete menu; | ||
3075 | 814 | } | ||
3076 | 815 | } | ||
3077 | 816 | #endif // QT_NO_CONTEXTMENU | ||
3078 | 817 | |||
3079 | 818 | /*! | ||
3080 | 819 | \since 4.5 | ||
3081 | 820 | This function creates the standard context menu which is shown when | ||
3082 | 821 | the user clicks on the web page with the right mouse button. It is | ||
3083 | 822 | called from the default contextMenuEvent() handler. The popup menu's | ||
3084 | 823 | ownership is transferred to the caller. | ||
3085 | 824 | */ | ||
3086 | 825 | QMenu *QWebPage::createStandardContextMenu() | ||
3087 | 826 | { | ||
3088 | 827 | #ifndef QT_NO_CONTEXTMENU | ||
3089 | 828 | QMenu* menu = d->currentContextMenu.data(); | ||
3090 | 829 | d->currentContextMenu = 0; | ||
3091 | 830 | return menu; | ||
3092 | 831 | #else | ||
3093 | 832 | return 0; | ||
3094 | 833 | #endif | ||
3095 | 834 | } | ||
3096 | 835 | |||
3097 | 836 | #ifndef QT_NO_WHEELEVENT | ||
3098 | 837 | template<class T> | ||
3099 | 838 | void QWebPagePrivate::wheelEvent(T *ev) | ||
3100 | 839 | { | ||
3101 | 840 | WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data()); | ||
3102 | 841 | if (!frame->view()) | ||
3103 | 842 | return; | ||
3104 | 843 | |||
3105 | 844 | PlatformWheelEvent pev = convertWheelEvent(ev); | ||
3106 | 845 | bool accepted = frame->eventHandler()->handleWheelEvent(pev); | ||
3107 | 846 | ev->setAccepted(accepted); | ||
3108 | 847 | } | ||
3109 | 848 | #endif // QT_NO_WHEELEVENT | ||
3110 | 849 | |||
3111 | 850 | #ifndef QT_NO_SHORTCUT | ||
3112 | 851 | QWebPage::WebAction QWebPagePrivate::editorActionForKeyEvent(QKeyEvent* event) | ||
3113 | 852 | { | ||
3114 | 853 | static struct { | ||
3115 | 854 | QKeySequence::StandardKey standardKey; | ||
3116 | 855 | QWebPage::WebAction action; | ||
3117 | 856 | } editorActions[] = { | ||
3118 | 857 | { QKeySequence::Cut, QWebPage::Cut }, | ||
3119 | 858 | { QKeySequence::Copy, QWebPage::Copy }, | ||
3120 | 859 | { QKeySequence::Paste, QWebPage::Paste }, | ||
3121 | 860 | { QKeySequence::Undo, QWebPage::Undo }, | ||
3122 | 861 | { QKeySequence::Redo, QWebPage::Redo }, | ||
3123 | 862 | { QKeySequence::MoveToNextChar, QWebPage::MoveToNextChar }, | ||
3124 | 863 | { QKeySequence::MoveToPreviousChar, QWebPage::MoveToPreviousChar }, | ||
3125 | 864 | { QKeySequence::MoveToNextWord, QWebPage::MoveToNextWord }, | ||
3126 | 865 | { QKeySequence::MoveToPreviousWord, QWebPage::MoveToPreviousWord }, | ||
3127 | 866 | { QKeySequence::MoveToNextLine, QWebPage::MoveToNextLine }, | ||
3128 | 867 | { QKeySequence::MoveToPreviousLine, QWebPage::MoveToPreviousLine }, | ||
3129 | 868 | { QKeySequence::MoveToStartOfLine, QWebPage::MoveToStartOfLine }, | ||
3130 | 869 | { QKeySequence::MoveToEndOfLine, QWebPage::MoveToEndOfLine }, | ||
3131 | 870 | { QKeySequence::MoveToStartOfBlock, QWebPage::MoveToStartOfBlock }, | ||
3132 | 871 | { QKeySequence::MoveToEndOfBlock, QWebPage::MoveToEndOfBlock }, | ||
3133 | 872 | { QKeySequence::MoveToStartOfDocument, QWebPage::MoveToStartOfDocument }, | ||
3134 | 873 | { QKeySequence::MoveToEndOfDocument, QWebPage::MoveToEndOfDocument }, | ||
3135 | 874 | { QKeySequence::SelectNextChar, QWebPage::SelectNextChar }, | ||
3136 | 875 | { QKeySequence::SelectPreviousChar, QWebPage::SelectPreviousChar }, | ||
3137 | 876 | { QKeySequence::SelectNextWord, QWebPage::SelectNextWord }, | ||
3138 | 877 | { QKeySequence::SelectPreviousWord, QWebPage::SelectPreviousWord }, | ||
3139 | 878 | { QKeySequence::SelectNextLine, QWebPage::SelectNextLine }, | ||
3140 | 879 | { QKeySequence::SelectPreviousLine, QWebPage::SelectPreviousLine }, | ||
3141 | 880 | { QKeySequence::SelectStartOfLine, QWebPage::SelectStartOfLine }, | ||
3142 | 881 | { QKeySequence::SelectEndOfLine, QWebPage::SelectEndOfLine }, | ||
3143 | 882 | { QKeySequence::SelectStartOfBlock, QWebPage::SelectStartOfBlock }, | ||
3144 | 883 | { QKeySequence::SelectEndOfBlock, QWebPage::SelectEndOfBlock }, | ||
3145 | 884 | { QKeySequence::SelectStartOfDocument, QWebPage::SelectStartOfDocument }, | ||
3146 | 885 | { QKeySequence::SelectEndOfDocument, QWebPage::SelectEndOfDocument }, | ||
3147 | 886 | { QKeySequence::DeleteStartOfWord, QWebPage::DeleteStartOfWord }, | ||
3148 | 887 | { QKeySequence::DeleteEndOfWord, QWebPage::DeleteEndOfWord }, | ||
3149 | 888 | { QKeySequence::InsertParagraphSeparator, QWebPage::InsertParagraphSeparator }, | ||
3150 | 889 | { QKeySequence::InsertLineSeparator, QWebPage::InsertLineSeparator }, | ||
3151 | 890 | { QKeySequence::SelectAll, QWebPage::SelectAll }, | ||
3152 | 891 | { QKeySequence::UnknownKey, QWebPage::NoWebAction } | ||
3153 | 892 | }; | ||
3154 | 893 | |||
3155 | 894 | for (int i = 0; editorActions[i].standardKey != QKeySequence::UnknownKey; ++i) | ||
3156 | 895 | if (event == editorActions[i].standardKey) | ||
3157 | 896 | return editorActions[i].action; | ||
3158 | 897 | |||
3159 | 898 | return QWebPage::NoWebAction; | ||
3160 | 899 | } | ||
3161 | 900 | #endif // QT_NO_SHORTCUT | ||
3162 | 901 | |||
3163 | 902 | void QWebPagePrivate::keyPressEvent(QKeyEvent *ev) | ||
3164 | 903 | { | ||
3165 | 904 | bool handled = false; | ||
3166 | 905 | WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); | ||
3167 | 906 | // we forward the key event to WebCore first to handle potential DOM | ||
3168 | 907 | // defined event handlers and later on end up in EditorClientQt::handleKeyboardEvent | ||
3169 | 908 | // to trigger editor commands via triggerAction(). | ||
3170 | 909 | if (!handled) | ||
3171 | 910 | handled = frame->eventHandler()->keyEvent(ev); | ||
3172 | 911 | if (!handled) { | ||
3173 | 912 | handled = true; | ||
3174 | 913 | if (!handleScrolling(ev, frame)) { | ||
3175 | 914 | switch (ev->key()) { | ||
3176 | 915 | case Qt::Key_Back: | ||
3177 | 916 | q->triggerAction(QWebPage::Back); | ||
3178 | 917 | break; | ||
3179 | 918 | case Qt::Key_Forward: | ||
3180 | 919 | q->triggerAction(QWebPage::Forward); | ||
3181 | 920 | break; | ||
3182 | 921 | case Qt::Key_Stop: | ||
3183 | 922 | q->triggerAction(QWebPage::Stop); | ||
3184 | 923 | break; | ||
3185 | 924 | case Qt::Key_Refresh: | ||
3186 | 925 | q->triggerAction(QWebPage::Reload); | ||
3187 | 926 | break; | ||
3188 | 927 | case Qt::Key_Backspace: | ||
3189 | 928 | if (ev->modifiers() == Qt::ShiftModifier) | ||
3190 | 929 | q->triggerAction(QWebPage::Forward); | ||
3191 | 930 | else | ||
3192 | 931 | q->triggerAction(QWebPage::Back); | ||
3193 | 932 | break; | ||
3194 | 933 | default: | ||
3195 | 934 | handled = false; | ||
3196 | 935 | break; | ||
3197 | 936 | } | ||
3198 | 937 | } | ||
3199 | 938 | } | ||
3200 | 939 | |||
3201 | 940 | ev->setAccepted(handled); | ||
3202 | 941 | } | ||
3203 | 942 | |||
3204 | 943 | void QWebPagePrivate::keyReleaseEvent(QKeyEvent *ev) | ||
3205 | 944 | { | ||
3206 | 945 | if (ev->isAutoRepeat()) { | ||
3207 | 946 | ev->setAccepted(true); | ||
3208 | 947 | return; | ||
3209 | 948 | } | ||
3210 | 949 | |||
3211 | 950 | WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); | ||
3212 | 951 | bool handled = frame->eventHandler()->keyEvent(ev); | ||
3213 | 952 | ev->setAccepted(handled); | ||
3214 | 953 | } | ||
3215 | 954 | |||
3216 | 955 | void QWebPagePrivate::focusInEvent(QFocusEvent*) | ||
3217 | 956 | { | ||
3218 | 957 | FocusController *focusController = page->focusController(); | ||
3219 | 958 | focusController->setActive(true); | ||
3220 | 959 | focusController->setFocused(true); | ||
3221 | 960 | if (!focusController->focusedFrame()) | ||
3222 | 961 | focusController->setFocusedFrame(QWebFramePrivate::core(mainFrame.data())); | ||
3223 | 962 | } | ||
3224 | 963 | |||
3225 | 964 | void QWebPagePrivate::focusOutEvent(QFocusEvent*) | ||
3226 | 965 | { | ||
3227 | 966 | // only set the focused frame inactive so that we stop painting the caret | ||
3228 | 967 | // and the focus frame. But don't tell the focus controller so that upon | ||
3229 | 968 | // focusInEvent() we can re-activate the frame. | ||
3230 | 969 | FocusController *focusController = page->focusController(); | ||
3231 | 970 | // Call setFocused first so that window.onblur doesn't get called twice | ||
3232 | 971 | focusController->setFocused(false); | ||
3233 | 972 | focusController->setActive(false); | ||
3234 | 973 | } | ||
3235 | 974 | |||
3236 | 975 | template<class T> | ||
3237 | 976 | void QWebPagePrivate::dragEnterEvent(T* ev) | ||
3238 | 977 | { | ||
3239 | 978 | #ifndef QT_NO_DRAGANDDROP | ||
3240 | 979 | DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(), | ||
3241 | 980 | QCursor::pos(), dropActionToDragOp(ev->possibleActions())); | ||
3242 | 981 | Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData).operation); | ||
3243 | 982 | ev->setDropAction(action); | ||
3244 | 983 | ev->acceptProposedAction(); | ||
3245 | 984 | #endif | ||
3246 | 985 | } | ||
3247 | 986 | |||
3248 | 987 | template<class T> | ||
3249 | 988 | void QWebPagePrivate::dragLeaveEvent(T *ev) | ||
3250 | 989 | { | ||
3251 | 990 | #ifndef QT_NO_DRAGANDDROP | ||
3252 | 991 | DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone); | ||
3253 | 992 | page->dragController()->dragExited(&dragData); | ||
3254 | 993 | ev->accept(); | ||
3255 | 994 | #endif | ||
3256 | 995 | } | ||
3257 | 996 | |||
3258 | 997 | template<class T> | ||
3259 | 998 | void QWebPagePrivate::dragMoveEvent(T *ev) | ||
3260 | 999 | { | ||
3261 | 1000 | #ifndef QT_NO_DRAGANDDROP | ||
3262 | 1001 | DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(), | ||
3263 | 1002 | QCursor::pos(), dropActionToDragOp(ev->possibleActions())); | ||
3264 | 1003 | m_lastDropAction = dragOpToDropAction(page->dragController()->dragUpdated(&dragData).operation); | ||
3265 | 1004 | ev->setDropAction(m_lastDropAction); | ||
3266 | 1005 | if (m_lastDropAction != Qt::IgnoreAction) | ||
3267 | 1006 | ev->accept(); | ||
3268 | 1007 | #endif | ||
3269 | 1008 | } | ||
3270 | 1009 | |||
3271 | 1010 | template<class T> | ||
3272 | 1011 | void QWebPagePrivate::dropEvent(T *ev) | ||
3273 | 1012 | { | ||
3274 | 1013 | #ifndef QT_NO_DRAGANDDROP | ||
3275 | 1014 | DragData dragData(ev->mimeData(), QPointF(ev->pos()).toPoint(), | ||
3276 | 1015 | QCursor::pos(), dropActionToDragOp(ev->possibleActions())); | ||
3277 | 1016 | if (page->dragController()->performDrag(&dragData)) { | ||
3278 | 1017 | ev->setDropAction(m_lastDropAction); | ||
3279 | 1018 | ev->accept(); | ||
3280 | 1019 | } | ||
3281 | 1020 | #endif | ||
3282 | 1021 | } | ||
3283 | 1022 | |||
3284 | 1023 | void QWebPagePrivate::leaveEvent(QEvent*) | ||
3285 | 1024 | { | ||
3286 | 1025 | // Fake a mouse move event just outside of the widget, since all | ||
3287 | 1026 | // the interesting mouse-out behavior like invalidating scrollbars | ||
3288 | 1027 | // is handled by the WebKit event handler's mouseMoved function. | ||
3289 | 1028 | QMouseEvent fakeEvent(QEvent::MouseMove, QCursor::pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier); | ||
3290 | 1029 | mouseMoveEvent(&fakeEvent); | ||
3291 | 1030 | } | ||
3292 | 1031 | |||
3293 | 1032 | /*! | ||
3294 | 1033 | \property QWebPage::palette | ||
3295 | 1034 | \brief the page's palette | ||
3296 | 1035 | |||
3297 | 1036 | The base brush of the palette is used to draw the background of the main frame. | ||
3298 | 1037 | |||
3299 | 1038 | By default, this property contains the application's default palette. | ||
3300 | 1039 | */ | ||
3301 | 1040 | void QWebPage::setPalette(const QPalette &pal) | ||
3302 | 1041 | { | ||
3303 | 1042 | d->palette = pal; | ||
3304 | 1043 | if (!d->mainFrame || !d->mainFrame.data()->d->frame->view()) | ||
3305 | 1044 | return; | ||
3306 | 1045 | |||
3307 | 1046 | QBrush brush = pal.brush(QPalette::Base); | ||
3308 | 1047 | QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor(); | ||
3309 | 1048 | QWebFramePrivate::core(d->mainFrame.data())->view()->updateBackgroundRecursively(backgroundColor, !backgroundColor.alpha()); | ||
3310 | 1049 | } | ||
3311 | 1050 | |||
3312 | 1051 | QPalette QWebPage::palette() const | ||
3313 | 1052 | { | ||
3314 | 1053 | return d->palette; | ||
3315 | 1054 | } | ||
3316 | 1055 | |||
3317 | 1056 | void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) | ||
3318 | 1057 | { | ||
3319 | 1058 | WebCore::Frame *frame = page->focusController()->focusedOrMainFrame(); | ||
3320 | 1059 | WebCore::Editor *editor = frame->editor(); | ||
3321 | 1060 | |||
3322 | 1061 | if (!editor->canEdit()) { | ||
3323 | 1062 | ev->ignore(); | ||
3324 | 1063 | return; | ||
3325 | 1064 | } | ||
3326 | 1065 | |||
3327 | 1066 | Node* node = 0; | ||
3328 | 1067 | if (frame->selection()->rootEditableElement()) | ||
3329 | 1068 | node = frame->selection()->rootEditableElement()->shadowAncestorNode(); | ||
3330 | 1069 | |||
3331 | 1070 | Vector<CompositionUnderline> underlines; | ||
3332 | 1071 | bool hasSelection = false; | ||
3333 | 1072 | |||
3334 | 1073 | for (int i = 0; i < ev->attributes().size(); ++i) { | ||
3335 | 1074 | const QInputMethodEvent::Attribute& a = ev->attributes().at(i); | ||
3336 | 1075 | switch (a.type) { | ||
3337 | 1076 | case QInputMethodEvent::TextFormat: { | ||
3338 | 1077 | QTextCharFormat textCharFormat = a.value.value<QTextFormat>().toCharFormat(); | ||
3339 | 1078 | QColor qcolor = textCharFormat.underlineColor(); | ||
3340 | 1079 | underlines.append(CompositionUnderline(qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length)), Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha())), false)); | ||
3341 | 1080 | break; | ||
3342 | 1081 | } | ||
3343 | 1082 | case QInputMethodEvent::Cursor: { | ||
3344 | 1083 | frame->selection()->setCaretVisible(a.length); //if length is 0 cursor is invisible | ||
3345 | 1084 | if (a.length > 0) { | ||
3346 | 1085 | RenderObject* caretRenderer = frame->selection()->caretRenderer(); | ||
3347 | 1086 | if (caretRenderer) { | ||
3348 | 1087 | QColor qcolor = a.value.value<QColor>(); | ||
3349 | 1088 | caretRenderer->style()->setColor(Color(makeRGBA(qcolor.red(), qcolor.green(), qcolor.blue(), qcolor.alpha()))); | ||
3350 | 1089 | } | ||
3351 | 1090 | } | ||
3352 | 1091 | break; | ||
3353 | 1092 | } | ||
3354 | 1093 | case QInputMethodEvent::Selection: { | ||
3355 | 1094 | hasSelection = true; | ||
3356 | 1095 | // A selection in the inputMethodEvent is always reflected in the visible text | ||
3357 | 1096 | if (node) { | ||
3358 | 1097 | if (HTMLTextFormControlElement* textControl = toTextFormControl(node)) | ||
3359 | 1098 | textControl->setSelectionRange(qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length))); | ||
3360 | 1099 | } | ||
3361 | 1100 | |||
3362 | 1101 | if (!ev->preeditString().isEmpty()) | ||
3363 | 1102 | editor->setComposition(ev->preeditString(), underlines, qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length))); | ||
3364 | 1103 | else { | ||
3365 | 1104 | // If we are in the middle of a composition, an empty pre-edit string and a selection of zero | ||
3366 | 1105 | // cancels the current composition | ||
3367 | 1106 | if (editor->hasComposition() && (a.start + a.length == 0)) | ||
3368 | 1107 | editor->setComposition(QString(), underlines, 0, 0); | ||
3369 | 1108 | } | ||
3370 | 1109 | break; | ||
3371 | 1110 | } | ||
3372 | 1111 | default: | ||
3373 | 1112 | break; | ||
3374 | 1113 | } | ||
3375 | 1114 | } | ||
3376 | 1115 | |||
3377 | 1116 | if (node && ev->replacementLength() > 0) { | ||
3378 | 1117 | int cursorPos = frame->selection()->extent().offsetInContainerNode(); | ||
3379 | 1118 | int start = cursorPos + ev->replacementStart(); | ||
3380 | 1119 | if (HTMLTextFormControlElement* textControl = toTextFormControl(node)) | ||
3381 | 1120 | textControl->setSelectionRange(start, start + ev->replacementLength()); | ||
3382 | 1121 | // Commit regardless of whether commitString is empty, to get rid of selection. | ||
3383 | 1122 | editor->confirmComposition(ev->commitString()); | ||
3384 | 1123 | } else if (!ev->commitString().isEmpty()) { | ||
3385 | 1124 | if (editor->hasComposition()) | ||
3386 | 1125 | editor->confirmComposition(ev->commitString()); | ||
3387 | 1126 | else | ||
3388 | 1127 | editor->insertText(ev->commitString(), 0); | ||
3389 | 1128 | } else if (!hasSelection && !ev->preeditString().isEmpty()) | ||
3390 | 1129 | editor->setComposition(ev->preeditString(), underlines, 0, 0); | ||
3391 | 1130 | else if (ev->preeditString().isEmpty() && editor->hasComposition()) | ||
3392 | 1131 | editor->confirmComposition(String()); | ||
3393 | 1132 | |||
3394 | 1133 | ev->accept(); | ||
3395 | 1134 | } | ||
3396 | 1135 | |||
3397 | 1136 | #ifndef QT_NO_PROPERTIES | ||
3398 | 1137 | typedef struct { | ||
3399 | 1138 | const char* name; | ||
3400 | 1139 | double deferredRepaintDelay; | ||
3401 | 1140 | double initialDeferredRepaintDelayDuringLoading; | ||
3402 | 1141 | double maxDeferredRepaintDelayDuringLoading; | ||
3403 | 1142 | double deferredRepaintDelayIncrementDuringLoading; | ||
3404 | 1143 | } QRepaintThrottlingPreset; | ||
3405 | 1144 | |||
3406 | 1145 | void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* event) | ||
3407 | 1146 | { | ||
3408 | 1147 | if (event->propertyName() == "_q_viewMode") { | ||
3409 | 1148 | page->setViewMode(Page::stringToViewMode(q->property("_q_viewMode").toString())); | ||
3410 | 1149 | } else if (event->propertyName() == "_q_HTMLTokenizerChunkSize") { | ||
3411 | 1150 | int chunkSize = q->property("_q_HTMLTokenizerChunkSize").toInt(); | ||
3412 | 1151 | q->handle()->page->setCustomHTMLTokenizerChunkSize(chunkSize); | ||
3413 | 1152 | } else if (event->propertyName() == "_q_HTMLTokenizerTimeDelay") { | ||
3414 | 1153 | double timeDelay = q->property("_q_HTMLTokenizerTimeDelay").toDouble(); | ||
3415 | 1154 | q->handle()->page->setCustomHTMLTokenizerTimeDelay(timeDelay); | ||
3416 | 1155 | } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelay") { | ||
3417 | 1156 | double p = q->property("_q_RepaintThrottlingDeferredRepaintDelay").toDouble(); | ||
3418 | 1157 | FrameView::setRepaintThrottlingDeferredRepaintDelay(p); | ||
3419 | 1158 | } else if (event->propertyName() == "_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading") { | ||
3420 | 1159 | double p = q->property("_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading").toDouble(); | ||
3421 | 1160 | FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(p); | ||
3422 | 1161 | } else if (event->propertyName() == "_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading") { | ||
3423 | 1162 | double p = q->property("_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading").toDouble(); | ||
3424 | 1163 | FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(p); | ||
3425 | 1164 | } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading") { | ||
3426 | 1165 | double p = q->property("_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading").toDouble(); | ||
3427 | 1166 | FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(p); | ||
3428 | 1167 | } else if (event->propertyName() == "_q_RepaintThrottlingPreset") { | ||
3429 | 1168 | static const QRepaintThrottlingPreset presets[] = { | ||
3430 | 1169 | { "NoThrottling", 0, 0, 0, 0 }, | ||
3431 | 1170 | { "Legacy", 0.025, 0, 2.5, 0.5 }, | ||
3432 | 1171 | { "Minimal", 0.01, 0, 1, 0.2 }, | ||
3433 | 1172 | { "Medium", 0.025, 1, 5, 0.5 }, | ||
3434 | 1173 | { "Heavy", 0.1, 2, 10, 1 } | ||
3435 | 1174 | }; | ||
3436 | 1175 | |||
3437 | 1176 | QString p = q->property("_q_RepaintThrottlingPreset").toString(); | ||
3438 | 1177 | for (size_t i = 0; i < sizeof(presets) / sizeof(presets[0]); i++) { | ||
3439 | 1178 | if (p == QLatin1String(presets[i].name)) { | ||
3440 | 1179 | FrameView::setRepaintThrottlingDeferredRepaintDelay( | ||
3441 | 1180 | presets[i].deferredRepaintDelay); | ||
3442 | 1181 | FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading( | ||
3443 | 1182 | presets[i].initialDeferredRepaintDelayDuringLoading); | ||
3444 | 1183 | FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading( | ||
3445 | 1184 | presets[i].maxDeferredRepaintDelayDuringLoading); | ||
3446 | 1185 | FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading( | ||
3447 | 1186 | presets[i].deferredRepaintDelayIncrementDuringLoading); | ||
3448 | 1187 | break; | ||
3449 | 1188 | } | ||
3450 | 1189 | } | ||
3451 | 1190 | } | ||
3452 | 1191 | else if (event->propertyName() == "_q_webInspectorServerPort") { | ||
3453 | 1192 | InspectorServerQt* inspectorServer = InspectorServerQt::server(); | ||
3454 | 1193 | inspectorServer->listen(inspectorServerPort()); | ||
3455 | 1194 | } else if (event->propertyName() == "_q_deadDecodedDataDeletionInterval") { | ||
3456 | 1195 | double interval = q->property("_q_deadDecodedDataDeletionInterval").toDouble(); | ||
3457 | 1196 | memoryCache()->setDeadDecodedDataDeletionInterval(interval); | ||
3458 | 1197 | } | ||
3459 | 1198 | } | ||
3460 | 1199 | #endif | ||
3461 | 1200 | |||
3462 | 1201 | void QWebPagePrivate::shortcutOverrideEvent(QKeyEvent* event) | ||
3463 | 1202 | { | ||
3464 | 1203 | WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); | ||
3465 | 1204 | WebCore::Editor* editor = frame->editor(); | ||
3466 | 1205 | if (editor->canEdit()) { | ||
3467 | 1206 | if (event->modifiers() == Qt::NoModifier | ||
3468 | 1207 | || event->modifiers() == Qt::ShiftModifier | ||
3469 | 1208 | || event->modifiers() == Qt::KeypadModifier) { | ||
3470 | 1209 | if (event->key() < Qt::Key_Escape) { | ||
3471 | 1210 | event->accept(); | ||
3472 | 1211 | } else { | ||
3473 | 1212 | switch (event->key()) { | ||
3474 | 1213 | case Qt::Key_Return: | ||
3475 | 1214 | case Qt::Key_Enter: | ||
3476 | 1215 | case Qt::Key_Delete: | ||
3477 | 1216 | case Qt::Key_Home: | ||
3478 | 1217 | case Qt::Key_End: | ||
3479 | 1218 | case Qt::Key_Backspace: | ||
3480 | 1219 | case Qt::Key_Left: | ||
3481 | 1220 | case Qt::Key_Right: | ||
3482 | 1221 | case Qt::Key_Up: | ||
3483 | 1222 | case Qt::Key_Down: | ||
3484 | 1223 | case Qt::Key_Tab: | ||
3485 | 1224 | event->accept(); | ||
3486 | 1225 | default: | ||
3487 | 1226 | break; | ||
3488 | 1227 | } | ||
3489 | 1228 | } | ||
3490 | 1229 | } | ||
3491 | 1230 | #ifndef QT_NO_SHORTCUT | ||
3492 | 1231 | else if (editorActionForKeyEvent(event) != QWebPage::NoWebAction) | ||
3493 | 1232 | event->accept(); | ||
3494 | 1233 | #endif | ||
3495 | 1234 | } | ||
3496 | 1235 | } | ||
3497 | 1236 | |||
3498 | 1237 | bool QWebPagePrivate::handleScrolling(QKeyEvent *ev, Frame *frame) | ||
3499 | 1238 | { | ||
3500 | 1239 | ScrollDirection direction; | ||
3501 | 1240 | ScrollGranularity granularity; | ||
3502 | 1241 | |||
3503 | 1242 | #ifndef QT_NO_SHORTCUT | ||
3504 | 1243 | if (ev == QKeySequence::MoveToNextPage | ||
3505 | 1244 | || (ev->key() == Qt::Key_Space && !(ev->modifiers() & Qt::ShiftModifier))) { | ||
3506 | 1245 | granularity = ScrollByPage; | ||
3507 | 1246 | direction = ScrollDown; | ||
3508 | 1247 | } else if (ev == QKeySequence::MoveToPreviousPage | ||
3509 | 1248 | || ((ev->key() == Qt::Key_Space) && (ev->modifiers() & Qt::ShiftModifier))) { | ||
3510 | 1249 | granularity = ScrollByPage; | ||
3511 | 1250 | direction = ScrollUp; | ||
3512 | 1251 | } else | ||
3513 | 1252 | #endif // QT_NO_SHORTCUT | ||
3514 | 1253 | if ((ev->key() == Qt::Key_Up && ev->modifiers() & Qt::ControlModifier) | ||
3515 | 1254 | || ev->key() == Qt::Key_Home) { | ||
3516 | 1255 | granularity = ScrollByDocument; | ||
3517 | 1256 | direction = ScrollUp; | ||
3518 | 1257 | } else if ((ev->key() == Qt::Key_Down && ev->modifiers() & Qt::ControlModifier) | ||
3519 | 1258 | || ev->key() == Qt::Key_End) { | ||
3520 | 1259 | granularity = ScrollByDocument; | ||
3521 | 1260 | direction = ScrollDown; | ||
3522 | 1261 | } else { | ||
3523 | 1262 | switch (ev->key()) { | ||
3524 | 1263 | case Qt::Key_Up: | ||
3525 | 1264 | granularity = ScrollByLine; | ||
3526 | 1265 | direction = ScrollUp; | ||
3527 | 1266 | break; | ||
3528 | 1267 | case Qt::Key_Down: | ||
3529 | 1268 | granularity = ScrollByLine; | ||
3530 | 1269 | direction = ScrollDown; | ||
3531 | 1270 | break; | ||
3532 | 1271 | case Qt::Key_Left: | ||
3533 | 1272 | granularity = ScrollByLine; | ||
3534 | 1273 | direction = ScrollLeft; | ||
3535 | 1274 | break; | ||
3536 | 1275 | case Qt::Key_Right: | ||
3537 | 1276 | granularity = ScrollByLine; | ||
3538 | 1277 | direction = ScrollRight; | ||
3539 | 1278 | break; | ||
3540 | 1279 | default: | ||
3541 | 1280 | return false; | ||
3542 | 1281 | } | ||
3543 | 1282 | } | ||
3544 | 1283 | |||
3545 | 1284 | return frame->eventHandler()->scrollRecursively(direction, granularity); | ||
3546 | 1285 | } | ||
3547 | 1286 | |||
3548 | 1287 | void QWebPagePrivate::adjustPointForClicking(QMouseEvent*) | ||
3549 | 1288 | { | ||
3550 | 1289 | notImplemented(); | ||
3551 | 1290 | } | ||
3552 | 1291 | |||
3553 | 1292 | #if !defined(QT_NO_GRAPHICSVIEW) | ||
3554 | 1293 | void QWebPagePrivate::adjustPointForClicking(QGraphicsSceneMouseEvent* ev) | ||
3555 | 1294 | { | ||
3556 | 1295 | QtPlatformPlugin platformPlugin; | ||
3557 | 1296 | OwnPtr<QWebTouchModifier> touchModifier = platformPlugin.createTouchModifier(); | ||
3558 | 1297 | if (!touchModifier) | ||
3559 | 1298 | return; | ||
3560 | 1299 | |||
3561 | 1300 | unsigned topPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Up); | ||
3562 | 1301 | unsigned rightPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Right); | ||
3563 | 1302 | unsigned bottomPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Down); | ||
3564 | 1303 | unsigned leftPadding = touchModifier->hitTestPaddingForTouch(QWebTouchModifier::Left); | ||
3565 | 1304 | |||
3566 | 1305 | touchModifier = nullptr; | ||
3567 | 1306 | |||
3568 | 1307 | if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) | ||
3569 | 1308 | return; | ||
3570 | 1309 | |||
3571 | 1310 | Document* startingDocument = page->mainFrame()->document(); | ||
3572 | 1311 | if (!startingDocument) | ||
3573 | 1312 | return; | ||
3574 | 1313 | |||
3575 | 1314 | IntPoint originalPoint(QPointF(ev->pos()).toPoint()); | ||
3576 | 1315 | TouchAdjuster touchAdjuster(topPadding, rightPadding, bottomPadding, leftPadding); | ||
3577 | 1316 | IntPoint adjustedPoint = touchAdjuster.findCandidatePointForTouch(originalPoint, startingDocument); | ||
3578 | 1317 | if (adjustedPoint == IntPoint::zero()) | ||
3579 | 1318 | return; | ||
3580 | 1319 | |||
3581 | 1320 | ev->setPos(QPointF(adjustedPoint)); | ||
3582 | 1321 | } | ||
3583 | 1322 | #endif | ||
3584 | 1323 | |||
3585 | 1324 | bool QWebPagePrivate::touchEvent(QTouchEvent* event) | ||
3586 | 1325 | { | ||
3587 | 1326 | #if ENABLE(TOUCH_EVENTS) | ||
3588 | 1327 | WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data()); | ||
3589 | 1328 | if (!frame->view()) | ||
3590 | 1329 | return false; | ||
3591 | 1330 | |||
3592 | 1331 | // Always accept the QTouchEvent so that we'll receive also TouchUpdate and TouchEnd events | ||
3593 | 1332 | event->setAccepted(true); | ||
3594 | 1333 | |||
3595 | 1334 | // Return whether the default action was cancelled in the JS event handler | ||
3596 | 1335 | return frame->eventHandler()->handleTouchEvent(convertTouchEvent(event)); | ||
3597 | 1336 | #else | ||
3598 | 1337 | event->ignore(); | ||
3599 | 1338 | return false; | ||
3600 | 1339 | #endif | ||
3601 | 1340 | } | ||
3602 | 1341 | |||
3603 | 1342 | bool QWebPagePrivate::gestureEvent(QGestureEvent* event) | ||
3604 | 1343 | { | ||
3605 | 1344 | #if ENABLE(GESTURE_EVENTS) | ||
3606 | 1345 | WebCore::Frame* frame = QWebFramePrivate::core(mainFrame.data()); | ||
3607 | 1346 | if (!frame->view()) | ||
3608 | 1347 | return false; | ||
3609 | 1348 | |||
3610 | 1349 | // QGestureEvents can contain updates for multiple gestures. | ||
3611 | 1350 | bool handled = false; | ||
3612 | 1351 | QGesture* gesture = event->gesture(Qt::TapGesture); | ||
3613 | 1352 | // Beware that gestures send by DumpRenderTree will have state Qt::NoGesture, | ||
3614 | 1353 | // due to not originating from a GestureRecognizer. | ||
3615 | 1354 | if (gesture && (gesture->state() == Qt::GestureStarted || gesture->state() == Qt::NoGesture)) { | ||
3616 | 1355 | frame->eventHandler()->handleGestureEvent(convertGesture(event, gesture)); | ||
3617 | 1356 | event->setAccepted(true); | ||
3618 | 1357 | handled = true; | ||
3619 | 1358 | } | ||
3620 | 1359 | gesture = event->gesture(Qt::TapAndHoldGesture); | ||
3621 | 1360 | if (gesture && (gesture->state() == Qt::GestureStarted || gesture->state() == Qt::NoGesture)) { | ||
3622 | 1361 | frame->eventHandler()->sendContextMenuEventForGesture(convertGesture(event, gesture)); | ||
3623 | 1362 | event->setAccepted(true); | ||
3624 | 1363 | handled = true; | ||
3625 | 1364 | } | ||
3626 | 1365 | |||
3627 | 1366 | return handled; | ||
3628 | 1367 | #else | ||
3629 | 1368 | event->ignore(); | ||
3630 | 1369 | return false; | ||
3631 | 1370 | #endif | ||
3632 | 1371 | } | ||
3633 | 1372 | |||
3634 | 1373 | /*! | ||
3635 | 1374 | This method is used by the input method to query a set of properties of the page | ||
3636 | 1375 | to be able to support complex input method operations as support for surrounding | ||
3637 | 1376 | text and reconversions. | ||
3638 | 1377 | |||
3639 | 1378 | \a property specifies which property is queried. | ||
3640 | 1379 | |||
3641 | 1380 | \sa QWidget::inputMethodEvent(), QInputMethodEvent, QInputContext | ||
3642 | 1381 | */ | ||
3643 | 1382 | QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const | ||
3644 | 1383 | { | ||
3645 | 1384 | Frame* frame = d->page->focusController()->focusedFrame(); | ||
3646 | 1385 | if (!frame) | ||
3647 | 1386 | return QVariant(); | ||
3648 | 1387 | |||
3649 | 1388 | WebCore::Editor* editor = frame->editor(); | ||
3650 | 1389 | |||
3651 | 1390 | RenderObject* renderer = 0; | ||
3652 | 1391 | RenderTextControl* renderTextControl = 0; | ||
3653 | 1392 | |||
3654 | 1393 | if (frame->selection()->rootEditableElement()) | ||
3655 | 1394 | renderer = frame->selection()->rootEditableElement()->shadowAncestorNode()->renderer(); | ||
3656 | 1395 | |||
3657 | 1396 | if (renderer && renderer->isTextControl()) | ||
3658 | 1397 | renderTextControl = toRenderTextControl(renderer); | ||
3659 | 1398 | |||
3660 | 1399 | switch (property) { | ||
3661 | 1400 | case Qt::ImMicroFocus: { | ||
3662 | 1401 | WebCore::FrameView* view = frame->view(); | ||
3663 | 1402 | if (view && view->needsLayout()) { | ||
3664 | 1403 | // We can't access absoluteCaretBounds() while the view needs to layout. | ||
3665 | 1404 | return QVariant(); | ||
3666 | 1405 | } | ||
3667 | 1406 | return QVariant(view->contentsToWindow(frame->selection()->absoluteCaretBounds())); | ||
3668 | 1407 | } | ||
3669 | 1408 | case Qt::ImFont: { | ||
3670 | 1409 | if (renderTextControl) { | ||
3671 | 1410 | RenderStyle* renderStyle = renderTextControl->style(); | ||
3672 | 1411 | return QVariant(QFont(renderStyle->font().syntheticFont())); | ||
3673 | 1412 | } | ||
3674 | 1413 | return QVariant(QFont()); | ||
3675 | 1414 | } | ||
3676 | 1415 | case Qt::ImCursorPosition: { | ||
3677 | 1416 | if (editor->hasComposition()) | ||
3678 | 1417 | return QVariant(frame->selection()->end().offsetInContainerNode()); | ||
3679 | 1418 | return QVariant(frame->selection()->extent().offsetInContainerNode()); | ||
3680 | 1419 | } | ||
3681 | 1420 | case Qt::ImSurroundingText: { | ||
3682 | 1421 | if (renderTextControl && renderTextControl->textFormControlElement()) { | ||
3683 | 1422 | QString text = renderTextControl->textFormControlElement()->value(); | ||
3684 | 1423 | RefPtr<Range> range = editor->compositionRange(); | ||
3685 | 1424 | if (range) | ||
3686 | 1425 | text.remove(range->startPosition().offsetInContainerNode(), TextIterator::rangeLength(range.get())); | ||
3687 | 1426 | return QVariant(text); | ||
3688 | 1427 | } | ||
3689 | 1428 | return QVariant(); | ||
3690 | 1429 | } | ||
3691 | 1430 | case Qt::ImCurrentSelection: { | ||
3692 | 1431 | if (!editor->hasComposition() && renderTextControl && renderTextControl->textFormControlElement()) { | ||
3693 | 1432 | int start = frame->selection()->start().offsetInContainerNode(); | ||
3694 | 1433 | int end = frame->selection()->end().offsetInContainerNode(); | ||
3695 | 1434 | if (end > start) | ||
3696 | 1435 | return QVariant(QString(renderTextControl->textFormControlElement()->value()).mid(start, end - start)); | ||
3697 | 1436 | } | ||
3698 | 1437 | return QVariant(); | ||
3699 | 1438 | |||
3700 | 1439 | } | ||
3701 | 1440 | case Qt::ImAnchorPosition: { | ||
3702 | 1441 | if (editor->hasComposition()) | ||
3703 | 1442 | return QVariant(frame->selection()->start().offsetInContainerNode()); | ||
3704 | 1443 | return QVariant(frame->selection()->base().offsetInContainerNode()); | ||
3705 | 1444 | } | ||
3706 | 1445 | case Qt::ImMaximumTextLength: { | ||
3707 | 1446 | if (frame->selection()->isContentEditable()) { | ||
3708 | 1447 | if (frame->document() && frame->document()->focusedNode()) { | ||
3709 | 1448 | if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) { | ||
3710 | 1449 | HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode()); | ||
3711 | 1450 | return QVariant(inputElement->maxLength()); | ||
3712 | 1451 | } | ||
3713 | 1452 | } | ||
3714 | 1453 | return QVariant(HTMLInputElement::maximumLength); | ||
3715 | 1454 | } | ||
3716 | 1455 | return QVariant(0); | ||
3717 | 1456 | } | ||
3718 | 1457 | default: | ||
3719 | 1458 | return QVariant(); | ||
3720 | 1459 | } | ||
3721 | 1460 | } | ||
3722 | 1461 | |||
3723 | 1462 | /*! | ||
3724 | 1463 | \internal | ||
3725 | 1464 | */ | ||
3726 | 1465 | void QWebPagePrivate::setInspector(QWebInspector* insp) | ||
3727 | 1466 | { | ||
3728 | 1467 | if (inspector) | ||
3729 | 1468 | inspector->d->setFrontend(0); | ||
3730 | 1469 | |||
3731 | 1470 | inspector = insp; | ||
3732 | 1471 | |||
3733 | 1472 | // Give inspector frontend web view if previously created | ||
3734 | 1473 | if (inspector && inspectorFrontend) | ||
3735 | 1474 | inspector->d->setFrontend(inspectorFrontend); | ||
3736 | 1475 | } | ||
3737 | 1476 | |||
3738 | 1477 | /*! | ||
3739 | 1478 | \internal | ||
3740 | 1479 | Returns the inspector and creates it if it wasn't created yet. | ||
3741 | 1480 | The instance created here will not be available through QWebPage's API. | ||
3742 | 1481 | */ | ||
3743 | 1482 | QWebInspector* QWebPagePrivate::getOrCreateInspector() | ||
3744 | 1483 | { | ||
3745 | 1484 | #if ENABLE(INSPECTOR) | ||
3746 | 1485 | if (!inspector) { | ||
3747 | 1486 | QWebInspector* insp = new QWebInspector; | ||
3748 | 1487 | insp->setPage(q); | ||
3749 | 1488 | inspectorIsInternalOnly = true; | ||
3750 | 1489 | |||
3751 | 1490 | Q_ASSERT(inspector); // Associated through QWebInspector::setPage(q) | ||
3752 | 1491 | } | ||
3753 | 1492 | #endif | ||
3754 | 1493 | return inspector; | ||
3755 | 1494 | } | ||
3756 | 1495 | |||
3757 | 1496 | /*! \internal */ | ||
3758 | 1497 | InspectorController* QWebPagePrivate::inspectorController() | ||
3759 | 1498 | { | ||
3760 | 1499 | #if ENABLE(INSPECTOR) | ||
3761 | 1500 | return page->inspectorController(); | ||
3762 | 1501 | #else | ||
3763 | 1502 | return 0; | ||
3764 | 1503 | #endif | ||
3765 | 1504 | } | ||
3766 | 1505 | |||
3767 | 1506 | quint16 QWebPagePrivate::inspectorServerPort() | ||
3768 | 1507 | { | ||
3769 | 1508 | #if ENABLE(INSPECTOR) && !defined(QT_NO_PROPERTIES) | ||
3770 | 1509 | if (q && q->property("_q_webInspectorServerPort").isValid()) | ||
3771 | 1510 | return q->property("_q_webInspectorServerPort").toInt(); | ||
3772 | 1511 | #endif | ||
3773 | 1512 | return 0; | ||
3774 | 1513 | } | ||
3775 | 1514 | |||
3776 | 1515 | static bool hasMouseListener(Element* element) | ||
3777 | 1516 | { | ||
3778 | 1517 | ASSERT(element); | ||
3779 | 1518 | return element->hasEventListeners(eventNames().clickEvent) | ||
3780 | 1519 | || element->hasEventListeners(eventNames().mousedownEvent) | ||
3781 | 1520 | || element->hasEventListeners(eventNames().mouseupEvent); | ||
3782 | 1521 | } | ||
3783 | 1522 | |||
3784 | 1523 | static bool isClickableElement(Element* element, RefPtr<NodeList> list) | ||
3785 | 1524 | { | ||
3786 | 1525 | ASSERT(element); | ||
3787 | 1526 | bool isClickable = hasMouseListener(element); | ||
3788 | 1527 | if (!isClickable && list) { | ||
3789 | 1528 | Element* parent = element->parentElement(); | ||
3790 | 1529 | unsigned count = list->length(); | ||
3791 | 1530 | for (unsigned i = 0; i < count && parent; i++) { | ||
3792 | 1531 | if (list->item(i) != parent) | ||
3793 | 1532 | continue; | ||
3794 | 1533 | |||
3795 | 1534 | isClickable = hasMouseListener(parent); | ||
3796 | 1535 | if (isClickable) | ||
3797 | 1536 | break; | ||
3798 | 1537 | |||
3799 | 1538 | parent = parent->parentElement(); | ||
3800 | 1539 | } | ||
3801 | 1540 | } | ||
3802 | 1541 | |||
3803 | 1542 | ExceptionCode ec = 0; | ||
3804 | 1543 | return isClickable | ||
3805 | 1544 | || element->webkitMatchesSelector("a,*:link,*:visited,*[role=button],button,input,select,label", ec) | ||
3806 | 1545 | || CSSComputedStyleDeclaration::create(element)->getPropertyValue(cssPropertyID("cursor")) == "pointer"; | ||
3807 | 1546 | } | ||
3808 | 1547 | |||
3809 | 1548 | static bool isValidFrameOwner(Element* element) | ||
3810 | 1549 | { | ||
3811 | 1550 | ASSERT(element); | ||
3812 | 1551 | return element->isFrameOwnerElement() && static_cast<HTMLFrameOwnerElement*>(element)->contentFrame(); | ||
3813 | 1552 | } | ||
3814 | 1553 | |||
3815 | 1554 | static Element* nodeToElement(Node* node) | ||
3816 | 1555 | { | ||
3817 | 1556 | if (node && node->isElementNode()) | ||
3818 | 1557 | return static_cast<Element*>(node); | ||
3819 | 1558 | return 0; | ||
3820 | 1559 | } | ||
3821 | 1560 | |||
3822 | 1561 | QWebPagePrivate::TouchAdjuster::TouchAdjuster(unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding) | ||
3823 | 1562 | : m_topPadding(topPadding) | ||
3824 | 1563 | , m_rightPadding(rightPadding) | ||
3825 | 1564 | , m_bottomPadding(bottomPadding) | ||
3826 | 1565 | , m_leftPadding(leftPadding) | ||
3827 | 1566 | { | ||
3828 | 1567 | } | ||
3829 | 1568 | |||
3830 | 1569 | IntPoint QWebPagePrivate::TouchAdjuster::findCandidatePointForTouch(const IntPoint& touchPoint, Document* document) const | ||
3831 | 1570 | { | ||
3832 | 1571 | if (!document) | ||
3833 | 1572 | return IntPoint(); | ||
3834 | 1573 | |||
3835 | 1574 | int x = touchPoint.x(); | ||
3836 | 1575 | int y = touchPoint.y(); | ||
3837 | 1576 | |||
3838 | 1577 | RefPtr<NodeList> intersectedNodes = document->nodesFromRect(x, y, m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding, false /*ignoreClipping*/, false /*allowShadowContent*/); | ||
3839 | 1578 | if (!intersectedNodes) | ||
3840 | 1579 | return IntPoint(); | ||
3841 | 1580 | |||
3842 | 1581 | Element* closestClickableElement = 0; | ||
3843 | 1582 | IntRect largestIntersectionRect; | ||
3844 | 1583 | FrameView* view = document->frame()->view(); | ||
3845 | 1584 | |||
3846 | 1585 | // Touch rect in contents coordinates. | ||
3847 | 1586 | IntRect touchRect(HitTestLocation::rectForPoint(view->windowToContents(IntPoint(x, y)), m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding)); | ||
3848 | 1587 | |||
3849 | 1588 | // Iterate over the list of nodes hit looking for the one whose bounding area | ||
3850 | 1589 | // has largest intersection with the touch area (point + padding). | ||
3851 | 1590 | for (unsigned i = 0; i < intersectedNodes->length(); i++) { | ||
3852 | 1591 | Node* currentNode = intersectedNodes->item(i); | ||
3853 | 1592 | |||
3854 | 1593 | Element* currentElement = nodeToElement(currentNode); | ||
3855 | 1594 | if (!currentElement || (!isClickableElement(currentElement, 0) && !isValidFrameOwner(currentElement))) | ||
3856 | 1595 | continue; | ||
3857 | 1596 | |||
3858 | 1597 | IntRect currentElementBoundingRect = currentElement->pixelSnappedBoundingBox(); | ||
3859 | 1598 | currentElementBoundingRect.intersect(touchRect); | ||
3860 | 1599 | |||
3861 | 1600 | if (currentElementBoundingRect.isEmpty()) | ||
3862 | 1601 | continue; | ||
3863 | 1602 | |||
3864 | 1603 | int currentIntersectionRectArea = currentElementBoundingRect.width() * currentElementBoundingRect.height(); | ||
3865 | 1604 | int largestIntersectionRectArea = largestIntersectionRect.width() * largestIntersectionRect.height(); | ||
3866 | 1605 | if (currentIntersectionRectArea > largestIntersectionRectArea) { | ||
3867 | 1606 | closestClickableElement = currentElement; | ||
3868 | 1607 | largestIntersectionRect = currentElementBoundingRect; | ||
3869 | 1608 | } | ||
3870 | 1609 | } | ||
3871 | 1610 | |||
3872 | 1611 | if (largestIntersectionRect.isEmpty()) | ||
3873 | 1612 | return IntPoint(); | ||
3874 | 1613 | |||
3875 | 1614 | // Handle the case when user taps a inner frame. It is done in three steps: | ||
3876 | 1615 | // 1) Transform the original touch point to the inner document coordinates; | ||
3877 | 1616 | // 1) Call nodesFromRect for the inner document in case; | ||
3878 | 1617 | // 3) Re-add the inner frame offset (location) before passing the new clicking | ||
3879 | 1618 | // position to WebCore. | ||
3880 | 1619 | if (closestClickableElement->isFrameOwnerElement()) { | ||
3881 | 1620 | // Adjust client coordinates' origin to be top left of inner frame viewport. | ||
3882 | 1621 | PassRefPtr<ClientRect> rect = closestClickableElement->getBoundingClientRect(); | ||
3883 | 1622 | IntPoint newTouchPoint = touchPoint; | ||
3884 | 1623 | IntSize offset = IntSize(rect->left(), rect->top()); | ||
3885 | 1624 | newTouchPoint -= offset; | ||
3886 | 1625 | |||
3887 | 1626 | HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(closestClickableElement); | ||
3888 | 1627 | Document* childDocument = owner->contentFrame()->document(); | ||
3889 | 1628 | return findCandidatePointForTouch(newTouchPoint, childDocument); | ||
3890 | 1629 | } | ||
3891 | 1630 | return view->contentsToWindow(largestIntersectionRect).center(); | ||
3892 | 1631 | } | ||
3893 | 1632 | |||
3894 | 1633 | /*! | ||
3895 | 1634 | \enum QWebPage::FindFlag | ||
3896 | 1635 | |||
3897 | 1636 | This enum describes the options available to the findText() function. The options | ||
3898 | 1637 | can be OR-ed together from the following list: | ||
3899 | 1638 | |||
3900 | 1639 | \value FindBackward Searches backwards instead of forwards. | ||
3901 | 1640 | \value FindCaseSensitively By default findText() works case insensitive. Specifying this option | ||
3902 | 1641 | changes the behaviour to a case sensitive find operation. | ||
3903 | 1642 | \value FindWrapsAroundDocument Makes findText() restart from the beginning of the document if the end | ||
3904 | 1643 | was reached and the text was not found. | ||
3905 | 1644 | \value HighlightAllOccurrences Highlights all existing occurrences of a specific string. | ||
3906 | 1645 | (This value was introduced in 4.6.) | ||
3907 | 1646 | */ | ||
3908 | 1647 | |||
3909 | 1648 | /*! | ||
3910 | 1649 | \enum QWebPage::LinkDelegationPolicy | ||
3911 | 1650 | |||
3912 | 1651 | This enum defines the delegation policies a webpage can have when activating links and emitting | ||
3913 | 1652 | the linkClicked() signal. | ||
3914 | 1653 | |||
3915 | 1654 | \value DontDelegateLinks No links are delegated. Instead, QWebPage tries to handle them all. | ||
3916 | 1655 | \value DelegateExternalLinks When activating links that point to documents not stored on the | ||
3917 | 1656 | local filesystem or an equivalent - such as the Qt resource system - then linkClicked() is emitted. | ||
3918 | 1657 | \value DelegateAllLinks Whenever a link is activated the linkClicked() signal is emitted. | ||
3919 | 1658 | |||
3920 | 1659 | \sa QWebPage::linkDelegationPolicy | ||
3921 | 1660 | */ | ||
3922 | 1661 | |||
3923 | 1662 | /*! | ||
3924 | 1663 | \enum QWebPage::NavigationType | ||
3925 | 1664 | |||
3926 | 1665 | This enum describes the types of navigation available when browsing through hyperlinked | ||
3927 | 1666 | documents. | ||
3928 | 1667 | |||
3929 | 1668 | \value NavigationTypeLinkClicked The user clicked on a link or pressed return on a focused link. | ||
3930 | 1669 | \value NavigationTypeFormSubmitted The user activated a submit button for an HTML form. | ||
3931 | 1670 | \value NavigationTypeBackOrForward Navigation to a previously shown document in the back or forward history is requested. | ||
3932 | 1671 | \value NavigationTypeReload The user activated the reload action. | ||
3933 | 1672 | \value NavigationTypeFormResubmitted An HTML form was submitted a second time. | ||
3934 | 1673 | \value NavigationTypeOther A navigation to another document using a method not listed above. | ||
3935 | 1674 | |||
3936 | 1675 | \sa acceptNavigationRequest() | ||
3937 | 1676 | */ | ||
3938 | 1677 | |||
3939 | 1678 | /*! | ||
3940 | 1679 | \enum QWebPage::WebAction | ||
3941 | 1680 | |||
3942 | 1681 | This enum describes the types of action which can be performed on the web page. | ||
3943 | 1682 | |||
3944 | 1683 | Actions only have an effect when they are applicable. The availability of | ||
3945 | 1684 | actions can be be determined by checking \l{QAction::}{isEnabled()} on the | ||
3946 | 1685 | action returned by action(). | ||
3947 | 1686 | |||
3948 | 1687 | One method of enabling the text editing, cursor movement, and text selection actions | ||
3949 | 1688 | is by setting \l contentEditable to true. | ||
3950 | 1689 | |||
3951 | 1690 | \value NoWebAction No action is triggered. | ||
3952 | 1691 | \value OpenLink Open the current link. | ||
3953 | 1692 | \value OpenLinkInNewWindow Open the current link in a new window. | ||
3954 | 1693 | \value OpenLinkInThisWindow Open the current link without opening a new window. Used on links that would default to opening in another frame or a new window. (Added in Qt 5.0) | ||
3955 | 1694 | \value OpenFrameInNewWindow Replicate the current frame in a new window. | ||
3956 | 1695 | \value DownloadLinkToDisk Download the current link to the disk. | ||
3957 | 1696 | \value CopyLinkToClipboard Copy the current link to the clipboard. | ||
3958 | 1697 | \value OpenImageInNewWindow Open the highlighted image in a new window. | ||
3959 | 1698 | \value DownloadImageToDisk Download the highlighted image to the disk. | ||
3960 | 1699 | \value CopyImageToClipboard Copy the highlighted image to the clipboard. (Added in Qt 4.8) | ||
3961 | 1700 | \value CopyImageUrlToClipboard Copy the highlighted image's URL to the clipboard. | ||
3962 | 1701 | \value Back Navigate back in the history of navigated links. | ||
3963 | 1702 | \value Forward Navigate forward in the history of navigated links. | ||
3964 | 1703 | \value Stop Stop loading the current page. | ||
3965 | 1704 | \value StopScheduledPageRefresh Stop all pending page refresh/redirect requests. (Added in Qt 4.7) | ||
3966 | 1705 | \value Reload Reload the current page. | ||
3967 | 1706 | \value ReloadAndBypassCache Reload the current page, but do not use any local cache. (Added in Qt 4.6) | ||
3968 | 1707 | \value Cut Cut the content currently selected into the clipboard. | ||
3969 | 1708 | \value Copy Copy the content currently selected into the clipboard. | ||
3970 | 1709 | \value Paste Paste content from the clipboard. | ||
3971 | 1710 | \value Undo Undo the last editing action. | ||
3972 | 1711 | \value Redo Redo the last editing action. | ||
3973 | 1712 | \value MoveToNextChar Move the cursor to the next character. | ||
3974 | 1713 | \value MoveToPreviousChar Move the cursor to the previous character. | ||
3975 | 1714 | \value MoveToNextWord Move the cursor to the next word. | ||
3976 | 1715 | \value MoveToPreviousWord Move the cursor to the previous word. | ||
3977 | 1716 | \value MoveToNextLine Move the cursor to the next line. | ||
3978 | 1717 | \value MoveToPreviousLine Move the cursor to the previous line. | ||
3979 | 1718 | \value MoveToStartOfLine Move the cursor to the start of the line. | ||
3980 | 1719 | \value MoveToEndOfLine Move the cursor to the end of the line. | ||
3981 | 1720 | \value MoveToStartOfBlock Move the cursor to the start of the block. | ||
3982 | 1721 | \value MoveToEndOfBlock Move the cursor to the end of the block. | ||
3983 | 1722 | \value MoveToStartOfDocument Move the cursor to the start of the document. | ||
3984 | 1723 | \value MoveToEndOfDocument Move the cursor to the end of the document. | ||
3985 | 1724 | \value SelectNextChar Select to the next character. | ||
3986 | 1725 | \value SelectPreviousChar Select to the previous character. | ||
3987 | 1726 | \value SelectNextWord Select to the next word. | ||
3988 | 1727 | \value SelectPreviousWord Select to the previous word. | ||
3989 | 1728 | \value SelectNextLine Select to the next line. | ||
3990 | 1729 | \value SelectPreviousLine Select to the previous line. | ||
3991 | 1730 | \value SelectStartOfLine Select to the start of the line. | ||
3992 | 1731 | \value SelectEndOfLine Select to the end of the line. | ||
3993 | 1732 | \value SelectStartOfBlock Select to the start of the block. | ||
3994 | 1733 | \value SelectEndOfBlock Select to the end of the block. | ||
3995 | 1734 | \value SelectStartOfDocument Select to the start of the document. | ||
3996 | 1735 | \value SelectEndOfDocument Select to the end of the document. | ||
3997 | 1736 | \value DeleteStartOfWord Delete to the start of the word. | ||
3998 | 1737 | \value DeleteEndOfWord Delete to the end of the word. | ||
3999 | 1738 | \value SetTextDirectionDefault Set the text direction to the default direction. | ||
4000 | 1739 | \value SetTextDirectionLeftToRight Set the text direction to left-to-right. | ||
4001 | 1740 | \value SetTextDirectionRightToLeft Set the text direction to right-to-left. | ||
4002 | 1741 | \value ToggleBold Toggle the formatting between bold and normal weight. | ||
4003 | 1742 | \value ToggleItalic Toggle the formatting between italic and normal style. | ||
4004 | 1743 | \value ToggleUnderline Toggle underlining. | ||
4005 | 1744 | \value InspectElement Show the Web Inspector with the currently highlighted HTML element. | ||
4006 | 1745 | \value InsertParagraphSeparator Insert a new paragraph. | ||
4007 | 1746 | \value InsertLineSeparator Insert a new line. | ||
4008 | 1747 | \value SelectAll Selects all content. | ||
4009 | 1748 | \value PasteAndMatchStyle Paste content from the clipboard with current style. (Added in Qt 4.6) | ||
4010 | 1749 | \value RemoveFormat Removes formatting and style. (Added in Qt 4.6) | ||
4011 | 1750 | \value ToggleStrikethrough Toggle the formatting between strikethrough and normal style. (Added in Qt 4.6) | ||
4012 | 1751 | \value ToggleSubscript Toggle the formatting between subscript and baseline. (Added in Qt 4.6) | ||
4013 | 1752 | \value ToggleSuperscript Toggle the formatting between supercript and baseline. (Added in Qt 4.6) | ||
4014 | 1753 | \value InsertUnorderedList Toggles the selection between an ordered list and a normal block. (Added in Qt 4.6) | ||
4015 | 1754 | \value InsertOrderedList Toggles the selection between an ordered list and a normal block. (Added in Qt 4.6) | ||
4016 | 1755 | \value Indent Increases the indentation of the currently selected format block by one increment. (Added in Qt 4.6) | ||
4017 | 1756 | \value Outdent Decreases the indentation of the currently selected format block by one increment. (Added in Qt 4.6) | ||
4018 | 1757 | \value AlignCenter Applies center alignment to content. (Added in Qt 4.6) | ||
4019 | 1758 | \value AlignJustified Applies full justification to content. (Added in Qt 4.6) | ||
4020 | 1759 | \value AlignLeft Applies left justification to content. (Added in Qt 4.6) | ||
4021 | 1760 | \value AlignRight Applies right justification to content. (Added in Qt 4.6) | ||
4022 | 1761 | |||
4023 | 1762 | |||
4024 | 1763 | \omitvalue WebActionCount | ||
4025 | 1764 | |||
4026 | 1765 | */ | ||
4027 | 1766 | |||
4028 | 1767 | /*! | ||
4029 | 1768 | \enum QWebPage::WebWindowType | ||
4030 | 1769 | |||
4031 | 1770 | This enum describes the types of window that can be created by the createWindow() function. | ||
4032 | 1771 | |||
4033 | 1772 | \value WebBrowserWindow The window is a regular web browser window. | ||
4034 | 1773 | \value WebModalDialog The window acts as modal dialog. | ||
4035 | 1774 | */ | ||
4036 | 1775 | |||
4037 | 1776 | |||
4038 | 1777 | /*! | ||
4039 | 1778 | \class QWebPage::ViewportAttributes | ||
4040 | 1779 | \since 4.7 | ||
4041 | 1780 | \brief The QWebPage::ViewportAttributes class describes hints that can be applied to a viewport. | ||
4042 | 1781 | |||
4043 | 1782 | QWebPage::ViewportAttributes provides a description of a viewport, such as viewport geometry, | ||
4044 | 1783 | initial scale factor with limits, plus information about whether a user should be able | ||
4045 | 1784 | to scale the contents in the viewport or not, ie. by zooming. | ||
4046 | 1785 | |||
4047 | 1786 | ViewportAttributes can be set by a web author using the viewport meta tag extension, documented | ||
4048 | 1787 | at \l{http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html}{Safari Reference Library: Using the Viewport Meta Tag}. | ||
4049 | 1788 | |||
4050 | 1789 | All values might not be set, as such when dealing with the hints, the developer needs to | ||
4051 | 1790 | check whether the values are valid. Negative values denote an invalid qreal value. | ||
4052 | 1791 | |||
4053 | 1792 | \inmodule QtWebKit | ||
4054 | 1793 | */ | ||
4055 | 1794 | |||
4056 | 1795 | /*! | ||
4057 | 1796 | Constructs an empty QWebPage::ViewportAttributes. | ||
4058 | 1797 | */ | ||
4059 | 1798 | QWebPage::ViewportAttributes::ViewportAttributes() | ||
4060 | 1799 | : d(0) | ||
4061 | 1800 | , m_initialScaleFactor(-1.0) | ||
4062 | 1801 | , m_minimumScaleFactor(-1.0) | ||
4063 | 1802 | , m_maximumScaleFactor(-1.0) | ||
4064 | 1803 | , m_devicePixelRatio(-1.0) | ||
4065 | 1804 | , m_isUserScalable(true) | ||
4066 | 1805 | , m_isValid(false) | ||
4067 | 1806 | { | ||
4068 | 1807 | |||
4069 | 1808 | } | ||
4070 | 1809 | |||
4071 | 1810 | /*! | ||
4072 | 1811 | Constructs a QWebPage::ViewportAttributes which is a copy from \a other . | ||
4073 | 1812 | */ | ||
4074 | 1813 | QWebPage::ViewportAttributes::ViewportAttributes(const QWebPage::ViewportAttributes& other) | ||
4075 | 1814 | : d(other.d) | ||
4076 | 1815 | , m_initialScaleFactor(other.m_initialScaleFactor) | ||
4077 | 1816 | , m_minimumScaleFactor(other.m_minimumScaleFactor) | ||
4078 | 1817 | , m_maximumScaleFactor(other.m_maximumScaleFactor) | ||
4079 | 1818 | , m_devicePixelRatio(other.m_devicePixelRatio) | ||
4080 | 1819 | , m_isUserScalable(other.m_isUserScalable) | ||
4081 | 1820 | , m_isValid(other.m_isValid) | ||
4082 | 1821 | , m_size(other.m_size) | ||
4083 | 1822 | { | ||
4084 | 1823 | |||
4085 | 1824 | } | ||
4086 | 1825 | |||
4087 | 1826 | /*! | ||
4088 | 1827 | Destroys the QWebPage::ViewportAttributes. | ||
4089 | 1828 | */ | ||
4090 | 1829 | QWebPage::ViewportAttributes::~ViewportAttributes() | ||
4091 | 1830 | { | ||
4092 | 1831 | |||
4093 | 1832 | } | ||
4094 | 1833 | |||
4095 | 1834 | /*! | ||
4096 | 1835 | Assigns the given QWebPage::ViewportAttributes to this viewport hints and returns a | ||
4097 | 1836 | reference to this. | ||
4098 | 1837 | */ | ||
4099 | 1838 | QWebPage::ViewportAttributes& QWebPage::ViewportAttributes::operator=(const QWebPage::ViewportAttributes& other) | ||
4100 | 1839 | { | ||
4101 | 1840 | if (this != &other) { | ||
4102 | 1841 | d = other.d; | ||
4103 | 1842 | m_initialScaleFactor = other.m_initialScaleFactor; | ||
4104 | 1843 | m_minimumScaleFactor = other.m_minimumScaleFactor; | ||
4105 | 1844 | m_maximumScaleFactor = other.m_maximumScaleFactor; | ||
4106 | 1845 | m_isUserScalable = other.m_isUserScalable; | ||
4107 | 1846 | m_isValid = other.m_isValid; | ||
4108 | 1847 | m_size = other.m_size; | ||
4109 | 1848 | } | ||
4110 | 1849 | |||
4111 | 1850 | return *this; | ||
4112 | 1851 | } | ||
4113 | 1852 | |||
4114 | 1853 | /*! \fn inline bool QWebPage::ViewportAttributes::isValid() const | ||
4115 | 1854 | Returns whether this is a valid ViewportAttributes or not. | ||
4116 | 1855 | |||
4117 | 1856 | An invalid ViewportAttributes will have an empty QSize, negative values for scale factors and | ||
4118 | 1857 | true for the boolean isUserScalable. | ||
4119 | 1858 | */ | ||
4120 | 1859 | |||
4121 | 1860 | /*! \fn inline QSize QWebPage::ViewportAttributes::size() const | ||
4122 | 1861 | Returns the size of the viewport. | ||
4123 | 1862 | */ | ||
4124 | 1863 | |||
4125 | 1864 | /*! \fn inline qreal QWebPage::ViewportAttributes::initialScaleFactor() const | ||
4126 | 1865 | Returns the initial scale of the viewport as a multiplier. | ||
4127 | 1866 | */ | ||
4128 | 1867 | |||
4129 | 1868 | /*! \fn inline qreal QWebPage::ViewportAttributes::minimumScaleFactor() const | ||
4130 | 1869 | Returns the minimum scale value of the viewport as a multiplier. | ||
4131 | 1870 | */ | ||
4132 | 1871 | |||
4133 | 1872 | /*! \fn inline qreal QWebPage::ViewportAttributes::maximumScaleFactor() const | ||
4134 | 1873 | Returns the maximum scale value of the viewport as a multiplier. | ||
4135 | 1874 | */ | ||
4136 | 1875 | |||
4137 | 1876 | /*! \fn inline bool QWebPage::ViewportAttributes::isUserScalable() const | ||
4138 | 1877 | Determines whether or not the scale can be modified by the user. | ||
4139 | 1878 | */ | ||
4140 | 1879 | |||
4141 | 1880 | |||
4142 | 1881 | /*! | ||
4143 | 1882 | \class QWebPage | ||
4144 | 1883 | \since 4.4 | ||
4145 | 1884 | \brief The QWebPage class provides an object to view and edit web documents. | ||
4146 | 1885 | |||
4147 | 1886 | \inmodule QtWebKit | ||
4148 | 1887 | |||
4149 | 1888 | QWebPage holds a main frame responsible for web content, settings, the history | ||
4150 | 1889 | of navigated links and actions. This class can be used, together with QWebFrame, | ||
4151 | 1890 | to provide functionality like QWebView in a widget-less environment. | ||
4152 | 1891 | |||
4153 | 1892 | QWebPage's API is very similar to QWebView, as you are still provided with | ||
4154 | 1893 | common functions like action() (known as | ||
4155 | 1894 | \l{QWebView::pageAction()}{pageAction}() in QWebView), triggerAction(), | ||
4156 | 1895 | findText() and settings(). More QWebView-like functions can be found in the | ||
4157 | 1896 | main frame of QWebPage, obtained via the mainFrame() function. For example, | ||
4158 | 1897 | the \l{QWebFrame::load()}{load}(), \l{QWebFrame::setUrl()}{setUrl}() and | ||
4159 | 1898 | \l{QWebFrame::setHtml()}{setHtml}() functions for QWebPage can be accessed | ||
4160 | 1899 | using QWebFrame. | ||
4161 | 1900 | |||
4162 | 1901 | The loadStarted() signal is emitted when the page begins to load.The | ||
4163 | 1902 | loadProgress() signal, on the other hand, is emitted whenever an element | ||
4164 | 1903 | of the web page completes loading, such as an embedded image, a script, | ||
4165 | 1904 | etc. Finally, the loadFinished() signal is emitted when the page contents | ||
4166 | 1905 | are loaded completely, independent of script execution or page rendering. | ||
4167 | 1906 | Its argument, either true or false, indicates whether or not the load | ||
4168 | 1907 | operation succeeded. | ||
4169 | 1908 | |||
4170 | 1909 | \section1 Using QWebPage in a Widget-less Environment | ||
4171 | 1910 | |||
4172 | 1911 | Before you begin painting a QWebPage object, you need to set the size of | ||
4173 | 1912 | the viewport by calling setViewportSize(). Then, you invoke the main | ||
4174 | 1913 | frame's render function (QWebFrame::render()). An example of this | ||
4175 | 1914 | is shown in the code snippet below. | ||
4176 | 1915 | |||
4177 | 1916 | Suppose we have a \c Thumbnail class as follows: | ||
4178 | 1917 | |||
4179 | 1918 | \snippet webkitsnippets/webpage/main.cpp 0 | ||
4180 | 1919 | |||
4181 | 1920 | The \c Thumbnail's constructor takes in a \a url. We connect our QWebPage | ||
4182 | 1921 | object's \l{QWebPage::}{loadFinished()} signal to our private slot, | ||
4183 | 1922 | \c render(). | ||
4184 | 1923 | |||
4185 | 1924 | \snippet webkitsnippets/webpage/main.cpp 1 | ||
4186 | 1925 | |||
4187 | 1926 | The \c render() function shows how we can paint a thumbnail using a | ||
4188 | 1927 | QWebPage object. | ||
4189 | 1928 | |||
4190 | 1929 | \snippet webkitsnippets/webpage/main.cpp 2 | ||
4191 | 1930 | |||
4192 | 1931 | We begin by setting the \l{QWebPage::viewportSize()}{viewportSize} and | ||
4193 | 1932 | then we instantiate a QImage object, \c image, with the same size as our | ||
4194 | 1933 | \l{QWebPage::viewportSize()}{viewportSize}. This image is then sent | ||
4195 | 1934 | as a parameter to \c painter. Next, we render the contents of the main | ||
4196 | 1935 | frame and its subframes into \c painter. Finally, we save the scaled image. | ||
4197 | 1936 | |||
4198 | 1937 | \sa QWebFrame | ||
4199 | 1938 | */ | ||
4200 | 1939 | |||
4201 | 1940 | /*! | ||
4202 | 1941 | Constructs an empty QWebPage with parent \a parent. | ||
4203 | 1942 | */ | ||
4204 | 1943 | QWebPage::QWebPage(QObject *parent) | ||
4205 | 1944 | : QObject(parent) | ||
4206 | 1945 | , d(new QWebPagePrivate(this)) | ||
4207 | 1946 | { | ||
4208 | 1947 | setView(qobject_cast<QWidget*>(parent)); | ||
4209 | 1948 | |||
4210 | 1949 | connect(this, SIGNAL(loadProgress(int)), this, SLOT(_q_onLoadProgressChanged(int))); | ||
4211 | 1950 | #ifndef NDEBUG | ||
4212 | 1951 | connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(_q_cleanupLeakMessages())); | ||
4213 | 1952 | #endif | ||
4214 | 1953 | } | ||
4215 | 1954 | |||
4216 | 1955 | /*! | ||
4217 | 1956 | Destroys the web page. | ||
4218 | 1957 | */ | ||
4219 | 1958 | QWebPage::~QWebPage() | ||
4220 | 1959 | { | ||
4221 | 1960 | d->createMainFrame(); | ||
4222 | 1961 | FrameLoader* loader = d->mainFrame.data()->d->frame->loader(); | ||
4223 | 1962 | if (loader) | ||
4224 | 1963 | loader->detachFromParent(); | ||
4225 | 1964 | delete d; | ||
4226 | 1965 | } | ||
4227 | 1966 | |||
4228 | 1967 | /*! | ||
4229 | 1968 | Returns the main frame of the page. | ||
4230 | 1969 | |||
4231 | 1970 | The main frame provides access to the hierarchy of sub-frames and is also needed if you | ||
4232 | 1971 | want to explicitly render a web page into a given painter. | ||
4233 | 1972 | |||
4234 | 1973 | \sa currentFrame() | ||
4235 | 1974 | */ | ||
4236 | 1975 | QWebFrame *QWebPage::mainFrame() const | ||
4237 | 1976 | { | ||
4238 | 1977 | d->createMainFrame(); | ||
4239 | 1978 | return d->mainFrame.data(); | ||
4240 | 1979 | } | ||
4241 | 1980 | |||
4242 | 1981 | /*! | ||
4243 | 1982 | Returns the frame currently active. | ||
4244 | 1983 | |||
4245 | 1984 | \sa mainFrame(), frameCreated() | ||
4246 | 1985 | */ | ||
4247 | 1986 | QWebFrame *QWebPage::currentFrame() const | ||
4248 | 1987 | { | ||
4249 | 1988 | d->createMainFrame(); | ||
4250 | 1989 | WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame(); | ||
4251 | 1990 | return qobject_cast<QWebFrame*>(frame->loader()->networkingContext()->originatingObject()); | ||
4252 | 1991 | } | ||
4253 | 1992 | |||
4254 | 1993 | |||
4255 | 1994 | /*! | ||
4256 | 1995 | \since 4.6 | ||
4257 | 1996 | |||
4258 | 1997 | Returns the frame at the given point \a pos, or 0 if there is no frame at | ||
4259 | 1998 | that position. | ||
4260 | 1999 | |||
4261 | 2000 | \sa mainFrame(), currentFrame() | ||
4262 | 2001 | */ | ||
4263 | 2002 | QWebFrame* QWebPage::frameAt(const QPoint& pos) const | ||
4264 | 2003 | { | ||
4265 | 2004 | QWebFrame* webFrame = mainFrame(); | ||
4266 | 2005 | if (!webFrame->geometry().contains(pos)) | ||
4267 | 2006 | return 0; | ||
4268 | 2007 | QWebHitTestResult hitTestResult = webFrame->hitTestContent(pos); | ||
4269 | 2008 | return hitTestResult.frame(); | ||
4270 | 2009 | } | ||
4271 | 2010 | |||
4272 | 2011 | /*! | ||
4273 | 2012 | Returns a pointer to the view's history of navigated web pages. | ||
4274 | 2013 | */ | ||
4275 | 2014 | QWebHistory *QWebPage::history() const | ||
4276 | 2015 | { | ||
4277 | 2016 | d->createMainFrame(); | ||
4278 | 2017 | return &d->history; | ||
4279 | 2018 | } | ||
4280 | 2019 | |||
4281 | 2020 | /*! | ||
4282 | 2021 | Sets the \a view that is associated with the web page. | ||
4283 | 2022 | |||
4284 | 2023 | \sa view() | ||
4285 | 2024 | */ | ||
4286 | 2025 | void QWebPage::setView(QWidget* view) | ||
4287 | 2026 | { | ||
4288 | 2027 | if (this->view() == view) | ||
4289 | 2028 | return; | ||
4290 | 2029 | |||
4291 | 2030 | d->view = view; | ||
4292 | 2031 | setViewportSize(view ? view->size() : QSize(0, 0)); | ||
4293 | 2032 | |||
4294 | 2033 | // If we have no client, we install a special client delegating | ||
4295 | 2034 | // the responsibility to the QWidget. This is the code path | ||
4296 | 2035 | // handling a.o. the "legacy" QWebView. | ||
4297 | 2036 | // | ||
4298 | 2037 | // If such a special delegate already exist, we substitute the view. | ||
4299 | 2038 | |||
4300 | 2039 | if (d->client) { | ||
4301 | 2040 | if (d->client->isQWidgetClient()) | ||
4302 | 2041 | static_cast<PageClientQWidget*>(d->client.get())->view = view; | ||
4303 | 2042 | return; | ||
4304 | 2043 | } | ||
4305 | 2044 | |||
4306 | 2045 | if (view) | ||
4307 | 2046 | d->client = adoptPtr(new PageClientQWidget(view, this)); | ||
4308 | 2047 | } | ||
4309 | 2048 | |||
4310 | 2049 | /*! | ||
4311 | 2050 | Returns the view widget that is associated with the web page. | ||
4312 | 2051 | |||
4313 | 2052 | \sa setView() | ||
4314 | 2053 | */ | ||
4315 | 2054 | QWidget *QWebPage::view() const | ||
4316 | 2055 | { | ||
4317 | 2056 | return d->view.data(); | ||
4318 | 2057 | } | ||
4319 | 2058 | |||
4320 | 2059 | /*! | ||
4321 | 2060 | This function is called whenever a JavaScript program tries to print a \a message to the web browser's console. | ||
4322 | 2061 | |||
4323 | 2062 | For example in case of evaluation errors the source URL may be provided in \a sourceID as well as the \a lineNumber. | ||
4324 | 2063 | |||
4325 | 2064 | The default implementation prints nothing. | ||
4326 | 2065 | */ | ||
4327 | 2066 | void QWebPage::javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID) | ||
4328 | 2067 | { | ||
4329 | 2068 | Q_UNUSED(sourceID) | ||
4330 | 2069 | |||
4331 | 2070 | // Catch plugin logDestroy message for LayoutTests/plugins/open-and-close-window-with-plugin.html | ||
4332 | 2071 | // At this point DRT's WebPage has already been destroyed | ||
4333 | 2072 | if (QWebPagePrivate::drtRun) { | ||
4334 | 2073 | if (message == QLatin1String("PLUGIN: NPP_Destroy")) { | ||
4335 | 2074 | fprintf(stdout, "CONSOLE MESSAGE: "); | ||
4336 | 2075 | if (lineNumber) | ||
4337 | 2076 | fprintf(stdout, "line %d: ", lineNumber); | ||
4338 | 2077 | fprintf(stdout, "%s\n", message.toUtf8().constData()); | ||
4339 | 2078 | } | ||
4340 | 2079 | } | ||
4341 | 2080 | } | ||
4342 | 2081 | |||
4343 | 2082 | /*! | ||
4344 | 2083 | This function is called whenever a JavaScript program running inside \a frame calls the alert() function with | ||
4345 | 2084 | the message \a msg. | ||
4346 | 2085 | |||
4347 | 2086 | The default implementation shows the message, \a msg, with QMessageBox::information. | ||
4348 | 2087 | */ | ||
4349 | 2088 | void QWebPage::javaScriptAlert(QWebFrame *frame, const QString& msg) | ||
4350 | 2089 | { | ||
4351 | 2090 | Q_UNUSED(frame) | ||
4352 | 2091 | #ifndef QT_NO_MESSAGEBOX | ||
4353 | 2092 | QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; | ||
4354 | 2093 | QMessageBox box(parent); | ||
4355 | 2094 | box.setWindowTitle(tr("JavaScript Alert - %1").arg(mainFrame()->url().host())); | ||
4356 | 2095 | box.setTextFormat(Qt::PlainText); | ||
4357 | 2096 | box.setText(msg); | ||
4358 | 2097 | box.setStandardButtons(QMessageBox::Ok); | ||
4359 | 2098 | box.exec(); | ||
4360 | 2099 | #endif | ||
4361 | 2100 | } | ||
4362 | 2101 | |||
4363 | 2102 | /*! | ||
4364 | 2103 | This function is called whenever a JavaScript program running inside \a frame calls the confirm() function | ||
4365 | 2104 | with the message, \a msg. Returns true if the user confirms the message; otherwise returns false. | ||
4366 | 2105 | |||
4367 | 2106 | The default implementation executes the query using QMessageBox::information with QMessageBox::Ok and QMessageBox::Cancel buttons. | ||
4368 | 2107 | */ | ||
4369 | 2108 | bool QWebPage::javaScriptConfirm(QWebFrame *frame, const QString& msg) | ||
4370 | 2109 | { | ||
4371 | 2110 | Q_UNUSED(frame) | ||
4372 | 2111 | #ifdef QT_NO_MESSAGEBOX | ||
4373 | 2112 | return true; | ||
4374 | 2113 | #else | ||
4375 | 2114 | QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; | ||
4376 | 2115 | QMessageBox box(parent); | ||
4377 | 2116 | box.setWindowTitle(tr("JavaScript Confirm - %1").arg(mainFrame()->url().host())); | ||
4378 | 2117 | box.setTextFormat(Qt::PlainText); | ||
4379 | 2118 | box.setText(msg); | ||
4380 | 2119 | box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); | ||
4381 | 2120 | return QMessageBox::Ok == box.exec(); | ||
4382 | 2121 | #endif | ||
4383 | 2122 | } | ||
4384 | 2123 | |||
4385 | 2124 | /*! | ||
4386 | 2125 | This function is called whenever a JavaScript program running inside \a frame tries to prompt the user for input. | ||
4387 | 2126 | The program may provide an optional message, \a msg, as well as a default value for the input in \a defaultValue. | ||
4388 | 2127 | |||
4389 | 2128 | If the prompt was cancelled by the user the implementation should return false; otherwise the | ||
4390 | 2129 | result should be written to \a result and true should be returned. If the prompt was not cancelled by the | ||
4391 | 2130 | user, the implementation should return true and the result string must not be null. | ||
4392 | 2131 | |||
4393 | 2132 | The default implementation uses QInputDialog::getText(). | ||
4394 | 2133 | */ | ||
4395 | 2134 | bool QWebPage::javaScriptPrompt(QWebFrame *frame, const QString& msg, const QString& defaultValue, QString* result) | ||
4396 | 2135 | { | ||
4397 | 2136 | Q_UNUSED(frame) | ||
4398 | 2137 | bool ok = false; | ||
4399 | 2138 | #ifndef QT_NO_INPUTDIALOG | ||
4400 | 2139 | |||
4401 | 2140 | QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; | ||
4402 | 2141 | QInputDialog dlg(parent); | ||
4403 | 2142 | dlg.setWindowTitle(tr("JavaScript Prompt - %1").arg(mainFrame()->url().host())); | ||
4404 | 2143 | |||
4405 | 2144 | // Hack to force the dialog's QLabel into plain text mode | ||
4406 | 2145 | // prevents https://bugs.webkit.org/show_bug.cgi?id=34429 | ||
4407 | 2146 | QLabel* label = dlg.findChild<QLabel*>(); | ||
4408 | 2147 | if (label) | ||
4409 | 2148 | label->setTextFormat(Qt::PlainText); | ||
4410 | 2149 | |||
4411 | 2150 | // double the &'s because single & will underline the following character | ||
4412 | 2151 | // (Accelerator mnemonics) | ||
4413 | 2152 | QString escMsg(msg); | ||
4414 | 2153 | escMsg.replace(QChar::fromLatin1('&'), QLatin1String("&&")); | ||
4415 | 2154 | dlg.setLabelText(escMsg); | ||
4416 | 2155 | |||
4417 | 2156 | dlg.setTextEchoMode(QLineEdit::Normal); | ||
4418 | 2157 | dlg.setTextValue(defaultValue); | ||
4419 | 2158 | |||
4420 | 2159 | ok = !!dlg.exec(); | ||
4421 | 2160 | |||
4422 | 2161 | if (ok && result) | ||
4423 | 2162 | *result = dlg.textValue(); | ||
4424 | 2163 | #endif | ||
4425 | 2164 | return ok; | ||
4426 | 2165 | } | ||
4427 | 2166 | |||
4428 | 2167 | /*! | ||
4429 | 2168 | \fn bool QWebPage::shouldInterruptJavaScript() | ||
4430 | 2169 | \since 4.6 | ||
4431 | 2170 | This function is called when a JavaScript program is running for a long period of time. | ||
4432 | 2171 | |||
4433 | 2172 | If the user wanted to stop the JavaScript the implementation should return true; otherwise false. | ||
4434 | 2173 | |||
4435 | 2174 | The default implementation executes the query using QMessageBox::information with QMessageBox::Yes and QMessageBox::No buttons. | ||
4436 | 2175 | |||
4437 | 2176 | \warning Because of binary compatibility constraints, this function is not virtual. If you want to | ||
4438 | 2177 | provide your own implementation in a QWebPage subclass, reimplement the shouldInterruptJavaScript() | ||
4439 | 2178 | slot in your subclass instead. QtWebKit will dynamically detect the slot and call it. | ||
4440 | 2179 | */ | ||
4441 | 2180 | bool QWebPage::shouldInterruptJavaScript() | ||
4442 | 2181 | { | ||
4443 | 2182 | #ifdef QT_NO_MESSAGEBOX | ||
4444 | 2183 | return false; | ||
4445 | 2184 | #else | ||
4446 | 2185 | QWidget* parent = (d->client) ? d->client->ownerWidget() : 0; | ||
4447 | 2186 | return QMessageBox::Yes == QMessageBox::information(parent, tr("JavaScript Problem - %1").arg(mainFrame()->url().host()), tr("The script on this page appears to have a problem. Do you want to stop the script?"), QMessageBox::Yes, QMessageBox::No); | ||
4448 | 2187 | #endif | ||
4449 | 2188 | } | ||
4450 | 2189 | |||
4451 | 2190 | void QWebPage::setFeaturePermission(QWebFrame* frame, Feature feature, PermissionPolicy policy) | ||
4452 | 2191 | { | ||
4453 | 2192 | #if !ENABLE(NOTIFICATIONS) && !ENABLE(LEGACY_NOTIFICATIONS) && !ENABLE(GEOLOCATION) | ||
4454 | 2193 | Q_UNUSED(frame); | ||
4455 | 2194 | Q_UNUSED(policy); | ||
4456 | 2195 | #endif | ||
4457 | 2196 | switch (feature) { | ||
4458 | 2197 | case Notifications: | ||
4459 | 2198 | #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) | ||
4460 | 2199 | if (policy != PermissionUnknown) | ||
4461 | 2200 | NotificationPresenterClientQt::notificationPresenter()->setNotificationsAllowedForFrame(frame->d->frame, (policy == PermissionGrantedByUser)); | ||
4462 | 2201 | #endif | ||
4463 | 2202 | break; | ||
4464 | 2203 | case Geolocation: | ||
4465 | 2204 | #if ENABLE(GEOLOCATION) | ||
4466 | 2205 | GeolocationPermissionClientQt::geolocationPermissionClient()->setPermission(frame, policy); | ||
4467 | 2206 | #endif | ||
4468 | 2207 | break; | ||
4469 | 2208 | |||
4470 | 2209 | default: | ||
4471 | 2210 | break; | ||
4472 | 2211 | } | ||
4473 | 2212 | } | ||
4474 | 2213 | |||
4475 | 2214 | /*! | ||
4476 | 2215 | This function is called whenever WebKit wants to create a new window of the given \a type, for | ||
4477 | 2216 | example when a JavaScript program requests to open a document in a new window. | ||
4478 | 2217 | |||
4479 | 2218 | If the new window can be created, the new window's QWebPage is returned; otherwise a null pointer is returned. | ||
4480 | 2219 | |||
4481 | 2220 | If the view associated with the web page is a QWebView object, then the default implementation forwards | ||
4482 | 2221 | the request to QWebView's createWindow() function; otherwise it returns a null pointer. | ||
4483 | 2222 | |||
4484 | 2223 | If \a type is WebModalDialog, the application must call setWindowModality(Qt::ApplicationModal) on the new window. | ||
4485 | 2224 | |||
4486 | 2225 | \note In the cases when the window creation is being triggered by JavaScript, apart from | ||
4487 | 2226 | reimplementing this method application must also set the JavaScriptCanOpenWindows attribute | ||
4488 | 2227 | of QWebSettings to true in order for it to get called. | ||
4489 | 2228 | |||
4490 | 2229 | \sa acceptNavigationRequest(), QWebView::createWindow() | ||
4491 | 2230 | */ | ||
4492 | 2231 | QWebPage *QWebPage::createWindow(WebWindowType type) | ||
4493 | 2232 | { | ||
4494 | 2233 | QWebView *webView = qobject_cast<QWebView*>(view()); | ||
4495 | 2234 | if (webView) { | ||
4496 | 2235 | QWebView *newView = webView->createWindow(type); | ||
4497 | 2236 | if (newView) | ||
4498 | 2237 | return newView->page(); | ||
4499 | 2238 | } | ||
4500 | 2239 | return 0; | ||
4501 | 2240 | } | ||
4502 | 2241 | |||
4503 | 2242 | /*! | ||
4504 | 2243 | This function is called whenever WebKit encounters a HTML object element with type "application/x-qt-plugin". It is | ||
4505 | 2244 | called regardless of the value of QWebSettings::PluginsEnabled. The \a classid, \a url, \a paramNames and \a paramValues | ||
4506 | 2245 | correspond to the HTML object element attributes and child elements to configure the embeddable object. | ||
4507 | 2246 | */ | ||
4508 | 2247 | QObject *QWebPage::createPlugin(const QString &classid, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) | ||
4509 | 2248 | { | ||
4510 | 2249 | Q_UNUSED(classid) | ||
4511 | 2250 | Q_UNUSED(url) | ||
4512 | 2251 | Q_UNUSED(paramNames) | ||
4513 | 2252 | Q_UNUSED(paramValues) | ||
4514 | 2253 | return 0; | ||
4515 | 2254 | } | ||
4516 | 2255 | |||
4517 | 2256 | static void extractContentTypeFromHash(const HashSet<String>& types, QStringList* list) | ||
4518 | 2257 | { | ||
4519 | 2258 | if (!list) | ||
4520 | 2259 | return; | ||
4521 | 2260 | |||
4522 | 2261 | HashSet<String>::const_iterator endIt = types.end(); | ||
4523 | 2262 | for (HashSet<String>::const_iterator it = types.begin(); it != endIt; ++it) | ||
4524 | 2263 | *list << *it; | ||
4525 | 2264 | } | ||
4526 | 2265 | |||
4527 | 2266 | static void extractContentTypeFromPluginVector(const Vector<PluginPackage*>& plugins, QStringList* list) | ||
4528 | 2267 | { | ||
4529 | 2268 | if (!list) | ||
4530 | 2269 | return; | ||
4531 | 2270 | |||
4532 | 2271 | for (unsigned int i = 0; i < plugins.size(); ++i) { | ||
4533 | 2272 | MIMEToDescriptionsMap::const_iterator map_it = plugins[i]->mimeToDescriptions().begin(); | ||
4534 | 2273 | MIMEToDescriptionsMap::const_iterator map_end = plugins[i]->mimeToDescriptions().end(); | ||
4535 | 2274 | for (; map_it != map_end; ++map_it) | ||
4536 | 2275 | *list << map_it->key; | ||
4537 | 2276 | } | ||
4538 | 2277 | } | ||
4539 | 2278 | |||
4540 | 2279 | /*! | ||
4541 | 2280 | * Returns the list of all content types supported by QWebPage. | ||
4542 | 2281 | */ | ||
4543 | 2282 | QStringList QWebPage::supportedContentTypes() const | ||
4544 | 2283 | { | ||
4545 | 2284 | QStringList mimeTypes; | ||
4546 | 2285 | |||
4547 | 2286 | extractContentTypeFromHash(MIMETypeRegistry::getSupportedImageMIMETypes(), &mimeTypes); | ||
4548 | 2287 | extractContentTypeFromHash(MIMETypeRegistry::getSupportedNonImageMIMETypes(), &mimeTypes); | ||
4549 | 2288 | if (d->page->settings() && d->page->settings()->arePluginsEnabled()) | ||
4550 | 2289 | extractContentTypeFromPluginVector(PluginDatabase::installedPlugins()->plugins(), &mimeTypes); | ||
4551 | 2290 | |||
4552 | 2291 | return mimeTypes; | ||
4553 | 2292 | } | ||
4554 | 2293 | |||
4555 | 2294 | /*! | ||
4556 | 2295 | * Returns true if QWebPage can handle the given \a mimeType; otherwise, returns false. | ||
4557 | 2296 | */ | ||
4558 | 2297 | bool QWebPage::supportsContentType(const QString& mimeType) const | ||
4559 | 2298 | { | ||
4560 | 2299 | const String type = mimeType.toLower(); | ||
4561 | 2300 | if (MIMETypeRegistry::isSupportedImageMIMEType(type)) | ||
4562 | 2301 | return true; | ||
4563 | 2302 | |||
4564 | 2303 | if (MIMETypeRegistry::isSupportedNonImageMIMEType(type)) | ||
4565 | 2304 | return true; | ||
4566 | 2305 | |||
4567 | 2306 | if (d->page->settings() && d->page->settings()->arePluginsEnabled() | ||
4568 | 2307 | && PluginDatabase::installedPlugins()->isMIMETypeRegistered(type)) | ||
4569 | 2308 | return true; | ||
4570 | 2309 | |||
4571 | 2310 | return false; | ||
4572 | 2311 | } | ||
4573 | 2312 | |||
4574 | 2313 | static WebCore::FrameLoadRequest frameLoadRequest(const QUrl &url, WebCore::Frame *frame) | ||
4575 | 2314 | { | ||
4576 | 2315 | return WebCore::FrameLoadRequest(frame->document()->securityOrigin(), | ||
4577 | 2316 | WebCore::ResourceRequest(url, frame->loader()->outgoingReferrer())); | ||
4578 | 2317 | } | ||
4579 | 2318 | |||
4580 | 2319 | static void openNewWindow(const QUrl& url, WebCore::Frame* frame) | ||
4581 | 2320 | { | ||
4582 | 2321 | if (Page* oldPage = frame->page()) { | ||
4583 | 2322 | WindowFeatures features; | ||
4584 | 2323 | NavigationAction action; | ||
4585 | 2324 | FrameLoadRequest request = frameLoadRequest(url, frame); | ||
4586 | 2325 | if (Page* newPage = oldPage->chrome()->createWindow(frame, request, features, action)) { | ||
4587 | 2326 | newPage->mainFrame()->loader()->loadFrameRequest(request, false, false, 0, 0, MaybeSendReferrer); | ||
4588 | 2327 | newPage->chrome()->show(); | ||
4589 | 2328 | } | ||
4590 | 2329 | } | ||
4591 | 2330 | } | ||
4592 | 2331 | |||
4593 | 2332 | static void collectChildFrames(QWebFrame* frame, QList<QWebFrame*>& list) | ||
4594 | 2333 | { | ||
4595 | 2334 | list << frame->childFrames(); | ||
4596 | 2335 | QListIterator<QWebFrame*> it(frame->childFrames()); | ||
4597 | 2336 | while (it.hasNext()) { | ||
4598 | 2337 | collectChildFrames(it.next(), list); | ||
4599 | 2338 | } | ||
4600 | 2339 | } | ||
4601 | 2340 | |||
4602 | 2341 | /*! | ||
4603 | 2342 | This function can be called to trigger the specified \a action. | ||
4604 | 2343 | It is also called by QtWebKit if the user triggers the action, for example | ||
4605 | 2344 | through a context menu item. | ||
4606 | 2345 | |||
4607 | 2346 | If \a action is a checkable action then \a checked specified whether the action | ||
4608 | 2347 | is toggled or not. | ||
4609 | 2348 | |||
4610 | 2349 | \sa action() | ||
4611 | 2350 | */ | ||
4612 | 2351 | void QWebPage::triggerAction(WebAction action, bool) | ||
4613 | 2352 | { | ||
4614 | 2353 | WebCore::Frame *frame = d->page->focusController()->focusedOrMainFrame(); | ||
4615 | 2354 | if (!frame) | ||
4616 | 2355 | return; | ||
4617 | 2356 | WebCore::Editor *editor = frame->editor(); | ||
4618 | 2357 | const char *command = 0; | ||
4619 | 2358 | |||
4620 | 2359 | switch (action) { | ||
4621 | 2360 | case OpenLink: | ||
4622 | 2361 | if (QWebFrame *targetFrame = d->hitTestResult.linkTargetFrame()) { | ||
4623 | 2362 | WTF::RefPtr<WebCore::Frame> wcFrame = targetFrame->d->frame; | ||
4624 | 2363 | targetFrame->d->frame->loader()->loadFrameRequest(frameLoadRequest(d->hitTestResult.linkUrl(), wcFrame.get()), | ||
4625 | 2364 | /*lockHistory*/ false, /*lockBackForwardList*/ false, /*event*/ 0, | ||
4626 | 2365 | /*FormState*/ 0, MaybeSendReferrer); | ||
4627 | 2366 | break; | ||
4628 | 2367 | } | ||
4629 | 2368 | // fall through | ||
4630 | 2369 | case OpenLinkInNewWindow: | ||
4631 | 2370 | openNewWindow(d->hitTestResult.linkUrl(), frame); | ||
4632 | 2371 | break; | ||
4633 | 2372 | case OpenLinkInThisWindow: | ||
4634 | 2373 | frame->loader()->loadFrameRequest(frameLoadRequest(d->hitTestResult.linkUrl(), frame), | ||
4635 | 2374 | /*lockHistory*/ false, /*lockBackForwardList*/ false, /*event*/ 0, /*FormState*/ 0, MaybeSendReferrer); | ||
4636 | 2375 | break; | ||
4637 | 2376 | case OpenFrameInNewWindow: { | ||
4638 | 2377 | KURL url = frame->loader()->documentLoader()->unreachableURL(); | ||
4639 | 2378 | if (url.isEmpty()) | ||
4640 | 2379 | url = frame->loader()->documentLoader()->url(); | ||
4641 | 2380 | openNewWindow(url, frame); | ||
4642 | 2381 | break; | ||
4643 | 2382 | } | ||
4644 | 2383 | case CopyLinkToClipboard: { | ||
4645 | 2384 | #if defined(Q_WS_X11) | ||
4646 | 2385 | bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode(); | ||
4647 | 2386 | Pasteboard::generalPasteboard()->setSelectionMode(true); | ||
4648 | 2387 | editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText()); | ||
4649 | 2388 | Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode); | ||
4650 | 2389 | #endif | ||
4651 | 2390 | editor->copyURL(d->hitTestResult.linkUrl(), d->hitTestResult.linkText()); | ||
4652 | 2391 | break; | ||
4653 | 2392 | } | ||
4654 | 2393 | case OpenImageInNewWindow: | ||
4655 | 2394 | openNewWindow(d->hitTestResult.imageUrl(), frame); | ||
4656 | 2395 | break; | ||
4657 | 2396 | case DownloadImageToDisk: | ||
4658 | 2397 | frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.imageUrl(), frame->loader()->outgoingReferrer())); | ||
4659 | 2398 | break; | ||
4660 | 2399 | case DownloadLinkToDisk: | ||
4661 | 2400 | frame->loader()->client()->startDownload(WebCore::ResourceRequest(d->hitTestResult.linkUrl(), frame->loader()->outgoingReferrer())); | ||
4662 | 2401 | break; | ||
4663 | 2402 | #ifndef QT_NO_CLIPBOARD | ||
4664 | 2403 | case CopyImageToClipboard: | ||
4665 | 2404 | QApplication::clipboard()->setPixmap(d->hitTestResult.pixmap()); | ||
4666 | 2405 | break; | ||
4667 | 2406 | case CopyImageUrlToClipboard: | ||
4668 | 2407 | QApplication::clipboard()->setText(d->hitTestResult.imageUrl().toString()); | ||
4669 | 2408 | break; | ||
4670 | 2409 | #endif | ||
4671 | 2410 | case Back: | ||
4672 | 2411 | d->page->goBack(); | ||
4673 | 2412 | break; | ||
4674 | 2413 | case Forward: | ||
4675 | 2414 | d->page->goForward(); | ||
4676 | 2415 | break; | ||
4677 | 2416 | case Stop: | ||
4678 | 2417 | mainFrame()->d->frame->loader()->stopForUserCancel(); | ||
4679 | 2418 | d->updateNavigationActions(); | ||
4680 | 2419 | break; | ||
4681 | 2420 | case Reload: | ||
4682 | 2421 | mainFrame()->d->frame->loader()->reload(/*endtoendreload*/false); | ||
4683 | 2422 | break; | ||
4684 | 2423 | case ReloadAndBypassCache: | ||
4685 | 2424 | mainFrame()->d->frame->loader()->reload(/*endtoendreload*/true); | ||
4686 | 2425 | break; | ||
4687 | 2426 | case SetTextDirectionDefault: | ||
4688 | 2427 | editor->setBaseWritingDirection(NaturalWritingDirection); | ||
4689 | 2428 | break; | ||
4690 | 2429 | case SetTextDirectionLeftToRight: | ||
4691 | 2430 | editor->setBaseWritingDirection(LeftToRightWritingDirection); | ||
4692 | 2431 | break; | ||
4693 | 2432 | case SetTextDirectionRightToLeft: | ||
4694 | 2433 | editor->setBaseWritingDirection(RightToLeftWritingDirection); | ||
4695 | 2434 | break; | ||
4696 | 2435 | case InspectElement: { | ||
4697 | 2436 | #if ENABLE(INSPECTOR) | ||
4698 | 2437 | if (!d->hitTestResult.isNull()) { | ||
4699 | 2438 | d->getOrCreateInspector(); // Make sure the inspector is created | ||
4700 | 2439 | d->inspector->show(); // The inspector is expected to be shown on inspection | ||
4701 | 2440 | d->page->inspectorController()->inspect(d->hitTestResult.d->innerNonSharedNode.get()); | ||
4702 | 2441 | } | ||
4703 | 2442 | #endif | ||
4704 | 2443 | break; | ||
4705 | 2444 | } | ||
4706 | 2445 | case StopScheduledPageRefresh: { | ||
4707 | 2446 | QWebFrame* topFrame = mainFrame(); | ||
4708 | 2447 | topFrame->d->frame->navigationScheduler()->cancel(); | ||
4709 | 2448 | QList<QWebFrame*> childFrames; | ||
4710 | 2449 | collectChildFrames(topFrame, childFrames); | ||
4711 | 2450 | QListIterator<QWebFrame*> it(childFrames); | ||
4712 | 2451 | while (it.hasNext()) | ||
4713 | 2452 | it.next()->d->frame->navigationScheduler()->cancel(); | ||
4714 | 2453 | break; | ||
4715 | 2454 | } | ||
4716 | 2455 | default: | ||
4717 | 2456 | command = QWebPagePrivate::editorCommandForWebActions(action); | ||
4718 | 2457 | break; | ||
4719 | 2458 | } | ||
4720 | 2459 | |||
4721 | 2460 | if (command) | ||
4722 | 2461 | editor->command(command).execute(); | ||
4723 | 2462 | } | ||
4724 | 2463 | |||
4725 | 2464 | |||
4726 | 2465 | QColor QWebPagePrivate::colorSelectionRequested(const QColor &selectedColor) | ||
4727 | 2466 | { | ||
4728 | 2467 | QColor ret = selectedColor; | ||
4729 | 2468 | #ifndef QT_NO_COLORDIALOG | ||
4730 | 2469 | QWidget* parent = (client) ? client->ownerWidget() : 0; | ||
4731 | 2470 | ret = QColorDialog::getColor(selectedColor, parent); | ||
4732 | 2471 | if (!ret.isValid()) | ||
4733 | 2472 | ret = selectedColor; | ||
4734 | 2473 | #endif | ||
4735 | 2474 | return ret; | ||
4736 | 2475 | } | ||
4737 | 2476 | |||
4738 | 2477 | QSize QWebPage::viewportSize() const | ||
4739 | 2478 | { | ||
4740 | 2479 | if (d->mainFrame && d->mainFrame.data()->d->frame->view()) | ||
4741 | 2480 | return d->mainFrame.data()->d->frame->view()->frameRect().size(); | ||
4742 | 2481 | |||
4743 | 2482 | return d->viewportSize; | ||
4744 | 2483 | } | ||
4745 | 2484 | |||
4746 | 2485 | /*! | ||
4747 | 2486 | \property QWebPage::viewportSize | ||
4748 | 2487 | \brief the size of the viewport | ||
4749 | 2488 | |||
4750 | 2489 | The size affects for example the visibility of scrollbars | ||
4751 | 2490 | if the document is larger than the viewport. | ||
4752 | 2491 | |||
4753 | 2492 | By default, for a newly-created Web page, this property contains a size with | ||
4754 | 2493 | zero width and height. | ||
4755 | 2494 | |||
4756 | 2495 | \sa QWebFrame::render(), preferredContentsSize | ||
4757 | 2496 | */ | ||
4758 | 2497 | void QWebPage::setViewportSize(const QSize &size) const | ||
4759 | 2498 | { | ||
4760 | 2499 | d->viewportSize = size; | ||
4761 | 2500 | |||
4762 | 2501 | QWebFrame *frame = mainFrame(); | ||
4763 | 2502 | if (frame->d->frame && frame->d->frame->view()) { | ||
4764 | 2503 | WebCore::FrameView* view = frame->d->frame->view(); | ||
4765 | 2504 | view->resize(size); | ||
4766 | 2505 | view->adjustViewSize(); | ||
4767 | 2506 | } | ||
4768 | 2507 | } | ||
4769 | 2508 | |||
4770 | 2509 | static int getintenv(const char* variable) | ||
4771 | 2510 | { | ||
4772 | 2511 | bool ok; | ||
4773 | 2512 | int value = qgetenv(variable).toInt(&ok); | ||
4774 | 2513 | return (ok) ? value : -1; | ||
4775 | 2514 | } | ||
4776 | 2515 | |||
4777 | 2516 | static QSize queryDeviceSizeForScreenContainingWidget(const QWidget* widget) | ||
4778 | 2517 | { | ||
4779 | 2518 | QDesktopWidget* desktop = QApplication::desktop(); | ||
4780 | 2519 | if (!desktop) | ||
4781 | 2520 | return QSize(); | ||
4782 | 2521 | |||
4783 | 2522 | QSize size; | ||
4784 | 2523 | |||
4785 | 2524 | if (widget) { | ||
4786 | 2525 | // Returns the available geometry of the screen which contains widget. | ||
4787 | 2526 | // NOTE: this must be the the full screen size including any fixed status areas etc. | ||
4788 | 2527 | size = desktop->availableGeometry(widget).size(); | ||
4789 | 2528 | } else | ||
4790 | 2529 | size = desktop->availableGeometry().size(); | ||
4791 | 2530 | |||
4792 | 2531 | // This must be in portrait mode, adjust if not. | ||
4793 | 2532 | if (size.width() > size.height()) { | ||
4794 | 2533 | int width = size.width(); | ||
4795 | 2534 | size.setWidth(size.height()); | ||
4796 | 2535 | size.setHeight(width); | ||
4797 | 2536 | } | ||
4798 | 2537 | |||
4799 | 2538 | return size; | ||
4800 | 2539 | } | ||
4801 | 2540 | |||
4802 | 2541 | /*! | ||
4803 | 2542 | Computes the optimal viewport configuration given the \a availableSize, when | ||
4804 | 2543 | user interface components are disregarded. | ||
4805 | 2544 | |||
4806 | 2545 | The configuration is also dependent on the device screen size which is obtained | ||
4807 | 2546 | automatically. For testing purposes the size can be overridden by setting two | ||
4808 | 2547 | environment variables QTWEBKIT_DEVICE_WIDTH and QTWEBKIT_DEVICE_HEIGHT, which | ||
4809 | 2548 | both needs to be set. | ||
4810 | 2549 | |||
4811 | 2550 | The ViewportAttributes includes a pixel density ratio, which will also be exposed to | ||
4812 | 2551 | the web author though the -webkit-pixel-ratio media feature. This is the ratio | ||
4813 | 2552 | between 1 density-independent pixel (DPI) and physical pixels. | ||
4814 | 2553 | |||
4815 | 2554 | A density-independent pixel is equivalent to one physical pixel on a 160 DPI screen, | ||
4816 | 2555 | so on our platform assumes that as the baseline density. | ||
4817 | 2556 | |||
4818 | 2557 | The conversion of DIP units to screen pixels is quite simple: | ||
4819 | 2558 | |||
4820 | 2559 | pixels = DIPs * (density / 160). | ||
4821 | 2560 | |||
4822 | 2561 | Thus, on a 240 DPI screen, 1 DIPs would equal 1.5 physical pixels. | ||
4823 | 2562 | |||
4824 | 2563 | An invalid instance will be returned in the case an empty size is passed to the | ||
4825 | 2564 | method. | ||
4826 | 2565 | |||
4827 | 2566 | \note The density is automatically obtained from the DPI of the screen where the page | ||
4828 | 2567 | is being shown, but as many X11 servers are reporting wrong DPI, it is possible to | ||
4829 | 2568 | override it using QX11Info::setAppDpiY(). | ||
4830 | 2569 | */ | ||
4831 | 2570 | |||
4832 | 2571 | QWebPage::ViewportAttributes QWebPage::viewportAttributesForSize(const QSize& availableSize) const | ||
4833 | 2572 | { | ||
4834 | 2573 | static int desktopWidth = 980; | ||
4835 | 2574 | |||
4836 | 2575 | ViewportAttributes result; | ||
4837 | 2576 | |||
4838 | 2577 | if (availableSize.isEmpty()) | ||
4839 | 2578 | return result; // Returns an invalid instance. | ||
4840 | 2579 | |||
4841 | 2580 | int deviceWidth = getintenv("QTWEBKIT_DEVICE_WIDTH"); | ||
4842 | 2581 | int deviceHeight = getintenv("QTWEBKIT_DEVICE_HEIGHT"); | ||
4843 | 2582 | |||
4844 | 2583 | // Both environment variables need to be set - or they will be ignored. | ||
4845 | 2584 | if (deviceWidth < 0 && deviceHeight < 0) { | ||
4846 | 2585 | QSize size = queryDeviceSizeForScreenContainingWidget((d->client) ? d->client->ownerWidget() : 0); | ||
4847 | 2586 | deviceWidth = size.width(); | ||
4848 | 2587 | deviceHeight = size.height(); | ||
4849 | 2588 | } | ||
4850 | 2589 | |||
4851 | 2590 | float devicePixelRatio = qt_defaultDpi() / WebCore::ViewportArguments::deprecatedTargetDPI; | ||
4852 | 2591 | |||
4853 | 2592 | WebCore::ViewportAttributes conf = WebCore::computeViewportAttributes(d->viewportArguments(), desktopWidth, deviceWidth, deviceHeight, devicePixelRatio, availableSize); | ||
4854 | 2593 | WebCore::restrictMinimumScaleFactorToViewportSize(conf, availableSize, devicePixelRatio); | ||
4855 | 2594 | WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(conf); | ||
4856 | 2595 | |||
4857 | 2596 | result.m_isValid = true; | ||
4858 | 2597 | result.m_size = QSize(conf.layoutSize.width(), conf.layoutSize.height()); | ||
4859 | 2598 | result.m_initialScaleFactor = conf.initialScale; | ||
4860 | 2599 | result.m_minimumScaleFactor = conf.minimumScale; | ||
4861 | 2600 | result.m_maximumScaleFactor = conf.maximumScale; | ||
4862 | 2601 | result.m_devicePixelRatio = devicePixelRatio; | ||
4863 | 2602 | result.m_isUserScalable = static_cast<bool>(conf.userScalable); | ||
4864 | 2603 | |||
4865 | 2604 | d->page->setDeviceScaleFactor(devicePixelRatio); | ||
4866 | 2605 | |||
4867 | 2606 | return result; | ||
4868 | 2607 | } | ||
4869 | 2608 | |||
4870 | 2609 | QSize QWebPage::preferredContentsSize() const | ||
4871 | 2610 | { | ||
4872 | 2611 | QWebFrame* frame = d->mainFrame.data(); | ||
4873 | 2612 | if (frame) { | ||
4874 | 2613 | WebCore::FrameView* view = frame->d->frame->view(); | ||
4875 | 2614 | if (view && view->useFixedLayout()) | ||
4876 | 2615 | return d->mainFrame.data()->d->frame->view()->fixedLayoutSize(); | ||
4877 | 2616 | } | ||
4878 | 2617 | |||
4879 | 2618 | return d->fixedLayoutSize; | ||
4880 | 2619 | } | ||
4881 | 2620 | |||
4882 | 2621 | /*! | ||
4883 | 2622 | \property QWebPage::preferredContentsSize | ||
4884 | 2623 | \since 4.6 | ||
4885 | 2624 | \brief a custom size used for laying out the page contents. | ||
4886 | 2625 | |||
4887 | 2626 | By default all pages are laid out using the viewport of the page as the base. | ||
4888 | 2627 | |||
4889 | 2628 | As pages mostly are designed for desktop usage, they often do not layout properly | ||
4890 | 2629 | on small devices as the contents require a certain view width. For this reason | ||
4891 | 2630 | it is common to use a different layout size and then scale the contents to fit | ||
4892 | 2631 | within the actual view. | ||
4893 | 2632 | |||
4894 | 2633 | If this property is set to a valid size, this size is used for all layout needs | ||
4895 | 2634 | instead of the size of the viewport. | ||
4896 | 2635 | |||
4897 | 2636 | Setting an invalid size, makes the page fall back to using the viewport size for layout. | ||
4898 | 2637 | |||
4899 | 2638 | \sa viewportSize | ||
4900 | 2639 | */ | ||
4901 | 2640 | void QWebPage::setPreferredContentsSize(const QSize& size) const | ||
4902 | 2641 | { | ||
4903 | 2642 | // FIXME: Rename this method to setCustomLayoutSize | ||
4904 | 2643 | |||
4905 | 2644 | d->fixedLayoutSize = size; | ||
4906 | 2645 | |||
4907 | 2646 | QWebFrame* frame = mainFrame(); | ||
4908 | 2647 | if (!frame->d->frame || !frame->d->frame->view()) | ||
4909 | 2648 | return; | ||
4910 | 2649 | |||
4911 | 2650 | WebCore::FrameView* view = frame->d->frame->view(); | ||
4912 | 2651 | |||
4913 | 2652 | if (size.isValid()) { | ||
4914 | 2653 | view->setUseFixedLayout(true); | ||
4915 | 2654 | view->setFixedLayoutSize(size); | ||
4916 | 2655 | } else if (view->useFixedLayout()) | ||
4917 | 2656 | view->setUseFixedLayout(false); | ||
4918 | 2657 | |||
4919 | 2658 | view->layout(); | ||
4920 | 2659 | } | ||
4921 | 2660 | |||
4922 | 2661 | /* | ||
4923 | 2662 | This function is to be called after any (animated) scroll/pan has ended, in the case the application handles the | ||
4924 | 2663 | scrolling/panning of the web contents. This is commonly used in combination with tiling where is it common for | ||
4925 | 2664 | the application to pan the actual view, which then resizes itself to the size of the contents. | ||
4926 | 2665 | |||
4927 | 2666 | \note Calling this function makes WebKit stop trying to calculate the visibleContentRect. To turn that on | ||
4928 | 2667 | again, call this method with an empty rect. | ||
4929 | 2668 | |||
4930 | 2669 | \sa QGraphicsWebView::resizesToContents, QWebSettings::TiledBackingStoreEnabled | ||
4931 | 2670 | */ | ||
4932 | 2671 | void QWebPage::setActualVisibleContentRect(const QRect& rect) const | ||
4933 | 2672 | { | ||
4934 | 2673 | QWebFrame* frame = mainFrame(); | ||
4935 | 2674 | if (!frame->d->frame || !frame->d->frame->view()) | ||
4936 | 2675 | return; | ||
4937 | 2676 | |||
4938 | 2677 | WebCore::FrameView* view = frame->d->frame->view(); | ||
4939 | 2678 | view->setFixedVisibleContentRect(rect); | ||
4940 | 2679 | } | ||
4941 | 2680 | |||
4942 | 2681 | /*! | ||
4943 | 2682 | \fn bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) | ||
4944 | 2683 | |||
4945 | 2684 | This function is called whenever WebKit requests to navigate \a frame to the resource specified by \a request by means of | ||
4946 | 2685 | the specified navigation type \a type. | ||
4947 | 2686 | |||
4948 | 2687 | If \a frame is a null pointer then navigation to a new window is requested. If the request is | ||
4949 | 2688 | accepted createWindow() will be called. | ||
4950 | 2689 | |||
4951 | 2690 | The default implementation interprets the page's linkDelegationPolicy and emits linkClicked accordingly or returns true | ||
4952 | 2691 | to let QWebPage handle the navigation itself. | ||
4953 | 2692 | |||
4954 | 2693 | \sa createWindow() | ||
4955 | 2694 | */ | ||
4956 | 2695 | bool QWebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, QWebPage::NavigationType type) | ||
4957 | 2696 | { | ||
4958 | 2697 | Q_UNUSED(frame) | ||
4959 | 2698 | if (type == NavigationTypeLinkClicked) { | ||
4960 | 2699 | switch (d->linkPolicy) { | ||
4961 | 2700 | case DontDelegateLinks: | ||
4962 | 2701 | return true; | ||
4963 | 2702 | |||
4964 | 2703 | case DelegateExternalLinks: | ||
4965 | 2704 | if (WebCore::SchemeRegistry::shouldTreatURLSchemeAsLocal(request.url().scheme())) | ||
4966 | 2705 | return true; | ||
4967 | 2706 | emit linkClicked(request.url()); | ||
4968 | 2707 | return false; | ||
4969 | 2708 | |||
4970 | 2709 | case DelegateAllLinks: | ||
4971 | 2710 | emit linkClicked(request.url()); | ||
4972 | 2711 | return false; | ||
4973 | 2712 | } | ||
4974 | 2713 | } | ||
4975 | 2714 | return true; | ||
4976 | 2715 | } | ||
4977 | 2716 | |||
4978 | 2717 | /*! | ||
4979 | 2718 | \property QWebPage::hasSelection | ||
4980 | 2719 | \brief whether this page contains selected content or not. | ||
4981 | 2720 | |||
4982 | 2721 | \sa selectionChanged() | ||
4983 | 2722 | */ | ||
4984 | 2723 | bool QWebPage::hasSelection() const | ||
4985 | 2724 | { | ||
4986 | 2725 | d->createMainFrame(); | ||
4987 | 2726 | WebCore::Frame* frame = d->page->focusController()->focusedOrMainFrame(); | ||
4988 | 2727 | if (frame) | ||
4989 | 2728 | return (frame->selection()->selection().selectionType() != VisibleSelection::NoSelection); | ||
4990 | 2729 | return false; | ||
4991 | 2730 | } | ||
4992 | 2731 | |||
4993 | 2732 | /*! | ||
4994 | 2733 | \property QWebPage::selectedText | ||
4995 | 2734 | \brief the text currently selected | ||
4996 | 2735 | |||
4997 | 2736 | By default, this property contains an empty string. | ||
4998 | 2737 | |||
4999 | 2738 | \sa selectionChanged(), selectedHtml() | ||
5000 | 2739 | */ |
A build done at https:/ /launchpad. net/~canonical- qt5-edgers/ +archive/ qt5-beta- proper