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 42 using namespace WebCore; 43 44 namespace WebKit { 45 46 SuggestionsPopupMenuClient::SuggestionsPopupMenuClient() 47 : m_textField(0) 48 , m_selectedIndex(0) 49 { 50 } 51 52 SuggestionsPopupMenuClient::~SuggestionsPopupMenuClient() 53 { 54 } 55 56 // FIXME: Implement this per-derived class? 57 void 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 72 String SuggestionsPopupMenuClient::itemText(unsigned listIndex) const 73 { 74 return getSuggestion(listIndex); 75 } 76 77 PopupMenuStyle SuggestionsPopupMenuClient::itemStyle(unsigned listIndex) const 78 { 79 return *m_style; 80 } 81 82 PopupMenuStyle SuggestionsPopupMenuClient::menuStyle() const 83 { 84 return *m_style; 85 } 86 87 int 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 97 int 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 107 void SuggestionsPopupMenuClient::popupDidHide() 108 { 109 WebViewImpl* webView = getWebView(); 110 if (webView) 111 webView->suggestionsPopupDidHide(); 112 } 113 114 void SuggestionsPopupMenuClient::setTextFromItem(unsigned listIndex) 115 { 116 m_textField->setValue(getSuggestion(listIndex)); 117 } 118 119 FontSelector* SuggestionsPopupMenuClient::fontSelector() const 120 { 121 return m_textField->document()->styleSelector()->fontSelector(); 122 } 123 124 HostWindow* SuggestionsPopupMenuClient::hostWindow() const 125 { 126 return m_textField->document()->view()->hostWindow(); 127 } 128 129 PassRefPtr<Scrollbar> SuggestionsPopupMenuClient::createScrollbar( 130 ScrollbarClient* client, 131 ScrollbarOrientation orientation, 132 ScrollbarControlSize size) 133 { 134 return Scrollbar::createNativeScrollbar(client, orientation, size); 135 } 136 137 RenderStyle* 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 150 void 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 173 WebViewImpl* 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