Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(659)

Side by Side Diff: webkit/api/src/WebFrameImpl.cpp

Issue 341030: Moves webview_impl.cc, webframe_impl.cc and webframeloaderclient_impl.cc into... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/api/src/WebFrameImpl.h ('k') | webkit/api/src/WebStorageEventDispatcherImpl.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
4 * 3 *
5 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions are
7 * are met: 6 * met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 7 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 8 * * Redistributions of source code must retain the above copyright
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9 * notice, this list of conditions and the following disclaimer.
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 10 * * Redistributions in binary form must reproduce the above
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 11 * copyright notice, this list of conditions and the following disclaimer
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 12 * in the documentation and/or other materials provided with the
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 13 * distribution.
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 14 * * Neither the name of Google Inc. nor the names of its
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 15 * contributors may be used to endorse or promote products derived from
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 29 */
26 30
27 // How ownership works 31 // How ownership works
28 // ------------------- 32 // -------------------
29 // 33 //
30 // Big oh represents a refcounted relationship: owner O--- ownee 34 // Big oh represents a refcounted relationship: owner O--- ownee
31 // 35 //
32 // WebView (for the toplevel frame only) 36 // WebView (for the toplevel frame only)
(...skipping 25 matching lines...) Expand all
58 // 62 //
59 // When frame content is replaced, all subframes are destroyed. This happens 63 // When frame content is replaced, all subframes are destroyed. This happens
60 // in FrameLoader::detachFromParent for each subframe. 64 // in FrameLoader::detachFromParent for each subframe.
61 // 65 //
62 // Frame going away causes the FrameLoader to get deleted. In FrameLoader's 66 // Frame going away causes the FrameLoader to get deleted. In FrameLoader's
63 // destructor, it notifies its client with frameLoaderDestroyed. This calls 67 // destructor, it notifies its client with frameLoaderDestroyed. This calls
64 // WebFrame::Closing and then derefs the WebFrame and will cause it to be 68 // WebFrame::Closing and then derefs the WebFrame and will cause it to be
65 // deleted (unless an external someone is also holding a reference). 69 // deleted (unless an external someone is also holding a reference).
66 70
67 #include "config.h" 71 #include "config.h"
72 #include "WebFrameImpl.h"
68 73
69 #include <algorithm> 74 #include <algorithm>
70 #include <string>
71 75
72 #include "HTMLFormElement.h" // need this before Document.h
73 #include "Chrome.h" 76 #include "Chrome.h"
74 #include "ChromiumBridge.h" 77 #include "ChromiumBridge.h"
75 #include "ClipboardUtilitiesChromium.h" 78 #include "ClipboardUtilitiesChromium.h"
76 #include "Console.h" 79 #include "Console.h"
77 #include "Document.h" 80 #include "Document.h"
78 #include "DocumentFragment.h" // Only needed for ReplaceSelectionCommand.h :( 81 #include "DocumentFragment.h" // Only needed for ReplaceSelectionCommand.h :(
79 #include "DocumentLoader.h" 82 #include "DocumentLoader.h"
80 #include "DocumentMarker.h" 83 #include "DocumentMarker.h"
81 #include "DOMWindow.h" 84 #include "DOMWindow.h"
85 #include "DOMUtilitiesPrivate.h"
82 #include "Editor.h" 86 #include "Editor.h"
83 #include "EventHandler.h" 87 #include "EventHandler.h"
84 #include "FormState.h" 88 #include "FormState.h"
85 #include "FrameChromium.h" 89 #include "FrameChromium.h"
86 #include "FrameLoader.h" 90 #include "FrameLoader.h"
87 #include "FrameLoadRequest.h" 91 #include "FrameLoadRequest.h"
88 #include "FrameTree.h" 92 #include "FrameTree.h"
89 #include "FrameView.h" 93 #include "FrameView.h"
90 #include "GraphicsContext.h" 94 #include "GraphicsContext.h"
91 #include "HTMLCollection.h" 95 #include "HTMLCollection.h"
92 #include "HTMLHeadElement.h" 96 #include "HTMLHeadElement.h"
93 #include "HTMLInputElement.h" 97 #include "HTMLInputElement.h"
98 #include "HTMLFormElement.h"
94 #include "HTMLFrameOwnerElement.h" 99 #include "HTMLFrameOwnerElement.h"
95 #include "HTMLLinkElement.h" 100 #include "HTMLLinkElement.h"
96 #include "HTMLNames.h" 101 #include "HTMLNames.h"
97 #include "HistoryItem.h" 102 #include "HistoryItem.h"
98 #include "InspectorController.h" 103 #include "InspectorController.h"
99 #if PLATFORM(DARWIN)
100 #include "LocalCurrentGraphicsContext.h"
101 #endif
102 #include "markup.h" 104 #include "markup.h"
103 #include "Page.h" 105 #include "Page.h"
106 #include "PasswordAutocompleteListener.h"
104 #include "PlatformContextSkia.h" 107 #include "PlatformContextSkia.h"
105 #include "PrintContext.h" 108 #include "PrintContext.h"
106 #include "RenderFrame.h" 109 #include "RenderFrame.h"
107 #if PLATFORM(WIN_OS)
108 #include "RenderThemeChromiumWin.h"
109 #endif
110 #include "RenderView.h" 110 #include "RenderView.h"
111 #include "RenderWidget.h" 111 #include "RenderWidget.h"
112 #include "ReplaceSelectionCommand.h" 112 #include "ReplaceSelectionCommand.h"
113 #include "ResourceHandle.h" 113 #include "ResourceHandle.h"
114 #include "ResourceRequest.h" 114 #include "ResourceRequest.h"
115 #include "ScriptController.h" 115 #include "ScriptController.h"
116 #include "ScriptSourceCode.h" 116 #include "ScriptSourceCode.h"
117 #include "ScriptValue.h" 117 #include "ScriptValue.h"
118 #include "ScrollbarTheme.h" 118 #include "ScrollbarTheme.h"
119 #include "ScrollTypes.h" 119 #include "ScrollTypes.h"
120 #include "SelectionController.h" 120 #include "SelectionController.h"
121 #include "Settings.h" 121 #include "Settings.h"
122 #include "SkiaUtils.h" 122 #include "SkiaUtils.h"
123 #include "SubstituteData.h" 123 #include "SubstituteData.h"
124 #include "TextIterator.h" 124 #include "TextIterator.h"
125 #include "TextAffinity.h" 125 #include "TextAffinity.h"
126 #include "XPathResult.h" 126 #include "XPathResult.h"
127 #include "WebConsoleMessage.h"
128 #include "WebDataSourceImpl.h"
129 #include "WebFindOptions.h"
130 #include "WebForm.h"
131 #include "WebFrameClient.h"
132 #include "WebHistoryItem.h"
133 #include "WebRange.h"
134 #include "WebRect.h"
135 #include "WebScriptSource.h"
136 #include "WebSecurityOrigin.h"
137 #include "WebSize.h"
138 #include "WebURLError.h"
139 #include "WebVector.h"
140 #include "WebViewImpl.h"
127 #include <wtf/CurrentTime.h> 141 #include <wtf/CurrentTime.h>
128 #undef LOG 142
129 143 #if PLATFORM(DARWIN)
130 #include "webkit/api/public/WebConsoleMessage.h" 144 #include "LocalCurrentGraphicsContext.h"
131 #include "webkit/api/public/WebFindOptions.h" 145 #endif
132 #include "webkit/api/public/WebForm.h"
133 #include "webkit/api/public/WebFrameClient.h"
134 #include "webkit/api/public/WebHistoryItem.h"
135 #include "webkit/api/public/WebRange.h"
136 #include "webkit/api/public/WebRect.h"
137 #include "webkit/api/public/WebScriptSource.h"
138 #include "webkit/api/public/WebSecurityOrigin.h"
139 #include "webkit/api/public/WebSize.h"
140 #include "webkit/api/public/WebURLError.h"
141 #include "webkit/api/public/WebVector.h"
142 #include "webkit/api/src/DOMUtilitiesPrivate.h"
143 #include "webkit/api/src/PasswordAutocompleteListener.h"
144 #include "webkit/api/src/WebDataSourceImpl.h"
145 #include "webkit/glue/glue_util.h"
146 #include "webkit/glue/webframe_impl.h"
147 #include "webkit/glue/webview_impl.h"
148 146
149 #if PLATFORM(LINUX) 147 #if PLATFORM(LINUX)
150 #include <gdk/gdk.h> 148 #include <gdk/gdk.h>
151 #endif 149 #endif
152 150
153 using WebCore::AtomicString; 151 using namespace WebCore;
154 using WebCore::ChromiumBridge; 152
155 using WebCore::Color; 153 namespace WebKit {
156 using WebCore::Document;
157 using WebCore::DocumentFragment;
158 using WebCore::DocumentLoader;
159 using WebCore::ExceptionCode;
160 using WebCore::GraphicsContext;
161 using WebCore::HTMLFrameOwnerElement;
162 using WebCore::HTMLInputElement;
163 using WebCore::Frame;
164 using WebCore::FrameLoader;
165 using WebCore::FrameLoadRequest;
166 using WebCore::FrameLoadType;
167 using WebCore::FrameTree;
168 using WebCore::FrameView;
169 using WebCore::HistoryItem;
170 using WebCore::HTMLFormElement;
171 using WebCore::IntRect;
172 using WebCore::KURL;
173 using WebCore::Node;
174 using WebCore::Range;
175 using WebCore::ReloadIgnoringCacheData;
176 using WebCore::RenderObject;
177 using WebCore::ResourceError;
178 using WebCore::ResourceHandle;
179 using WebCore::ResourceRequest;
180 using WebCore::ResourceResponse;
181 using WebCore::VisibleSelection;
182 using WebCore::ScriptValue;
183 using WebCore::SecurityOrigin;
184 using WebCore::SharedBuffer;
185 using WebCore::String;
186 using WebCore::SubstituteData;
187 using WebCore::TextIterator;
188 using WebCore::Timer;
189 using WebCore::VisiblePosition;
190 using WebCore::XPathResult;
191
192 using WebKit::PasswordAutocompleteListener;
193 using WebKit::WebCanvas;
194 using WebKit::WebConsoleMessage;
195 using WebKit::WebData;
196 using WebKit::WebDataSource;
197 using WebKit::WebDataSourceImpl;
198 using WebKit::WebFindOptions;
199 using WebKit::WebFrame;
200 using WebKit::WebFrameClient;
201 using WebKit::WebHistoryItem;
202 using WebKit::WebForm;
203 using WebKit::WebRange;
204 using WebKit::WebRect;
205 using WebKit::WebScriptSource;
206 using WebKit::WebSecurityOrigin;
207 using WebKit::WebSize;
208 using WebKit::WebString;
209 using WebKit::WebURL;
210 using WebKit::WebURLError;
211 using WebKit::WebURLRequest;
212 using WebKit::WebURLResponse;
213 using WebKit::WebVector;
214 using WebKit::WebView;
215 154
216 // Key for a StatsCounter tracking how many WebFrames are active. 155 // Key for a StatsCounter tracking how many WebFrames are active.
217 static const char* const kWebFrameActiveCount = "WebFrameActiveCount"; 156 static const char* const webFrameActiveCount = "WebFrameActiveCount";
218 157
219 static const char* const kOSDType = "application/opensearchdescription+xml"; 158 static const char* const osdType = "application/opensearchdescription+xml";
220 static const char* const kOSDRel = "search"; 159 static const char* const osdRel = "search";
221
222 // The separator between frames when the frames are converted to plain text.
223 static const wchar_t kFrameSeparator[] = L"\n\n";
224 static const size_t kFrameSeparatorLen = arraysize(kFrameSeparator) - 1;
225 160
226 // Backend for contentAsPlainText, this is a recursive function that gets 161 // Backend for contentAsPlainText, this is a recursive function that gets
227 // the text for the current frame and all of its subframes. It will append 162 // the text for the current frame and all of its subframes. It will append
228 // the text of each frame in turn to the |output| up to |max_chars| length. 163 // the text of each frame in turn to the |output| up to |maxChars| length.
229 // 164 //
230 // The |frame| must be non-NULL. 165 // The |frame| must be non-null.
231 static void FrameContentAsPlainText(size_t max_chars, Frame* frame, 166 static void frameContentAsPlainText(size_t maxChars, Frame* frame,
232 Vector<UChar>* output) { 167 Vector<UChar>* output)
233 Document* doc = frame->document(); 168 {
234 if (!doc) 169 Document* doc = frame->document();
235 return; 170 if (!doc)
236 171 return;
237 if (!frame->view()) 172
238 return; 173 if (!frame->view())
239 174 return;
240 // TextIterator iterates over the visual representation of the DOM. As such, 175
241 // it requires you to do a layout before using it (otherwise it'll crash). 176 // TextIterator iterates over the visual representation of the DOM. As such,
242 if (frame->view()->needsLayout()) 177 // it requires you to do a layout before using it (otherwise it'll crash).
243 frame->view()->layout(); 178 if (frame->view()->needsLayout())
244 179 frame->view()->layout();
245 // Select the document body. 180
246 RefPtr<Range> range(doc->createRange()); 181 // Select the document body.
247 ExceptionCode exception = 0; 182 RefPtr<Range> range(doc->createRange());
248 range->selectNodeContents(doc->body(), exception); 183 ExceptionCode exception = 0;
249 184 range->selectNodeContents(doc->body(), exception);
250 if (exception == 0) { 185
251 // The text iterator will walk nodes giving us text. This is similar to 186 if (exception == 0) {
252 // the plainText() function in TextIterator.h, but we implement the maximum 187 // The text iterator will walk nodes giving us text. This is similar to
253 // size and also copy the results directly into a wstring, avoiding the 188 // the plainText() function in TextIterator.h, but we implement the maximum
254 // string conversion. 189 // size and also copy the results directly into a wstring, avoiding the
255 for (TextIterator it(range.get()); !it.atEnd(); it.advance()) { 190 // string conversion.
256 const UChar* chars = it.characters(); 191 for (TextIterator it(range.get()); !it.atEnd(); it.advance()) {
257 if (!chars) { 192 const UChar* chars = it.characters();
258 if (it.length() != 0) { 193 if (!chars) {
259 // It appears from crash reports that an iterator can get into a state 194 if (it.length() != 0) {
260 // where the character count is nonempty but the character pointer is 195 // It appears from crash reports that an iterator can get into a state
261 // NULL. advance()ing it will then just add that many to the NULL 196 // where the character count is nonempty but the character pointer is
262 // pointer which won't be caught in a NULL check but will crash. 197 // null. advance()ing it will then just add that many to the null
263 // 198 // pointer which won't be caught in a null check but will crash.
264 // A NULL pointer and 0 length is common for some nodes. 199 //
265 // 200 // A null pointer and 0 length is common for some nodes.
266 // IF YOU CATCH THIS IN A DEBUGGER please let brettw know. We don't 201 //
267 // currently understand the conditions for this to occur. Ideally, the 202 // IF YOU CATCH THIS IN A DEBUGGER please let brettw know. We don't
268 // iterators would never get into the condition so we should fix them 203 // currently understand the conditions for this to occur. Ideally, the
269 // if we can. 204 // iterators would never get into the condition so we should fix them
270 ASSERT_NOT_REACHED(); 205 // if we can.
271 break; 206 ASSERT_NOT_REACHED();
207 break;
208 }
209
210 // Just got a null node, we can forge ahead!
211 continue;
212 }
213 size_t toAppend =
214 std::min(static_cast<size_t>(it.length()), maxChars - output->size());
215 output->append(chars, toAppend);
216 if (output->size() >= maxChars)
217 return; // Filled up the buffer.
272 } 218 }
273 219 }
274 // Just got a NULL node, we can forge ahead! 220
275 continue; 221 // The separator between frames when the frames are converted to plain text.
276 } 222 const UChar frameSeparator[] = { '\n', '\n' };
277 size_t to_append = std::min(static_cast<size_t>(it.length()), 223 const size_t frameSeparatorLen = 2;
278 max_chars - output->size()); 224
279 output->append(chars, to_append); 225 // Recursively walk the children.
280 if (output->size() >= max_chars) 226 FrameTree* frameTree = frame->tree();
281 return; // Filled up the buffer. 227 for (Frame* curChild = frameTree->firstChild(); curChild; curChild = curChild->tree()->nextSibling()) {
282 } 228 // Make sure the frame separator won't fill up the buffer, and give up if
283 } 229 // it will. The danger is if the separator will make the buffer longer than
284 230 // maxChars. This will cause the computation above:
285 // Recursively walk the children. 231 // maxChars - output->size()
286 FrameTree* frame_tree = frame->tree(); 232 // to be a negative number which will crash when the subframe is added.
287 for (Frame* cur_child = frame_tree->firstChild(); cur_child; 233 if (output->size() >= maxChars - frameSeparatorLen)
288 cur_child = cur_child->tree()->nextSibling()) { 234 return;
289 // Make sure the frame separator won't fill up the buffer, and give up if 235
290 // it will. The danger is if the separator will make the buffer longer than 236 output->append(frameSeparator, frameSeparatorLen);
291 // max_chars. This will cause the computation above: 237 frameContentAsPlainText(maxChars, curChild, output);
292 // max_chars - output->size() 238 if (output->size() >= maxChars)
293 // to be a negative number which will crash when the subframe is added. 239 return; // Filled up the buffer.
294 if (output->size() >= max_chars - kFrameSeparatorLen) 240 }
295 return;
296
297 output->append(kFrameSeparator, kFrameSeparatorLen);
298 FrameContentAsPlainText(max_chars, cur_child, output);
299 if (output->size() >= max_chars)
300 return; // Filled up the buffer.
301 }
302 } 241 }
303 242
304 // Simple class to override some of PrintContext behavior. 243 // Simple class to override some of PrintContext behavior.
305 class ChromePrintContext : public WebCore::PrintContext { 244 class ChromePrintContext : public PrintContext, public Noncopyable {
306 public: 245 public:
307 ChromePrintContext(Frame* frame) 246 ChromePrintContext(Frame* frame)
308 : PrintContext(frame), 247 : PrintContext(frame)
309 printed_page_width_(0) { 248 , m_printedPageWidth(0)
310 } 249 {
311 void begin(float width) { 250 }
312 ASSERT(!printed_page_width_); 251
313 printed_page_width_ = width; 252 void begin(float width)
314 WebCore::PrintContext::begin(printed_page_width_); 253 {
315 } 254 ASSERT(!m_printedPageWidth);
316 float getPageShrink(int pageNumber) const { 255 m_printedPageWidth = width;
317 IntRect pageRect = m_pageRects[pageNumber]; 256 PrintContext::begin(m_printedPageWidth);
318 return printed_page_width_ / pageRect.width(); 257 }
319 } 258
320 // Spools the printed page, a subrect of m_frame. 259 float getPageShrink(int pageNumber) const
321 // Skip the scale step. NativeTheme doesn't play well with scaling. Scaling 260 {
322 // is done browser side instead. 261 IntRect pageRect = m_pageRects[pageNumber];
323 // Returns the scale to be applied. 262 return m_printedPageWidth / pageRect.width();
324 float spoolPage(GraphicsContext& ctx, int pageNumber) { 263 }
325 IntRect pageRect = m_pageRects[pageNumber]; 264
326 float scale = printed_page_width_ / pageRect.width(); 265 // Spools the printed page, a subrect of m_frame. Skip the scale step.
327 266 // NativeTheme doesn't play well with scaling. Scaling is done browser side
328 ctx.save(); 267 // instead. Returns the scale to be applied.
329 ctx.translate(static_cast<float>(-pageRect.x()), 268 float spoolPage(GraphicsContext& ctx, int pageNumber)
330 static_cast<float>(-pageRect.y())); 269 {
331 ctx.clip(pageRect); 270 IntRect pageRect = m_pageRects[pageNumber];
332 m_frame->view()->paintContents(&ctx, pageRect); 271 float scale = m_printedPageWidth / pageRect.width();
333 ctx.restore(); 272
334 return scale; 273 ctx.save();
335 } 274 ctx.translate(static_cast<float>(-pageRect.x()),
336 protected: 275 static_cast<float>(-pageRect.y()));
337 // Set when printing. 276 ctx.clip(pageRect);
338 float printed_page_width_; 277 m_frame->view()->paintContents(&ctx, pageRect);
339 278 ctx.restore();
340 private: 279 return scale;
341 DISALLOW_COPY_AND_ASSIGN(ChromePrintContext); 280 }
281
282 private:
283 // Set when printing.
284 float m_printedPageWidth;
342 }; 285 };
343 286
344 static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader) { 287 static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader)
345 return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : NULL; 288 {
289 return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0;
346 } 290 }
347 291
348 292
349 // WebFrame ------------------------------------------------------------------- 293 // WebFrame -------------------------------------------------------------------
350 294
351 class WebFrameImpl::DeferredScopeStringMatches { 295 class WebFrameImpl::DeferredScopeStringMatches {
352 public: 296 public:
353 DeferredScopeStringMatches(WebFrameImpl* webframe, 297 DeferredScopeStringMatches(WebFrameImpl* webFrame,
354 int identifier, 298 int identifier,
355 const WebString& search_text, 299 const WebString& searchText,
356 const WebFindOptions& options, 300 const WebFindOptions& options,
357 bool reset) 301 bool reset)
358 : ALLOW_THIS_IN_INITIALIZER_LIST( 302 : m_timer(this, &DeferredScopeStringMatches::doTimeout)
359 timer_(this, &DeferredScopeStringMatches::DoTimeout)), 303 , m_webFrame(webFrame)
360 webframe_(webframe), 304 , m_identifier(identifier)
361 identifier_(identifier), 305 , m_searchText(searchText)
362 search_text_(search_text), 306 , m_options(options)
363 options_(options), 307 , m_reset(reset)
364 reset_(reset) { 308 {
365 timer_.startOneShot(0.0); 309 m_timer.startOneShot(0.0);
366 } 310 }
367 311
368 private: 312 private:
369 void DoTimeout(Timer<DeferredScopeStringMatches>*) { 313 void doTimeout(Timer<DeferredScopeStringMatches>*)
370 webframe_->CallScopeStringMatches( 314 {
371 this, identifier_, search_text_, options_, reset_); 315 m_webFrame->callScopeStringMatches(
372 } 316 this, m_identifier, m_searchText, m_options, m_reset);
373 317 }
374 Timer<DeferredScopeStringMatches> timer_; 318
375 RefPtr<WebFrameImpl> webframe_; 319 Timer<DeferredScopeStringMatches> m_timer;
376 int identifier_; 320 RefPtr<WebFrameImpl> m_webFrame;
377 WebString search_text_; 321 int m_identifier;
378 WebFindOptions options_; 322 WebString m_searchText;
379 bool reset_; 323 WebFindOptions m_options;
324 bool m_reset;
380 }; 325 };
381 326
382 327
383 // WebFrame ------------------------------------------------------------------- 328 // WebFrame -------------------------------------------------------------------
384 329
385 // static 330 WebFrame* WebFrame::frameForEnteredContext()
386 WebFrame* WebFrame::frameForEnteredContext() { 331 {
387 Frame* frame = 332 Frame* frame =
388 WebCore::ScriptController::retrieveFrameForEnteredContext(); 333 ScriptController::retrieveFrameForEnteredContext();
389 return WebFrameImpl::FromFrame(frame); 334 return WebFrameImpl::fromFrame(frame);
390 } 335 }
391 336
392 // static 337 WebFrame* WebFrame::frameForCurrentContext()
393 WebFrame* WebFrame::frameForCurrentContext() { 338 {
394 Frame* frame = 339 Frame* frame =
395 WebCore::ScriptController::retrieveFrameForCurrentContext(); 340 ScriptController::retrieveFrameForCurrentContext();
396 return WebFrameImpl::FromFrame(frame); 341 return WebFrameImpl::fromFrame(frame);
397 } 342 }
398 343
399 WebString WebFrameImpl::name() const { 344 WebString WebFrameImpl::name() const
400 return webkit_glue::StringToWebString(frame_->tree()->name()); 345 {
401 } 346 return m_frame->tree()->name();
402 347 }
403 WebURL WebFrameImpl::url() const { 348
404 const WebDataSource* ds = dataSource(); 349 WebURL WebFrameImpl::url() const
405 if (!ds) 350 {
351 const WebDataSource* ds = dataSource();
352 if (!ds)
353 return WebURL();
354 return ds->request().url();
355 }
356
357 WebURL WebFrameImpl::favIconURL() const
358 {
359 FrameLoader* frameLoader = m_frame->loader();
360 // The URL to the favicon may be in the header. As such, only
361 // ask the loader for the favicon if it's finished loading.
362 if (frameLoader->state() == FrameStateComplete) {
363 const KURL& url = frameLoader->iconURL();
364 if (!url.isEmpty())
365 return url;
366 }
406 return WebURL(); 367 return WebURL();
407 return ds->request().url(); 368 }
408 } 369
409 370 WebURL WebFrameImpl::openSearchDescriptionURL() const
410 WebURL WebFrameImpl::favIconURL() const { 371 {
411 WebCore::FrameLoader* frame_loader = frame_->loader(); 372 FrameLoader* frameLoader = m_frame->loader();
412 // The URL to the favicon may be in the header. As such, only 373 if (frameLoader->state() == FrameStateComplete
413 // ask the loader for the favicon if it's finished loading. 374 && m_frame->document() && m_frame->document()->head()
414 if (frame_loader->state() == WebCore::FrameStateComplete) { 375 && !m_frame->tree()->parent()) {
415 const KURL& url = frame_loader->iconURL(); 376 HTMLHeadElement* head = m_frame->document()->head();
416 if (!url.isEmpty()) { 377 if (head) {
417 return webkit_glue::KURLToWebURL(url); 378 RefPtr<HTMLCollection> children = head->children();
418 } 379 for (Node* child = children->firstItem(); child != 0; child = children->nextItem()) {
419 } 380 HTMLLinkElement* linkElement = toHTMLLinkElement(child);
420 return WebURL(); 381 if (linkElement
421 } 382 && linkElement->type() == osdType
422 383 && linkElement->rel() == osdRel
423 WebURL WebFrameImpl::openSearchDescriptionURL() const { 384 && !linkElement->href().isEmpty())
424 WebCore::FrameLoader* frame_loader = frame_->loader(); 385 return linkElement->href();
425 if (frame_loader->state() == WebCore::FrameStateComplete && 386 }
426 frame_->document() && frame_->document()->head() &&
427 !frame_->tree()->parent()) {
428 WebCore::HTMLHeadElement* head = frame_->document()->head();
429 if (head) {
430 RefPtr<WebCore::HTMLCollection> children = head->children();
431 for (Node* child = children->firstItem(); child != NULL;
432 child = children->nextItem()) {
433 WebCore::HTMLLinkElement* link_element =
434 WebKit::toHTMLLinkElement(child);
435 if (link_element && link_element->type() == kOSDType &&
436 link_element->rel() == kOSDRel && !link_element->href().isEmpty()) {
437 return webkit_glue::KURLToWebURL(link_element->href());
438 } 387 }
439 } 388 }
440 } 389 return WebURL();
441 } 390 }
442 return WebURL(); 391
443 } 392 WebSize WebFrameImpl::scrollOffset() const
444 393 {
445 WebSize WebFrameImpl::scrollOffset() const { 394 FrameView* view = frameView();
446 WebCore::FrameView* view = frameview(); 395 if (view)
447 if (view) 396 return view->scrollOffset();
448 return webkit_glue::IntSizeToWebSize(view->scrollOffset()); 397
449 398 return WebSize();
450 return WebSize(); 399 }
451 } 400
452 401 WebSize WebFrameImpl::contentsSize() const
453 WebSize WebFrameImpl::contentsSize() const { 402 {
454 return webkit_glue::IntSizeToWebSize(frame()->view()->contentsSize()); 403 return frame()->view()->contentsSize();
455 } 404 }
456 405
457 int WebFrameImpl::contentsPreferredWidth() const { 406 int WebFrameImpl::contentsPreferredWidth() const
458 if ((frame_->document() != NULL) && 407 {
459 (frame_->document()->renderView() != NULL)) { 408 if ((m_frame->document() != 0) && (m_frame->document()->renderView() != 0))
460 return frame_->document()->renderView()->minPrefWidth(); 409 return m_frame->document()->renderView()->minPrefWidth();
461 } else { 410
462 return 0; 411 return 0;
463 } 412 }
464 } 413
465 414 bool WebFrameImpl::hasVisibleContent() const
466 bool WebFrameImpl::hasVisibleContent() const { 415 {
467 return frame()->view()->visibleWidth() > 0 && 416 return frame()->view()->visibleWidth() > 0 && frame()->view()->visibleHeight() > 0;
468 frame()->view()->visibleHeight() > 0; 417 }
469 } 418
470 419 WebView* WebFrameImpl::view() const
471 WebView* WebFrameImpl::view() const { 420 {
472 return GetWebViewImpl(); 421 return viewImpl();
473 } 422 }
474 423
475 WebFrame* WebFrameImpl::opener() const { 424 WebFrame* WebFrameImpl::opener() const
476 Frame* opener = NULL; 425 {
477 if (frame_) 426 Frame* opener = 0;
478 opener = frame_->loader()->opener(); 427 if (m_frame)
479 return FromFrame(opener); 428 opener = m_frame->loader()->opener();
480 } 429 return fromFrame(opener);
481 430 }
482 WebFrame* WebFrameImpl::parent() const { 431
483 Frame *parent = NULL; 432 WebFrame* WebFrameImpl::parent() const
484 if (frame_) 433 {
485 parent = frame_->tree()->parent(); 434 Frame *parent = 0;
486 return FromFrame(parent); 435 if (m_frame)
487 } 436 parent = m_frame->tree()->parent();
488 437 return fromFrame(parent);
489 WebFrame* WebFrameImpl::top() const { 438 }
490 if (frame_) 439
491 return FromFrame(frame_->tree()->top()); 440 WebFrame* WebFrameImpl::top() const
492 441 {
493 return NULL; 442 if (m_frame)
494 } 443 return fromFrame(m_frame->tree()->top());
495 444
496 WebFrame* WebFrameImpl::firstChild() const { 445 return 0;
497 return FromFrame(frame()->tree()->firstChild()); 446 }
498 } 447
499 448 WebFrame* WebFrameImpl::firstChild() const
500 WebFrame* WebFrameImpl::lastChild() const { 449 {
501 return FromFrame(frame()->tree()->lastChild()); 450 return fromFrame(frame()->tree()->firstChild());
502 } 451 }
503 452
504 WebFrame* WebFrameImpl::nextSibling() const { 453 WebFrame* WebFrameImpl::lastChild() const
505 return FromFrame(frame()->tree()->nextSibling()); 454 {
506 } 455 return fromFrame(frame()->tree()->lastChild());
507 456 }
508 WebFrame* WebFrameImpl::previousSibling() const { 457
509 return FromFrame(frame()->tree()->previousSibling()); 458 WebFrame* WebFrameImpl::nextSibling() const
510 } 459 {
511 460 return fromFrame(frame()->tree()->nextSibling());
512 WebFrame* WebFrameImpl::traverseNext(bool wrap) const { 461 }
513 return FromFrame(frame()->tree()->traverseNextWithWrap(wrap)); 462
514 } 463 WebFrame* WebFrameImpl::previousSibling() const
515 464 {
516 WebFrame* WebFrameImpl::traversePrevious(bool wrap) const { 465 return fromFrame(frame()->tree()->previousSibling());
517 return FromFrame(frame()->tree()->traversePreviousWithWrap(wrap)); 466 }
518 } 467
519 468 WebFrame* WebFrameImpl::traverseNext(bool wrap) const
520 WebFrame* WebFrameImpl::findChildByName(const WebKit::WebString& name) const { 469 {
521 return FromFrame(frame()->tree()->child( 470 return fromFrame(frame()->tree()->traverseNextWithWrap(wrap));
522 webkit_glue::WebStringToString(name))); 471 }
523 } 472
524 473 WebFrame* WebFrameImpl::traversePrevious(bool wrap) const
525 WebFrame* WebFrameImpl::findChildByExpression( 474 {
526 const WebKit::WebString& xpath) const { 475 return fromFrame(frame()->tree()->traversePreviousWithWrap(wrap));
527 if (xpath.isEmpty()) 476 }
528 return NULL; 477
529 478 WebFrame* WebFrameImpl::findChildByName(const WebString& name) const
530 Document* document = frame_->document(); 479 {
531 480 return fromFrame(frame()->tree()->child(name));
532 ExceptionCode ec = 0; 481 }
533 PassRefPtr<XPathResult> xpath_result = 482
534 document->evaluate(webkit_glue::WebStringToString(xpath), 483 WebFrame* WebFrameImpl::findChildByExpression(const WebString& xpath) const
535 document, 484 {
536 NULL, /* namespace */ 485 if (xpath.isEmpty())
537 XPathResult::ORDERED_NODE_ITERATOR_TYPE, 486 return 0;
538 NULL, /* XPathResult object */ 487
539 ec); 488 Document* document = m_frame->document();
540 if (!xpath_result.get()) 489
541 return NULL; 490 ExceptionCode ec = 0;
542 491 PassRefPtr<XPathResult> xpathResult =
543 Node* node = xpath_result->iterateNext(ec); 492 document->evaluate(xpath,
544 493 document,
545 if (!node || !node->isFrameOwnerElement()) 494 0, // namespace
546 return NULL; 495 XPathResult::ORDERED_NODE_ITERATOR_TYPE,
547 HTMLFrameOwnerElement* frame_element = 496 0, // XPathResult object
548 static_cast<HTMLFrameOwnerElement*>(node); 497 ec);
549 return FromFrame(frame_element->contentFrame()); 498 if (!xpathResult.get())
550 } 499 return 0;
551 500
552 void WebFrameImpl::forms(WebVector<WebForm>& results) const { 501 Node* node = xpathResult->iterateNext(ec);
553 if (!frame_) 502
554 return; 503 if (!node || !node->isFrameOwnerElement())
555 504 return 0;
556 RefPtr<WebCore::HTMLCollection> forms = frame_->document()->forms(); 505 HTMLFrameOwnerElement* frameElement =
557 size_t form_count = forms->length(); 506 static_cast<HTMLFrameOwnerElement*>(node);
558 507 return fromFrame(frameElement->contentFrame());
559 WebVector<WebForm> temp(form_count); 508 }
560 for (size_t i = 0; i < form_count; ++i) { 509
561 Node* node = forms->item(i); 510 void WebFrameImpl::forms(WebVector<WebForm>& results) const
562 // Strange but true, sometimes item can be NULL. 511 {
563 if (node) { 512 if (!m_frame)
564 temp[i] = webkit_glue::HTMLFormElementToWebForm( 513 return;
565 static_cast<HTMLFormElement*>(node)); 514
566 } 515 RefPtr<HTMLCollection> forms = m_frame->document()->forms();
567 } 516 size_t formCount = forms->length();
568 results.swap(temp); 517
569 } 518 WebVector<WebForm> temp(formCount);
570 519 for (size_t i = 0; i < formCount; ++i) {
571 WebSecurityOrigin WebFrameImpl::securityOrigin() const { 520 Node* node = forms->item(i);
572 if (!frame_ || !frame_->document()) 521 // Strange but true, sometimes item can be 0.
573 return WebSecurityOrigin(); 522 if (node)
574 523 temp[i] = static_cast<HTMLFormElement*>(node);
575 return webkit_glue::SecurityOriginToWebSecurityOrigin( 524 }
576 frame_->document()->securityOrigin()); 525 results.swap(temp);
577 } 526 }
578 527
579 void WebFrameImpl::grantUniversalAccess() { 528 WebSecurityOrigin WebFrameImpl::securityOrigin() const
580 ASSERT(frame_ && frame_->document()); 529 {
581 if (frame_ && frame_->document()) { 530 if (!m_frame || !m_frame->document())
582 frame_->document()->securityOrigin()->grantUniversalAccess(); 531 return WebSecurityOrigin();
583 } 532
584 } 533 return WebSecurityOrigin(m_frame->document()->securityOrigin());
585 534 }
586 NPObject* WebFrameImpl::windowObject() const { 535
587 if (!frame_) 536 void WebFrameImpl::grantUniversalAccess()
588 return NULL; 537 {
589 538 ASSERT(m_frame && m_frame->document());
590 return frame_->script()->windowScriptNPObject(); 539 if (m_frame && m_frame->document())
591 } 540 m_frame->document()->securityOrigin()->grantUniversalAccess();
592 541 }
593 void WebFrameImpl::bindToWindowObject(const WebString& name, 542
594 NPObject* object) { 543 NPObject* WebFrameImpl::windowObject() const
595 ASSERT(frame_); 544 {
596 if (!frame_ || !frame_->script()->isEnabled()) 545 if (!m_frame)
597 return; 546 return 0;
598 547
599 String key = webkit_glue::WebStringToString(name); 548 return m_frame->script()->windowScriptNPObject();
549 }
550
551 void WebFrameImpl::bindToWindowObject(const WebString& name, NPObject* object)
552 {
553 ASSERT(m_frame);
554 if (!m_frame || !m_frame->script()->isEnabled())
555 return;
556
557 String key = name;
600 #if USE(V8) 558 #if USE(V8)
601 frame_->script()->bindToWindowObject(frame_, key, object); 559 m_frame->script()->bindToWindowObject(m_frame, key, object);
602 #else 560 #else
603 notImplemented(); 561 notImplemented();
604 #endif 562 #endif
605 } 563 }
606 564
607 void WebFrameImpl::executeScript(const WebScriptSource& source) { 565 void WebFrameImpl::executeScript(const WebScriptSource& source)
608 frame_->script()->executeScript( 566 {
609 WebCore::ScriptSourceCode( 567 m_frame->script()->executeScript(
610 webkit_glue::WebStringToString(source.code), 568 ScriptSourceCode(source.code, source.url, source.startLine));
611 webkit_glue::WebURLToKURL(source.url),
612 source.startLine));
613 } 569 }
614 570
615 void WebFrameImpl::executeScriptInNewContext( 571 void WebFrameImpl::executeScriptInNewContext(
616 const WebScriptSource* sources_in, unsigned num_sources, 572 const WebScriptSource* sourcesIn, unsigned numSources, int extensionGroup)
617 int extension_group) { 573 {
618 Vector<WebCore::ScriptSourceCode> sources; 574 Vector<ScriptSourceCode> sources;
619 575
620 for (unsigned i = 0; i < num_sources; ++i) { 576 for (unsigned i = 0; i < numSources; ++i) {
621 sources.append(WebCore::ScriptSourceCode( 577 sources.append(ScriptSourceCode(
622 webkit_glue::WebStringToString(sources_in[i].code), 578 sourcesIn[i].code, sourcesIn[i].url, sourcesIn[i].startLine));
623 webkit_glue::WebURLToKURL(sources_in[i].url), 579 }
624 sources_in[i].startLine)); 580
625 } 581 m_frame->script()->evaluateInNewContext(sources, extensionGroup);
626
627 frame_->script()->evaluateInNewContext(sources, extension_group);
628 } 582 }
629 583
630 void WebFrameImpl::executeScriptInIsolatedWorld( 584 void WebFrameImpl::executeScriptInIsolatedWorld(
631 int world_id, const WebScriptSource* sources_in, unsigned num_sources, 585 int worldId, const WebScriptSource* sourcesIn, unsigned numSources,
632 int extension_group) { 586 int extensionGroup)
633 Vector<WebCore::ScriptSourceCode> sources; 587 {
634 588 Vector<ScriptSourceCode> sources;
635 for (unsigned i = 0; i < num_sources; ++i) { 589
636 sources.append(WebCore::ScriptSourceCode( 590 for (unsigned i = 0; i < numSources; ++i) {
637 webkit_glue::WebStringToString(sources_in[i].code), 591 sources.append(ScriptSourceCode(
638 webkit_glue::WebURLToKURL(sources_in[i].url), 592 sourcesIn[i].code, sourcesIn[i].url, sourcesIn[i].startLine));
639 sources_in[i].startLine)); 593 }
640 } 594
641 595 m_frame->script()->evaluateInIsolatedWorld(worldId, sources, extensionGroup);
642 frame_->script()->evaluateInIsolatedWorld(world_id, sources, extension_group); 596 }
643 } 597
644 598 void WebFrameImpl::addMessageToConsole(const WebConsoleMessage& message)
645 void WebFrameImpl::addMessageToConsole(const WebConsoleMessage& message) { 599 {
646 ASSERT(frame()); 600 ASSERT(frame());
647 601
648 WebCore::MessageLevel webcore_message_level; 602 MessageLevel webCoreMessageLevel;
649 switch (message.level) { 603 switch (message.level) {
650 case WebConsoleMessage::LevelTip: 604 case WebConsoleMessage::LevelTip:
651 webcore_message_level = WebCore::TipMessageLevel; 605 webCoreMessageLevel = TipMessageLevel;
652 break; 606 break;
653 case WebConsoleMessage::LevelLog: 607 case WebConsoleMessage::LevelLog:
654 webcore_message_level = WebCore::LogMessageLevel; 608 webCoreMessageLevel = LogMessageLevel;
655 break; 609 break;
656 case WebConsoleMessage::LevelWarning: 610 case WebConsoleMessage::LevelWarning:
657 webcore_message_level = WebCore::WarningMessageLevel; 611 webCoreMessageLevel = WarningMessageLevel;
658 break; 612 break;
659 case WebConsoleMessage::LevelError: 613 case WebConsoleMessage::LevelError:
660 webcore_message_level = WebCore::ErrorMessageLevel; 614 webCoreMessageLevel = ErrorMessageLevel;
661 break; 615 break;
662 default: 616 default:
663 ASSERT_NOT_REACHED(); 617 ASSERT_NOT_REACHED();
664 return; 618 return;
665 } 619 }
666 620
667 frame()->domWindow()->console()->addMessage( 621 frame()->domWindow()->console()->addMessage(
668 WebCore::OtherMessageSource, WebCore::LogMessageType, 622 OtherMessageSource, LogMessageType, webCoreMessageLevel, message.text,
669 webcore_message_level, webkit_glue::WebStringToString(message.text), 623 1, String());
670 1, String()); 624 }
671 } 625
672 626 void WebFrameImpl::collectGarbage()
673 void WebFrameImpl::collectGarbage() { 627 {
674 if (!frame_) 628 if (!m_frame)
675 return; 629 return;
676 if (!frame_->settings()->isJavaScriptEnabled()) 630 if (!m_frame->settings()->isJavaScriptEnabled())
677 return; 631 return;
678 // TODO(mbelshe): Move this to the ScriptController and make it JS neutral. 632 // FIXME: Move this to the ScriptController and make it JS neutral.
679 #if USE(V8) 633 #if USE(V8)
680 frame_->script()->collectGarbage(); 634 m_frame->script()->collectGarbage();
681 #else 635 #else
682 notImplemented(); 636 notImplemented();
683 #endif 637 #endif
684 } 638 }
685 639
686 #if USE(V8) 640 #if USE(V8)
687 // Returns the V8 context for this frame, or an empty handle if there is none. 641 // Returns the V8 context for this frame, or an empty handle if there is none.
688 v8::Local<v8::Context> WebFrameImpl::mainWorldScriptContext() const { 642 v8::Local<v8::Context> WebFrameImpl::mainWorldScriptContext() const
689 if (!frame_) 643 {
690 return v8::Local<v8::Context>(); 644 if (!m_frame)
691 645 return v8::Local<v8::Context>();
692 return WebCore::V8Proxy::mainWorldContext(frame_); 646
647 return V8Proxy::mainWorldContext(m_frame);
693 } 648 }
694 #endif 649 #endif
695 650
696 bool WebFrameImpl::insertStyleText( 651 bool WebFrameImpl::insertStyleText(
697 const WebString& css, const WebString& id) { 652 const WebString& css, const WebString& id) {
698 Document* document = frame()->document(); 653 Document* document = frame()->document();
699 if (!document) 654 if (!document)
655 return false;
656 Element* documentElement = document->documentElement();
657 if (!documentElement)
658 return false;
659
660 ExceptionCode err = 0;
661
662 if (!id.isEmpty()) {
663 Element* oldElement = document->getElementById(id);
664 if (oldElement) {
665 Node* parent = oldElement->parent();
666 if (!parent)
667 return false;
668 parent->removeChild(oldElement, err);
669 }
670 }
671
672 RefPtr<Element> stylesheet = document->createElement(
673 HTMLNames::styleTag, false);
674 if (!id.isEmpty())
675 stylesheet->setAttribute(HTMLNames::idAttr, id);
676 stylesheet->setTextContent(css, err);
677 ASSERT(!err);
678 Node* first = documentElement->firstChild();
679 bool success = documentElement->insertBefore(stylesheet, first, err);
680 ASSERT(success);
681 return success;
682 }
683
684 void WebFrameImpl::reload()
685 {
686 m_frame->loader()->history()->saveDocumentAndScrollState();
687
688 stopLoading(); // Make sure existing activity stops.
689 m_frame->loader()->reload();
690 }
691
692 void WebFrameImpl::loadRequest(const WebURLRequest& request)
693 {
694 ASSERT(!request.isNull());
695 const ResourceRequest& resourceRequest = request.toResourceRequest();
696
697 if (resourceRequest.url().protocolIs("javascript")) {
698 loadJavaScriptURL(resourceRequest.url());
699 return;
700 }
701
702 stopLoading(); // Make sure existing activity stops.
703 m_frame->loader()->load(resourceRequest, false);
704 }
705
706 void WebFrameImpl::loadHistoryItem(const WebHistoryItem& item)
707 {
708 RefPtr<HistoryItem> historyItem = PassRefPtr<HistoryItem>(item);
709 ASSERT(historyItem.get());
710
711 stopLoading(); // Make sure existing activity stops.
712
713 // If there is no currentItem, which happens when we are navigating in
714 // session history after a crash, we need to manufacture one otherwise WebKit
715 // hoarks. This is probably the wrong thing to do, but it seems to work.
716 RefPtr<HistoryItem> currentItem = m_frame->loader()->history()->currentItem();
717 if (!currentItem) {
718 currentItem = HistoryItem::create();
719 currentItem->setLastVisitWasFailure(true);
720 m_frame->loader()->history()->setCurrentItem(currentItem.get());
721 viewImpl()->setCurrentHistoryItem(currentItem.get());
722 }
723
724 m_frame->loader()->history()->goToItem(
725 historyItem.get(), FrameLoadTypeIndexedBackForward);
726 }
727
728 void WebFrameImpl::loadData(const WebData& data,
729 const WebString& mimeType,
730 const WebString& textEncoding,
731 const WebURL& baseURL,
732 const WebURL& unreachableURL,
733 bool replace)
734 {
735 SubstituteData substData(data, mimeType, textEncoding, unreachableURL);
736 ASSERT(substData.isValid());
737
738 stopLoading(); // Make sure existing activity stops.
739 m_frame->loader()->load(ResourceRequest(baseURL), substData, false);
740 if (replace) {
741 // Do this to force WebKit to treat the load as replacing the currently
742 // loaded page.
743 m_frame->loader()->setReplacing();
744 }
745 }
746
747 void WebFrameImpl::loadHTMLString(const WebData& data,
748 const WebURL& baseURL,
749 const WebURL& unreachableURL,
750 bool replace)
751 {
752 loadData(data,
753 WebString::fromUTF8("text/html"),
754 WebString::fromUTF8("UTF-8"),
755 baseURL,
756 unreachableURL,
757 replace);
758 }
759
760 bool WebFrameImpl::isLoading() const
761 {
762 if (!m_frame)
763 return false;
764 return m_frame->loader()->isLoading();
765 }
766
767 void WebFrameImpl::stopLoading()
768 {
769 if (!m_frame)
770 return;
771
772 // FIXME: Figure out what we should really do here. It seems like a bug
773 // that FrameLoader::stopLoading doesn't call stopAllLoaders.
774 m_frame->loader()->stopAllLoaders();
775 m_frame->loader()->stopLoading(UnloadEventPolicyNone);
776 }
777
778 WebDataSource* WebFrameImpl::provisionalDataSource() const
779 {
780 FrameLoader* frameLoader = m_frame->loader();
781
782 // We regard the policy document loader as still provisional.
783 DocumentLoader* docLoader = frameLoader->provisionalDocumentLoader();
784 if (!docLoader)
785 docLoader = frameLoader->policyDocumentLoader();
786
787 return DataSourceForDocLoader(docLoader);
788 }
789
790 WebDataSource* WebFrameImpl::dataSource() const
791 {
792 return DataSourceForDocLoader(m_frame->loader()->documentLoader());
793 }
794
795 WebHistoryItem WebFrameImpl::previousHistoryItem() const
796 {
797 // We use the previous item here because documentState (filled-out forms)
798 // only get saved to history when it becomes the previous item. The caller
799 // is expected to query the history item after a navigation occurs, after
800 // the desired history item has become the previous entry.
801 return WebHistoryItem(viewImpl()->previousHistoryItem());
802 }
803
804 WebHistoryItem WebFrameImpl::currentHistoryItem() const
805 {
806 m_frame->loader()->history()->saveDocumentAndScrollState();
807
808 return WebHistoryItem(m_frame->page()->backForwardList()->currentItem());
809 }
810
811 void WebFrameImpl::enableViewSourceMode(bool enable)
812 {
813 if (m_frame)
814 m_frame->setInViewSourceMode(enable);
815 }
816
817 bool WebFrameImpl::isViewSourceModeEnabled() const
818 {
819 if (m_frame)
820 return m_frame->inViewSourceMode();
821
700 return false; 822 return false;
701 WebCore::Element* document_element = document->documentElement(); 823 }
702 if (!document_element) 824
703 return false; 825 void WebFrameImpl::setReferrerForRequest(
704 826 WebURLRequest& request, const WebURL& referrerURL) {
705 ExceptionCode err = 0; 827 String referrer;
706 828 if (referrerURL.isEmpty())
707 if (!id.isEmpty()) { 829 referrer = m_frame->loader()->outgoingReferrer();
708 WebCore::Element* old_element = 830 else
709 document->getElementById(webkit_glue::WebStringToString(id)); 831 referrer = referrerURL.spec().utf16();
710 if (old_element) { 832 if (SecurityOrigin::shouldHideReferrer(request.url(), referrer))
711 Node* parent = old_element->parent(); 833 return;
712 if (!parent) 834 request.setHTTPHeaderField(WebString::fromUTF8("Referer"), referrer);
835 }
836
837 void WebFrameImpl::dispatchWillSendRequest(WebURLRequest& request)
838 {
839 ResourceResponse response;
840 m_frame->loader()->client()->dispatchWillSendRequest(
841 0, 0, request.toMutableResourceRequest(), response);
842 }
843
844 void WebFrameImpl::commitDocumentData(const char* data, size_t dataLen)
845 {
846 DocumentLoader* documentLoader = m_frame->loader()->documentLoader();
847
848 // Set the text encoding. This calls begin() for us. It is safe to call
849 // this multiple times (Mac does: page/mac/WebCoreFrameBridge.mm).
850 bool userChosen = true;
851 String encoding = documentLoader->overrideEncoding();
852 if (encoding.isNull()) {
853 userChosen = false;
854 encoding = documentLoader->response().textEncodingName();
855 }
856 m_frame->loader()->setEncoding(encoding, userChosen);
857
858 // NOTE: mac only does this if there is a document
859 m_frame->loader()->addData(data, dataLen);
860 }
861
862 unsigned WebFrameImpl::unloadListenerCount() const
863 {
864 return frame()->domWindow()->pendingUnloadEventListeners();
865 }
866
867 bool WebFrameImpl::isProcessingUserGesture() const
868 {
869 return frame()->loader()->isProcessingUserGesture();
870 }
871
872 bool WebFrameImpl::willSuppressOpenerInNewFrame() const
873 {
874 return frame()->loader()->suppressOpenerInNewFrame();
875 }
876
877 void WebFrameImpl::replaceSelection(const WebString& text)
878 {
879 RefPtr<DocumentFragment> fragment = createFragmentFromText(
880 frame()->selection()->toNormalizedRange().get(), text);
881 applyCommand(ReplaceSelectionCommand::create(
882 frame()->document(), fragment.get(), false, true, true));
883 }
884
885 void WebFrameImpl::insertText(const WebString& text)
886 {
887 frame()->editor()->insertText(text, 0);
888 }
889
890 void WebFrameImpl::setMarkedText(
891 const WebString& text, unsigned location, unsigned length)
892 {
893 Editor* editor = frame()->editor();
894
895 editor->confirmComposition(text);
896
897 Vector<CompositionUnderline> decorations;
898 editor->setComposition(text, decorations, location, length);
899 }
900
901 void WebFrameImpl::unmarkText()
902 {
903 frame()->editor()->confirmCompositionWithoutDisturbingSelection();
904 }
905
906 bool WebFrameImpl::hasMarkedText() const
907 {
908 return frame()->editor()->hasComposition();
909 }
910
911 WebRange WebFrameImpl::markedRange() const
912 {
913 return frame()->editor()->compositionRange();
914 }
915
916 bool WebFrameImpl::executeCommand(const WebString& name)
917 {
918 ASSERT(frame());
919
920 if (name.length() <= 2)
713 return false; 921 return false;
714 parent->removeChild(old_element, err); 922
715 } 923 // Since we don't have NSControl, we will convert the format of command
716 } 924 // string and call the function on Editor directly.
717 925 String command = name;
718 RefPtr<WebCore::Element> stylesheet = document->createElement( 926
719 WebCore::HTMLNames::styleTag, false); 927 // Make sure the first letter is upper case.
720 if (!id.isEmpty()) 928 command.replace(0, 1, command.substring(0, 1).upper());
721 stylesheet->setAttribute(WebCore::HTMLNames::idAttr, 929
722 webkit_glue::WebStringToString(id)); 930 // Remove the trailing ':' if existing.
723 stylesheet->setTextContent(webkit_glue::WebStringToString(css), err); 931 if (command[command.length() - 1] == UChar(':'))
724 ASSERT(!err); 932 command = command.substring(0, command.length() - 1);
725 WebCore::Node* first = document_element->firstChild(); 933
726 bool success = document_element->insertBefore(stylesheet, first, err); 934 bool rv = true;
727 ASSERT(success); 935
728 return success; 936 // Specially handling commands that Editor::execCommand does not directly
729 } 937 // support.
730 938 if (command == "DeleteToEndOfParagraph") {
731 void WebFrameImpl::reload() { 939 Editor* editor = frame()->editor();
732 frame_->loader()->history()->saveDocumentAndScrollState(); 940 if (!editor->deleteWithDirection(SelectionController::FORWARD,
733 941 ParagraphBoundary,
734 stopLoading(); // Make sure existing activity stops. 942 true,
735 frame_->loader()->reload(); 943 false)) {
736 } 944 editor->deleteWithDirection(SelectionController::FORWARD,
737 945 CharacterGranularity,
738 void WebFrameImpl::loadRequest(const WebURLRequest& request) { 946 true,
739 const ResourceRequest* resource_request = 947 false);
740 webkit_glue::WebURLRequestToResourceRequest(&request); 948 }
741 ASSERT(resource_request); 949 } else if (command == "Indent")
742 950 frame()->editor()->indent();
743 if (resource_request->url().protocolIs("javascript")) { 951 else if (command == "Outdent")
744 LoadJavaScriptURL(resource_request->url()); 952 frame()->editor()->outdent();
745 return; 953 else if (command == "DeleteBackward")
746 } 954 rv = frame()->editor()->command(AtomicString("BackwardDelete")).execute();
747 955 else if (command == "DeleteForward")
748 stopLoading(); // Make sure existing activity stops. 956 rv = frame()->editor()->command(AtomicString("ForwardDelete")).execute();
749 frame_->loader()->load(*resource_request, false); 957 else if (command == "AdvanceToNextMisspelling") {
750 } 958 // False must be passed here, or the currently selected word will never be
751 959 // skipped.
752 void WebFrameImpl::loadHistoryItem(const WebHistoryItem& item) { 960 frame()->editor()->advanceToNextMisspelling(false);
753 RefPtr<HistoryItem> history_item = 961 } else if (command == "ToggleSpellPanel")
754 webkit_glue::WebHistoryItemToHistoryItem(item); 962 frame()->editor()->showSpellingGuessPanel();
755 ASSERT(history_item.get()); 963 else
756 964 rv = frame()->editor()->command(command).execute();
757 stopLoading(); // Make sure existing activity stops. 965 return rv;
758 966 }
759 // If there is no current_item, which happens when we are navigating in 967
760 // session history after a crash, we need to manufacture one otherwise WebKit 968 bool WebFrameImpl::executeCommand(const WebString& name, const WebString& value)
761 // hoarks. This is probably the wrong thing to do, but it seems to work. 969 {
762 RefPtr<HistoryItem> current_item = frame_->loader()->history()->currentItem(); 970 ASSERT(frame());
763 if (!current_item) { 971 String webName = name;
764 current_item = HistoryItem::create(); 972
765 current_item->setLastVisitWasFailure(true); 973 // moveToBeginningOfDocument and moveToEndfDocument are only handled by WebKit
766 frame_->loader()->history()->setCurrentItem(current_item.get()); 974 // for editable nodes.
767 GetWebViewImpl()->SetCurrentHistoryItem(current_item.get()); 975 if (!frame()->editor()->canEdit() && webName == "moveToBeginningOfDocument")
768 } 976 return viewImpl()->propagateScroll(ScrollUp, ScrollByDocument);
769 977
770 frame_->loader()->history()->goToItem(history_item.get(), 978 if (!frame()->editor()->canEdit() && webName == "moveToEndOfDocument")
771 WebCore::FrameLoadTypeIndexedBackForward); 979 return viewImpl()->propagateScroll(ScrollDown, ScrollByDocument);
772 } 980
773 981 return frame()->editor()->command(webName).execute(value);
774 void WebFrameImpl::loadData(const WebData& data, 982 }
775 const WebString& mime_type, 983
776 const WebString& text_encoding, 984 bool WebFrameImpl::isCommandEnabled(const WebString& name) const
777 const WebURL& base_url, 985 {
778 const WebURL& unreachable_url, 986 ASSERT(frame());
779 bool replace) { 987 return frame()->editor()->command(name).isEnabled();
780 SubstituteData subst_data( 988 }
781 webkit_glue::WebDataToSharedBuffer(data), 989
782 webkit_glue::WebStringToString(mime_type), 990 void WebFrameImpl::enableContinuousSpellChecking(bool enable)
783 webkit_glue::WebStringToString(text_encoding), 991 {
784 webkit_glue::WebURLToKURL(unreachable_url)); 992 if (enable == isContinuousSpellCheckingEnabled())
785 ASSERT(subst_data.isValid()); 993 return;
786 994 frame()->editor()->toggleContinuousSpellChecking();
787 stopLoading(); // Make sure existing activity stops. 995 }
788 frame_->loader()->load(ResourceRequest(webkit_glue::WebURLToKURL(base_url)), 996
789 subst_data, false); 997 bool WebFrameImpl::isContinuousSpellCheckingEnabled() const
790 if (replace) { 998 {
791 // Do this to force WebKit to treat the load as replacing the currently 999 return frame()->editor()->isContinuousSpellCheckingEnabled();
792 // loaded page. 1000 }
793 frame_->loader()->setReplacing(); 1001
794 } 1002 bool WebFrameImpl::hasSelection() const
795 } 1003 {
796 1004 // frame()->selection()->isNone() never returns true.
797 void WebFrameImpl::loadHTMLString(const WebData& data, 1005 return (frame()->selection()->start() != frame()->selection()->end());
798 const WebURL& base_url, 1006 }
799 const WebURL& unreachable_url, 1007
800 bool replace) { 1008 WebRange WebFrameImpl::selectionRange() const
801 loadData(data, 1009 {
802 WebString::fromUTF8("text/html"), 1010 return frame()->selection()->toNormalizedRange();
803 WebString::fromUTF8("UTF-8"), 1011 }
804 base_url, 1012
805 unreachable_url, 1013 WebString WebFrameImpl::selectionAsText() const
806 replace); 1014 {
807 } 1015 RefPtr<Range> range = frame()->selection()->toNormalizedRange();
808 1016 if (!range.get())
809 bool WebFrameImpl::isLoading() const { 1017 return WebString();
810 if (!frame_) 1018
811 return false; 1019 String text = range->text();
812 return frame_->loader()->isLoading();
813 }
814
815 void WebFrameImpl::stopLoading() {
816 if (!frame_)
817 return;
818
819 // TODO(darin): Figure out what we should really do here. It seems like a
820 // bug that FrameLoader::stopLoading doesn't call stopAllLoaders.
821 frame_->loader()->stopAllLoaders();
822 frame_->loader()->stopLoading(WebCore::UnloadEventPolicyNone);
823 }
824
825 WebDataSource* WebFrameImpl::provisionalDataSource() const {
826 FrameLoader* frame_loader = frame_->loader();
827
828 // We regard the policy document loader as still provisional.
829 DocumentLoader* doc_loader = frame_loader->provisionalDocumentLoader();
830 if (!doc_loader)
831 doc_loader = frame_loader->policyDocumentLoader();
832
833 return DataSourceForDocLoader(doc_loader);
834 }
835
836 WebDataSource* WebFrameImpl::dataSource() const {
837 return DataSourceForDocLoader(frame_->loader()->documentLoader());
838 }
839
840 WebHistoryItem WebFrameImpl::previousHistoryItem() const {
841 // We use the previous item here because documentState (filled-out forms)
842 // only get saved to history when it becomes the previous item. The caller
843 // is expected to query the history item after a navigation occurs, after
844 // the desired history item has become the previous entry.
845 return webkit_glue::HistoryItemToWebHistoryItem(
846 GetWebViewImpl()->GetPreviousHistoryItem());
847 }
848
849 WebHistoryItem WebFrameImpl::currentHistoryItem() const {
850 frame_->loader()->history()->saveDocumentAndScrollState();
851
852 return webkit_glue::HistoryItemToWebHistoryItem(
853 frame_->page()->backForwardList()->currentItem());
854 }
855
856 void WebFrameImpl::enableViewSourceMode(bool enable) {
857 if (frame_)
858 frame_->setInViewSourceMode(enable);
859 }
860
861 bool WebFrameImpl::isViewSourceModeEnabled() const {
862 if (frame_)
863 return frame_->inViewSourceMode();
864
865 return false;
866 }
867
868 void WebFrameImpl::setReferrerForRequest(
869 WebURLRequest& request, const WebURL& referrer_url) {
870 String referrer;
871 if (referrer_url.isEmpty()) {
872 referrer = frame_->loader()->outgoingReferrer();
873 } else {
874 referrer = webkit_glue::WebStringToString(referrer_url.spec().utf16());
875 }
876 if (SecurityOrigin::shouldHideReferrer(
877 webkit_glue::WebURLToKURL(request.url()), referrer))
878 return;
879 request.setHTTPHeaderField(WebString::fromUTF8("Referer"),
880 webkit_glue::StringToWebString(referrer));
881 }
882
883 void WebFrameImpl::dispatchWillSendRequest(WebURLRequest& request) {
884 ResourceResponse response;
885 frame_->loader()->client()->dispatchWillSendRequest(NULL, 0,
886 *webkit_glue::WebURLRequestToMutableResourceRequest(&request),
887 response);
888 }
889
890 void WebFrameImpl::commitDocumentData(const char* data, size_t data_len) {
891 DocumentLoader* document_loader = frame_->loader()->documentLoader();
892
893 // Set the text encoding. This calls begin() for us. It is safe to call
894 // this multiple times (Mac does: page/mac/WebCoreFrameBridge.mm).
895 bool user_chosen = true;
896 String encoding = document_loader->overrideEncoding();
897 if (encoding.isNull()) {
898 user_chosen = false;
899 encoding = document_loader->response().textEncodingName();
900 }
901 frame_->loader()->setEncoding(encoding, user_chosen);
902
903 // NOTE: mac only does this if there is a document
904 frame_->loader()->addData(data, data_len);
905 }
906
907 unsigned WebFrameImpl::unloadListenerCount() const {
908 return frame()->domWindow()->pendingUnloadEventListeners();
909 }
910
911 bool WebFrameImpl::isProcessingUserGesture() const {
912 return frame()->loader()->isProcessingUserGesture();
913 }
914
915 bool WebFrameImpl::willSuppressOpenerInNewFrame() const {
916 return frame()->loader()->suppressOpenerInNewFrame();
917 }
918
919 void WebFrameImpl::replaceSelection(const WebString& wtext) {
920 String text = webkit_glue::WebStringToString(wtext);
921 RefPtr<DocumentFragment> fragment = createFragmentFromText(
922 frame()->selection()->toNormalizedRange().get(), text);
923 WebCore::applyCommand(WebCore::ReplaceSelectionCommand::create(
924 frame()->document(), fragment.get(), false, true, true));
925 }
926
927 void WebFrameImpl::insertText(const WebString& text) {
928 frame()->editor()->insertText(webkit_glue::WebStringToString(text), NULL);
929 }
930
931 void WebFrameImpl::setMarkedText(
932 const WebString& text, unsigned location, unsigned length) {
933 WebCore::Editor* editor = frame()->editor();
934 WebCore::String str = webkit_glue::WebStringToString(text);
935
936 editor->confirmComposition(str);
937
938 WTF::Vector<WebCore::CompositionUnderline> decorations;
939 editor->setComposition(str, decorations, location, length);
940 }
941
942 void WebFrameImpl::unmarkText() {
943 frame()->editor()->confirmCompositionWithoutDisturbingSelection();
944 }
945
946 bool WebFrameImpl::hasMarkedText() const {
947 return frame()->editor()->hasComposition();
948 }
949
950 WebRange WebFrameImpl::markedRange() const {
951 return webkit_glue::RangeToWebRange(frame()->editor()->compositionRange());
952 }
953
954 bool WebFrameImpl::executeCommand(const WebString& name) {
955 ASSERT(frame());
956
957 if (name.length() <= 2)
958 return false;
959
960 // Since we don't have NSControl, we will convert the format of command
961 // string and call the function on Editor directly.
962 String command = webkit_glue::WebStringToString(name);
963
964 // Make sure the first letter is upper case.
965 command.replace(0, 1, command.substring(0, 1).upper());
966
967 // Remove the trailing ':' if existing.
968 if (command[command.length() - 1] == UChar(':'))
969 command = command.substring(0, command.length() - 1);
970
971 bool rv = true;
972
973 // Specially handling commands that Editor::execCommand does not directly
974 // support.
975 if (command == "DeleteToEndOfParagraph") {
976 WebCore::Editor* editor = frame()->editor();
977 if (!editor->deleteWithDirection(WebCore::SelectionController::FORWARD,
978 WebCore::ParagraphBoundary,
979 true,
980 false)) {
981 editor->deleteWithDirection(WebCore::SelectionController::FORWARD,
982 WebCore::CharacterGranularity,
983 true,
984 false);
985 }
986 } else if (command == "Indent") {
987 frame()->editor()->indent();
988 } else if (command == "Outdent") {
989 frame()->editor()->outdent();
990 } else if (command == "DeleteBackward") {
991 rv = frame()->editor()->command(AtomicString("BackwardDelete")).execute();
992 } else if (command == "DeleteForward") {
993 rv = frame()->editor()->command(AtomicString("ForwardDelete")).execute();
994 } else if (command == "AdvanceToNextMisspelling") {
995 // False must be passed here, or the currently selected word will never be
996 // skipped.
997 frame()->editor()->advanceToNextMisspelling(false);
998 } else if (command == "ToggleSpellPanel") {
999 frame()->editor()->showSpellingGuessPanel();
1000 } else {
1001 rv = frame()->editor()->command(command).execute();
1002 }
1003 return rv;
1004 }
1005
1006 bool WebFrameImpl::executeCommand(const WebString& name,
1007 const WebString& value) {
1008 ASSERT(frame());
1009 WebCore::String web_name = webkit_glue::WebStringToString(name);
1010
1011 // moveToBeginningOfDocument and moveToEndfDocument are only handled by WebKit
1012 // for editable nodes.
1013 if (!frame()->editor()->canEdit() &&
1014 web_name == "moveToBeginningOfDocument") {
1015 return GetWebViewImpl()->PropagateScroll(WebCore::ScrollUp,
1016 WebCore::ScrollByDocument);
1017 } else if (!frame()->editor()->canEdit() &&
1018 web_name == "moveToEndOfDocument") {
1019 return GetWebViewImpl()->PropagateScroll(WebCore::ScrollDown,
1020 WebCore::ScrollByDocument);
1021 } else {
1022 return frame()->editor()->command(web_name).
1023 execute(webkit_glue::WebStringToString(value));
1024 }
1025 }
1026
1027 bool WebFrameImpl::isCommandEnabled(const WebString& name) const {
1028 ASSERT(frame());
1029 return frame()->editor()->command(webkit_glue::WebStringToString(name)).
1030 isEnabled();
1031 }
1032
1033 void WebFrameImpl::enableContinuousSpellChecking(bool enable) {
1034 if (enable == isContinuousSpellCheckingEnabled())
1035 return;
1036 frame()->editor()->toggleContinuousSpellChecking();
1037 }
1038
1039 bool WebFrameImpl::isContinuousSpellCheckingEnabled() const {
1040 return frame()->editor()->isContinuousSpellCheckingEnabled();
1041 }
1042
1043 bool WebFrameImpl::hasSelection() const {
1044 // frame()->selection()->isNone() never returns true.
1045 return (frame()->selection()->start() != frame()->selection()->end());
1046 }
1047
1048 WebRange WebFrameImpl::selectionRange() const {
1049 return webkit_glue::RangeToWebRange(
1050 frame()->selection()->toNormalizedRange());
1051 }
1052
1053 WebString WebFrameImpl::selectionAsText() const {
1054 RefPtr<Range> range = frame()->selection()->toNormalizedRange();
1055 if (!range.get())
1056 return WebString();
1057
1058 String text = range->text();
1059 #if PLATFORM(WIN_OS) 1020 #if PLATFORM(WIN_OS)
1060 WebCore::replaceNewlinesWithWindowsStyleNewlines(text); 1021 replaceNewlinesWithWindowsStyleNewlines(text);
1061 #endif 1022 #endif
1062 WebCore::replaceNBSPWithSpace(text); 1023 replaceNBSPWithSpace(text);
1063 return webkit_glue::StringToWebString(text); 1024 return text;
1064 } 1025 }
1065 1026
1066 WebString WebFrameImpl::selectionAsMarkup() const { 1027 WebString WebFrameImpl::selectionAsMarkup() const
1067 RefPtr<Range> range = frame()->selection()->toNormalizedRange(); 1028 {
1068 if (!range.get()) 1029 RefPtr<Range> range = frame()->selection()->toNormalizedRange();
1069 return WebString(); 1030 if (!range.get())
1070 1031 return WebString();
1071 String markup = WebCore::createMarkup(range.get(), 0); 1032
1072 return webkit_glue::StringToWebString(markup); 1033 return createMarkup(range.get(), 0);
1073 } 1034 }
1074 1035
1075 int WebFrameImpl::printBegin(const WebSize& page_size) { 1036 int WebFrameImpl::printBegin(const WebSize& pageSize)
1076 ASSERT(!frame()->document()->isFrameSet()); 1037 {
1077 1038 ASSERT(!frame()->document()->isFrameSet());
1078 print_context_.set(new ChromePrintContext(frame())); 1039
1079 WebCore::FloatRect rect(0, 0, 1040 m_printContext.set(new ChromePrintContext(frame()));
1080 static_cast<float>(page_size.width), 1041 FloatRect rect(0, 0, static_cast<float>(pageSize.width),
1081 static_cast<float>(page_size.height)); 1042 static_cast<float>(pageSize.height));
1082 print_context_->begin(rect.width()); 1043 m_printContext->begin(rect.width());
1083 float page_height; 1044 float pageHeight;
1084 // We ignore the overlays calculation for now since they are generated in the 1045 // We ignore the overlays calculation for now since they are generated in the
1085 // browser. page_height is actually an output parameter. 1046 // browser. pageHeight is actually an output parameter.
1086 print_context_->computePageRects(rect, 0, 0, 1.0, page_height); 1047 m_printContext->computePageRects(rect, 0, 0, 1.0, pageHeight);
1087 return print_context_->pageCount(); 1048 return m_printContext->pageCount();
1088 } 1049 }
1089 1050
1090 float WebFrameImpl::getPrintPageShrink(int page) { 1051 float WebFrameImpl::getPrintPageShrink(int page)
1091 // Ensure correct state. 1052 {
1092 if (!print_context_.get() || page < 0) { 1053 // Ensure correct state.
1093 ASSERT_NOT_REACHED(); 1054 if (!m_printContext.get() || page < 0) {
1094 return 0; 1055 ASSERT_NOT_REACHED();
1095 } 1056 return 0;
1096 1057 }
1097 return print_context_->getPageShrink(page); 1058
1098 } 1059 return m_printContext->getPageShrink(page);
1099 1060 }
1100 float WebFrameImpl::printPage(int page, WebCanvas* canvas) { 1061
1101 // Ensure correct state. 1062 float WebFrameImpl::printPage(int page, WebCanvas* canvas)
1102 if (!print_context_.get() || page < 0 || !frame() || !frame()->document()) { 1063 {
1103 ASSERT_NOT_REACHED(); 1064 // Ensure correct state.
1104 return 0; 1065 if (!m_printContext.get() || page < 0 || !frame() || !frame()->document()) {
1105 } 1066 ASSERT_NOT_REACHED();
1067 return 0;
1068 }
1106 1069
1107 #if PLATFORM(WIN_OS) || PLATFORM(LINUX) || PLATFORM(FREEBSD) 1070 #if PLATFORM(WIN_OS) || PLATFORM(LINUX) || PLATFORM(FREEBSD)
1108 PlatformContextSkia context(canvas); 1071 PlatformContextSkia context(canvas);
1109 GraphicsContext spool(&context); 1072 GraphicsContext spool(&context);
1110 #elif PLATFORM(DARWIN) 1073 #elif PLATFORM(DARWIN)
1111 GraphicsContext spool(canvas); 1074 GraphicsContext spool(canvas);
1112 WebCore::LocalCurrentGraphicsContext localContext(&spool); 1075 LocalCurrentGraphicsContext localContext(&spool);
1113 #endif 1076 #endif
1114 1077
1115 return print_context_->spoolPage(spool, page); 1078 return m_printContext->spoolPage(spool, page);
1116 } 1079 }
1117 1080
1118 void WebFrameImpl::printEnd() { 1081 void WebFrameImpl::printEnd()
1119 ASSERT(print_context_.get()); 1082 {
1120 if (print_context_.get()) 1083 ASSERT(m_printContext.get());
1121 print_context_->end(); 1084 if (m_printContext.get())
1122 print_context_.clear(); 1085 m_printContext->end();
1123 } 1086 m_printContext.clear();
1124 1087 }
1125 bool WebFrameImpl::find(int request_id, 1088
1126 const WebString& search_text, 1089 bool WebFrameImpl::find(int identifier,
1090 const WebString& searchText,
1127 const WebFindOptions& options, 1091 const WebFindOptions& options,
1128 bool wrap_within_frame, 1092 bool wrapWithinFrame,
1129 WebRect* selection_rect) { 1093 WebRect* selectionRect)
1130 WebCore::String webcore_string = webkit_glue::WebStringToString(search_text); 1094 {
1131 1095 WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
1132 WebFrameImpl* const main_frame_impl = GetWebViewImpl()->main_frame(); 1096
1133 1097 if (!options.findNext)
1134 if (!options.findNext) 1098 frame()->page()->unmarkAllTextMatches();
1135 frame()->page()->unmarkAllTextMatches(); 1099 else
1136 else 1100 setMarkerActive(m_activeMatch.get(), false); // Active match is changing.
1137 SetMarkerActive(active_match_.get(), false); // Active match is changing. 1101
1138 1102 // Starts the search from the current selection.
1139 // Starts the search from the current selection. 1103 bool startInSelection = true;
1140 bool start_in_selection = true; 1104
1141 1105 // If the user has selected something since the last Find operation we want
1142 // If the user has selected something since the last Find operation we want 1106 // to start from there. Otherwise, we start searching from where the last Find
1143 // to start from there. Otherwise, we start searching from where the last Find 1107 // operation left off (either a Find or a FindNext operation).
1144 // operation left off (either a Find or a FindNext operation). 1108 VisibleSelection selection(frame()->selection()->selection());
1145 VisibleSelection selection(frame()->selection()->selection()); 1109 if (selection.isNone() && m_activeMatch) {
1146 if (selection.isNone() && active_match_) { 1110 selection = VisibleSelection(m_activeMatch.get());
1147 selection = VisibleSelection(active_match_.get()); 1111 frame()->selection()->setSelection(selection);
1148 frame()->selection()->setSelection(selection); 1112 }
1149 } 1113
1150 1114 ASSERT(frame() && frame()->view());
1151 ASSERT(frame() && frame()->view()); 1115 bool found = frame()->findString(
1152 bool found = frame()->findString(webcore_string, options.forward, 1116 searchText, options.forward, options.matchCase, wrapWithinFrame,
1153 options.matchCase, wrap_within_frame, 1117 startInSelection);
1154 start_in_selection); 1118 if (found) {
1155 if (found) { 1119 // Store which frame was active. This will come in handy later when we
1156 // Store which frame was active. This will come in handy later when we 1120 // change the active match ordinal below.
1157 // change the active match ordinal below. 1121 WebFrameImpl* oldActiveFrame = mainFrameImpl->m_activeMatchFrame;
1158 WebFrameImpl* old_active_frame = main_frame_impl->active_match_frame_; 1122 // Set this frame as the active frame (the one with the active highlight).
1159 // Set this frame as the active frame (the one with the active highlight). 1123 mainFrameImpl->m_activeMatchFrame = this;
1160 main_frame_impl->active_match_frame_ = this; 1124
1161 1125 // We found something, so we can now query the selection for its position.
1162 // We found something, so we can now query the selection for its position. 1126 VisibleSelection newSelection(frame()->selection()->selection());
1163 VisibleSelection new_selection(frame()->selection()->selection()); 1127 IntRect currSelectionRect;
1164 IntRect curr_selection_rect; 1128
1165 1129 // If we thought we found something, but it couldn't be selected (perhaps
1166 // If we thought we found something, but it couldn't be selected (perhaps 1130 // because it was marked -webkit-user-select: none), we can't set it to
1167 // because it was marked -webkit-user-select: none), we can't set it to 1131 // be active but we still continue searching. This matches Safari's
1168 // be active but we still continue searching. This matches Safari's 1132 // behavior, including some oddities when selectable and un-selectable text
1169 // behavior, including some oddities when selectable and un-selectable text 1133 // are mixed on a page: see https://bugs.webkit.org/show_bug.cgi?id=19127.
1170 // are mixed on a page: see https://bugs.webkit.org/show_bug.cgi?id=19127. 1134 if (newSelection.isNone() || (newSelection.start() == newSelection.end()))
1171 if (new_selection.isNone() || 1135 m_activeMatch = 0;
1172 (new_selection.start() == new_selection.end())) { 1136 else {
1173 active_match_ = NULL; 1137 m_activeMatch = newSelection.toNormalizedRange();
1138 currSelectionRect = m_activeMatch->boundingBox();
1139 setMarkerActive(m_activeMatch.get(), true); // Active.
1140 // WebKit draws the highlighting for all matches.
1141 executeCommand(WebString::fromUTF8("Unselect"));
1142 }
1143
1144 if (!options.findNext) {
1145 // This is a Find operation, so we set the flag to ask the scoping effort
1146 // to find the active rect for us so we can update the ordinal (n of m).
1147 m_locatingActiveRect = true;
1148 } else {
1149 if (oldActiveFrame != this) {
1150 // If the active frame has changed it means that we have a multi-frame
1151 // page and we just switch to searching in a new frame. Then we just
1152 // want to reset the index.
1153 if (options.forward)
1154 m_activeMatchIndex = 0;
1155 else
1156 m_activeMatchIndex = m_lastMatchCount - 1;
1157 } else {
1158 // We are still the active frame, so increment (or decrement) the
1159 // |m_activeMatchIndex|, wrapping if needed (on single frame pages).
1160 options.forward ? ++m_activeMatchIndex : --m_activeMatchIndex;
1161 if (m_activeMatchIndex + 1 > m_lastMatchCount)
1162 m_activeMatchIndex = 0;
1163 if (m_activeMatchIndex + 1 == 0)
1164 m_activeMatchIndex = m_lastMatchCount - 1;
1165 }
1166 if (selectionRect) {
1167 WebRect rect = frame()->view()->convertToContainingWindow(currSelectionRect);
1168 rect.x -= frameView()->scrollOffset().width();
1169 rect.y -= frameView()->scrollOffset().height();
1170 *selectionRect = rect;
1171
1172 reportFindInPageSelection(rect, m_activeMatchIndex + 1, identifier);
1173 }
1174 }
1174 } else { 1175 } else {
1175 active_match_ = new_selection.toNormalizedRange(); 1176 // Nothing was found in this frame.
1176 curr_selection_rect = active_match_->boundingBox(); 1177 m_activeMatch = 0;
1177 SetMarkerActive(active_match_.get(), true); // Active. 1178
1178 // WebKit draws the highlighting for all matches. 1179 // Erase all previous tickmarks and highlighting.
1179 executeCommand(WebString::fromUTF8("Unselect")); 1180 invalidateArea(InvalidateAll);
1180 } 1181 }
1181 1182
1182 if (!options.findNext) { 1183 return found;
1183 // This is a Find operation, so we set the flag to ask the scoping effort 1184 }
1184 // to find the active rect for us so we can update the ordinal (n of m). 1185
1185 locating_active_rect_ = true; 1186 void WebFrameImpl::stopFinding(bool clearSelection)
1186 } else { 1187 {
1187 if (old_active_frame != this) { 1188 if (!clearSelection)
1188 // If the active frame has changed it means that we have a multi-frame 1189 setFindEndstateFocusAndSelection();
1189 // page and we just switch to searching in a new frame. Then we just 1190 cancelPendingScopingEffort();
1190 // want to reset the index. 1191
1191 if (options.forward) 1192 // Remove all markers for matches found and turn off the highlighting.
1192 active_match_index_ = 0; 1193 if (!parent())
1193 else 1194 frame()->document()->removeMarkers(DocumentMarker::TextMatch);
1194 active_match_index_ = last_match_count_ - 1; 1195 frame()->setMarkedTextMatchesAreHighlighted(false);
1195 } else { 1196
1196 // We are still the active frame, so increment (or decrement) the 1197 // Let the frame know that we don't want tickmarks or highlighting anymore.
1197 // |active_match_index|, wrapping if needed (on single frame pages). 1198 invalidateArea(InvalidateAll);
1198 options.forward ? ++active_match_index_ : --active_match_index_; 1199 }
1199 if (active_match_index_ + 1 > last_match_count_) 1200
1200 active_match_index_ = 0; 1201 void WebFrameImpl::scopeStringMatches(int identifier,
1201 if (active_match_index_ + 1 == 0) 1202 const WebString& searchText,
1202 active_match_index_ = last_match_count_ - 1;
1203 }
1204 if (selection_rect) {
1205 WebRect rect = webkit_glue::IntRectToWebRect(
1206 frame()->view()->convertToContainingWindow(curr_selection_rect));
1207 rect.x -= frameview()->scrollOffset().width();
1208 rect.y -= frameview()->scrollOffset().height();
1209 *selection_rect = rect;
1210
1211 ReportFindInPageSelection(rect,
1212 active_match_index_ + 1,
1213 request_id);
1214 }
1215 }
1216 } else {
1217 // Nothing was found in this frame.
1218 active_match_ = NULL;
1219
1220 // Erase all previous tickmarks and highlighting.
1221 InvalidateArea(INVALIDATE_ALL);
1222 }
1223
1224 return found;
1225 }
1226
1227 void WebFrameImpl::stopFinding(bool clear_selection) {
1228 if (!clear_selection)
1229 SetFindEndstateFocusAndSelection();
1230 cancelPendingScopingEffort();
1231
1232 // Remove all markers for matches found and turn off the highlighting.
1233 if (!parent())
1234 frame()->document()->removeMarkers(WebCore::DocumentMarker::TextMatch);
1235 frame()->setMarkedTextMatchesAreHighlighted(false);
1236
1237 // Let the frame know that we don't want tickmarks or highlighting anymore.
1238 InvalidateArea(INVALIDATE_ALL);
1239 }
1240
1241 void WebFrameImpl::scopeStringMatches(int request_id,
1242 const WebString& search_text,
1243 const WebFindOptions& options, 1203 const WebFindOptions& options,
1244 bool reset) { 1204 bool reset)
1245 if (!ShouldScopeMatches(search_text)) 1205 {
1246 return; 1206 if (!shouldScopeMatches(searchText))
1247 1207 return;
1248 WebFrameImpl* main_frame_impl = GetWebViewImpl()->main_frame(); 1208
1249 1209 WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
1250 if (reset) { 1210
1251 // This is a brand new search, so we need to reset everything. 1211 if (reset) {
1252 // Scoping is just about to begin. 1212 // This is a brand new search, so we need to reset everything.
1253 scoping_complete_ = false; 1213 // Scoping is just about to begin.
1254 // Clear highlighting for this frame. 1214 m_scopingComplete = false;
1255 if (frame()->markedTextMatchesAreHighlighted()) 1215 // Clear highlighting for this frame.
1256 frame()->page()->unmarkAllTextMatches(); 1216 if (frame()->markedTextMatchesAreHighlighted())
1257 // Clear the counters from last operation. 1217 frame()->page()->unmarkAllTextMatches();
1258 last_match_count_ = 0; 1218 // Clear the counters from last operation.
1259 next_invalidate_after_ = 0; 1219 m_lastMatchCount = 0;
1260 1220 m_nextInvalidateAfter = 0;
1261 resume_scoping_from_range_ = NULL; 1221
1262 1222 m_resumeScopingFromRange = 0;
1263 main_frame_impl->frames_scoping_count_++; 1223
1264 1224 mainFrameImpl->m_framesScopingCount++;
1265 // Now, defer scoping until later to allow find operation to finish quickly. 1225
1266 ScopeStringMatchesSoon( 1226 // Now, defer scoping until later to allow find operation to finish quickly.
1267 request_id, 1227 scopeStringMatchesSoon(
1268 search_text, 1228 identifier,
1269 options, 1229 searchText,
1270 false); // false=we just reset, so don't do it again. 1230 options,
1271 return; 1231 false); // false=we just reset, so don't do it again.
1272 } 1232 return;
1273 1233 }
1274 WebCore::String webcore_string = webkit_glue::String16ToString(search_text); 1234
1275 1235 RefPtr<Range> searchRange(rangeOfContents(frame()->document()));
1276 RefPtr<Range> search_range(rangeOfContents(frame()->document())); 1236
1277 1237 ExceptionCode ec = 0, ec2 = 0;
1278 ExceptionCode ec = 0, ec2 = 0; 1238 if (m_resumeScopingFromRange.get()) {
1279 if (resume_scoping_from_range_.get()) { 1239 // This is a continuation of a scoping operation that timed out and didn't
1280 // This is a continuation of a scoping operation that timed out and didn't 1240 // complete last time around, so we should start from where we left off.
1281 // complete last time around, so we should start from where we left off. 1241 searchRange->setStart(m_resumeScopingFromRange->startContainer(),
1282 search_range->setStart(resume_scoping_from_range_->startContainer(), 1242 m_resumeScopingFromRange->startOffset(ec2) + 1,
1283 resume_scoping_from_range_->startOffset(ec2) + 1, 1243 ec);
1284 ec); 1244 if (ec != 0 || ec2 != 0) {
1285 if (ec != 0 || ec2 != 0) { 1245 if (ec2 != 0) // A non-zero |ec| happens when navigating during search.
1286 if (ec2 != 0) // A non-zero |ec| happens when navigating during search. 1246 ASSERT_NOT_REACHED();
1287 ASSERT_NOT_REACHED(); 1247 return;
1288 return; 1248 }
1289 } 1249 }
1290 } 1250
1291 1251 // This timeout controls how long we scope before releasing control. This
1292 // This timeout controls how long we scope before releasing control. This 1252 // value does not prevent us from running for longer than this, but it is
1293 // value does not prevent us from running for longer than this, but it is 1253 // periodically checked to see if we have exceeded our allocated time.
1294 // periodically checked to see if we have exceeded our allocated time. 1254 const double maxScopingDuration = 0.1; // seconds
1295 const double kTimeout = 0.1; // seconds 1255
1296 1256 int matchCount = 0;
1297 int match_count = 0; 1257 bool timedOut = false;
1298 bool timeout = false; 1258 double startTime = currentTime();
1299 double start_time = currentTime(); 1259 do {
1300 do { 1260 // Find next occurrence of the search string.
1301 // Find next occurrence of the search string. 1261 // FIXME: (http://b/1088245) This WebKit operation may run for longer
1302 // TODO(finnur): (http://b/1088245) This WebKit operation may run 1262 // than the timeout value, and is not interruptible as it is currently
1303 // for longer than the timeout value, and is not interruptible as it is 1263 // written. We may need to rewrite it with interruptibility in mind, or
1304 // currently written. We may need to rewrite it with interruptibility in 1264 // find an alternative.
1305 // mind, or find an alternative. 1265 RefPtr<Range> resultRange(findPlainText(searchRange.get(),
1306 RefPtr<Range> result_range(findPlainText(search_range.get(), 1266 searchText,
1307 webcore_string, 1267 true,
1308 true, 1268 options.matchCase));
1309 options.matchCase)); 1269 if (resultRange->collapsed(ec)) {
1310 if (result_range->collapsed(ec)) { 1270 if (!resultRange->startContainer()->isInShadowTree())
1311 if (!result_range->startContainer()->isInShadowTree()) 1271 break;
1312 break; 1272
1313 1273 searchRange = rangeOfContents(frame()->document());
1314 search_range = rangeOfContents(frame()->document()); 1274 searchRange->setStartAfter(
1315 search_range->setStartAfter( 1275 resultRange->startContainer()->shadowAncestorNode(), ec);
1316 result_range->startContainer()->shadowAncestorNode(), ec); 1276 continue;
1317 continue; 1277 }
1318 } 1278
1319 1279 // A non-collapsed result range can in some funky whitespace cases still not
1320 // A non-collapsed result range can in some funky whitespace cases still not 1280 // advance the range's start position (4509328). Break to avoid infinite
1321 // advance the range's start position (4509328). Break to avoid infinite 1281 // loop. (This function is based on the implementation of
1322 // loop. (This function is based on the implementation of 1282 // Frame::markAllMatchesForText, which is where this safeguard comes from).
1323 // Frame::markAllMatchesForText, which is where this safeguard comes from). 1283 VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
1324 VisiblePosition new_start = endVisiblePosition(result_range.get(), 1284 if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
1325 WebCore::DOWNSTREAM); 1285 break;
1326 if (new_start == startVisiblePosition(search_range.get(), 1286
1327 WebCore::DOWNSTREAM)) 1287 // Only treat the result as a match if it is visible
1328 break; 1288 if (frame()->editor()->insideVisibleArea(resultRange.get())) {
1329 1289 ++matchCount;
1330 // Only treat the result as a match if it is visible 1290
1331 if (frame()->editor()->insideVisibleArea(result_range.get())) { 1291 setStart(searchRange.get(), newStart);
1332 ++match_count; 1292 Node* shadowTreeRoot = searchRange->shadowTreeRootNode();
1333 1293 if (searchRange->collapsed(ec) && shadowTreeRoot)
1334 setStart(search_range.get(), new_start); 1294 searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec);
1335 Node* shadow_tree_root = search_range->shadowTreeRootNode(); 1295
1336 if (search_range->collapsed(ec) && shadow_tree_root) 1296 // Catch a special case where Find found something but doesn't know what
1337 search_range->setEnd(shadow_tree_root, 1297 // the bounding box for it is. In this case we set the first match we find
1338 shadow_tree_root->childNodeCount(), ec); 1298 // as the active rect.
1339 1299 IntRect resultBounds = resultRange->boundingBox();
1340 // Catch a special case where Find found something but doesn't know what 1300 IntRect activeSelectionRect;
1341 // the bounding box for it is. In this case we set the first match we find 1301 if (m_locatingActiveRect) {
1342 // as the active rect. 1302 activeSelectionRect = m_activeMatch.get() ?
1343 IntRect result_bounds = result_range->boundingBox(); 1303 m_activeMatch->boundingBox() : resultBounds;
1344 IntRect active_selection_rect; 1304 }
1345 if (locating_active_rect_) { 1305
1346 active_selection_rect = active_match_.get() ? 1306 // If the Find function found a match it will have stored where the
1347 active_match_->boundingBox() : result_bounds; 1307 // match was found in m_activeSelectionRect on the current frame. If we
1348 } 1308 // find this rect during scoping it means we have found the active
1349 1309 // tickmark.
1350 // If the Find function found a match it will have stored where the 1310 bool foundActiveMatch = false;
1351 // match was found in active_selection_rect_ on the current frame. If we 1311 if (m_locatingActiveRect && (activeSelectionRect == resultBounds)) {
1352 // find this rect during scoping it means we have found the active 1312 // We have found the active tickmark frame.
1353 // tickmark. 1313 mainFrameImpl->m_activeMatchFrame = this;
1354 bool found_active_match = false; 1314 foundActiveMatch = true;
1355 if (locating_active_rect_ && (active_selection_rect == result_bounds)) { 1315 // We also know which tickmark is active now.
1356 // We have found the active tickmark frame. 1316 m_activeMatchIndex = matchCount - 1;
1357 main_frame_impl->active_match_frame_ = this; 1317 // To stop looking for the active tickmark, we set this flag.
1358 found_active_match = true; 1318 m_locatingActiveRect = false;
1359 // We also know which tickmark is active now. 1319
1360 active_match_index_ = match_count - 1; 1320 // Notify browser of new location for the selected rectangle.
1361 // To stop looking for the active tickmark, we set this flag. 1321 resultBounds.move(-frameView()->scrollOffset().width(),
1362 locating_active_rect_ = false; 1322 -frameView()->scrollOffset().height());
1363 1323 reportFindInPageSelection(
1364 // Notify browser of new location for the selected rectangle. 1324 frame()->view()->convertToContainingWindow(resultBounds),
1365 result_bounds.move(-frameview()->scrollOffset().width(), 1325 m_activeMatchIndex + 1,
1366 -frameview()->scrollOffset().height()); 1326 identifier);
1367 ReportFindInPageSelection( 1327 }
1368 webkit_glue::IntRectToWebRect( 1328
1369 frame()->view()->convertToContainingWindow(result_bounds)), 1329 addMarker(resultRange.get(), foundActiveMatch);
1370 active_match_index_ + 1, 1330 }
1371 request_id); 1331
1372 } 1332 m_resumeScopingFromRange = resultRange;
1373 1333 timedOut = (currentTime() - startTime) >= maxScopingDuration;
1374 AddMarker(result_range.get(), found_active_match); 1334 } while (!timedOut);
1375 } 1335
1376 1336 // Remember what we search for last time, so we can skip searching if more
1377 resume_scoping_from_range_ = result_range; 1337 // letters are added to the search string (and last outcome was 0).
1378 timeout = (currentTime() - start_time) >= kTimeout; 1338 m_lastSearchString = searchText;
1379 } while (!timeout); 1339
1380 1340 if (matchCount > 0) {
1381 // Remember what we search for last time, so we can skip searching if more 1341 frame()->setMarkedTextMatchesAreHighlighted(true);
1382 // letters are added to the search string (and last outcome was 0). 1342
1383 last_search_string_ = search_text; 1343 m_lastMatchCount += matchCount;
1384 1344
1385 if (match_count > 0) { 1345 // Let the mainframe know how much we found during this pass.
1386 frame()->setMarkedTextMatchesAreHighlighted(true); 1346 mainFrameImpl->increaseMatchCount(matchCount, identifier);
1387 1347 }
1388 last_match_count_ += match_count; 1348
1389 1349 if (timedOut) {
1390 // Let the mainframe know how much we found during this pass. 1350 // If we found anything during this pass, we should redraw. However, we
1391 main_frame_impl->increaseMatchCount(match_count, request_id); 1351 // don't want to spam too much if the page is extremely long, so if we
1392 } 1352 // reach a certain point we start throttling the redraw requests.
1393 1353 if (matchCount > 0)
1394 if (timeout) { 1354 invalidateIfNecessary();
1395 // If we found anything during this pass, we should redraw. However, we 1355
1396 // don't want to spam too much if the page is extremely long, so if we 1356 // Scoping effort ran out of time, lets ask for another time-slice.
1397 // reach a certain point we start throttling the redraw requests. 1357 scopeStringMatchesSoon(
1398 if (match_count > 0) 1358 identifier,
1399 InvalidateIfNecessary(); 1359 searchText,
1400 1360 options,
1401 // Scoping effort ran out of time, lets ask for another time-slice. 1361 false); // don't reset.
1402 ScopeStringMatchesSoon( 1362 return; // Done for now, resume work later.
1403 request_id, 1363 }
1404 search_text, 1364
1405 options, 1365 // This frame has no further scoping left, so it is done. Other frames might,
1406 false); // don't reset. 1366 // of course, continue to scope matches.
1407 return; // Done for now, resume work later. 1367 m_scopingComplete = true;
1408 } 1368 mainFrameImpl->m_framesScopingCount--;
1409 1369
1410 // This frame has no further scoping left, so it is done. Other frames might, 1370 // If this is the last frame to finish scoping we need to trigger the final
1411 // of course, continue to scope matches. 1371 // update to be sent.
1412 scoping_complete_ = true; 1372 if (mainFrameImpl->m_framesScopingCount == 0)
1413 main_frame_impl->frames_scoping_count_--; 1373 mainFrameImpl->increaseMatchCount(0, identifier);
1414 1374
1415 // If this is the last frame to finish scoping we need to trigger the final 1375 // This frame is done, so show any scrollbar tickmarks we haven't drawn yet.
1416 // update to be sent. 1376 invalidateArea(InvalidateScrollbar);
1417 if (main_frame_impl->frames_scoping_count_ == 0) 1377 }
1418 main_frame_impl->increaseMatchCount(0, request_id); 1378
1419 1379 void WebFrameImpl::cancelPendingScopingEffort()
1420 // This frame is done, so show any scrollbar tickmarks we haven't drawn yet. 1380 {
1421 InvalidateArea(INVALIDATE_SCROLLBAR); 1381 deleteAllValues(m_deferredScopingWork);
1422 } 1382 m_deferredScopingWork.clear();
1423 1383
1424 void WebFrameImpl::cancelPendingScopingEffort() { 1384 m_activeMatchIndex = -1;
1425 deleteAllValues(deferred_scoping_work_); 1385 }
1426 deferred_scoping_work_.clear(); 1386
1427 1387 void WebFrameImpl::increaseMatchCount(int count, int identifier)
1428 active_match_index_ = -1; 1388 {
1429 } 1389 // This function should only be called on the mainframe.
1430 1390 ASSERT(!parent());
1431 void WebFrameImpl::increaseMatchCount(int count, int request_id) { 1391
1432 // This function should only be called on the mainframe. 1392 m_totalMatchCount += count;
1433 ASSERT(!parent()); 1393
1434 1394 // Update the UI with the latest findings.
1435 total_matchcount_ += count; 1395 if (client()) {
1436 1396 client()->reportFindInPageMatchCount(identifier, m_totalMatchCount,
1437 // Update the UI with the latest findings. 1397 m_framesScopingCount == 0);
1438 if (client()) { 1398 }
1439 client()->reportFindInPageMatchCount( 1399 }
1440 request_id, total_matchcount_, frames_scoping_count_ == 0); 1400
1441 } 1401 void WebFrameImpl::reportFindInPageSelection(const WebRect& selectionRect,
1442 } 1402 int activeMatchOrdinal,
1443 1403 int identifier)
1444 void WebFrameImpl::ReportFindInPageSelection(const WebRect& selection_rect, 1404 {
1445 int active_match_ordinal, 1405 // Update the UI with the latest selection rect.
1446 int request_id) { 1406 if (client()) {
1447 // Update the UI with the latest selection rect. 1407 client()->reportFindInPageSelection(
1448 if (client()) { 1408 identifier, ordinalOfFirstMatchForFrame(this) + activeMatchOrdinal,
1449 client()->reportFindInPageSelection( 1409 selectionRect);
1450 request_id, OrdinalOfFirstMatchForFrame(this) + active_match_ordinal, 1410 }
1451 selection_rect); 1411 }
1452 } 1412
1453 } 1413 void WebFrameImpl::resetMatchCount()
1454 1414 {
1455 void WebFrameImpl::resetMatchCount() { 1415 m_totalMatchCount = 0;
1456 total_matchcount_ = 0; 1416 m_framesScopingCount = 0;
1457 frames_scoping_count_ = 0; 1417 }
1458 } 1418
1459 1419 WebURL WebFrameImpl::completeURL(const WebString& url) const
1460 WebURL WebFrameImpl::completeURL(const WebString& url) const { 1420 {
1461 if (!frame_ || !frame_->document()) 1421 if (!m_frame || !m_frame->document())
1462 return WebURL(); 1422 return WebURL();
1463 1423
1464 return webkit_glue::KURLToWebURL( 1424 return m_frame->document()->completeURL(url);
1465 frame_->document()->completeURL(webkit_glue::WebStringToString(url))); 1425 }
1466 } 1426
1467 1427 WebString WebFrameImpl::contentAsText(size_t maxChars) const
1468 WebString WebFrameImpl::contentAsText(size_t max_chars) const { 1428 {
1469 if (!frame_) 1429 if (!m_frame)
1470 return WebString(); 1430 return WebString();
1471 1431
1472 Vector<UChar> text; 1432 Vector<UChar> text;
1473 FrameContentAsPlainText(max_chars, frame_, &text); 1433 frameContentAsPlainText(maxChars, m_frame, &text);
1474 return webkit_glue::StringToWebString(String::adopt(text)); 1434 return String::adopt(text);
1475 } 1435 }
1476 1436
1477 WebString WebFrameImpl::contentAsMarkup() const { 1437 WebString WebFrameImpl::contentAsMarkup() const
1478 return webkit_glue::StringToWebString(createFullMarkup(frame_->document())); 1438 {
1439 return createFullMarkup(m_frame->document());
1479 } 1440 }
1480 1441
1481 // WebFrameImpl public --------------------------------------------------------- 1442 // WebFrameImpl public ---------------------------------------------------------
1482 1443
1483 int WebFrameImpl::live_object_count_ = 0; 1444 int WebFrameImpl::m_liveObjectCount = 0;
1484 1445
1485 PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client) { 1446 PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client)
1486 return adoptRef(new WebFrameImpl(ClientHandle::create(client))); 1447 {
1487 } 1448 return adoptRef(new WebFrameImpl(ClientHandle::create(client)));
1488 1449 }
1489 WebFrameImpl::WebFrameImpl(PassRefPtr<ClientHandle> client_handle) 1450
1490 : ALLOW_THIS_IN_INITIALIZER_LIST(frame_loader_client_(this)), 1451 WebFrameImpl::WebFrameImpl(PassRefPtr<ClientHandle> clientHandle)
1491 client_handle_(client_handle), 1452 : m_frameLoaderClient(this)
1492 active_match_frame_(NULL), 1453 , m_clientHandle(clientHandle)
1493 active_match_index_(-1), 1454 , m_activeMatchFrame(0)
1494 locating_active_rect_(false), 1455 , m_activeMatchIndex(-1)
1495 resume_scoping_from_range_(NULL), 1456 , m_locatingActiveRect(false)
1496 last_match_count_(-1), 1457 , m_resumeScopingFromRange(0)
1497 total_matchcount_(-1), 1458 , m_lastMatchCount(-1)
1498 frames_scoping_count_(-1), 1459 , m_totalMatchCount(-1)
1499 scoping_complete_(false), 1460 , m_framesScopingCount(-1)
1500 next_invalidate_after_(0) { 1461 , m_scopingComplete(false)
1501 ChromiumBridge::incrementStatsCounter(kWebFrameActiveCount); 1462 , m_nextInvalidateAfter(0)
1502 live_object_count_++; 1463 {
1503 } 1464 ChromiumBridge::incrementStatsCounter(webFrameActiveCount);
1504 1465 m_liveObjectCount++;
1505 WebFrameImpl::~WebFrameImpl() { 1466 }
1506 ChromiumBridge::decrementStatsCounter(kWebFrameActiveCount); 1467
1507 live_object_count_--; 1468 WebFrameImpl::~WebFrameImpl()
1508 1469 {
1509 cancelPendingScopingEffort(); 1470 ChromiumBridge::decrementStatsCounter(webFrameActiveCount);
1510 ClearPasswordListeners(); 1471 m_liveObjectCount--;
1511 } 1472
1512 1473 cancelPendingScopingEffort();
1513 void WebFrameImpl::InitMainFrame(WebViewImpl* webview_impl) { 1474 clearPasswordListeners();
1514 RefPtr<Frame> frame = 1475 }
1515 Frame::create(webview_impl->page(), 0, &frame_loader_client_); 1476
1516 frame_ = frame.get(); 1477 void WebFrameImpl::initializeAsMainFrame(WebViewImpl* webViewImpl)
1517 1478 {
1518 // Add reference on behalf of FrameLoader. See comments in 1479 RefPtr<Frame> frame = Frame::create(webViewImpl->page(), 0, &m_frameLoaderClient);
1519 // WebFrameLoaderClient::frameLoaderDestroyed for more info. 1480 m_frame = frame.get();
1520 ref(); 1481
1521 1482 // Add reference on behalf of FrameLoader. See comments in
1522 // We must call init() after frame_ is assigned because it is referenced 1483 // WebFrameLoaderClient::frameLoaderDestroyed for more info.
1523 // during init(). 1484 ref();
1524 frame_->init(); 1485
1525 } 1486 // We must call init() after m_frame is assigned because it is referenced
1526 1487 // during init().
1527 PassRefPtr<Frame> WebFrameImpl::CreateChildFrame( 1488 m_frame->init();
1528 const FrameLoadRequest& request, HTMLFrameOwnerElement* owner_element) { 1489 }
1529 // TODO(darin): share code with initWithName() 1490
1530 1491 PassRefPtr<Frame> WebFrameImpl::createChildFrame(
1531 RefPtr<WebFrameImpl> webframe(adoptRef(new WebFrameImpl(client_handle_))); 1492 const FrameLoadRequest& request, HTMLFrameOwnerElement* ownerElement)
1532 1493 {
1533 // Add an extra ref on behalf of the Frame/FrameLoader, which references the 1494 RefPtr<WebFrameImpl> webframe(adoptRef(new WebFrameImpl(m_clientHandle)));
1534 // WebFrame via the FrameLoaderClient interface. See the comment at the top 1495
1535 // of this file for more info. 1496 // Add an extra ref on behalf of the Frame/FrameLoader, which references the
1536 webframe->ref(); 1497 // WebFrame via the FrameLoaderClient interface. See the comment at the top
1537 1498 // of this file for more info.
1538 RefPtr<Frame> child_frame = Frame::create( 1499 webframe->ref();
1539 frame_->page(), owner_element, &webframe->frame_loader_client_); 1500
1540 webframe->frame_ = child_frame.get(); 1501 RefPtr<Frame> childFrame = Frame::create(
1541 1502 m_frame->page(), ownerElement, &webframe->m_frameLoaderClient);
1542 child_frame->tree()->setName(request.frameName()); 1503 webframe->m_frame = childFrame.get();
1543 1504
1544 frame_->tree()->appendChild(child_frame); 1505 childFrame->tree()->setName(request.frameName());
1545 1506
1546 // Frame::init() can trigger onload event in the parent frame, 1507 m_frame->tree()->appendChild(childFrame);
1547 // which may detach this frame and trigger a null-pointer access 1508
1548 // in FrameTree::removeChild. Move init() after appendChild call 1509 // Frame::init() can trigger onload event in the parent frame,
1549 // so that webframe->frame_ is in the tree before triggering 1510 // which may detach this frame and trigger a null-pointer access
1550 // onload event handler. 1511 // in FrameTree::removeChild. Move init() after appendChild call
1551 // Because the event handler may set webframe->frame_ to null, 1512 // so that webframe->mFrame is in the tree before triggering
1552 // it is necessary to check the value after calling init() and 1513 // onload event handler.
1553 // return without loading URL. 1514 // Because the event handler may set webframe->mFrame to null,
1554 // (b:791612) 1515 // it is necessary to check the value after calling init() and
1555 child_frame->init(); // create an empty document 1516 // return without loading URL.
1556 if (!child_frame->tree()->parent()) 1517 // (b:791612)
1557 return NULL; 1518 childFrame->init(); // create an empty document
1558 1519 if (!childFrame->tree()->parent())
1559 frame_->loader()->loadURLIntoChildFrame( 1520 return 0;
1560 request.resourceRequest().url(), 1521
1561 request.resourceRequest().httpReferrer(), 1522 m_frame->loader()->loadURLIntoChildFrame(
1562 child_frame.get()); 1523 request.resourceRequest().url(),
1563 1524 request.resourceRequest().httpReferrer(),
1564 // A synchronous navigation (about:blank) would have already processed 1525 childFrame.get());
1565 // onload, so it is possible for the frame to have already been destroyed by 1526
1566 // script in the page. 1527 // A synchronous navigation (about:blank) would have already processed
1567 if (!child_frame->tree()->parent()) 1528 // onload, so it is possible for the frame to have already been destroyed by
1568 return NULL; 1529 // script in the page.
1569 1530 if (!childFrame->tree()->parent())
1570 return child_frame.release(); 1531 return 0;
1571 } 1532
1572 1533 return childFrame.release();
1573 void WebFrameImpl::Layout() { 1534 }
1574 // layout this frame 1535
1575 FrameView* view = frame_->view(); 1536 void WebFrameImpl::layout()
1576 if (view) 1537 {
1577 view->layoutIfNeededRecursive(); 1538 // layout this frame
1578 } 1539 FrameView* view = m_frame->view();
1579 1540 if (view)
1580 void WebFrameImpl::Paint(WebCanvas* canvas, const WebRect& rect) { 1541 view->layoutIfNeededRecursive();
1581 if (rect.isEmpty()) 1542 }
1582 return; 1543
1583 IntRect dirty_rect(webkit_glue::WebRectToIntRect(rect)); 1544 void WebFrameImpl::paint(WebCanvas* canvas, const WebRect& rect)
1545 {
1546 if (rect.isEmpty())
1547 return;
1548 IntRect dirtyRect(rect);
1584 #if WEBKIT_USING_CG 1549 #if WEBKIT_USING_CG
1585 GraphicsContext gc(canvas); 1550 GraphicsContext gc(canvas);
1586 WebCore::LocalCurrentGraphicsContext localContext(&gc); 1551 LocalCurrentGraphicsContext localContext(&gc);
1587 #elif WEBKIT_USING_SKIA 1552 #elif WEBKIT_USING_SKIA
1588 PlatformContextSkia context(canvas); 1553 PlatformContextSkia context(canvas);
1589 1554
1590 // PlatformGraphicsContext is actually a pointer to PlatformContextSkia 1555 // PlatformGraphicsContext is actually a pointer to PlatformContextSkia
1591 GraphicsContext gc(reinterpret_cast<PlatformGraphicsContext*>(&context)); 1556 GraphicsContext gc(reinterpret_cast<PlatformGraphicsContext*>(&context));
1592 #else 1557 #else
1593 notImplemented(); 1558 notImplemented();
1594 #endif 1559 #endif
1595 gc.save(); 1560 gc.save();
1596 if (frame_->document() && frameview()) { 1561 if (m_frame->document() && frameView()) {
1597 gc.clip(dirty_rect); 1562 gc.clip(dirtyRect);
1598 frameview()->paint(&gc, dirty_rect); 1563 frameView()->paint(&gc, dirtyRect);
1599 frame_->page()->inspectorController()->drawNodeHighlight(gc); 1564 m_frame->page()->inspectorController()->drawNodeHighlight(gc);
1600 } else { 1565 } else
1601 gc.fillRect(dirty_rect, Color::white); 1566 gc.fillRect(dirtyRect, Color::white);
1602 } 1567 gc.restore();
1603 gc.restore(); 1568 }
1604 } 1569
1605 1570 void WebFrameImpl::createFrameView()
1606 void WebFrameImpl::CreateFrameView() { 1571 {
1607 ASSERT(frame_); // If frame_ doesn't exist, we probably didn't init properly. 1572 ASSERT(m_frame); // If m_frame doesn't exist, we probably didn't init properly.
1608 1573
1609 WebCore::Page* page = frame_->page(); 1574 Page* page = m_frame->page();
1610 ASSERT(page); 1575 ASSERT(page);
1611 1576
1612 ASSERT(page->mainFrame() != NULL); 1577 ASSERT(page->mainFrame() != 0);
1613 1578
1614 bool is_main_frame = frame_ == page->mainFrame(); 1579 bool isMainFrame = m_frame == page->mainFrame();
1615 if (is_main_frame && frame_->view()) 1580 if (isMainFrame && m_frame->view())
1616 frame_->view()->setParentVisible(false); 1581 m_frame->view()->setParentVisible(false);
1617 1582
1618 frame_->setView(0); 1583 m_frame->setView(0);
1619 1584
1620 WebViewImpl* web_view = GetWebViewImpl(); 1585 WebViewImpl* webView = viewImpl();
1621 1586
1622 RefPtr<WebCore::FrameView> view; 1587 RefPtr<FrameView> view;
1623 if (is_main_frame) { 1588 if (isMainFrame)
1624 IntSize size = webkit_glue::WebSizeToIntSize(web_view->size()); 1589 view = FrameView::create(m_frame, webView->size());
1625 view = FrameView::create(frame_, size); 1590 else
1626 } else { 1591 view = FrameView::create(m_frame);
1627 view = FrameView::create(frame_); 1592
1628 } 1593 m_frame->setView(view);
1629 1594
1630 frame_->setView(view); 1595 if (webView->isTransparent())
1631 1596 view->setTransparent(true);
1632 if (web_view->isTransparent()) 1597
1633 view->setTransparent(true); 1598 // FIXME: The Mac code has a comment about this possibly being unnecessary.
1634 1599 // See installInFrame in WebCoreFrameBridge.mm
1635 // TODO(darin): The Mac code has a comment about this possibly being 1600 if (m_frame->ownerRenderer())
1636 // unnecessary. See installInFrame in WebCoreFrameBridge.mm 1601 m_frame->ownerRenderer()->setWidget(view.get());
1637 if (frame_->ownerRenderer()) 1602
1638 frame_->ownerRenderer()->setWidget(view.get()); 1603 if (HTMLFrameOwnerElement* owner = m_frame->ownerElement())
1639 1604 view->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
1640 if (HTMLFrameOwnerElement* owner = frame_->ownerElement()) { 1605
1641 view->setCanHaveScrollbars( 1606 if (isMainFrame)
1642 owner->scrollingMode() != WebCore::ScrollbarAlwaysOff); 1607 view->setParentVisible(true);
1643 } 1608 }
1644 1609
1645 if (is_main_frame) 1610 WebFrameImpl* WebFrameImpl::fromFrame(Frame* frame)
1646 view->setParentVisible(true); 1611 {
1647 } 1612 if (!frame)
1648 1613 return 0;
1649 // static 1614
1650 WebFrameImpl* WebFrameImpl::FromFrame(WebCore::Frame* frame) { 1615 return static_cast<FrameLoaderClientImpl*>(frame->loader()->client())->webFrame();
1651 if (!frame) 1616 }
1652 return NULL; 1617
1653 return static_cast<WebFrameLoaderClient*>( 1618 WebViewImpl* WebFrameImpl::viewImpl() const
1654 frame->loader()->client())->webframe(); 1619 {
1655 } 1620 if (!m_frame)
1656 1621 return 0;
1657 WebViewImpl* WebFrameImpl::GetWebViewImpl() const { 1622
1658 if (!frame_) 1623 return WebViewImpl::fromPage(m_frame->page());
1659 return NULL; 1624 }
1660 1625
1661 return WebViewImpl::FromPage(frame_->page()); 1626 WebDataSourceImpl* WebFrameImpl::dataSourceImpl() const
1662 } 1627 {
1663 1628 return static_cast<WebDataSourceImpl*>(dataSource());
1664 WebDataSourceImpl* WebFrameImpl::GetDataSourceImpl() const { 1629 }
1665 return static_cast<WebDataSourceImpl*>(dataSource()); 1630
1666 } 1631 WebDataSourceImpl* WebFrameImpl::provisionalDataSourceImpl() const
1667 1632 {
1668 WebDataSourceImpl* WebFrameImpl::GetProvisionalDataSourceImpl() const { 1633 return static_cast<WebDataSourceImpl*>(provisionalDataSource());
1669 return static_cast<WebDataSourceImpl*>(provisionalDataSource()); 1634 }
1670 } 1635
1671 1636 void WebFrameImpl::setFindEndstateFocusAndSelection()
1672 void WebFrameImpl::SetFindEndstateFocusAndSelection() { 1637 {
1673 WebFrameImpl* main_frame_impl = GetWebViewImpl()->main_frame(); 1638 WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
1674 1639
1675 if (this == main_frame_impl->active_match_frame() && 1640 if (this == mainFrameImpl->activeMatchFrame() && m_activeMatch.get()) {
1676 active_match_.get()) { 1641 // If the user has set the selection since the match was found, we
1677 // If the user has set the selection since the match was found, we 1642 // don't focus anything.
1678 // don't focus anything. 1643 VisibleSelection selection(frame()->selection()->selection());
1679 VisibleSelection selection(frame()->selection()->selection()); 1644 if (!selection.isNone())
1680 if (!selection.isNone()) 1645 return;
1681 return; 1646
1682 1647 // Try to find the first focusable node up the chain, which will, for
1683 // Try to find the first focusable node up the chain, which will, for 1648 // example, focus links if we have found text within the link.
1684 // example, focus links if we have found text within the link. 1649 Node* node = m_activeMatch->firstNode();
1685 Node* node = active_match_->firstNode(); 1650 while (node && !node->isFocusable() && node != frame()->document())
1686 while (node && !node->isFocusable() && node != frame()->document()) 1651 node = node->parent();
1687 node = node->parent(); 1652
1688 1653 if (node && node != frame()->document()) {
1689 if (node && node != frame()->document()) { 1654 // Found a focusable parent node. Set focus to it.
1690 // Found a focusable parent node. Set focus to it. 1655 frame()->document()->setFocusedNode(node);
1691 frame()->document()->setFocusedNode(node); 1656 } else {
1692 } else { 1657 // Iterate over all the nodes in the range until we find a focusable node.
1693 // Iterate over all the nodes in the range until we find a focusable node. 1658 // This, for example, sets focus to the first link if you search for
1694 // This, for example, sets focus to the first link if you search for 1659 // text and text that is within one or more links.
1695 // text and text that is within one or more links. 1660 node = m_activeMatch->firstNode();
1696 node = active_match_->firstNode(); 1661 while (node && node != m_activeMatch->pastLastNode()) {
1697 while (node && node != active_match_->pastLastNode()) { 1662 if (node->isFocusable()) {
1698 if (node->isFocusable()) { 1663 frame()->document()->setFocusedNode(node);
1699 frame()->document()->setFocusedNode(node); 1664 break;
1700 break; 1665 }
1666 node = node->traverseNextNode();
1667 }
1701 } 1668 }
1702 node = node->traverseNextNode(); 1669 }
1703 } 1670 }
1704 } 1671
1705 } 1672 void WebFrameImpl::didFail(const ResourceError& error, bool wasProvisional)
1706 } 1673 {
1707 1674 if (!client())
1708 void WebFrameImpl::DidFail(const ResourceError& error, bool was_provisional) { 1675 return;
1709 if (!client()) 1676 WebURLError webError = error;
1710 return; 1677 if (wasProvisional)
1711 const WebURLError& web_error = 1678 client()->didFailProvisionalLoad(this, webError);
1712 webkit_glue::ResourceErrorToWebURLError(error); 1679 else
1713 if (was_provisional) { 1680 client()->didFailLoad(this, webError);
1714 client()->didFailProvisionalLoad(this, web_error); 1681 }
1715 } else { 1682
1716 client()->didFailLoad(this, web_error); 1683 void WebFrameImpl::setAllowsScrolling(bool flag)
1717 } 1684 {
1718 } 1685 m_frame->view()->setCanHaveScrollbars(flag);
1719 1686 }
1720 void WebFrameImpl::SetAllowsScrolling(bool flag) { 1687
1721 frame_->view()->setCanHaveScrollbars(flag); 1688 void WebFrameImpl::registerPasswordListener(
1722 } 1689 PassRefPtr<HTMLInputElement> inputElement,
1723 1690 PasswordAutocompleteListener* listener)
1724 void WebFrameImpl::RegisterPasswordListener( 1691 {
1725 PassRefPtr<HTMLInputElement> input_element, 1692 RefPtr<HTMLInputElement> element = inputElement;
1726 PasswordAutocompleteListener* listener) { 1693 ASSERT(m_passwordListeners.find(element) == m_passwordListeners.end());
1727 RefPtr<HTMLInputElement> element = input_element; 1694 m_passwordListeners.set(element, listener);
1728 ASSERT(password_listeners_.find(element) == password_listeners_.end()); 1695 }
1729 password_listeners_.set(element, listener); 1696
1730 } 1697 PasswordAutocompleteListener* WebFrameImpl::getPasswordListener(
1731 1698 HTMLInputElement* inputElement)
1732 PasswordAutocompleteListener* WebFrameImpl::GetPasswordListener( 1699 {
1733 HTMLInputElement* input_element) { 1700 return m_passwordListeners.get(RefPtr<HTMLInputElement>(inputElement));
1734 return password_listeners_.get(RefPtr<HTMLInputElement>(input_element));
1735 }
1736
1737 // WebFrameImpl protected ------------------------------------------------------
1738
1739 void WebFrameImpl::Closing() {
1740 frame_ = NULL;
1741 } 1701 }
1742 1702
1743 // WebFrameImpl private -------------------------------------------------------- 1703 // WebFrameImpl private --------------------------------------------------------
1744 1704
1745 void WebFrameImpl::InvalidateArea(AreaToInvalidate area) { 1705 void WebFrameImpl::closing()
1746 ASSERT(frame() && frame()->view()); 1706 {
1747 FrameView* view = frame()->view(); 1707 m_frame = 0;
1748 1708 }
1749 if ((area & INVALIDATE_ALL) == INVALIDATE_ALL) { 1709
1750 view->invalidateRect(view->frameRect()); 1710 void WebFrameImpl::invalidateArea(AreaToInvalidate area)
1751 } else { 1711 {
1752 if ((area & INVALIDATE_CONTENT_AREA) == INVALIDATE_CONTENT_AREA) { 1712 ASSERT(frame() && frame()->view());
1753 IntRect content_area( 1713 FrameView* view = frame()->view();
1754 view->x(), view->y(), view->visibleWidth(), view->visibleHeight()); 1714
1755 view->invalidateRect(content_area); 1715 if ((area & InvalidateAll) == InvalidateAll)
1756 } 1716 view->invalidateRect(view->frameRect());
1757 1717 else {
1758 if ((area & INVALIDATE_SCROLLBAR) == INVALIDATE_SCROLLBAR) { 1718 if ((area & InvalidateContentArea) == InvalidateContentArea) {
1759 // Invalidate the vertical scroll bar region for the view. 1719 IntRect contentArea(
1760 IntRect scroll_bar_vert( 1720 view->x(), view->y(), view->visibleWidth(), view->visibleHeight());
1761 view->x() + view->visibleWidth(), view->y(), 1721 view->invalidateRect(contentArea);
1762 WebCore::ScrollbarTheme::nativeTheme()->scrollbarThickness(), 1722 }
1763 view->visibleHeight()); 1723
1764 view->invalidateRect(scroll_bar_vert); 1724 if ((area & InvalidateScrollbar) == InvalidateScrollbar) {
1765 } 1725 // Invalidate the vertical scroll bar region for the view.
1766 } 1726 IntRect scrollBarVert(
1767 } 1727 view->x() + view->visibleWidth(), view->y(),
1768 1728 ScrollbarTheme::nativeTheme()->scrollbarThickness(),
1769 void WebFrameImpl::AddMarker(WebCore::Range* range, bool active_match) { 1729 view->visibleHeight());
1770 // Use a TextIterator to visit the potentially multiple nodes the range 1730 view->invalidateRect(scrollBarVert);
1771 // covers. 1731 }
1772 TextIterator markedText(range); 1732 }
1773 for (; !markedText.atEnd(); markedText.advance()) { 1733 }
1774 RefPtr<Range> textPiece = markedText.range(); 1734
1775 int exception = 0; 1735 void WebFrameImpl::addMarker(Range* range, bool activeMatch)
1776 1736 {
1777 WebCore::DocumentMarker marker = { 1737 // Use a TextIterator to visit the potentially multiple nodes the range
1778 WebCore::DocumentMarker::TextMatch, 1738 // covers.
1779 textPiece->startOffset(exception), 1739 TextIterator markedText(range);
1780 textPiece->endOffset(exception), 1740 for (; !markedText.atEnd(); markedText.advance()) {
1781 "", 1741 RefPtr<Range> textPiece = markedText.range();
1782 active_match }; 1742 int exception = 0;
1783 1743
1784 if (marker.endOffset > marker.startOffset) { 1744 DocumentMarker marker = {
1785 // Find the node to add a marker to and add it. 1745 DocumentMarker::TextMatch,
1786 Node* node = textPiece->startContainer(exception); 1746 textPiece->startOffset(exception),
1787 frame()->document()->addMarker(node, marker); 1747 textPiece->endOffset(exception),
1788 1748 "",
1789 // Rendered rects for markers in WebKit are not populated until each time 1749 activeMatch
1790 // the markers are painted. However, we need it to happen sooner, because 1750 };
1791 // the whole purpose of tickmarks on the scrollbar is to show where 1751
1792 // matches off-screen are (that haven't been painted yet). 1752 if (marker.endOffset > marker.startOffset) {
1793 Vector<WebCore::DocumentMarker> markers = 1753 // Find the node to add a marker to and add it.
1794 frame()->document()->markersForNode(node); 1754 Node* node = textPiece->startContainer(exception);
1795 frame()->document()->setRenderedRectForMarker( 1755 frame()->document()->addMarker(node, marker);
1796 textPiece->startContainer(exception), 1756
1797 markers[markers.size() - 1], 1757 // Rendered rects for markers in WebKit are not populated until each time
1798 range->boundingBox()); 1758 // the markers are painted. However, we need it to happen sooner, because
1799 } 1759 // the whole purpose of tickmarks on the scrollbar is to show where
1800 } 1760 // matches off-screen are (that haven't been painted yet).
1801 } 1761 Vector<DocumentMarker> markers = frame()->document()->markersForNode(node);
1802 1762 frame()->document()->setRenderedRectForMarker(
1803 void WebFrameImpl::SetMarkerActive(WebCore::Range* range, bool active) { 1763 textPiece->startContainer(exception),
1804 if (!range) 1764 markers[markers.size() - 1],
1805 return; 1765 range->boundingBox());
1806 1766 }
1807 frame()->document()->setMarkersActive(range, active); 1767 }
1808 } 1768 }
1809 1769
1810 int WebFrameImpl::OrdinalOfFirstMatchForFrame(WebFrameImpl* frame) const { 1770 void WebFrameImpl::setMarkerActive(Range* range, bool active)
1811 int ordinal = 0; 1771 {
1812 WebFrameImpl* main_frame_impl = GetWebViewImpl()->main_frame(); 1772 if (!range)
1813 // Iterate from the main frame up to (but not including) |frame| and 1773 return;
1814 // add up the number of matches found so far. 1774
1815 for (WebFrameImpl* it = main_frame_impl; 1775 frame()->document()->setMarkersActive(range, active);
1816 it != frame; 1776 }
1817 it = static_cast<WebFrameImpl*>(it->traverseNext(true))) { 1777
1818 if (it->last_match_count_ > 0) 1778 int WebFrameImpl::ordinalOfFirstMatchForFrame(WebFrameImpl* frame) const
1819 ordinal += it->last_match_count_; 1779 {
1820 } 1780 int ordinal = 0;
1821 1781 WebFrameImpl* mainFrameImpl = viewImpl()->mainFrameImpl();
1822 return ordinal; 1782 // Iterate from the main frame up to (but not including) |frame| and
1823 } 1783 // add up the number of matches found so far.
1824 1784 for (WebFrameImpl* it = mainFrameImpl;
1825 bool WebFrameImpl::ShouldScopeMatches(const string16& search_text) { 1785 it != frame;
1826 // Don't scope if we can't find a frame or if the frame is not visible. 1786 it = static_cast<WebFrameImpl*>(it->traverseNext(true))) {
1827 // The user may have closed the tab/application, so abort. 1787 if (it->m_lastMatchCount > 0)
1828 if (!frame() || !hasVisibleContent()) 1788 ordinal += it->m_lastMatchCount;
1829 return false; 1789 }
1830 1790 return ordinal;
1831 ASSERT(frame()->document() && frame()->view()); 1791 }
1832 1792
1833 // If the frame completed the scoping operation and found 0 matches the last 1793 bool WebFrameImpl::shouldScopeMatches(const String& searchText)
1834 // time it was searched, then we don't have to search it again if the user is 1794 {
1835 // just adding to the search string or sending the same search string again. 1795 // Don't scope if we can't find a frame or if the frame is not visible.
1836 if (scoping_complete_ && 1796 // The user may have closed the tab/application, so abort.
1837 !last_search_string_.empty() && last_match_count_ == 0) { 1797 if (!frame() || !hasVisibleContent())
1838 // Check to see if the search string prefixes match. 1798 return false;
1839 string16 previous_search_prefix = 1799
1840 search_text.substr(0, last_search_string_.length()); 1800 ASSERT(frame()->document() && frame()->view());
1841 1801
1842 if (previous_search_prefix == last_search_string_) { 1802 // If the frame completed the scoping operation and found 0 matches the last
1843 return false; // Don't search this frame, it will be fruitless. 1803 // time it was searched, then we don't have to search it again if the user is
1844 } 1804 // just adding to the search string or sending the same search string again.
1845 } 1805 if (m_scopingComplete && !m_lastSearchString.isEmpty() && m_lastMatchCount == 0) {
1846 1806 // Check to see if the search string prefixes match.
1847 return true; 1807 String previousSearchPrefix =
1848 } 1808 searchText.substring(0, m_lastSearchString.length());
1849 1809
1850 void WebFrameImpl::ScopeStringMatchesSoon( 1810 if (previousSearchPrefix == m_lastSearchString)
1851 int identifier, const WebString& search_text, 1811 return false; // Don't search this frame, it will be fruitless.
1852 const WebFindOptions& options, bool reset) { 1812 }
1853 deferred_scoping_work_.append(new DeferredScopeStringMatches( 1813
1854 this, identifier, search_text, options, reset)); 1814 return true;
1855 } 1815 }
1856 1816
1857 void WebFrameImpl::CallScopeStringMatches( 1817 void WebFrameImpl::scopeStringMatchesSoon(int identifier, const WebString& searchText,
1858 DeferredScopeStringMatches* caller, int identifier, 1818 const WebFindOptions& options, bool reset)
1859 const WebString& search_text, const WebFindOptions& options, bool reset) { 1819 {
1860 deferred_scoping_work_.remove(deferred_scoping_work_.find(caller)); 1820 m_deferredScopingWork.append(new DeferredScopeStringMatches(
1861 1821 this, identifier, searchText, options, reset));
1862 scopeStringMatches(identifier, search_text, options, reset); 1822 }
1863 1823
1864 // This needs to happen last since search_text is passed by reference. 1824 void WebFrameImpl::callScopeStringMatches(DeferredScopeStringMatches* caller,
1865 delete caller; 1825 int identifier, const WebString& searchText,
1866 } 1826 const WebFindOptions& options, bool reset)
1867 1827 {
1868 void WebFrameImpl::InvalidateIfNecessary() { 1828 m_deferredScopingWork.remove(m_deferredScopingWork.find(caller));
1869 if (last_match_count_ > next_invalidate_after_) { 1829
1870 // TODO(finnur): (http://b/1088165) Optimize the drawing of the 1830 scopeStringMatches(identifier, searchText, options, reset);
1871 // tickmarks and remove this. This calculation sets a milestone for when 1831
1872 // next to invalidate the scrollbar and the content area. We do this so that 1832 // This needs to happen last since searchText is passed by reference.
1873 // we don't spend too much time drawing the scrollbar over and over again. 1833 delete caller;
1874 // Basically, up until the first 500 matches there is no throttle. After the 1834 }
1875 // first 500 matches, we set set the milestone further and further out (750, 1835
1876 // 1125, 1688, 2K, 3K). 1836 void WebFrameImpl::invalidateIfNecessary()
1877 static const int start_slowing_down_after = 500; 1837 {
1878 static const int slowdown = 750; 1838 if (m_lastMatchCount > m_nextInvalidateAfter) {
1879 int i = (last_match_count_ / start_slowing_down_after); 1839 // FIXME: (http://b/1088165) Optimize the drawing of the tickmarks and
1880 next_invalidate_after_ += i * slowdown; 1840 // remove this. This calculation sets a milestone for when next to
1881 1841 // invalidate the scrollbar and the content area. We do this so that we
1882 InvalidateArea(INVALIDATE_SCROLLBAR); 1842 // don't spend too much time drawing the scrollbar over and over again.
1883 } 1843 // Basically, up until the first 500 matches there is no throttle.
1884 } 1844 // After the first 500 matches, we set set the milestone further and
1885 1845 // further out (750, 1125, 1688, 2K, 3K).
1886 void WebFrameImpl::ClearPasswordListeners() { 1846 static const int startSlowingDownAfter = 500;
1887 for (PasswordListenerMap::iterator iter = password_listeners_.begin(); 1847 static const int slowdown = 750;
1888 iter != password_listeners_.end(); ++iter) { 1848 int i = (m_lastMatchCount / startSlowingDownAfter);
1889 delete iter->second; 1849 m_nextInvalidateAfter += i * slowdown;
1890 } 1850
1891 password_listeners_.clear(); 1851 invalidateArea(InvalidateScrollbar);
1892 } 1852 }
1893 1853 }
1894 void WebFrameImpl::LoadJavaScriptURL(const KURL& url) { 1854
1895 // This is copied from FrameLoader::executeIfJavaScriptURL. Unfortunately, 1855 void WebFrameImpl::clearPasswordListeners()
1896 // we cannot just use that method since it is private, and it also doesn't 1856 {
1897 // quite behave as we require it to for bookmarklets. The key difference is 1857 deleteAllValues(m_passwordListeners);
1898 // that we need to suppress loading the string result from evaluating the JS 1858 m_passwordListeners.clear();
1899 // URL if executing the JS URL resulted in a location change. We also allow 1859 }
1900 // a JS URL to be loaded even if scripts on the page are otherwise disabled. 1860
1901 1861 void WebFrameImpl::loadJavaScriptURL(const KURL& url)
1902 if (!frame_->document() || !frame_->page()) 1862 {
1903 return; 1863 // This is copied from FrameLoader::executeIfJavaScriptURL. Unfortunately,
1904 1864 // we cannot just use that method since it is private, and it also doesn't
1905 String script = 1865 // quite behave as we require it to for bookmarklets. The key difference is
1906 decodeURLEscapeSequences(url.string().substring(strlen("javascript:"))); 1866 // that we need to suppress loading the string result from evaluating the JS
1907 ScriptValue result = frame_->script()->executeScript(script, true); 1867 // URL if executing the JS URL resulted in a location change. We also allow
1908 1868 // a JS URL to be loaded even if scripts on the page are otherwise disabled.
1909 String script_result; 1869
1910 if (!result.getString(script_result)) 1870 if (!m_frame->document() || !m_frame->page())
1911 return; 1871 return;
1912 1872
1913 SecurityOrigin* security_origin = frame_->document()->securityOrigin(); 1873 String script = decodeURLEscapeSequences(url.string().substring(strlen("javascript:")));
1914 1874 ScriptValue result = m_frame->script()->executeScript(script, true);
1915 if (!frame_->redirectScheduler()->locationChangePending()) { 1875
1916 frame_->loader()->stopAllLoaders(); 1876 String scriptResult;
1917 frame_->loader()->begin(frame_->loader()->url(), true, security_origin); 1877 if (!result.getString(scriptResult))
1918 frame_->loader()->write(script_result); 1878 return;
1919 frame_->loader()->end(); 1879
1920 } 1880 SecurityOrigin* securityOrigin = m_frame->document()->securityOrigin();
1921 } 1881
1882 if (!m_frame->redirectScheduler()->locationChangePending()) {
1883 m_frame->loader()->stopAllLoaders();
1884 m_frame->loader()->begin(m_frame->loader()->url(), true, securityOrigin);
1885 m_frame->loader()->write(scriptResult);
1886 m_frame->loader()->end();
1887 }
1888 }
1889
1890 } // namespace WebKit
OLDNEW
« no previous file with comments | « webkit/api/src/WebFrameImpl.h ('k') | webkit/api/src/WebStorageEventDispatcherImpl.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698