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

Unified Diff: webkit/glue/autocomplete_input_listener.cc

Issue 11479: New take at implementing autofill using the editor client API (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webkit/build/glue/glue.vcproj ('k') | webkit/glue/autocomplete_input_listener_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/glue/autocomplete_input_listener.cc
===================================================================
--- webkit/glue/autocomplete_input_listener.cc (revision 5578)
+++ webkit/glue/autocomplete_input_listener.cc (working copy)
@@ -1,231 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// This file provides an abstract implementation of the inline autocomplete
-// infrastructure defined in autocomplete_input_listener.h.
-
-#include "webkit/glue/autocomplete_input_listener.h"
-#include <set>
-
-MSVC_PUSH_WARNING_LEVEL(0);
-#include "HTMLInputElement.h"
-#include "HTMLFormElement.h"
-#include "Document.h"
-#include "Frame.h"
-#include "Editor.h"
-#include "EventNames.h"
-#include "Event.h"
-#include "HTMLNames.h"
-MSVC_POP_WARNING();
-
-#undef LOG
-
-#include "base/logging.h"
-#include "webkit/glue/editor_client_impl.h"
-#include "webkit/glue/glue_util.h"
-
-namespace webkit_glue {
-
-// Hack (1 of 2) for http://bugs.webkit.org/show_bug.cgi?id=16976. This bug
-// causes the caret position to be set after handling input events, which
-// trumps our modifications, so for now we tell the EditorClient to preserve
-// whatever selection set by our code.
-// TODO(timsteele): Remove this function altogether once bug is fixed.
-static void PreserveSelection(WebCore::HTMLInputElement* element) {
- WebCore::EditorClient* ec =
- element->form()->document()->frame()->editor()->client();
- EditorClientImpl* client = static_cast<EditorClientImpl*>(ec);
- client->PreserveSelection();
-}
-
-HTMLInputDelegate::HTMLInputDelegate(WebCore::HTMLInputElement* element)
- : element_(element) {
- // Reference the element for the lifetime of this delegate.
- // e is NULL when testing.
- if (element_)
- element_->ref();
-}
-
-HTMLInputDelegate::~HTMLInputDelegate() {
- if (element_)
- element_->deref();
-}
-
-void HTMLInputDelegate::SetValue(const std::wstring& value) {
- element_->setValue(StdWStringToString(value));
-}
-
-void HTMLInputDelegate::SetSelectionRange(size_t start, size_t end) {
- element_->setSelectionRange(start, end);
- // Hack, see comments for PreserveSelection().
- PreserveSelection(element_);
-}
-
-void HTMLInputDelegate::OnFinishedAutocompleting() {
- // This sets the input element to an autofilled state which will result in it
- // having a yellow background.
- element_->setAutofilled(true);
- // Notify any changeEvent listeners.
- element_->onChange();
-}
-
-AutocompleteBodyListener::AutocompleteBodyListener(WebCore::Frame* frame) {
- WebCore::HTMLElement* body = frame->document()->body();
- body->addEventListener(WebCore::eventNames().DOMFocusOutEvent, this, false);
- body->addEventListener(WebCore::eventNames().inputEvent, this, false);
- // Attaching to the WebCore body element effectively transfers ownership of
- // the listener object. When WebCore is tearing down the document, any
- // attached listeners are destroyed.
- // See Document::removeAllEventListenersFromAllNodes which is called by
- // FrameLoader::stopLoading. Also, there is no need for matching calls to
- // removeEventListener because the simplest and most convienient thing to do
- // for autocompletion is to stop listening once the element is destroyed.
-}
-
-AutocompleteBodyListener::~AutocompleteBodyListener() {
- // Delete the listener. Pay special attention since we may have the same
- // listener registered for several elements.
- std::set<AutocompleteInputListener*> to_be_deleted_;
- for (InputElementInfoMap::iterator iter = elements_info_.begin();
- iter != elements_info_.end(); ++iter) {
- to_be_deleted_.insert(iter->second.listener);
- }
-
- std::set<AutocompleteInputListener*>::iterator iter;
- for (iter = to_be_deleted_.begin(); iter != to_be_deleted_.end(); ++iter)
- delete *iter;
- elements_info_.clear();
-}
-
-// The following method is based on Firefox2 code in
-// toolkit/components/autocomplete/src/nsAutoCompleteController.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 Communicator client code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Joe Hewitt <hewitt@netscape.com> (Original Author)
- * Dean Tessman <dean_tessman@hotmail.com>
- * Johnny Stenback <jst@mozilla.jstenback.com>
- * Masayuki Nakano <masayuki@d-toybox.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 ***** */
-bool AutocompleteBodyListener::ShouldInlineAutocomplete(
- WebCore::HTMLInputElement* input,
- const std::wstring& old_text,
- const std::wstring& new_text) {
- size_t prev_length = old_text.length();
- // The following are a bunch of early returns in cases we don't want to
- // go through with inline autocomplete.
-
- // Don't bother doing AC if nothing changed.
- if (new_text.length() > 0 && (new_text == old_text))
- return false;
-
- // Did user backspace?
- if ((new_text.length() < old_text.length()) &&
- old_text.substr(0, new_text.length()) == new_text) {
- return false;
- }
-
- // Is search string empty?
- if (new_text.empty())
- return false;
- return IsCaretAtEndOfText(input, new_text.length(), prev_length);
-}
-
-void AutocompleteBodyListener::handleEvent(WebCore::Event* event,
- bool /*is_window_event*/) {
- const WebCore::AtomicString& webcore_type = event->type();
- DCHECK(event->target()->toNode());
- if (!event->target()->toNode()->hasTagName(WebCore::HTMLNames::inputTag))
- return; // Not a node of interest to us.
-
- WebCore::HTMLInputElement* input =
- static_cast<WebCore::HTMLInputElement*>(event->target()->toNode());
- InputElementInfoMap::const_iterator iter = elements_info_.find(input);
- if (iter == elements_info_.end())
- return; // Not an input node we are listening to.
-
- InputElementInfo input_info = iter->second;
- const std::wstring& user_input = StringToStdWString(input->value());
- if (webcore_type == WebCore::eventNames().DOMFocusOutEvent) {
- input_info.listener->OnBlur(input, user_input);
- } else if (webcore_type == WebCore::eventNames().inputEvent) {
- // Perform inline autocomplete if it is safe to do so.
- if (ShouldInlineAutocomplete(input,
- input_info.previous_text, user_input)) {
- input_info.listener->OnInlineAutocompleteNeeded(input, user_input);
- }
- // Update the info.
- input_info.previous_text = user_input;
- elements_info_[input] = input_info;
- } else {
- NOTREACHED() << "unexpected EventName for autocomplete listener";
- }
-}
-
-void AutocompleteBodyListener::AddInputListener(
- WebCore::HTMLInputElement* element,
- AutocompleteInputListener* listener) {
- DCHECK(elements_info_.find(element) == elements_info_.end());
- InputElementInfo elem_info;
- elem_info.listener = listener;
- elements_info_[element] = elem_info;
-}
-
-bool AutocompleteBodyListener::IsCaretAtEndOfText(
- WebCore::HTMLInputElement* element,
- size_t input_length,
- size_t previous_length) const {
- // Hack 2 of 2 for http://bugs.webkit.org/show_bug.cgi?id=16976.
- // TODO(timsteele): This check should only return early if
- // !(selectionEnd == selectionStart == user_input.length()).
- // However, because of webkit bug #16976 the caret is not properly moved
- // until after the handlers have executed, so for now we do the following
- // several checks. The first check handles the case webkit sets the End
- // selection but not the Start selection correctly, and the second is for
- // when webcore sets neither. This won't be perfect if the user moves the
- // selection around during inline autocomplete, but for now its the
- // friendliest behavior we can offer. Once the bug is fixed this method
- // should no longer need the previous_length parameter.
- if (((element->selectionEnd() != element->selectionStart() + 1) ||
- (element->selectionEnd() != static_cast<int>(input_length))) &&
- ((element->selectionEnd() != element->selectionStart()) ||
- (element->selectionEnd() != static_cast<int>(previous_length)))) {
- return false;
- }
- return true;
-}
-} // webkit_glue
« no previous file with comments | « webkit/build/glue/glue.vcproj ('k') | webkit/glue/autocomplete_input_listener_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698