Fix issue 5079: Incorrect "Active match ordinal" count during Find-in-page
[chromium-blink-merge.git] / webkit / glue / webframe_impl.h
blob44c3ed8523685448f83ae16bca182ef896c993a8
1 /*
2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef WEBKIT_GLUE_WEBFRAME_IMPL_H_
27 #define WEBKIT_GLUE_WEBFRAME_IMPL_H_
29 #include <string>
31 #include "base/basictypes.h"
32 #include "base/compiler_specific.h"
33 #include "base/scoped_ptr.h"
34 #include "base/task.h"
35 #include "skia/ext/platform_canvas.h"
36 #include "webkit/glue/password_autocomplete_listener.h"
37 #include "webkit/glue/webdatasource_impl.h"
38 #include "webkit/glue/webframe.h"
39 #include "webkit/glue/webframeloaderclient_impl.h"
40 #include "webkit/glue/webplugin_delegate.h"
41 #include "webkit/glue/webview_delegate.h"
43 MSVC_PUSH_WARNING_LEVEL(0);
44 #include "ResourceHandleClient.h"
45 #include "Frame.h"
46 #include "PlatformString.h"
47 MSVC_POP_WARNING();
49 class AltErrorPageResourceFetcher;
50 class WebErrorImpl;
51 class WebHistoryItemImpl;
52 class WebRequest;
53 class WebView;
54 class WebViewImpl;
55 class WebTextInput;
56 class WebTextInputImpl;
58 namespace WebCore {
59 class Frame;
60 class FrameView;
61 class HistoryItem;
62 class Node;
63 class Range;
64 class SubstituteData;
65 struct WindowFeatures;
68 namespace gfx {
69 class BitmapPlatformDeviceWin;
72 // Implementation of WebFrame, note that this is a reference counted object.
73 class WebFrameImpl : public WebFrame {
74 public:
75 WebFrameImpl();
76 ~WebFrameImpl();
78 static int live_object_count() {
79 return live_object_count_;
82 // Called by the WebViewImpl to initialize its main frame:
83 void InitMainFrame(WebViewImpl* webview_impl);
85 // WebFrame
86 virtual void LoadRequest(WebRequest* request);
87 virtual void LoadHTMLString(const std::string& html_text,
88 const GURL& base_url);
89 virtual void LoadAlternateHTMLString(const WebRequest* request,
90 const std::string& html_text,
91 const GURL& display_url,
92 bool replace);
93 virtual void LoadAlternateHTMLErrorPage(const WebRequest* request,
94 const WebError& error,
95 const GURL& error_page_url,
96 bool replace,
97 const GURL& fake_url);
98 virtual void ExecuteJavaScript(const std::string& js_code,
99 const GURL& script_url);
100 virtual bool GetPreviousHistoryState(std::string* history_state) const;
101 virtual bool GetCurrentHistoryState(std::string* history_state) const;
102 virtual bool HasCurrentHistoryState() const;
103 virtual GURL GetURL() const;
104 virtual GURL GetFavIconURL() const;
105 virtual GURL GetOSDDURL() const;
106 virtual WebDataSource* GetDataSource() const;
107 virtual WebDataSource* GetProvisionalDataSource() const;
108 virtual void StopLoading();
109 virtual WebFrame* GetOpener() const;
110 virtual WebFrame* GetParent() const;
111 virtual WebFrame* GetChildFrame(const std::wstring& xpath) const;
112 virtual WebView* GetView() const;
113 virtual bool CaptureImage(scoped_ptr<gfx::BitmapPlatformDevice>* image,
114 bool scroll_to_zero);
116 // This method calls createRuntimeObject (in KJS::Bindings::Instance), which
117 // increments the refcount of the NPObject passed in.
118 virtual void BindToWindowObject(const std::wstring& name, NPObject* object);
119 virtual void CallJSGC();
121 virtual void* GetFrameImplementation() { return frame(); }
123 virtual void GetContentAsPlainText(int max_chars, std::wstring* text) const;
124 virtual bool Find(const FindInPageRequest& request,
125 bool wrap_within_frame,
126 gfx::Rect* selection_rect);
127 virtual void StopFinding(bool clear_selection);
128 virtual void ScopeStringMatches(FindInPageRequest request, bool reset);
129 virtual void CancelPendingScopingEffort();
130 virtual void ResetMatchCount();
131 virtual bool Visible();
132 virtual void SelectAll();
133 virtual void Copy();
134 virtual void Cut();
135 virtual void Paste();
136 virtual void Replace(const std::wstring& text);
137 virtual void Delete();
138 virtual void Undo();
139 virtual void Redo();
140 virtual void ClearSelection();
141 virtual std::string GetSelection(bool as_html);
143 virtual void SetInViewSourceMode(bool enable);
145 virtual bool GetInViewSourceMode() const;
147 virtual void DidReceiveData(WebCore::DocumentLoader* loader,
148 const char* data,
149 int length);
150 virtual void DidFail(const WebCore::ResourceError&, bool was_provisional);
152 virtual std::wstring GetName();
154 virtual WebTextInput* GetTextInput();
156 virtual bool ExecuteCoreCommandByName(const std::string& name, const std::string& value);
158 virtual void AddMessageToConsole(const std::wstring& msg,
159 ConsoleMessageLevel level);
161 virtual void ClosePage();
163 virtual gfx::Size ScrollOffset() const;
165 virtual bool SetPrintingMode(bool printing,
166 float page_width_min,
167 float page_width_max,
168 int* width);
169 virtual int ComputePageRects(const gfx::Size& page_size_px);
170 virtual void GetPageRect(int page, gfx::Rect* page_size) const;
171 virtual bool SpoolPage(int page, gfx::PlatformCanvas* canvas);
173 // Reformats this frame for printing or for screen display, depending on
174 // |printing| flag. Acts recursively on inner frames.
175 // Note: It fails if the main frame failed to load. It will succeed even if a
176 // child frame failed to load.
177 void SetPrinting(bool printing, float page_width_min, float page_width_max);
179 PassRefPtr<WebCore::Frame> CreateChildFrame(
180 const WebCore::FrameLoadRequest&,
181 WebCore::HTMLFrameOwnerElement* owner_element);
183 // WebFrameImpl
184 void Layout();
185 void Paint(gfx::PlatformCanvas* canvas, const gfx::Rect& rect);
187 bool IsLoading();
189 void CreateFrameView();
191 // The plugin delegate is used to get notifications when downloads complete.
192 // This is used by the NPAPI method getURLNotify. plugin_delegate() may
193 // return NULL. TODO(darin): how come there is only one per frame?!?
194 WebPluginDelegate* plugin_delegate() const {
195 return plugin_delegate_;
197 void set_plugin_delegate(WebPluginDelegate* plugin_delegate) {
198 plugin_delegate_ = plugin_delegate;
201 WebCore::Frame* frame() const {
202 return frame_;
205 static WebFrameImpl* FromFrame(WebCore::Frame* frame);
207 WebViewImpl* webview_impl() const {
208 return webview_impl_;
211 WebCore::FrameView* frameview() const {
212 return frame_ ? frame_->view() : NULL;
215 // Update the given datasource with currently_loading_request's info.
216 // If currently_loading_request is NULL, does nothing.
217 void CacheCurrentRequestInfo(WebDataSourceImpl* datasource);
219 void set_currently_loading_history_item(WebHistoryItemImpl* item);
221 // Getters for the impls corresponding to Get(Provisional)DataSource. They
222 // may return NULL if there is no corresponding data source.
223 WebDataSourceImpl* GetDataSourceImpl() const;
224 WebDataSourceImpl* GetProvisionalDataSourceImpl() const;
226 const WebCore::Node* inspected_node() const {
227 return inspected_node_;
230 void selectNodeFromInspector(WebCore::Node* node);
232 // Returns which frame has an active match. This function should only be
233 // called on the main frame, as it is the only frame keeping track. Returned
234 // value can be NULL if no frame has an active match.
235 const WebFrameImpl* active_match_frame() const {
236 return active_match_frame_;
239 // When a Find operation ends, we want to set the selection to what was active
240 // and set focus to the first focusable node we find (starting with the first
241 // node in the matched range and going up the inheritance chain). If we find
242 // nothing to focus we focus the first focusable node in the range. This
243 // allows us to set focus to a link (when we find text inside a link), which
244 // allows us to navigate by pressing Enter after closing the Find box.
245 void SetFindEndstateFocusAndSelection();
247 // Sets whether the WebFrameImpl allows its document to be scrolled.
248 // If the parameter is true, allow the document to be scrolled.
249 // Otherwise, disallow scrolling
250 void SetAllowsScrolling(bool flag);
252 // Returns true if the frame CSS is in "printing" mode.
253 bool printing() const { return printing_; }
255 virtual bool IsReloadAllowingStaleData() const;
257 // Registers a listener for the specified user name input element. The
258 // listener will receive notifications for blur and when autocomplete should
259 // be triggered.
260 // The WebFrameImpl becomes the owner of the passed listener.
261 void RegisterPasswordListener(
262 PassRefPtr<WebCore::HTMLInputElement> user_name_input_element,
263 webkit_glue::PasswordAutocompleteListener* listener);
265 // Returns the password autocomplete listener associated with the passed
266 // user name input element, or NULL if none available.
267 // Note that the returned listener is owner by the WebFrameImpl and should not
268 // be kept around as it is deleted when the page goes away.
269 webkit_glue::PasswordAutocompleteListener* GetPasswordListener(
270 WebCore::HTMLInputElement* user_name_input_element);
272 protected:
273 friend class WebFrameLoaderClient;
275 // Informs the WebFrame that the Frame is being closed, called by the
276 // WebFrameLoaderClient
277 void Closing();
279 // A helper function for loading some document, given all of its data, into
280 // this frame. The charset may be empty if unknown, but a mime type must be
281 // specified. TODO(darin): Add option for storing this in session history.
282 void LoadDocumentData(const WebCore::KURL& base_url,
283 const WebCore::String& data,
284 const WebCore::String& mime_type,
285 const WebCore::String& charset);
287 // See WebFrame.h for details.
288 virtual void IncreaseMatchCount(int count, int request_id);
289 virtual void ReportFindInPageSelection(const gfx::Rect& selection_rect,
290 int active_match_ordinal,
291 int request_id);
293 // Resource fetcher for downloading an alternate DNS error page.
294 scoped_ptr<AltErrorPageResourceFetcher> alt_error_page_fetcher_;
296 // Used to check for leaks of this object.
297 static int live_object_count_;
299 WebFrameLoaderClient frame_loader_client_;
301 // This is a factory for creating cancelable tasks for this frame that run
302 // asynchronously in order to scope string matches during a find operation.
303 ScopedRunnableMethodFactory<WebFrameImpl> scope_matches_factory_;
305 // This is a weak pointer to our containing WebViewImpl.
306 WebViewImpl* webview_impl_;
308 // This is a weak pointer to our corresponding WebCore frame. A reference to
309 // ourselves is held while frame_ is valid. See our Closing method.
310 WebCore::Frame* frame_;
312 // This holds the request passed to LoadRequest, for access by the
313 // WebFrameLoaderClient. Unfortunately we have no other way to pass this
314 // information to him. Only non-NULL during a call to LoadRequest.
315 const WebRequest* currently_loading_request_;
317 // Similar to currently_loading_request_, except this will be set when
318 // WebCore initiates a history navigation (probably via javascript).
319 scoped_refptr<WebHistoryItemImpl> currently_loading_history_item_;
321 // Plugins sometimes need to be notified when loads are complete so we keep
322 // a pointer back to the appropriate plugin.
323 WebPluginDelegate* plugin_delegate_;
325 // Handling requests from TextInputController on this frame.
326 scoped_ptr<WebTextInputImpl> webtextinput_impl_;
328 // The node selected in the web inspector. Used for highlighting it on the page.
329 WebCore::Node* inspected_node_;
331 // A way for the main frame to keep track of which frame has an active
332 // match. Should be NULL for all other frames.
333 WebFrameImpl* active_match_frame_;
335 // The range of the active match for the current frame.
336 RefPtr<WebCore::Range> active_match_;
338 // The index of the active match.
339 int active_match_index_;
341 // This flag is used by the scoping effort to determine if we need to figure
342 // out which rectangle is the active match. Once we find the active
343 // rectangle we clear this flag.
344 bool locating_active_rect_;
346 // The scoping effort can time out and we need to keep track of where we
347 // ended our last search so we can continue from where we left of.
348 RefPtr<WebCore::Range> resume_scoping_from_range_;
350 // Keeps track of the last string this frame searched for. This is used for
351 // short-circuiting searches in the following scenarios: When a frame has
352 // been searched and returned 0 results, we don't need to search that frame
353 // again if the user is just adding to the search (making it more specific).
354 std::wstring last_search_string_;
356 // Keeps track of how many matches this frame has found so far, so that we
357 // don't loose count between scoping efforts, and is also used (in conjunction
358 // with last_search_string_ and scoping_complete_) to figure out if we need to
359 // search the frame again.
360 int last_match_count_;
362 // This variable keeps a cumulative total of matches found so far for ALL the
363 // frames on the page, and is only incremented by calling IncreaseMatchCount
364 // (on the main frame only). It should be -1 for all other frames.
365 size_t total_matchcount_;
367 // This variable keeps a cumulative total of how many frames are currently
368 // scoping, and is incremented/decremented on the main frame only.
369 // It should be -1 for all other frames.
370 int frames_scoping_count_;
372 // Keeps track of whether the scoping effort was completed (the user may
373 // interrupt it before it completes by submitting a new search).
374 bool scoping_complete_;
376 // Keeps track of when the scoping effort should next invalidate the scrollbar
377 // and the frame area.
378 int next_invalidate_after_;
380 private:
381 // A bit mask specifying area of the frame to invalidate.
382 enum AreaToInvalidate {
383 INVALIDATE_NOTHING = 0,
384 INVALIDATE_CONTENT_AREA = 1,
385 INVALIDATE_SCROLLBAR = 2, // vertical scrollbar only.
386 INVALIDATE_ALL = 3 // both content area and the scrollbar.
389 // Invalidates a certain area within the frame.
390 void InvalidateArea(AreaToInvalidate area);
392 // Add a WebKit TextMatch-highlight marker to nodes in a range.
393 void AddMarker(WebCore::Range* range);
395 // Returns the ordinal of the first match in the frame specified. This
396 // function enumerates the frames, starting with the main frame and up to (but
397 // not including) the frame passed in as a parameter and counts how many
398 // matches have been found.
399 int OrdinalOfFirstMatchForFrame(WebFrameImpl* frame) const;
401 // Determines whether the scoping effort is required for a particular frame.
402 // It is not necessary if the frame is invisible, for example, or if this
403 // is a repeat search that already returned nothing last time the same prefix
404 // was searched.
405 bool ShouldScopeMatches(FindInPageRequest request);
407 // Only for test_shell
408 int PendingFrameUnloadEventCount() const;
410 // Determines whether to invalidate the content area and scrollbar.
411 void InvalidateIfNecessary();
413 void InternalLoadRequest(const WebRequest* request,
414 const WebCore::SubstituteData& data,
415 bool replace);
417 // Clears the map of password listeners.
418 void ClearPasswordListeners();
420 // In "printing" mode. Used as a state check.
421 bool printing_;
423 // For each printed page, the view of the document in pixels.
424 Vector<WebCore::IntRect> pages_;
426 // The input fields that are interested in edit events and their associated
427 // listeners.
428 typedef HashMap<RefPtr<WebCore::HTMLInputElement>,
429 webkit_glue::PasswordAutocompleteListener*> PasswordListenerMap;
430 PasswordListenerMap password_listeners_;
432 DISALLOW_COPY_AND_ASSIGN(WebFrameImpl);
435 #endif // WEBKIT_GLUE_WEBFRAME_IMPL_H_