diff options
author | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-15 17:21:10 +0000 |
---|---|---|
committer | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-15 17:21:10 +0000 |
commit | daa8c58ee49795d292312bbf217999c93693919c (patch) | |
tree | 561a327f148d74b0522871f15103e25a27b841f5 | |
parent | 0b97342d07fd3ef047432b52809d31d10432ee85 (diff) | |
download | chromium_src-daa8c58ee49795d292312bbf217999c93693919c.zip chromium_src-daa8c58ee49795d292312bbf217999c93693919c.tar.gz chromium_src-daa8c58ee49795d292312bbf217999c93693919c.tar.bz2 |
Extract form related classes from the guts of WebFrameImpl.
Instead of having WebFrameImpl generate SearchableFormData, PasswordForm, and AutofillForm classes, allow the embedder (RenderView) to do so.
This is done to help minimize the dependencies WebFrameImpl has on other code, which will make it easier to move WebFrame and WebDataSource into the WebKit API.
Most significant change: Now, RenderView always sets a NavigationState on WebDataSource instances. We used to only do so for browser initiated navigations. This is done so that we can store things like SearchableFormData and friends on the NavigationState.
To facilitate this change, it was necessary to add a way through the WebKit API to refer to a HTMLFormElement. This CL introduces WebForm, which is like a RefPtr<HTMLFormElement>, so you can just copy a WebForm around by value and the right thing happens.
Some of the other changes are about moving more things into the webkit_glue namespace. On hindsight, I probably should have done that as a separate CL.
BUG=10041
TEST=none
R=brettw
Review URL: http://codereview.chromium.org/126083
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18395 0039d316-1c4b-4281-b951-d872f2087c98
42 files changed, 665 insertions, 601 deletions
diff --git a/chrome/browser/autofill_manager.cc b/chrome/browser/autofill_manager.cc index 441d708..3e87674 100644 --- a/chrome/browser/autofill_manager.cc +++ b/chrome/browser/autofill_manager.cc @@ -46,7 +46,7 @@ Profile* AutofillManager::profile() { return tab_contents_->profile(); } -void AutofillManager::AutofillFormSubmitted(const AutofillForm& form) { +void AutofillManager::AutofillFormSubmitted(const webkit_glue::AutofillForm& form) { StoreFormEntriesInWebDatabase(form); } @@ -117,7 +117,7 @@ void AutofillManager::OnWebDataServiceRequestDone(WebDataService::Handle h, } void AutofillManager::StoreFormEntriesInWebDatabase( - const AutofillForm& form) { + const webkit_glue::AutofillForm& form) { if (!*form_autofill_enabled_) return; diff --git a/chrome/browser/autofill_manager.h b/chrome/browser/autofill_manager.h index 020c2ce..06320fc 100644 --- a/chrome/browser/autofill_manager.h +++ b/chrome/browser/autofill_manager.h @@ -10,7 +10,10 @@ #include "chrome/browser/webdata/web_data_service.h" #include "chrome/common/pref_member.h" +namespace webkit_glue { class AutofillForm; +} + class Profile; class TabContents; @@ -27,7 +30,7 @@ class AutofillManager : public WebDataServiceConsumer { // Called when a form is submitted (i.e. when the user hits the submit button) // to store the form entries in the profile's sql database. - void AutofillFormSubmitted(const AutofillForm& form); + void AutofillFormSubmitted(const webkit_glue::AutofillForm& form); // Starts a query into the database for the values corresponding to name. // OnWebDataServiceRequestDone gets called when the query completes. @@ -47,7 +50,7 @@ class AutofillManager : public WebDataServiceConsumer { static void RegisterUserPrefs(PrefService* prefs); private: - void StoreFormEntriesInWebDatabase(const AutofillForm& form); + void StoreFormEntriesInWebDatabase(const webkit_glue::AutofillForm& form); TabContents* tab_contents_; diff --git a/chrome/browser/password_manager/password_manager.cc b/chrome/browser/password_manager/password_manager.cc index e09aa08..5566e99 100644 --- a/chrome/browser/password_manager/password_manager.cc +++ b/chrome/browser/password_manager/password_manager.cc @@ -226,11 +226,12 @@ void PasswordManager::Autofill( // schemed password form may have been freed, so we need to distinguish. bool action_mismatch = form_for_autofill.action.GetWithEmptyPath() != preferred_match->action.GetWithEmptyPath(); - PasswordFormDomManager::FillData fill_data; - PasswordFormDomManager::InitFillData(form_for_autofill, - best_matches, preferred_match, - action_mismatch, - &fill_data); + webkit_glue::PasswordFormDomManager::FillData fill_data; + webkit_glue::PasswordFormDomManager::InitFillData(form_for_autofill, + best_matches, + preferred_match, + action_mismatch, + &fill_data); tab_contents_->render_view_host()->FillPasswordForm(fill_data); return; } diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index dff92be..fff947a 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -48,6 +48,8 @@ #endif using base::TimeDelta; +using webkit_glue::AutofillForm; +using webkit_glue::PasswordFormDomManager; using WebKit::WebConsoleMessage; using WebKit::WebFindOptions; using WebKit::WebInputEvent; diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 8759231..8773323 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -19,7 +19,6 @@ #include "webkit/glue/password_form_dom_manager.h" #include "webkit/glue/window_open_disposition.h" -class AutofillForm; class NavigationEntry; class RenderViewHostDelegate; class SiteInstance; @@ -44,6 +43,7 @@ enum LoadState; } namespace webkit_glue { +class AutofillForm; struct WebApplicationInfo; } @@ -213,7 +213,8 @@ class RenderViewHost : public RenderWidgetHost { // Fill out a password form and trigger DOM autocomplete in the case // of multiple matching logins. - void FillPasswordForm(const PasswordFormDomManager::FillData& form_data); + void FillPasswordForm( + const webkit_glue::PasswordFormDomManager::FillData& form_data); // D&d drop target messages that get sent to WebKit. void DragTargetDragEnter(const WebDropData& drop_data, @@ -518,7 +519,7 @@ class RenderViewHost : public RenderWidgetHost { const std::string& json_arguments, IPC::Message* reply_msg); void OnMsgPasswordFormsSeen(const std::vector<PasswordForm>& forms); - void OnMsgAutofillFormSubmitted(const AutofillForm& forms); + void OnMsgAutofillFormSubmitted(const webkit_glue::AutofillForm& forms); void OnMsgStartDragging(const WebDropData& drop_data); void OnUpdateDragCursor(bool is_drop_target); void OnTakeFocus(bool reverse); diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index 0626b5e..52a72c7 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -21,7 +21,6 @@ #include "chrome/browser/extensions/extension_function_dispatcher.h" -class AutofillForm; class ExtensionFunctionDispatcher; class NavigationEntry; class Profile; @@ -45,6 +44,7 @@ class Message; } namespace webkit_glue { +class AutofillForm; struct WebApplicationInfo; } @@ -329,7 +329,7 @@ class RenderViewHostDelegate { virtual void PasswordFormsSeen(const std::vector<PasswordForm>& forms) { } // Forms fillable by autofill have been detected in the page. - virtual void AutofillFormSubmitted(const AutofillForm& form) { } + virtual void AutofillFormSubmitted(const webkit_glue::AutofillForm& form) { } // Called to retrieve a list of suggestions from the web database given // the name of the field |field_name| and what the user has already typed in diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 06ffba6..0ccd724 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -1960,7 +1960,7 @@ void TabContents::PasswordFormsSeen( } void TabContents::AutofillFormSubmitted( - const AutofillForm& form) { + const webkit_glue::AutofillForm& form) { GetAutofillManager()->AutofillFormSubmitted(form); } diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index c496b51..d57f221 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -48,20 +48,24 @@ namespace gfx { class Rect; class Size; } + namespace views { class WindowDelegate; } + namespace base { class WaitableEvent; } + namespace webkit_glue { +class AutofillForm; struct WebApplicationInfo; } + namespace IPC { class Message; } -class AutofillForm; class AutofillManager; class BlockedPopupContainer; class DOMUI; @@ -801,7 +805,7 @@ class TabContents : public PageNavigator, const std::string& json_arguments, IPC::Message* reply_msg); virtual void PasswordFormsSeen(const std::vector<PasswordForm>& forms); - virtual void AutofillFormSubmitted(const AutofillForm& form); + virtual void AutofillFormSubmitted(const webkit_glue::AutofillForm& form); virtual void GetAutofillSuggestions(const std::wstring& field_name, const std::wstring& user_text, int64 node_id, int request_id); virtual void RemoveAutofillEntry(const std::wstring& field_name, diff --git a/chrome/browser/webdata/web_data_service.cc b/chrome/browser/webdata/web_data_service.cc index e514847..7dbf1eb 100644 --- a/chrome/browser/webdata/web_data_service.cc +++ b/chrome/browser/webdata/web_data_service.cc @@ -19,6 +19,7 @@ //////////////////////////////////////////////////////////////////////////////// using base::Time; +using webkit_glue::AutofillForm; WebDataService::WebDataService() : thread_(NULL), db_(NULL), diff --git a/chrome/browser/webdata/web_data_service.h b/chrome/browser/webdata/web_data_service.h index 4c38e1b..212e958 100644 --- a/chrome/browser/webdata/web_data_service.h +++ b/chrome/browser/webdata/web_data_service.h @@ -368,7 +368,7 @@ class WebDataService : public base::RefCountedThreadSafe<WebDataService> { // Schedules a task to add form elements to the web database. void AddAutofillFormElements( - const std::vector<AutofillForm::Element>& elements); + const std::vector<webkit_glue::AutofillForm::Element>& elements); // Initiates the request for a vector of values which have been entered in // form input fields named |name|. The method OnWebDataServiceRequestDone of @@ -457,7 +457,7 @@ class WebDataService : public base::RefCountedThreadSafe<WebDataService> { // ////////////////////////////////////////////////////////////////////////////// void AddAutofillFormElementsImpl( - GenericRequest<std::vector<AutofillForm::Element> >* request); + GenericRequest<std::vector<webkit_glue::AutofillForm::Element> >* request); void GetFormValuesForElementNameImpl(WebDataRequest* request, const std::wstring& name, const std::wstring& prefix, int limit); void RemoveFormElementsAddedBetweenImpl( diff --git a/chrome/browser/webdata/web_database.cc b/chrome/browser/webdata/web_database.cc index e6a1731..8914906 100644 --- a/chrome/browser/webdata/web_database.cc +++ b/chrome/browser/webdata/web_database.cc @@ -94,6 +94,7 @@ //////////////////////////////////////////////////////////////////////////////// using base::Time; +using webkit_glue::AutofillForm; // Current version number. static const int kCurrentVersionNumber = 22; diff --git a/chrome/browser/webdata/web_database.h b/chrome/browser/webdata/web_database.h index 3b5197b..c4d0d23 100644 --- a/chrome/browser/webdata/web_database.h +++ b/chrome/browser/webdata/web_database.h @@ -127,10 +127,11 @@ class WebDatabase { // Records the form elements in |elements| in the database in the autofill // table. bool AddAutofillFormElements( - const std::vector<AutofillForm::Element>& elements); + const std::vector<webkit_glue::AutofillForm::Element>& elements); // Records a single form element in in the database in the autofill table. - bool AddAutofillFormElement(const AutofillForm::Element& element); + bool AddAutofillFormElement( + const webkit_glue::AutofillForm::Element& element); // Retrieves a vector of all values which have been recorded in the autofill // table as the value in a form element with name |name| and which start with @@ -160,9 +161,10 @@ class WebDatabase { // Gets the pair_id and count entries from name and value specified in // |element|. Sets *count to 0 if there is no such row in the table. - bool GetIDAndCountOfFormElement(const AutofillForm::Element& element, - int64* pair_id, - int* count) const; + bool GetIDAndCountOfFormElement( + const webkit_glue::AutofillForm::Element& element, + int64* pair_id, + int* count) const; // Gets the count only given the pair_id. bool GetCountOfFormElement(int64 pair_id, @@ -173,7 +175,9 @@ class WebDatabase { // Adds a new row to the autofill table with name and value given in // |element|. Sets *pair_id to the pair_id of the new row. - bool InsertFormElement(const AutofillForm::Element& element, int64* pair_id); + bool InsertFormElement( + const webkit_glue::AutofillForm::Element& element, + int64* pair_id); // Adds a new row to the autofill_dates table. bool InsertPairIDAndDate(int64 pair_id, const base::Time date_created); diff --git a/chrome/browser/webdata/web_database_unittest.cc b/chrome/browser/webdata/web_database_unittest.cc index 4c27b1e..a456f91 100644 --- a/chrome/browser/webdata/web_database_unittest.cc +++ b/chrome/browser/webdata/web_database_unittest.cc @@ -18,6 +18,7 @@ using base::Time; using base::TimeDelta; +using webkit_glue::AutofillForm; class WebDatabaseTest : public testing::Test { protected: diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 63f210f..9ccce61 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -704,11 +704,11 @@ struct ParamTraits<PasswordForm> { // Traits for AutofillForm_Params structure to pack/unpack. template <> -struct ParamTraits<AutofillForm> { - typedef AutofillForm param_type; +struct ParamTraits<webkit_glue::AutofillForm> { + typedef webkit_glue::AutofillForm param_type; static void Write(Message* m, const param_type& p) { WriteParam(m, p.elements.size()); - for (std::vector<AutofillForm::Element>::const_iterator itr = + for (std::vector<webkit_glue::AutofillForm::Element>::const_iterator itr = p.elements.begin(); itr != p.elements.end(); itr++) { @@ -1127,10 +1127,10 @@ struct ParamTraits<scoped_refptr<net::UploadData> > { } }; -// Traits for PasswordFormDomManager::FillData. +// Traits for webkit_glue::PasswordFormDomManager::FillData. template <> -struct ParamTraits<PasswordFormDomManager::FillData> { - typedef PasswordFormDomManager::FillData param_type; +struct ParamTraits<webkit_glue::PasswordFormDomManager::FillData> { + typedef webkit_glue::PasswordFormDomManager::FillData param_type; static void Write(Message* m, const param_type& p) { WriteParam(m, p.basic_data); WriteParam(m, p.additional_logins); diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 2ff6eec..16d5fb9 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -293,7 +293,7 @@ IPC_BEGIN_MESSAGES(View) // Fill a password form and prepare field autocomplete for multiple // matching logins. IPC_MESSAGE_ROUTED1(ViewMsg_FillPasswordForm, - PasswordFormDomManager::FillData /* form_data */) + webkit_glue::PasswordFormDomManager::FillData) // D&d drop target messages. IPC_MESSAGE_ROUTED3(ViewMsg_DragTargetDragEnter, @@ -988,7 +988,7 @@ IPC_BEGIN_MESSAGES(ViewHost) // Notification that a form has been submitted. The user hit the button. IPC_MESSAGE_ROUTED1(ViewHostMsg_AutofillFormSubmitted, - AutofillForm /* form */) + webkit_glue::AutofillForm /* form */) // Used to tell the parent the user started dragging in the content area. The // WebDropData struct contains contextual information about the pieces of the diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 7c26b73..3922941 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -54,6 +54,7 @@ #include "skia/ext/bitmap_platform_device.h" #include "skia/ext/image_operations.h" #include "webkit/api/public/WebDragData.h" +#include "webkit/api/public/WebForm.h" #include "webkit/api/public/WebPoint.h" #include "webkit/api/public/WebRect.h" #include "webkit/api/public/WebScriptSource.h" @@ -88,8 +89,12 @@ using base::Time; using base::TimeDelta; +using webkit_glue::AutofillForm; +using webkit_glue::PasswordFormDomManager; +using webkit_glue::SearchableFormData; using WebKit::WebConsoleMessage; using WebKit::WebDragData; +using WebKit::WebForm; using WebKit::WebRect; using WebKit::WebScriptSource; using WebKit::WebWorker; @@ -139,13 +144,21 @@ static const char* const kBackForwardNavigationScheme = "history"; // Associated with browser-initiated navigations to hold tracking data. class RenderView::NavigationState : public WebDataSource::ExtraData { public: - NavigationState(int32 pending_page_id, - PageTransition::Type transition, - Time request_time) - : transition_type(transition), - request_time(request_time), - request_committed(false), - pending_page_id_(pending_page_id) { + static NavigationState* CreateBrowserInitiated( + int32 pending_page_id, + PageTransition::Type transition_type, + Time request_time) { + return new NavigationState(transition_type, request_time, false, + pending_page_id); + } + + static NavigationState* CreateContentInitiated() { + // We assume navigations initiated by content are link clicks. + return new NavigationState(PageTransition::LINK, Time(), true, -1); + } + + static NavigationState* FromDataSource(WebDataSource* ds) { + return static_cast<NavigationState*>(ds->GetExtraData()); } // Contains the page_id for this navigation or -1 if there is none yet. @@ -156,17 +169,55 @@ class RenderView::NavigationState : public WebDataSource::ExtraData { // Contains the transition type that the browser specified when it // initiated the load. - PageTransition::Type transition_type; + PageTransition::Type transition_type() const { return transition_type_; } + void set_transition_type(PageTransition::Type type) { + transition_type_ = type; + } // The time that this navigation was requested. - Time request_time; + const Time& request_time() const { return request_time_; } // True if we have already processed the "DidCommitLoad" event for this // request. Used by session history. - bool request_committed; + bool request_committed() const { return request_committed_; } + void set_request_committed(bool value) { request_committed_ = value; } + + // True if this navigation was not initiated via WebFrame::LoadRequest. + bool is_content_initiated() const { return is_content_initiated_; } + + SearchableFormData* searchable_form_data() const { + return searchable_form_data_.get(); + } + void set_searchable_form_data(SearchableFormData* data) { + searchable_form_data_.reset(data); + } + + PasswordForm* password_form_data() const { + return password_form_data_.get(); + } + void set_password_form_data(PasswordForm* data) { + password_form_data_.reset(data); + } private: + NavigationState(PageTransition::Type transition_type, + const Time& request_time, + bool is_content_initiated, + int32 pending_page_id) + : transition_type_(transition_type), + request_time_(request_time), + request_committed_(false), + is_content_initiated_(is_content_initiated), + pending_page_id_(pending_page_id) { + } + + PageTransition::Type transition_type_; + Time request_time_; + bool request_committed_; + bool is_content_initiated_; int32 pending_page_id_; + scoped_ptr<SearchableFormData> searchable_form_data_; + scoped_ptr<PasswordForm> password_form_data_; DISALLOW_COPY_AND_ASSIGN(NavigationState); }; @@ -645,7 +696,7 @@ void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) { // as a browser initiated event. Instead, we want it to look as if the page // initiated any load resulting from JS execution. if (!params.url.SchemeIs(chrome::kJavaScriptScheme)) { - pending_navigation_state_.reset(new NavigationState( + pending_navigation_state_.reset(NavigationState::CreateBrowserInitiated( params.page_id, params.transition, params.request_time)); } @@ -841,9 +892,8 @@ void RenderView::UpdateURL(WebFrame* frame) { const WebRequest& initial_request = ds->GetInitialRequest(); const WebResponse& response = ds->GetResponse(); - // This will be null if we did not initiate the navigation. - NavigationState* navigation_state = - static_cast<NavigationState*>(ds->GetExtraData()); + NavigationState* navigation_state = NavigationState::FromDataSource(ds); + DCHECK(navigation_state); ViewHostMsg_FrameNavigate_Params params; params.http_status_code = response.GetHttpStatusCode(); @@ -872,7 +922,7 @@ void RenderView::UpdateURL(WebFrame* frame) { params.should_update_history = !ds->HasUnreachableURL(); const SearchableFormData* searchable_form_data = - frame->GetDataSource()->GetSearchableFormData(); + navigation_state->searchable_form_data(); if (searchable_form_data) { params.searchable_form_url = searchable_form_data->url(); params.searchable_form_element_name = searchable_form_data->element_name(); @@ -880,7 +930,7 @@ void RenderView::UpdateURL(WebFrame* frame) { } const PasswordForm* password_form_data = - frame->GetDataSource()->GetPasswordFormData(); + navigation_state->password_form_data(); if (password_form_data) params.password_form = *password_form_data; @@ -893,10 +943,7 @@ void RenderView::UpdateURL(WebFrame* frame) { // Update contents MIME type for main frame. params.contents_mime_type = ds->GetResponse().GetMimeType(); - // We assume top level navigations initiated by the renderer are link - // clicks. - params.transition = navigation_state ? - navigation_state->transition_type : PageTransition::LINK; + params.transition = navigation_state->transition_type(); if (!PageTransition::IsMainFrame(params.transition)) { // If the main frame does a load, it should not be reported as a subframe // navigation. This can occur in the following case: @@ -912,11 +959,6 @@ void RenderView::UpdateURL(WebFrame* frame) { params.transition = PageTransition::LINK; } - if (params.transition == PageTransition::LINK && - frame->GetDataSource()->IsFormSubmit()) { - params.transition = PageTransition::FORM_SUBMIT; - } - // If we have a valid consumed client redirect source, // the page contained a client redirect (meta refresh, document.loc...), // so we set the referrer and transition to match. @@ -954,9 +996,8 @@ void RenderView::UpdateURL(WebFrame* frame) { std::max(last_page_id_sent_to_browser_, page_id_); // If we end up reusing this WebRequest (for example, due to a #ref click), - // we don't want the transition type to persist. - if (navigation_state) - navigation_state->transition_type = PageTransition::LINK; // Just clear it. + // we don't want the transition type to persist. Just clear it. + navigation_state->set_transition_type(PageTransition::LINK); #if defined(OS_WIN) if (web_accessibility_manager_.get()) { @@ -1065,7 +1106,13 @@ void RenderView::DidStopLoading(WebView* webview) { } void RenderView::DidCreateDataSource(WebFrame* frame, WebDataSource* ds) { - ds->SetExtraData(pending_navigation_state_.release()); + // The rest of RenderView assumes that a WebDataSource will always have a + // non-null NavigationState. + if (pending_navigation_state_.get()) { + ds->SetExtraData(pending_navigation_state_.release()); + } else { + ds->SetExtraData(NavigationState::CreateContentInitiated()); + } } void RenderView::DidStartProvisionalLoadForFrame( @@ -1079,13 +1126,14 @@ void RenderView::DidStartProvisionalLoadForFrame( completed_client_redirect_src_ = GURL(); } + // We may have better knowledge of when this navigation was requested. WebDataSource* ds = frame->GetProvisionalDataSource(); if (ds) { - NavigationState* navigation_state = - static_cast<NavigationState*>(ds->GetExtraData()); - if (navigation_state) - ds->SetRequestTime(navigation_state->request_time); + NavigationState* navigation_state = NavigationState::FromDataSource(ds); + if (!navigation_state->request_time().is_null()) + ds->SetRequestTime(navigation_state->request_time()); } + Send(new ViewHostMsg_DidStartProvisionalLoadForFrame( routing_id_, webview->GetMainFrame() == frame, frame->GetProvisionalDataSource()->GetRequest().GetURL())); @@ -1156,9 +1204,7 @@ void RenderView::DidFailProvisionalLoadWithError(WebView* webview, // 'replace' load. This is necessary to avoid messing up session history. // Otherwise, we do a normal load, which simulates a 'go' navigation as far // as session history is concerned. - NavigationState* navigation_state = - static_cast<NavigationState*>(ds->GetExtraData()); - bool replace = navigation_state && !navigation_state->is_new_navigation(); + bool replace = !NavigationState::FromDataSource(ds)->is_new_navigation(); // Use the alternate error page service if this is a DNS failure or // connection failure. ERR_CONNECTION_FAILED can be dropped once we no longer @@ -1225,8 +1271,8 @@ void RenderView::LoadNavigationErrorPage(WebFrame* frame, void RenderView::DidCommitLoadForFrame(WebView *webview, WebFrame* frame, bool is_new_navigation) { - NavigationState* navigation_state = static_cast<NavigationState*>( - frame->GetDataSource()->GetExtraData()); + NavigationState* navigation_state = + NavigationState::FromDataSource(frame->GetDataSource()); if (is_new_navigation) { // When we perform a new navigation, we need to update the previous session @@ -1251,8 +1297,8 @@ void RenderView::DidCommitLoadForFrame(WebView *webview, WebFrame* frame, // Note that we need to check if the page ID changed. In the case of a // reload, the page ID doesn't change, and UpdateSessionHistory gets the // previous URL and the current page ID, which would be wrong. - if (navigation_state && !navigation_state->is_new_navigation() && - !navigation_state->request_committed && + if (!navigation_state->is_new_navigation() && + !navigation_state->request_committed() && page_id_ != navigation_state->pending_page_id()) { // This is a successful session history navigation! UpdateSessionHistory(frame); @@ -1265,8 +1311,7 @@ void RenderView::DidCommitLoadForFrame(WebView *webview, WebFrame* frame, // a session history navigation, because if we attempted a session history // navigation without valid HistoryItem state, WebCore will think it is a // new navigation. - if (navigation_state) - navigation_state->request_committed = true; + navigation_state->set_request_committed(true); UpdateURL(frame); @@ -1304,6 +1349,10 @@ void RenderView::DidFinishDocumentLoadForFrame(WebView* webview, WebFrame* frame) { Send(new ViewHostMsg_DocumentLoadedInFrame(routing_id_)); + // The document has now been fully loaded. Scan for password forms to be + // sent up to the browser. + SendPasswordForms(frame); + // Check whether we have new encoding name. UpdateEncoding(frame, webview->GetMainFrameEncodingName()); @@ -1323,9 +1372,10 @@ void RenderView::DidChangeLocationWithinPageForFrame(WebView* webview, // could end up having a non-null pending navigation state. We just need to // update the ExtraData on the datasource so that others who read the // ExtraData will get the new NavigationState. Similarly, if we did not - // initiate this navigation, then we need to take care to clear any pre- - // existing navigation state. - frame->GetDataSource()->SetExtraData(pending_navigation_state_.release()); + // initiate this navigation, then we need to take care to reset any pre- + // existing navigation state to a content-initiated navigation state. + // DidCreateDataSource conveniently takes care of this for us. + DidCreateDataSource(frame, frame->GetDataSource()); DidCommitLoadForFrame(webview, frame, is_new_navigation); @@ -1334,25 +1384,6 @@ void RenderView::DidChangeLocationWithinPageForFrame(WebView* webview, UpdateTitle(frame, UTF16ToWideHack(title)); } -void RenderView::DidReceiveIconForFrame(WebView* webview, - WebFrame* frame) { -} - -void RenderView::WillPerformClientRedirect(WebView* webview, - WebFrame* frame, - const GURL& src_url, - const GURL& dest_url, - unsigned int delay_seconds, - unsigned int fire_date) { -} - -void RenderView::DidCancelClientRedirect(WebView* webview, - WebFrame* frame) { -} - -void RenderView::WillCloseFrame(WebView* view, WebFrame* frame) { -} - void RenderView::DidCompleteClientRedirect(WebView* webview, WebFrame* frame, const GURL& source) { @@ -1360,6 +1391,27 @@ void RenderView::DidCompleteClientRedirect(WebView* webview, completed_client_redirect_src_ = source; } +void RenderView::WillSubmitForm(WebView* webview, WebFrame* frame, + const WebForm& form) { + NavigationState* navigation_state = + NavigationState::FromDataSource(frame->GetProvisionalDataSource()); + + if (navigation_state->transition_type() == PageTransition::LINK) + navigation_state->set_transition_type(PageTransition::FORM_SUBMIT); + + // Save these to be processed when the ensuing navigation is committed. + navigation_state->set_searchable_form_data( + SearchableFormData::Create(form)); + navigation_state->set_password_form_data( + PasswordFormDomManager::CreatePasswordForm(form)); + + if (form.isAutoCompleteEnabled()) { + scoped_ptr<AutofillForm> autofill_form(AutofillForm::Create(form)); + if (autofill_form.get()) + Send(new ViewHostMsg_AutofillFormSubmitted(routing_id_, *autofill_form)); + } +} + void RenderView::WillSendRequest(WebView* webview, uint32 identifier, WebRequest* request) { @@ -1414,11 +1466,11 @@ WindowOpenDisposition RenderView::DispositionForNavigationAction( WebNavigationType type, WindowOpenDisposition disposition, bool is_redirect) { - // GetExtraData is NULL when we did not issue the request ourselves (see - // OnNavigate), and so such a request may correspond to a link-click, - // script, or drag-n-drop initiated navigation. + // A content initiated navigation may have originated from a link-click, + // script, drag-n-drop operation, etc. bool is_content_initiated = - !frame->GetProvisionalDataSource()->GetExtraData(); + NavigationState::FromDataSource(frame->GetProvisionalDataSource())-> + is_content_initiated(); // Webkit is asking whether to navigate to a new URL. // This is fine normally, except if we're showing UI from one security @@ -2262,16 +2314,6 @@ void RenderView::OnSetPageEncoding(const std::wstring& encoding_name) { webview()->SetPageEncoding(encoding_name); } -void RenderView::OnPasswordFormsSeen(WebView* webview, - const std::vector<PasswordForm>& forms) { - Send(new ViewHostMsg_PasswordFormsSeen(routing_id_, forms)); -} - -void RenderView::OnAutofillFormSubmitted(WebView* webview, - const AutofillForm& form) { - Send(new ViewHostMsg_AutofillFormSubmitted(routing_id_, form)); -} - void RenderView::NavigateBackForwardSoon(int offset) { history_back_list_count_ += offset; history_forward_list_count_ -= offset; @@ -2472,7 +2514,7 @@ void RenderView::OnFormFill(const FormData& form) { } void RenderView::OnFillPasswordForm( - const PasswordFormDomManager::FillData& form_data) { + const webkit_glue::PasswordFormDomManager::FillData& form_data) { webkit_glue::FillPasswordForm(this->webview(), form_data); } @@ -2679,11 +2721,8 @@ void RenderView::DidAddHistoryItem() { WebDataSource* ds = main_frame->GetDataSource(); DCHECK(ds != NULL); - NavigationState* navigation_state = - static_cast<NavigationState*>(ds->GetExtraData()); - - if (navigation_state && - navigation_state->transition_type == PageTransition::START_PAGE) + NavigationState* navigation_state = NavigationState::FromDataSource(ds); + if (navigation_state->transition_type() == PageTransition::START_PAGE) return; history_back_list_count_++; @@ -2852,3 +2891,24 @@ void RenderView::FocusAccessibilityObject( NOTIMPLEMENTED(); #endif } + +void RenderView::SendPasswordForms(WebFrame* frame) { + std::vector<WebForm> forms; + frame->GetForms(&forms); + + std::vector<PasswordForm> password_forms; + for (size_t i = 0; i < forms.size(); ++i) { + const WebForm& form = forms[i]; + + // Respect autocomplete=off. + if (form.isAutoCompleteEnabled()) { + scoped_ptr<PasswordForm> password_form( + PasswordFormDomManager::CreatePasswordForm(form)); + if (password_form.get()) + password_forms.push_back(*password_form); + } + } + + if (!password_forms.empty()) + Send(new ViewHostMsg_PasswordFormsSeen(routing_id_, password_forms)); +} diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 237b79c..f1108eb 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -207,23 +207,15 @@ class RenderView : public RenderWidget, virtual void DidChangeLocationWithinPageForFrame(WebView* webview, WebFrame* frame, bool is_new_navigation); - virtual void DidReceiveIconForFrame(WebView* webview, WebFrame* frame); virtual void DidContentsSizeChange(WebWidget* webwidget, int new_width, int new_height); - virtual void WillPerformClientRedirect(WebView* webview, - WebFrame* frame, - const GURL& src_url, - const GURL& dest_url, - unsigned int delay_seconds, - unsigned int fire_date); - virtual void DidCancelClientRedirect(WebView* webview, - WebFrame* frame); virtual void DidCompleteClientRedirect(WebView* webview, WebFrame* frame, const GURL& source); - virtual void WillCloseFrame(WebView* webview, WebFrame* frame); + virtual void WillSubmitForm(WebView* webview, WebFrame* frame, + const WebKit::WebForm& form); virtual void WillSendRequest(WebView* webview, uint32 identifier, WebRequest* request); @@ -300,12 +292,6 @@ class RenderView : public RenderWidget, virtual void PasteFromSelectionClipboard(); - virtual void OnPasswordFormsSeen(WebView* webview, - const std::vector<PasswordForm>& forms); - - virtual void OnAutofillFormSubmitted(WebView* webview, - const AutofillForm& form); - virtual void ReportFindInPageMatchCount(int count, int request_id, bool final_update); virtual void ReportFindInPageSelection(int request_id, @@ -506,7 +492,8 @@ class RenderView : public RenderWidget, const FilePath& local_directory_name); void OnUploadFileRequest(const ViewMsg_UploadFile_Params& p); void OnFormFill(const FormData& form); - void OnFillPasswordForm(const PasswordFormDomManager::FillData& form_data); + void OnFillPasswordForm( + const webkit_glue::PasswordFormDomManager::FillData& form_data); void OnDragTargetDragEnter(const WebDropData& drop_data, const gfx::Point& client_pt, const gfx::Point& screen_pt); @@ -620,6 +607,9 @@ class RenderView : public RenderWidget, void DumpLoadHistograms() const; + // Scan the given frame for password forms and send them up to the browser. + void SendPasswordForms(WebFrame* frame); + // Bitwise-ORed set of extra bindings that have been enabled. See // BindingsPolicy for details. int enabled_bindings_; diff --git a/webkit/api/public/WebForm.h b/webkit/api/public/WebForm.h new file mode 100644 index 0000000..fe2e168 --- /dev/null +++ b/webkit/api/public/WebForm.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebForm_h +#define WebForm_h + +#include "WebCommon.h" + +#if WEBKIT_IMPLEMENTATION +namespace WebCore { class HTMLFormElement; } +namespace WTF { template <typename T> class PassRefPtr; } +#endif + +namespace WebKit { + class WebFormPrivate; + + // A container for passing around a reference to a form element. Provides + // some information about the form. + class WebForm { + public: + ~WebForm() { reset(); } + + WebForm() : m_private(0) { } + WebForm(const WebForm& f) : m_private(0) { assign(f); } + WebForm& operator=(const WebForm& f) { assign(f); return *this; } + + WEBKIT_API void reset(); + WEBKIT_API void assign(const WebForm&); + + bool isNull() const { return m_private == 0; } + + // Returns true if the form does not have "autocomplete=off" specified. + WEBKIT_API bool isAutoCompleteEnabled() const; + +#if WEBKIT_IMPLEMENTATION + WebForm(const WTF::PassRefPtr<WebCore::HTMLFormElement>&); + WebForm& operator=(const WTF::PassRefPtr<WebCore::HTMLFormElement>&); + operator WTF::PassRefPtr<WebCore::HTMLFormElement>() const; +#endif + + private: + void assign(WebFormPrivate*); + WebFormPrivate* m_private; + }; + +} // namespace WebKit + +#endif diff --git a/webkit/api/public/WebFrameClient.h b/webkit/api/public/WebFrameClient.h index d03cf12..8140997 100644 --- a/webkit/api/public/WebFrameClient.h +++ b/webkit/api/public/WebFrameClient.h @@ -1,10 +1,10 @@ /* * Copyright (C) 2009 Google Inc. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above @@ -14,7 +14,7 @@ * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -37,6 +37,7 @@ #include "WebNavigationGesture.h" namespace WebKit { + class WebForm; class WebFrame; class WebMediaPlayer; class WebMediaPlayerClient; @@ -47,7 +48,7 @@ namespace WebKit { class WebFrameClient { public: - // Factory methods ----------------------------------------------------- + // Factory methods ----------------------------------------------------- // May return null. virtual WebPlugin* createPlugin( @@ -85,6 +86,9 @@ namespace WebKit { // Navigational notifications ------------------------------------------ + // A form submission is about to occur. + virtual void willSubmitForm(WebFrame*, const WebForm&) = 0; + // A client-side redirect will occur. This may correspond to a <META // refresh> or some script activity. virtual void willPerformClientRedirect( @@ -139,7 +143,7 @@ namespace WebKit { // The navigation resulted in scrolling the page to a named anchor instead // of downloading a new document. - virtual void didChangeLocationWithinPage(WebFrame*, bool isNewNavigation) = 0; + virtual void didChangeLocationWithinPage(WebFrame*, bool isNewNavigation) = 0; // Called upon update to scroll position, document state, and other // non-navigational events related to the data held by WebHistoryItem. diff --git a/webkit/api/src/WebForm.cpp b/webkit/api/src/WebForm.cpp new file mode 100644 index 0000000..3ab7c4a --- /dev/null +++ b/webkit/api/src/WebForm.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebForm.h" + +#include "HTMLFormElement.h" +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + +class WebFormPrivate : public HTMLFormElement { +}; + +void WebForm::reset() +{ + assign(0); +} + +void WebForm::assign(const WebForm& other) +{ + WebFormPrivate* p = const_cast<WebFormPrivate*>(other.m_private); + p->ref(); + assign(p); +} + +bool WebForm::isAutoCompleteEnabled() const +{ + ASSERT(!isNull()); + return m_private->autoComplete(); +} + +WebForm::WebForm(const WTF::PassRefPtr<WebCore::HTMLFormElement>& element) + : m_private(static_cast<WebFormPrivate*>(element.releaseRef())) +{ +} + +WebForm& WebForm::operator=(const WTF::PassRefPtr<WebCore::HTMLFormElement>& element) +{ + assign(static_cast<WebFormPrivate*>(element.releaseRef())); + return *this; +} + +WebForm::operator WTF::PassRefPtr<WebCore::HTMLFormElement>() const +{ + return PassRefPtr<HTMLFormElement>(const_cast<WebFormPrivate*>(m_private)); +} + +void WebForm::assign(WebFormPrivate* p) +{ + // p is already ref'd for us by the caller + if (m_private) + m_private->deref(); + m_private = p; +} + +} // namespace WebKit diff --git a/webkit/glue/autofill_form.cc b/webkit/glue/autofill_form.cc index ff0725c..e484716 100644 --- a/webkit/glue/autofill_form.cc +++ b/webkit/glue/autofill_form.cc @@ -3,35 +3,33 @@ // found in the LICENSE file. #include "config.h" -#include "base/compiler_specific.h" -MSVC_PUSH_WARNING_LEVEL(0); #include "Frame.h" #include "HTMLFormElement.h" #include "HTMLInputElement.h" #include "HTMLNames.h" -MSVC_POP_WARNING(); - #undef LOG #include "base/basictypes.h" #include "base/logging.h" #include "base/string_util.h" +#include "webkit/api/public/WebForm.h" #include "webkit/glue/autofill_form.h" #include "webkit/glue/glue_util.h" -AutofillForm* AutofillForm::CreateAutofillForm( - WebCore::HTMLFormElement* form) { +using WebKit::WebForm; + +namespace webkit_glue { +AutofillForm* AutofillForm::Create(const WebForm& webform) { + RefPtr<WebCore::HTMLFormElement> form = WebFormToHTMLFormElement(webform); DCHECK(form); WebCore::Frame* frame = form->document()->frame(); - if (!frame) return NULL; WebCore::FrameLoader* loader = frame->loader(); - if (!loader) return NULL; @@ -59,8 +57,7 @@ AutofillForm* AutofillForm::CreateAutofillForm( continue; // For each TEXT input field, store the name and value - std::wstring value = webkit_glue::StringToStdWString( - input_element->value()); + std::wstring value = StringToStdWString(input_element->value()); TrimWhitespace(value, TRIM_LEADING, &value); if (value.length() == 0) continue; @@ -78,16 +75,18 @@ AutofillForm* AutofillForm::CreateAutofillForm( // static std::wstring AutofillForm::GetNameForInputElement(WebCore::HTMLInputElement* element) { - std::wstring name = webkit_glue::StringToStdWString(element->name()); + std::wstring name = StringToStdWString(element->name()); std::wstring trimmed_name; TrimWhitespace(name, TRIM_LEADING, &trimmed_name); if (trimmed_name.length() > 0) return trimmed_name; - name = webkit_glue::StringToStdWString(element->id()); + name = StringToStdWString(element->id()); TrimWhitespace(name, TRIM_LEADING, &trimmed_name); if (trimmed_name.length() > 0) return trimmed_name; return std::wstring(); } + +} // namespace webkit_glue diff --git a/webkit/glue/autofill_form.h b/webkit/glue/autofill_form.h index 8375e75..4cf1b20 100644 --- a/webkit/glue/autofill_form.h +++ b/webkit/glue/autofill_form.h @@ -9,13 +9,17 @@ #include <vector> namespace WebCore { - class HTMLInputElement; - class HTMLFormElement; +class HTMLInputElement; } +namespace WebKit { +class WebForm; +} + +namespace webkit_glue { + // The AutofillForm struct represents a single HTML form together with the // values entered in the fields. - class AutofillForm { public: // Struct for storing name/value pairs. @@ -29,7 +33,7 @@ class AutofillForm { std::wstring value; }; - static AutofillForm* CreateAutofillForm(WebCore::HTMLFormElement* form); + static AutofillForm* Create(const WebKit::WebForm& form); // Returns the name that should be used for the specified |element| when // storing autofill data. This is either the field name or its id, an empty @@ -41,4 +45,6 @@ class AutofillForm { std::vector<Element> elements; }; +} // namespace webkit_glue + #endif // WEBKIT_GLUE_AUTOFILL_FORM_H_ diff --git a/webkit/glue/dom_operations.h b/webkit/glue/dom_operations.h index a088ef7..f202def 100644 --- a/webkit/glue/dom_operations.h +++ b/webkit/glue/dom_operations.h @@ -14,6 +14,7 @@ namespace WebCore { class Element; +class HTMLInputElement; class Node; } diff --git a/webkit/glue/editor_client_impl.cc b/webkit/glue/editor_client_impl.cc index f2575c8..07d1b5c 100644 --- a/webkit/glue/editor_client_impl.cc +++ b/webkit/glue/editor_client_impl.cc @@ -35,6 +35,8 @@ #include "webkit/glue/webview.h" #include "webkit/glue/webview_impl.h" +using webkit_glue::AutofillForm; + // Arbitrary depth limit for the undo stack, to keep it from using // unbounded memory. This is the maximum number of distinct undoable // actions -- unbroken stretches of typed characters are coalesced diff --git a/webkit/glue/glue_util.cc b/webkit/glue/glue_util.cc index b85ad71..34bd0fe 100644 --- a/webkit/glue/glue_util.cc +++ b/webkit/glue/glue_util.cc @@ -17,6 +17,7 @@ #include "ChromiumDataObject.h" #include "CString.h" +#include "HTMLFormElement.h" #include "IntPoint.h" #include "IntRect.h" #include "PlatformString.h" @@ -30,6 +31,7 @@ #include "base/sys_string_conversions.h" #include "googleurl/src/gurl.h" #include "webkit/api/public/WebDragData.h" +#include "webkit/api/public/WebForm.h" #include "webkit/api/public/WebPoint.h" #include "webkit/api/public/WebRect.h" #include "webkit/api/public/WebSize.h" @@ -226,6 +228,18 @@ PassRefPtr<WebCore::ChromiumDataObject> WebDragDataToChromiumDataObject( return data; } +// FormElement conversions ----------------------------------------------------- + +WebKit::WebForm HTMLFormElementToWebForm( + const WTF::PassRefPtr<WebCore::HTMLFormElement>& form) { + return form; +} + +WTF::PassRefPtr<WebCore::HTMLFormElement> WebFormToHTMLFormElement( + const WebKit::WebForm& form) { + return form; +} + // WebURLRequest conversions --------------------------------------------------- WebCore::ResourceRequest* WebURLRequestToMutableResourceRequest( diff --git a/webkit/glue/glue_util.h b/webkit/glue/glue_util.h index 553802c..776dc7e 100644 --- a/webkit/glue/glue_util.h +++ b/webkit/glue/glue_util.h @@ -13,6 +13,7 @@ class GURL; namespace WebCore { class ChromiumDataObject; class CString; +class HTMLFormElement; class IntPoint; class IntRect; class IntSize; @@ -25,6 +26,7 @@ struct ResourceRequest; namespace WebKit { class WebCString; class WebDragData; +class WebForm; class WebString; class WebURL; class WebURLRequest; @@ -107,6 +109,12 @@ WebKit::WebDragData ChromiumDataObjectToWebDragData( WTF::PassRefPtr<WebCore::ChromiumDataObject> WebDragDataToChromiumDataObject( const WebKit::WebDragData&); +// WebForm <-> HTMLFormElement +WebKit::WebForm HTMLFormElementToWebForm( + const WTF::PassRefPtr<WebCore::HTMLFormElement>&); +WTF::PassRefPtr<WebCore::HTMLFormElement> WebFormToHTMLFormElement( + const WebKit::WebForm&); + // Exposes the ResourceRequest contained by a WebURLRequest WebCore::ResourceRequest* WebURLRequestToMutableResourceRequest( WebKit::WebURLRequest* req); diff --git a/webkit/glue/password_autocomplete_listener_unittest.cc b/webkit/glue/password_autocomplete_listener_unittest.cc index ef5a4b1..05337d9 100644 --- a/webkit/glue/password_autocomplete_listener_unittest.cc +++ b/webkit/glue/password_autocomplete_listener_unittest.cc @@ -28,6 +28,7 @@ MSVC_POP_WARNING(); #include "testing/gtest/include/gtest/gtest.h" using webkit_glue::PasswordAutocompleteListener; +using webkit_glue::PasswordFormDomManager; using webkit_glue::HTMLInputDelegate; class TestHTMLInputDelegate : public HTMLInputDelegate { diff --git a/webkit/glue/password_form_dom_manager.cc b/webkit/glue/password_form_dom_manager.cc index fb99302..ceef5b4 100644 --- a/webkit/glue/password_form_dom_manager.cc +++ b/webkit/glue/password_form_dom_manager.cc @@ -4,9 +4,6 @@ #include "config.h" -#include "base/compiler_specific.h" - -MSVC_PUSH_WARNING_LEVEL(0); #include "Document.h" #include "DocumentLoader.h" #include "Frame.h" @@ -15,80 +12,127 @@ MSVC_PUSH_WARNING_LEVEL(0); #include "HTMLInputElement.h" #include "HTMLNames.h" #include "KURL.h" -MSVC_POP_WARNING(); - #undef LOG #include "base/logging.h" -#include "base/basictypes.h" #include "webkit/glue/glue_util.h" #include "webkit/glue/password_form_dom_manager.h" +using WebKit::WebForm; + +namespace webkit_glue { + +namespace { + // Maximum number of password fields we will observe before throwing our // hands in the air and giving up with a given form. -static const size_t kMaxPasswords = 3; +const size_t kMaxPasswords = 3; -PasswordForm* PasswordFormDomManager::CreatePasswordForm( - WebCore::HTMLFormElement* form) { - WebCore::Frame* frame = form->document()->frame(); - if (frame == NULL) - return NULL; +// Helper structure to locate username, passwords and submit fields. +struct PasswordFormFields { + WebCore::HTMLInputElement* username; + std::vector<WebCore::HTMLInputElement*> passwords; + WebCore::HTMLFormControlElement* submit; + PasswordFormFields() : username(NULL), submit(NULL) { + } +}; - WebCore::FrameLoader* loader = frame->loader(); - if (loader == NULL) - return NULL; +// Helper to CreatePasswordForm to do the locating of username/password +// fields. +// This method based on Firefox2 code in +// toolkit/components/passwordmgr/base/nsPasswordManager.cpp +// Its license block is - PasswordFormFields fields; - FindPasswordFormFields(form, &fields); +/* ***** BEGIN LICENSE BLOCK ***** +* Version: MPL 1.1/GPL 2.0/LGPL 2.1 +* +* The contents of this file are subject to the Mozilla Public License Version +* 1.1 (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS IS" basis, +* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +* for the specific language governing rights and limitations under the +* License. +* +* The Original Code is Mozilla Password Manager. +* +* The Initial Developer of the Original Code is +* Brian Ryner. +* Portions created by the Initial Developer are Copyright (C) 2003 +* the Initial Developer. All Rights Reserved. +* +* Contributor(s): +* Brian Ryner <bryner@brianryner.com> +* +* Alternatively, the contents of this file may be used under the terms of +* either the GNU General Public License Version 2 or later (the "GPL"), or +* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +* in which case the provisions of the GPL or the LGPL are applicable instead +* of those above. If you wish to allow use of your version of this file only +* under the terms of either the GPL or the LGPL, and not to allow others to +* use your version of this file under the terms of the MPL, indicate your +* decision by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL or the LGPL. If you do not delete +* the provisions above, a recipient may use your version of this file under +* the terms of any one of the MPL, the GPL or the LGPL. +* +* ***** END LICENSE BLOCK ***** */ +void FindPasswordFormFields( + WebCore::HTMLFormElement* form, + PasswordFormFields* fields) { + DCHECK(form && fields); + int first_password_index = 0; + // First, find the password fields and activated submit button + const WTF::Vector<WebCore::HTMLFormControlElement*>& form_elements = + form->formElements; + for (size_t i = 0; i < form_elements.size(); i++) { + WebCore::HTMLFormControlElement* form_element = form_elements[i]; + if (form_element->isActivatedSubmit()) + fields->submit = form_element; - // Get the document URL - WebCore::String origin_string = form->document()->documentURI(); - GURL full_origin(webkit_glue::StringToStdString(origin_string)); + if (!form_element->hasLocalName(WebCore::HTMLNames::inputTag)) + continue; - // Calculate the canonical action URL - GURL full_action(webkit_glue::KURLToGURL(loader->completeURL(form->action()))); - if (!full_action.is_valid()) - return NULL; + WebCore::HTMLInputElement* input_element = + static_cast<WebCore::HTMLInputElement*>(form_element); + if (!input_element->isEnabledFormControl()) + continue; - // Determine the types of the password fields - WebCore::HTMLInputElement* password = NULL; - WebCore::HTMLInputElement* old_password = NULL; - if (!LocateSpecificPasswords(&fields, &password, &old_password)) - return NULL; + if ((fields->passwords.size() < kMaxPasswords) && + (input_element->inputType() == WebCore::HTMLInputElement::PASSWORD) && + (input_element->autoComplete())) { + if (fields->passwords.empty()) + first_password_index = i; + fields->passwords.push_back(input_element); + } + } - return AssemblePasswordFormResult(full_origin, full_action, - fields.submit, fields.username, - old_password, password); -} + if (!fields->passwords.empty()) { + // Then, search backwards for the username field + for (int i = first_password_index - 1; i >= 0; i--) { + WebCore::HTMLFormControlElement* form_element = form_elements[i]; + if (!form_element->hasLocalName(WebCore::HTMLNames::inputTag)) + continue; -// static -void PasswordFormDomManager::InitFillData( - const PasswordForm& form_on_page, - const PasswordFormMap& matches, - const PasswordForm* const preferred_match, - bool wait_for_username_before_autofill, - PasswordFormDomManager::FillData* result) { - DCHECK(preferred_match); - // Fill basic form data. - result->basic_data.origin = form_on_page.origin; - result->basic_data.action = form_on_page.action; - result->basic_data.elements.push_back(form_on_page.username_element); - result->basic_data.values.push_back(preferred_match->username_value); - result->basic_data.elements.push_back(form_on_page.password_element); - result->basic_data.values.push_back(preferred_match->password_value); - result->basic_data.submit = form_on_page.submit_element; - result->wait_for_username = wait_for_username_before_autofill; + WebCore::HTMLInputElement* input_element = + static_cast<WebCore::HTMLInputElement*>(form_element); + if (!input_element->isEnabledFormControl()) + continue; - // Copy additional username/value pairs. - PasswordFormMap::const_iterator iter; - for (iter = matches.begin(); iter != matches.end(); iter++) { - if (iter->second != preferred_match) - result->additional_logins[iter->first] = iter->second->password_value; + if ((input_element->inputType() == WebCore::HTMLInputElement::TEXT) && + (input_element->autoComplete())) { + fields->username = input_element; + break; + } + } } } -// static -bool PasswordFormDomManager::LocateSpecificPasswords( +// Helper to determine which password is the main one, and which is +// an old password (e.g on a "make new password" form), if any. +bool LocateSpecificPasswords( PasswordFormFields* fields, WebCore::HTMLInputElement** password, WebCore::HTMLInputElement** old_password) { @@ -133,100 +177,9 @@ bool PasswordFormDomManager::LocateSpecificPasswords( } return true; } - // This method based on Firefox2 code in - // toolkit/components/passwordmgr/base/nsPasswordManager.cpp - // Its license block is - // - /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Password Manager. - * - * The Initial Developer of the Original Code is - * Brian Ryner. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Ryner <bryner@brianryner.com> - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -// static -void PasswordFormDomManager::FindPasswordFormFields( - WebCore::HTMLFormElement* form, - PasswordFormFields* fields) { - DCHECK(form && fields); - int first_password_index = 0; - // First, find the password fields and activated submit button - const WTF::Vector<WebCore::HTMLFormControlElement*>& form_elements = - form->formElements; - for (size_t i = 0; i < form_elements.size(); i++) { - WebCore::HTMLFormControlElement* form_element = form_elements[i]; - if (form_element->isActivatedSubmit()) - fields->submit = form_element; - - if (!form_element->hasLocalName(WebCore::HTMLNames::inputTag)) - continue; - - WebCore::HTMLInputElement* input_element = - static_cast<WebCore::HTMLInputElement*>(form_element); - if (!input_element->isEnabledFormControl()) - continue; - - if ((fields->passwords.size() < kMaxPasswords) && - (input_element->inputType() == WebCore::HTMLInputElement::PASSWORD) && - (input_element->autoComplete())) { - if (fields->passwords.empty()) - first_password_index = i; - fields->passwords.push_back(input_element); - } - } - - if (!fields->passwords.empty()) { - // Then, search backwards for the username field - for (int i = first_password_index - 1; i >= 0; i--) { - WebCore::HTMLFormControlElement* form_element = form_elements[i]; - if (!form_element->hasLocalName(WebCore::HTMLNames::inputTag)) - continue; - - WebCore::HTMLInputElement* input_element = - static_cast<WebCore::HTMLInputElement*>(form_element); - if (!input_element->isEnabledFormControl()) - continue; - - if ((input_element->inputType() == WebCore::HTMLInputElement::TEXT) && - (input_element->autoComplete())) { - fields->username = input_element; - break; - } - } - } -} -// static -PasswordForm* PasswordFormDomManager::AssemblePasswordFormResult( +// Helper to gather up the final form data and create a PasswordForm. +PasswordForm* AssemblePasswordFormResult( const GURL& full_origin, const GURL& full_action, WebCore::HTMLFormControlElement* submit, @@ -252,24 +205,79 @@ PasswordForm* PasswordFormDomManager::AssemblePasswordFormResult( result->signon_realm = full_origin.GetOrigin().spec(); // Note PasswordManager sets ssl_valid by asking the WebContents' SSLManager. result->submit_element = - submit == NULL ? empty : webkit_glue::StringToStdWString(submit->name()); + submit == NULL ? empty : StringToStdWString(submit->name()); result->username_element = - username == NULL ? empty - : webkit_glue::StringToStdWString(username->name()); + username == NULL ? empty : StringToStdWString(username->name()); result->username_value = - username == NULL ? empty - : webkit_glue::StringToStdWString(username->value()); + username == NULL ? empty : StringToStdWString(username->value()); result->password_element = - password == NULL ? empty - : webkit_glue::StringToStdWString(password->name()); + password == NULL ? empty : StringToStdWString(password->name()); result->password_value = - password == NULL ? empty - : webkit_glue::StringToStdWString(password->value()); + password == NULL ? empty : StringToStdWString(password->value()); result->old_password_element = - old_password == NULL ? empty - : webkit_glue::StringToStdWString(old_password->name()); + old_password == NULL ? empty : StringToStdWString(old_password->name()); result->old_password_value = - old_password == NULL ? empty - : webkit_glue::StringToStdWString(old_password->value()); + old_password == NULL ? empty : StringToStdWString(old_password->value()); return result; } + +} // namespace + +PasswordForm* PasswordFormDomManager::CreatePasswordForm( + const WebForm& webform) { + RefPtr<WebCore::HTMLFormElement> form = WebFormToHTMLFormElement(webform); + + WebCore::Frame* frame = form->document()->frame(); + if (!frame) + return NULL; + + PasswordFormFields fields; + FindPasswordFormFields(form.get(), &fields); + + // Get the document URL + WebCore::String origin_string = form->document()->documentURI(); + GURL full_origin(StringToStdString(origin_string)); + + // Calculate the canonical action URL + GURL full_action(KURLToGURL(frame->loader()->completeURL(form->action()))); + if (!full_action.is_valid()) + return NULL; + + // Determine the types of the password fields + WebCore::HTMLInputElement* password = NULL; + WebCore::HTMLInputElement* old_password = NULL; + if (!LocateSpecificPasswords(&fields, &password, &old_password)) + return NULL; + + return AssemblePasswordFormResult(full_origin, full_action, + fields.submit, fields.username, + old_password, password); +} + +// static +void PasswordFormDomManager::InitFillData( + const PasswordForm& form_on_page, + const PasswordFormMap& matches, + const PasswordForm* const preferred_match, + bool wait_for_username_before_autofill, + PasswordFormDomManager::FillData* result) { + DCHECK(preferred_match); + // Fill basic form data. + result->basic_data.origin = form_on_page.origin; + result->basic_data.action = form_on_page.action; + result->basic_data.elements.push_back(form_on_page.username_element); + result->basic_data.values.push_back(preferred_match->username_value); + result->basic_data.elements.push_back(form_on_page.password_element); + result->basic_data.values.push_back(preferred_match->password_value); + result->basic_data.submit = form_on_page.submit_element; + result->wait_for_username = wait_for_username_before_autofill; + + // Copy additional username/value pairs. + PasswordFormMap::const_iterator iter; + for (iter = matches.begin(); iter != matches.end(); iter++) { + if (iter->second != preferred_match) + result->additional_logins[iter->first] = iter->second->password_value; + } +} + +} // namespace webkit_glue diff --git a/webkit/glue/password_form_dom_manager.h b/webkit/glue/password_form_dom_manager.h index 84dbc93..9963a5d 100644 --- a/webkit/glue/password_form_dom_manager.h +++ b/webkit/glue/password_form_dom_manager.h @@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef WEBKIT_GLUE_PASSWORD_FORM_DOM_MANAGER_H__ -#define WEBKIT_GLUE_PASSWORD_FORM_DOM_MANAGER_H__ +#ifndef WEBKIT_GLUE_PASSWORD_FORM_DOM_MANAGER_H_ +#define WEBKIT_GLUE_PASSWORD_FORM_DOM_MANAGER_H_ #include "webkit/glue/form_data.h" #include "webkit/glue/password_form.h" -namespace WebCore { -class HTMLFormElement; -class HTMLInputElement; -class HTMLFormControlElement; +namespace WebKit { +class WebForm; } class GURL; +namespace webkit_glue { + class PasswordFormDomManager { public: typedef std::map<std::wstring, std::wstring> LoginCollection; @@ -41,7 +41,7 @@ class PasswordFormDomManager { // custom metadata to DOM nodes, so we have to do this every time an event // happens with a given form and compare against previously Create'd forms // to identify..which sucks. - static PasswordForm* CreatePasswordForm(WebCore::HTMLFormElement* form); + static PasswordForm* CreatePasswordForm(const WebKit::WebForm& form); // Create a FillData structure in preparation for autofilling a form, // from basic_data identifying which form to fill, and a collection of @@ -55,77 +55,9 @@ class PasswordFormDomManager { bool wait_for_username_before_autofill, FillData* result); private: - // Helper structure to locate username, passwords and submit fields. - struct PasswordFormFields { - WebCore::HTMLInputElement* username; - std::vector<WebCore::HTMLInputElement*> passwords; - WebCore::HTMLFormControlElement* submit; - PasswordFormFields() : username(NULL), submit(NULL) { - } - }; - - // Helper to CreatePasswordForm to do the locating of username/password - // fields. - // This method based on Firefox2 code in - // toolkit/components/passwordmgr/base/nsPasswordManager.cpp - // Its license block is - - /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Password Manager. - * - * The Initial Developer of the Original Code is - * Brian Ryner. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Ryner <bryner@brianryner.com> - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - static void FindPasswordFormFields(WebCore::HTMLFormElement* form, - PasswordFormFields* fields); - // Helper to determine which password is the main one, and which is - // an old password (e.g on a "make new password" form), if any. - static bool LocateSpecificPasswords( - PasswordFormFields* fields, - WebCore::HTMLInputElement** password, - WebCore::HTMLInputElement** old_password_index); - - // Helper to gather up the final form data and create a PasswordForm. - static PasswordForm* AssemblePasswordFormResult( - const GURL& full_origin, - const GURL& full_action, - WebCore::HTMLFormControlElement* submit, - WebCore::HTMLInputElement* username, - WebCore::HTMLInputElement* old_password, - WebCore::HTMLInputElement* password); - - // This class can't be instantiated. DISALLOW_IMPLICIT_CONSTRUCTORS(PasswordFormDomManager); }; +} // namespace webkit_glue + #endif // WEBKIT_GLUE_PASSWORD_FORM_DOM_MANAGER_H__ diff --git a/webkit/glue/searchable_form_data.cc b/webkit/glue/searchable_form_data.cc index 6187897..5955745a 100644 --- a/webkit/glue/searchable_form_data.cc +++ b/webkit/glue/searchable_form_data.cc @@ -36,10 +36,15 @@ MSVC_POP_WARNING(); #include "webkit/glue/searchable_form_data.h" #include "webkit/glue/webframe_impl.h" +using WebCore::HTMLFormElement; using WebCore::HTMLInputElement; using WebCore::HTMLOptionElement; +using WebKit::WebForm; + +namespace webkit_glue { namespace { + // TODO(eseidel): appendString and appendEncodedString do *not* follow Google // style because they are copy/paste from WebKit and will go away as soon as the // WebKit functions are made public. @@ -154,8 +159,7 @@ bool IsSelectInDefaultState(WebCore::HTMLSelectElement* select) { // least one item is selected, determine which one. HTMLOptionElement* initial_selected = NULL; while (node) { - HTMLOptionElement* option_element = - webkit_glue::CastToHTMLOptionElement(node); + HTMLOptionElement* option_element = CastToHTMLOptionElement(node); if (option_element) { if (!initial_selected) initial_selected = option_element; @@ -171,8 +175,7 @@ bool IsSelectInDefaultState(WebCore::HTMLSelectElement* select) { return initial_selected->selected(); } else { while (node) { - HTMLOptionElement* option_element = - webkit_glue::CastToHTMLOptionElement(node); + HTMLOptionElement* option_element = CastToHTMLOptionElement(node); if (option_element && option_element->selected() != option_element->defaultSelected()) { return false; @@ -296,37 +299,20 @@ WebCore::HTMLInputElement* GetTextElement( } // namespace -SearchableFormData* SearchableFormData::Create(WebCore::Element* element) { - if (!element->isFormControlElement() || !element->isHTMLElement()) { - return NULL; - } - - WebCore::Frame* frame = element->document()->frame(); - if (frame == NULL) - return NULL; +SearchableFormData* SearchableFormData::Create(const WebForm& webform) { + RefPtr<HTMLFormElement> form = WebFormToHTMLFormElement(webform); - WebCore::HTMLFormControlElement* input_element = - static_cast<WebCore::HTMLFormControlElement*>(element); - - WebCore::HTMLFormElement* form = input_element->form(); - if (form == NULL) - return NULL; - - return Create(form); -} - -SearchableFormData* SearchableFormData::Create(WebCore::HTMLFormElement* form) { WebCore::Frame* frame = form->document()->frame(); if (frame == NULL) return NULL; // Only consider forms that GET data and the action targets an http page. - if (!IsFormMethodGet(form) || !IsHTTPFormSubmit(form)) + if (!IsFormMethodGet(form.get()) || !IsHTTPFormSubmit(form.get())) return NULL; Vector<char> enc_string; WebCore::HTMLFormControlElement* first_submit_button = - GetButtonToActivate(form); + GetButtonToActivate(form.get()); if (first_submit_button) { // The form does not have an active submit button, make the first button @@ -337,7 +323,7 @@ SearchableFormData* SearchableFormData::Create(WebCore::HTMLFormElement* form) { std::string encoding; WebCore::HTMLInputElement* text_element = - GetTextElement(form, &enc_string, &encoding); + GetTextElement(form.get(), &enc_string, &encoding); if (first_submit_button) first_submit_button->setActivatedSubmit(false); @@ -354,11 +340,10 @@ SearchableFormData* SearchableFormData::Create(WebCore::HTMLFormElement* form) { WebCore::FrameLoader* loader = frame->loader(); WebCore::KURL url = loader->completeURL(action.isNull() ? "" : action); url.setQuery(form_data->flattenToString()); - std::wstring current_value = webkit_glue::StringToStdWString( - static_cast<WebCore::HTMLInputElement*>(text_element)->value()); - std::wstring text_name = - webkit_glue::StringToStdWString(text_element->name()); - GURL gurl(webkit_glue::KURLToGURL(url)); + std::wstring current_value = StringToStdWString( + static_cast<WebCore::HTMLInputElement*>(text_element)->value()); + std::wstring text_name = StringToStdWString(text_element->name()); + GURL gurl(KURLToGURL(url)); return new SearchableFormData(gurl, text_name, current_value, encoding); } @@ -382,3 +367,5 @@ SearchableFormData::SearchableFormData(const GURL& url, element_value_(element_value), encoding_(encoding) { } + +} // namespace webkit_glue diff --git a/webkit/glue/searchable_form_data.h b/webkit/glue/searchable_form_data.h index 2164189..fc76c57 100644 --- a/webkit/glue/searchable_form_data.h +++ b/webkit/glue/searchable_form_data.h @@ -9,22 +9,19 @@ #include "googleurl/src/gurl.h" -namespace WebCore { -class Element; -class HTMLFormElement; +namespace WebKit { +class WebForm; } +namespace webkit_glue { + // SearchableFormData encapsulates a URL and class name of an INPUT field // that correspond to a searchable form request. class SearchableFormData { public: // If form contains elements that constitutes a valid searchable form // request, a SearchableFormData is created and returned. - static SearchableFormData* Create(WebCore::HTMLFormElement* form); - - // If the element is contained in a form that constitutes a valid searchable - // form, a SearchableFormData is created and returned. - static SearchableFormData* Create(WebCore::Element* element); + static SearchableFormData* Create(const WebKit::WebForm& form); // Returns true if the two SearchableFormData are equal, false otherwise. // Either argument may be NULL. If both elements are NULL, true is returned. @@ -53,7 +50,9 @@ class SearchableFormData { const std::wstring element_value_; const std::string encoding_; - DISALLOW_EVIL_CONSTRUCTORS(SearchableFormData); + DISALLOW_COPY_AND_ASSIGN(SearchableFormData); }; +} // namespace webkit_glue + #endif // WEBKIT_GLUE_SEARCHABLE_FORM_H__ diff --git a/webkit/glue/webdatasource.h b/webkit/glue/webdatasource.h index 53e9492..5885db7 100644 --- a/webkit/glue/webdatasource.h +++ b/webkit/glue/webdatasource.h @@ -10,7 +10,6 @@ #include "base/string16.h" class GURL; -class SearchableFormData; class WebFrame; class WebRequest; class WebResponse; @@ -82,21 +81,6 @@ class WebDataSource { // redirect, it will contain the source and destination URL). virtual const std::vector<GURL>& GetRedirectChain() const = 0; - // Returns the SearchableFormData, or NULL if the request wasn't a search - // request. The returned object is owned by the WebDataSource (actually - // the WebDocumentLoader) and shouldn't be freed. - virtual const SearchableFormData* GetSearchableFormData() const = 0; - - // Returns the PasswordFormData, or NULL if the request isn't a form submission - // or doesn't have any password fields. The returned object is owned by the - // WebDataSource (actually the WebDocumentLoader) and shouldn't be freed. - virtual const PasswordForm* GetPasswordFormData() const = 0; - - // Returns true if this request was the result of submitting a form. - // NOTE: this returns false if the user submitted a form, but the form used - // script to do the actuall submission. - virtual bool IsFormSubmit() const = 0; - // Returns the page title. virtual string16 GetPageTitle() const = 0; diff --git a/webkit/glue/webdatasource_impl.cc b/webkit/glue/webdatasource_impl.cc index 6980e13..c0ace9b 100644 --- a/webkit/glue/webdatasource_impl.cc +++ b/webkit/glue/webdatasource_impl.cc @@ -32,8 +32,7 @@ PassRefPtr<WebDataSourceImpl> WebDataSourceImpl::Create( WebDataSourceImpl::WebDataSourceImpl(const WebCore::ResourceRequest& request, const WebCore::SubstituteData& data) - : WebCore::DocumentLoader(request, data), - form_submit_(false) { + : WebCore::DocumentLoader(request, data) { } WebDataSourceImpl::~WebDataSourceImpl() { @@ -79,18 +78,6 @@ void WebDataSourceImpl::AppendRedirect(const GURL& url) { redirect_chain_.push_back(url); } -const SearchableFormData* WebDataSourceImpl::GetSearchableFormData() const { - return searchable_form_data(); -} - -const PasswordForm* WebDataSourceImpl::GetPasswordFormData() const { - return password_form_data(); -} - -bool WebDataSourceImpl::IsFormSubmit() const { - return is_form_submit(); -} - string16 WebDataSourceImpl::GetPageTitle() const { return webkit_glue::StringToString16(title()); } diff --git a/webkit/glue/webdatasource_impl.h b/webkit/glue/webdatasource_impl.h index 912dffb..d2e98bf 100644 --- a/webkit/glue/webdatasource_impl.h +++ b/webkit/glue/webdatasource_impl.h @@ -9,7 +9,6 @@ #include "base/scoped_ptr.h" #include "base/time.h" -#include "webkit/glue/searchable_form_data.h" #include "webkit/glue/webdatasource.h" #include "webkit/glue/webresponse_impl.h" #include "webkit/glue/weburlrequest_impl.h" @@ -33,9 +32,6 @@ class WebDataSourceImpl : public WebCore::DocumentLoader, public WebDataSource { virtual GURL GetUnreachableURL() const; virtual bool HasUnreachableURL() const; virtual const std::vector<GURL>& GetRedirectChain() const; - virtual const SearchableFormData* GetSearchableFormData() const; - virtual const PasswordForm* GetPasswordFormData() const; - virtual bool IsFormSubmit() const; virtual string16 GetPageTitle() const; virtual base::Time GetRequestTime() const; virtual void SetRequestTime(base::Time time); @@ -53,35 +49,6 @@ class WebDataSourceImpl : public WebCore::DocumentLoader, public WebDataSource { void ClearRedirectChain(); void AppendRedirect(const GURL& url); - // Sets the SearchableFormData for this DocumentLoader. - // WebDocumentLoaderImpl will own the SearchableFormData. - void set_searchable_form_data(SearchableFormData* searchable_form_data) { - searchable_form_data_.reset(searchable_form_data); - } - // Returns the SearchableFormData for this DocumentLoader. - // WebDocumentLoaderImpl owns the returned SearchableFormData. - const SearchableFormData* searchable_form_data() const { - return searchable_form_data_.get(); - } - - // Sets the PasswordFormData for this DocumentLoader. - // WebDocumentLoaderImpl will own the PasswordFormData. - void set_password_form_data(PasswordForm* password_form_data) { - password_form_data_.reset(password_form_data); - } - // Returns the PasswordFormData for this DocumentLoader. - // WebDocumentLoaderImpl owns the returned PasswordFormData. - const PasswordForm* password_form_data() const { - return password_form_data_.get(); - } - - void set_form_submit(bool value) { - form_submit_ = value; - } - bool is_form_submit() const { - return form_submit_; - } - void set_request_time(base::Time request_time) { request_time_ = request_time; } @@ -119,13 +86,8 @@ class WebDataSourceImpl : public WebCore::DocumentLoader, public WebDataSource { // who modifies this when to keep it up to date. std::vector<GURL> redirect_chain_; - scoped_ptr<const SearchableFormData> searchable_form_data_; - scoped_ptr<const PasswordForm> password_form_data_; - OwnPtr<ExtraData> extra_data_; - bool form_submit_; - // See webdatasource.h for a description of these time stamps. base::Time request_time_; base::Time start_load_time_; diff --git a/webkit/glue/webframe.h b/webkit/glue/webframe.h index e630f35..ad80a0d 100644 --- a/webkit/glue/webframe.h +++ b/webkit/glue/webframe.h @@ -5,6 +5,8 @@ #ifndef WEBKIT_GLUE_WEBFRAME_H_ #define WEBKIT_GLUE_WEBFRAME_H_ +#include <vector> + #include "base/scoped_ptr.h" #include "base/string16.h" #include "skia/ext/bitmap_platform_device.h" @@ -20,6 +22,7 @@ class WebTextInput; struct NPObject; namespace WebKit { +class WebForm; struct WebConsoleMessage; struct WebFindOptions; struct WebRect; @@ -59,14 +62,6 @@ class WebFrame { virtual void CallJSGC() = 0; - // WARNING: DON'T USE THIS METHOD unless you know what it is doing. - // - // Returns a pointer to the underlying implementation WebCore::Frame. - // Currently it is a hack to avoid including "Frame.h". The caller - // casts the return value to WebCore::Frame. - // TODO(fqian): Remove this method when V8 supports NP runtime. - virtual void* GetFrameImplementation() = 0; - // This grants the currently loaded Document access to all security origins // (including file URLs). Use with care. The access is revoked when a new // document is loaded into this frame. @@ -214,6 +209,9 @@ class WebFrame { // unless it is AddRef'd separately by the caller. virtual WebView* GetView() const = 0; + // Returns a vector of WebForms (corresponds to document.forms). + virtual void GetForms(std::vector<WebKit::WebForm>* forms) const = 0; + // Returns the serialization of the frame's security origin. virtual std::string GetSecurityOrigin() const = 0; diff --git a/webkit/glue/webframe_impl.cc b/webkit/glue/webframe_impl.cc index 0d78729..f573dcb 100644 --- a/webkit/glue/webframe_impl.cc +++ b/webkit/glue/webframe_impl.cc @@ -142,6 +142,7 @@ MSVC_POP_WARNING(); #include "skia/ext/platform_canvas.h" #include "webkit/api/public/WebConsoleMessage.h" #include "webkit/api/public/WebFindOptions.h" +#include "webkit/api/public/WebForm.h" #include "webkit/api/public/WebRect.h" #include "webkit/api/public/WebScriptSource.h" #include "webkit/api/public/WebSize.h" @@ -185,6 +186,7 @@ using WebCore::FrameLoadType; using WebCore::FrameTree; using WebCore::FrameView; using WebCore::HistoryItem; +using WebCore::HTMLFormElement; using WebCore::IntRect; using WebCore::KURL; using WebCore::Node; @@ -204,6 +206,7 @@ using WebCore::XPathResult; using WebKit::WebConsoleMessage; using WebKit::WebFindOptions; +using WebKit::WebForm; using WebKit::WebRect; using WebKit::WebScriptSource; using WebKit::WebSize; @@ -750,6 +753,22 @@ WebView* WebFrameImpl::GetView() const { return GetWebViewImpl(); } +void WebFrameImpl::GetForms(std::vector<WebForm>* results) const { + results->clear(); + if (!frame_) + return; + RefPtr<WebCore::HTMLCollection> forms = frame_->document()->forms(); + unsigned int form_count = forms->length(); + for (unsigned int i = 0; i < form_count; ++i) { + Node* node = forms->item(i); + // Strange but true, sometimes item can be NULL. + if (node) { + results->push_back(webkit_glue::HTMLFormElementToWebForm( + static_cast<HTMLFormElement*>(node))); + } + } +} + std::string WebFrameImpl::GetSecurityOrigin() const { if (frame_) { if (frame_->document()) diff --git a/webkit/glue/webframe_impl.h b/webkit/glue/webframe_impl.h index c7eeb8d..54da684 100644 --- a/webkit/glue/webframe_impl.h +++ b/webkit/glue/webframe_impl.h @@ -110,6 +110,7 @@ class WebFrameImpl : public WebFrame, public base::RefCounted<WebFrameImpl> { virtual WebFrame* GetTop() const; virtual WebFrame* GetChildFrame(const std::wstring& xpath) const; virtual WebView* GetView() const; + virtual void GetForms(std::vector<WebKit::WebForm>* forms) const; virtual std::string GetSecurityOrigin() const; virtual bool CaptureImage(scoped_ptr<skia::BitmapPlatformDevice>* image, bool scroll_to_zero); @@ -119,7 +120,6 @@ class WebFrameImpl : public WebFrame, public base::RefCounted<WebFrameImpl> { virtual void BindToWindowObject(const std::wstring& name, NPObject* object); virtual void CallJSGC(); - virtual void* GetFrameImplementation() { return frame(); } virtual void GrantUniversalAccess(); virtual NPObject* GetWindowNPObject(); diff --git a/webkit/glue/webframeloaderclient_impl.cc b/webkit/glue/webframeloaderclient_impl.cc index a21e401..a4a77a9 100644 --- a/webkit/glue/webframeloaderclient_impl.cc +++ b/webkit/glue/webframeloaderclient_impl.cc @@ -44,6 +44,7 @@ MSVC_POP_WARNING(); #if defined(OS_WIN) #include "webkit/activex_shim/activex_shared.h" #endif +#include "webkit/api/public/WebForm.h" #include "webkit/glue/autofill_form.h" #include "webkit/glue/alt_404_page_resource_fetcher.h" #include "webkit/glue/glue_util.h" @@ -376,35 +377,6 @@ void WebFrameLoaderClient::dispatchDidFinishDocumentLoad() { // listeners and their associated HTMLInputElements. webframe_->ClearPasswordListeners(); - // The document has now been fully loaded. - // Scan for password forms to be sent to the browser - PassRefPtr<WebCore::HTMLCollection> forms = - webframe_->frame()->document()->forms(); - - std::vector<PasswordForm> passwordForms; - - unsigned int form_count = forms->length(); - for (unsigned int i = 0; i < form_count; ++i) { - // Strange but true, sometimes item can be NULL. - WebCore::Node* item = forms->item(i); - if (item) { - WebCore::HTMLFormElement* form = - static_cast<WebCore::HTMLFormElement*>(item); - - // Honour autocomplete=off. - if (!form->autoComplete()) - continue; - - scoped_ptr<PasswordForm> passwordFormPtr( - PasswordFormDomManager::CreatePasswordForm(form)); - - if (passwordFormPtr.get()) - passwordForms.push_back(*passwordFormPtr); - } - } - - if (d && (passwordForms.size() > 0)) - d->OnPasswordFormsSeen(webview, passwordForms); if (d) d->DidFinishDocumentLoadForFrame(webview, webframe_); data_source->set_finish_document_load_time(base::Time::Now()); @@ -1010,32 +982,12 @@ void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError&) void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> form_ref) { - SearchableFormData* form_data = SearchableFormData::Create(form_ref->form()); - WebDataSourceImpl* ds = WebDataSourceImpl::FromLoader( - webframe_->frame()->loader()->provisionalDocumentLoader()); - // Don't free the SearchableFormData, the datasource will do that. - ds->set_searchable_form_data(form_data); - - PasswordForm* pass_data = - PasswordFormDomManager::CreatePasswordForm(form_ref->form()); - // Don't free the PasswordFormData, the datasource will do that. - ds->set_password_form_data(pass_data); - WebViewImpl* webview = webframe_->GetWebViewImpl(); WebViewDelegate* d = webview->delegate(); - - // Unless autocomplete=off, record what the user put in it for future - // autofilling. - if (form_ref->form()->autoComplete()) { - scoped_ptr<AutofillForm> autofill_form( - AutofillForm::CreateAutofillForm(form_ref->form())); - if (autofill_form.get()) { - d->OnAutofillFormSubmitted(webview, *autofill_form); - } + if (d) { + d->WillSubmitForm(webview, webframe_, + webkit_glue::HTMLFormElementToWebForm(form_ref->form())); } - - ds->set_form_submit(true); - (webframe_->frame()->loader()->*function)(PolicyUse); } diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h index 9c658e2..7002c57 100644 --- a/webkit/glue/webview_delegate.h +++ b/webkit/glue/webview_delegate.h @@ -42,6 +42,7 @@ class AccessibilityObject; namespace WebKit { class WebDragData; +class WebForm; class WebWorker; class WebWorkerClient; class WebMediaPlayer; @@ -50,9 +51,7 @@ struct WebPoint; struct WebRect; } -struct PasswordForm; struct WebPreferences; -class AutofillForm; class FilePath; class SkBitmap; class WebDevToolsAgentDelegate; @@ -418,6 +417,12 @@ class WebViewDelegate : virtual public WebWidgetDelegate { WebFrame* frame, const GURL& source) { } + + // Notifies the delegate that a form is about to be submitted. + virtual void WillSubmitForm(WebView* webview, WebFrame* frame, + const WebKit::WebForm& form) { + } + // // @method webView:willCloseFrame: // @abstract Notifies the delegate that a frame will be closed @@ -470,18 +475,6 @@ class WebViewDelegate : virtual public WebWidgetDelegate { const std::wstring& source_id) { } - // Notification of possible password forms to be filled/submitted by - // the password manager - virtual void OnPasswordFormsSeen(WebView* webview, - const std::vector<PasswordForm>& forms) { - } - - // Notification of the submission of a form so that its contents can be - // recorded for future autofilling. - virtual void OnAutofillFormSubmitted(WebView* webview, - const AutofillForm& form) { - } - // Queries the browser for suggestions to be shown for the form text field // named |field_name|. |text| is the text entered by the user so far and // |node_id| is the id of the node of the input field. diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc index b568a9f..57d594a 100644 --- a/webkit/glue/webview_impl.cc +++ b/webkit/glue/webview_impl.cc @@ -1730,24 +1730,6 @@ bool WebViewImpl::SetDropEffect(bool accept) { } } -SearchableFormData* WebViewImpl::CreateSearchableFormDataForFocusedNode() { - if (!page_.get()) - return NULL; - - if (RefPtr<Frame> focused = page_->focusController()->focusedFrame()) { - RefPtr<Document> document = focused->document(); - if (document.get()) { - RefPtr<Node> focused_node = document->focusedNode(); - if (focused_node.get() && - focused_node->nodeType() == Node::ELEMENT_NODE) { - return SearchableFormData::Create( - static_cast<Element*>(focused_node.get())); - } - } - } - return NULL; -} - void WebViewImpl::AutofillSuggestionsForNode( int64 node_id, const std::vector<std::wstring>& suggestions, diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h index caac1c8..28e3666 100644 --- a/webkit/glue/webview_impl.h +++ b/webkit/glue/webview_impl.h @@ -230,11 +230,6 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> { WebCore::Frame* frame, const WebCore::PlatformKeyboardEvent& e); - // Creates and returns a new SearchableFormData for the focused node. - // It's up to the caller to free the returned SearchableFormData. - // This returns NULL if the focused node is NULL, or not in a valid form. - SearchableFormData* CreateSearchableFormDataForFocusedNode(); - scoped_refptr<WebViewDelegate> delegate_; WebKit::WebSize size_; diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp index 3e8df1e..7c54e1e 100644 --- a/webkit/webkit.gyp +++ b/webkit/webkit.gyp @@ -4189,6 +4189,7 @@ 'api/public/WebData.h', 'api/public/WebDragData.h', 'api/public/WebFindOptions.h', + 'api/public/WebForm.h', 'api/public/WebHTTPBody.h', 'api/public/WebImage.h', 'api/public/WebInputEvent.h', @@ -4230,6 +4231,7 @@ 'api/src/WebCString.cpp', 'api/src/WebData.cpp', 'api/src/WebDragData.cpp', + 'api/src/WebForm.cpp', 'api/src/WebHTTPBody.cpp', 'api/src/WebImageSkia.cpp', 'api/src/WebInputEvent.cpp', |