1/* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32#include "SuggestionsPopupMenuClient.h" 33 34#include "CSSStyleSelector.h" 35#include "CSSValueKeywords.h" 36#include "Chrome.h" 37#include "FrameView.h" 38#include "HTMLInputElement.h" 39#include "RenderTheme.h" 40#include "WebViewImpl.h" 41 42using namespace WebCore; 43 44namespace WebKit { 45 46SuggestionsPopupMenuClient::SuggestionsPopupMenuClient() 47 : m_textField(0) 48 , m_selectedIndex(0) 49{ 50} 51 52SuggestionsPopupMenuClient::~SuggestionsPopupMenuClient() 53{ 54} 55 56// FIXME: Implement this per-derived class? 57void SuggestionsPopupMenuClient::valueChanged(unsigned listIndex, bool fireEvents) 58{ 59 m_textField->setValue(getSuggestion(listIndex)); 60 61 WebViewImpl* webView = getWebView(); 62 if (!webView) 63 return; 64 65 EditorClientImpl* editor = 66 static_cast<EditorClientImpl*>(webView->page()->editorClient()); 67 ASSERT(editor); 68 editor->onAutofillSuggestionAccepted( 69 static_cast<HTMLInputElement*>(m_textField.get())); 70} 71 72String SuggestionsPopupMenuClient::itemText(unsigned listIndex) const 73{ 74 return getSuggestion(listIndex); 75} 76 77PopupMenuStyle SuggestionsPopupMenuClient::itemStyle(unsigned listIndex) const 78{ 79 return *m_style; 80} 81 82PopupMenuStyle SuggestionsPopupMenuClient::menuStyle() const 83{ 84 return *m_style; 85} 86 87int SuggestionsPopupMenuClient::clientPaddingLeft() const 88{ 89 // Bug http://crbug.com/7708 seems to indicate the style can be 0. 90 RenderStyle* style = textFieldStyle(); 91 if (!style) 92 return 0; 93 94 return RenderTheme::defaultTheme()->popupInternalPaddingLeft(style); 95} 96 97int SuggestionsPopupMenuClient::clientPaddingRight() const 98{ 99 // Bug http://crbug.com/7708 seems to indicate the style can be 0. 100 RenderStyle* style = textFieldStyle(); 101 if (!style) 102 return 0; 103 104 return RenderTheme::defaultTheme()->popupInternalPaddingRight(style); 105} 106 107void SuggestionsPopupMenuClient::popupDidHide() 108{ 109 WebViewImpl* webView = getWebView(); 110 if (webView) 111 webView->suggestionsPopupDidHide(); 112} 113 114void SuggestionsPopupMenuClient::setTextFromItem(unsigned listIndex) 115{ 116 m_textField->setValue(getSuggestion(listIndex)); 117} 118 119FontSelector* SuggestionsPopupMenuClient::fontSelector() const 120{ 121 return m_textField->document()->styleSelector()->fontSelector(); 122} 123 124HostWindow* SuggestionsPopupMenuClient::hostWindow() const 125{ 126 return m_textField->document()->view()->hostWindow(); 127} 128 129PassRefPtr<Scrollbar> SuggestionsPopupMenuClient::createScrollbar( 130 ScrollbarClient* client, 131 ScrollbarOrientation orientation, 132 ScrollbarControlSize size) 133{ 134 return Scrollbar::createNativeScrollbar(client, orientation, size); 135} 136 137RenderStyle* SuggestionsPopupMenuClient::textFieldStyle() const 138{ 139 RenderStyle* style = m_textField->computedStyle(); 140 if (!style) { 141 // It seems we can only have a 0 style in a TextField if the 142 // node is detached, in which case we the popup shoud not be 143 // showing. Please report this in http://crbug.com/7708 and 144 // include the page you were visiting. 145 ASSERT_NOT_REACHED(); 146 } 147 return style; 148} 149 150void SuggestionsPopupMenuClient::initialize(HTMLInputElement* textField, 151 int defaultSuggestionIndex) 152{ 153 m_textField = textField; 154 m_selectedIndex = defaultSuggestionIndex; 155 156 FontDescription fontDescription; 157 RenderTheme::defaultTheme()->systemFont(CSSValueWebkitControl, 158 fontDescription); 159 160 // Use a smaller font size to match IE/Firefox. 161 // FIXME: http://crbug.com/7376 use the system size instead of a 162 // fixed font size value. 163 fontDescription.setComputedSize(12.0); 164 Font font(fontDescription, 0, 0); 165 font.update(textField->document()->styleSelector()->fontSelector()); 166 // The direction of text in popup menu is set the same as the direction of 167 // the input element: textField. 168 m_style.set(new PopupMenuStyle(Color::black, Color::white, font, true, 169 Length(WebCore::Fixed), 170 textField->renderer()->style()->direction())); 171} 172 173WebViewImpl* SuggestionsPopupMenuClient::getWebView() const 174{ 175 Frame* frame = m_textField->document()->frame(); 176 if (!frame) 177 return 0; 178 179 Page* page = frame->page(); 180 if (!page) 181 return 0; 182 183 return static_cast<ChromeClientImpl*>(page->chrome()->client())->webView(); 184} 185 186} // namespace WebKit 187