Changeset 88030 in webkit
- Timestamp:
- Jun 3, 2011 10:39:10 AM (13 years ago)
- Location:
- trunk/Source/WebKit/chromium
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/chromium/ChangeLog
r88021 r88030 1 2011-06-03 Philippe Beauchamp <philippe.beauchamp@gmail.com> 2 3 Reviewed by Dimitri Glazkov. 4 5 Add the feature "Add as search engine..." in a search text field context menu for chromium 6 https://bugs.webkit.org/show_bug.cgi?id=47980 7 8 * public/WebContextMenuData.h: 9 * public/WebSearchableFormData.h: 10 * src/ContextMenuClientImpl.cpp: 11 (WebKit::ContextMenuClientImpl::getCustomMenuFromDefaultItems): 12 * src/WebSearchableFormData.cpp: 13 (WebKit::WebSearchableFormData::WebSearchableFormData): 14 1 15 2011-06-03 Naoki Takano <takano.naoki@gmail.com> 2 16 -
trunk/Source/WebKit/chromium/public/WebContextMenuData.h
r83617 r88030 77 77 // The absolute URL of the page in context. 78 78 WebURL pageURL; 79 80 // The absolute keyword search URL including the %s search tag when the 81 // "Add as search engine..." option is clicked (left empty if not used). 82 WebURL keywordURL; 79 83 80 84 // The absolute URL of the subframe in context. -
trunk/Source/WebKit/chromium/public/WebSearchableFormData.h
r62133 r88030 32 32 #define WebSearchableFormData_h 33 33 34 #include "WebInputElement.h" 34 35 #include "WebString.h" 35 36 #include "WebURL.h" … … 44 45 // If the provided form is suitable for automated searching, isValid() 45 46 // will return false. 46 WEBKIT_API WebSearchableFormData(const WebFormElement& );47 WEBKIT_API WebSearchableFormData(const WebFormElement&, const WebInputElement& selectedInputElement = WebInputElement()); 47 48 48 49 bool isValid() { return m_url.isValid(); } -
trunk/Source/WebKit/chromium/src/ContextMenuClientImpl.cpp
r83660 r88030 42 42 #include "FrameLoader.h" 43 43 #include "FrameView.h" 44 #include "H istoryItem.h"45 #include "H itTestResult.h"44 #include "HTMLFormElement.h" 45 #include "HTMLInputElement.h" 46 46 #include "HTMLMediaElement.h" 47 47 #include "HTMLNames.h" 48 48 #include "HTMLPlugInImageElement.h" 49 50 #include "HistoryItem.h" 51 #include "HitTestResult.h" 49 52 #include "KURL.h" 50 53 #include "MediaError.h" … … 57 60 #include "WebContextMenuData.h" 58 61 #include "WebDataSourceImpl.h" 62 #include "WebFormElement.h" 59 63 #include "WebFrameImpl.h" 60 64 #include "WebMenuItemInfo.h" … … 62 66 #include "WebPluginContainerImpl.h" 63 67 #include "WebPoint.h" 68 #include "WebSearchableFormData.h" 64 69 #include "WebSpellCheckClient.h" 65 70 #include "WebString.h" … … 270 275 } 271 276 } 277 HTMLFormElement* form = selectedFrame->selection()->currentForm(); 278 if (form && form->checkValidity() && r.innerNonSharedNode()->hasTagName(HTMLNames::inputTag)) { 279 HTMLInputElement* selectedElement = static_cast<HTMLInputElement*>(r.innerNonSharedNode()); 280 if (selectedElement) { 281 WebSearchableFormData ws = WebSearchableFormData(WebFormElement(form), WebInputElement(selectedElement)); 282 if (ws.url().isValid()) 283 data.keywordURL = ws.url(); 284 } 285 } 272 286 } 273 287 -
trunk/Source/WebKit/chromium/src/WebSearchableFormData.cpp
r79123 r88030 46 46 #include "TextEncoding.h" 47 47 #include "WebFormElement.h" 48 #include "WebInputElement.h" 48 49 49 50 using namespace WebCore; … … 142 143 } 143 144 144 // If form has only one text input element, return true. If a valid input 145 // element is not found, return false. Additionally, the form data for all 146 // elements is added to enc_string and the encoding used is set in 147 // encoding_name. 148 bool HasSuitableTextElement(const HTMLFormElement* form, Vector<char>* encodedString, String* encodingName) 149 { 145 // Look for a suitable search text field in a given HTMLFormElement 146 // Return nothing if one of those items are found: 147 // - A text area field 148 // - A file upload field 149 // - A Password field 150 // - More than one text field 151 HTMLInputElement* findSuitableSearchInputElement(const HTMLFormElement* form) 152 { 153 HTMLInputElement* textElement = 0; 154 // FIXME: Consider refactoring this code so that we don't call form->associatedElements() twice. 155 for (Vector<FormAssociatedElement*>::const_iterator i(form->associatedElements().begin()); i != form->associatedElements().end(); ++i) { 156 if (!(*i)->isFormControlElement()) 157 continue; 158 159 HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(*i); 160 161 if (formElement->disabled() || formElement->name().isNull()) 162 continue; 163 164 if (!IsInDefaultState(formElement) || formElement->hasTagName(HTMLNames::textareaTag)) 165 return 0; 166 167 if (formElement->hasTagName(HTMLNames::inputTag) && formElement->willValidate()) { 168 const HTMLInputElement* input = static_cast<const HTMLInputElement*>(formElement); 169 170 // Return nothing if a file upload field or a password field are found. 171 if (input->isFileUpload() || input->isPasswordField()) 172 return 0; 173 174 if (input->isTextField()) { 175 if (textElement) { 176 // The auto-complete bar only knows how to fill in one value. 177 // This form has multiple fields; don't treat it as searchable. 178 return 0; 179 } 180 textElement = static_cast<HTMLInputElement*>(formElement); 181 } 182 } 183 } 184 return textElement; 185 } 186 187 // Build a search string based on a given HTMLFormElement and HTMLInputElement 188 // 189 // Search string output example from www.google.com: 190 // "hl=en&source=hp&biw=1085&bih=854&q={searchTerms}&btnG=Google+Search&aq=f&aqi=&aql=&oq=" 191 // 192 // Return false if the provided HTMLInputElement is not found in the form 193 bool buildSearchString(const HTMLFormElement* form, Vector<char>* encodedString, TextEncoding* encoding, const HTMLInputElement* textElement) 194 { 195 bool isElementFound = false; 196 197 // FIXME: Consider refactoring this code so that we don't call form->associatedElements() twice. 198 for (Vector<FormAssociatedElement*>::const_iterator i(form->associatedElements().begin()); i != form->associatedElements().end(); ++i) { 199 if (!(*i)->isFormControlElement()) 200 continue; 201 202 HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(*i); 203 204 if (formElement->disabled() || formElement->name().isNull()) 205 continue; 206 207 FormDataList dataList(*encoding); 208 if (!formElement->appendFormData(dataList, false)) 209 continue; 210 211 const Vector<FormDataList::Item>& items = dataList.items(); 212 213 for (Vector<FormDataList::Item>::const_iterator j(items.begin()); j != items.end(); ++j) { 214 // Handle ISINDEX / <input name=isindex> specially, but only if it's 215 // the first entry. 216 if (!encodedString->isEmpty() || j->data() != "isindex") { 217 if (!encodedString->isEmpty()) 218 encodedString->append('&'); 219 FormDataBuilder::encodeStringAsFormData(*encodedString, j->data()); 220 encodedString->append('='); 221 } 222 ++j; 223 if (formElement == textElement) { 224 encodedString->append("{searchTerms}", 13); 225 isElementFound = true; 226 } else 227 FormDataBuilder::encodeStringAsFormData(*encodedString, j->data()); 228 } 229 } 230 return isElementFound; 231 } 232 } // namespace 233 234 namespace WebKit { 235 236 WebSearchableFormData::WebSearchableFormData(const WebFormElement& form, const WebInputElement& selectedInputElement) 237 { 238 RefPtr<HTMLFormElement> formElement = form.operator PassRefPtr<HTMLFormElement>(); 239 const Frame* frame = formElement->document()->frame(); 240 if (!frame) 241 return; 242 243 HTMLInputElement* inputElement = selectedInputElement.operator PassRefPtr<HTMLInputElement>().get(); 244 245 // Only consider forms that GET data. 246 // Allow HTTPS only when an input element is provided. 247 if (equalIgnoringCase(formElement->getAttribute(methodAttr), "post") 248 || (!IsHTTPFormSubmit(formElement.get()) && !inputElement)) 249 return; 250 251 Vector<char> encodedString; 150 252 TextEncoding encoding; 151 GetFormEncoding(form, &encoding); 253 254 GetFormEncoding(formElement.get(), &encoding); 152 255 if (!encoding.isValid()) { 153 256 // Need a valid encoding to encode the form elements. 154 257 // If the encoding isn't found webkit ends up replacing the params with 155 258 // empty strings. So, we don't try to do anything here. 156 return 0; 157 } 158 *encodingName = encoding.name(); 159 160 HTMLInputElement* textElement = 0; 161 // FIXME: Consider refactoring this code so that we don't call form->associatedElements() twice. 162 for (Vector<FormAssociatedElement*>::const_iterator i(form->associatedElements().begin()); i != form->associatedElements().end(); ++i) { 163 if (!(*i)->isFormControlElement()) 164 continue; 165 HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(*i); 166 if (formElement->disabled() || formElement->name().isNull()) 167 continue; 168 169 if (!IsInDefaultState(formElement) || formElement->hasTagName(HTMLNames::textareaTag)) 170 return 0; 171 172 bool isTextElement = false; 173 if (formElement->hasTagName(HTMLNames::inputTag)) { 174 const HTMLInputElement* input = static_cast<const HTMLInputElement*>(formElement); 175 if (input->isFileUpload()) { 176 // Too big, don't try to index this. 177 return 0; 178 } 179 180 if (input->isPasswordField()) { 181 // Don't store passwords! This is most likely an https anyway. 182 return 0; 183 } 184 185 if (input->isTextField()) 186 isTextElement = true; 187 } 188 189 FormDataList dataList(encoding); 190 if (!formElement->appendFormData(dataList, false)) 191 continue; 192 193 const Vector<FormDataList::Item>& items = dataList.items(); 194 if (isTextElement && !items.isEmpty()) { 195 if (textElement) { 196 // The auto-complete bar only knows how to fill in one value. 197 // This form has multiple fields; don't treat it as searchable. 198 return false; 199 } 200 textElement = static_cast<HTMLInputElement*>(formElement); 201 } 202 for (Vector<FormDataList::Item>::const_iterator j(items.begin()); j != items.end(); ++j) { 203 // Handle ISINDEX / <input name=isindex> specially, but only if it's 204 // the first entry. 205 if (!encodedString->isEmpty() || j->data() != "isindex") { 206 if (!encodedString->isEmpty()) 207 encodedString->append('&'); 208 FormDataBuilder::encodeStringAsFormData(*encodedString, j->data()); 209 encodedString->append('='); 210 } 211 ++j; 212 if (formElement == textElement) 213 encodedString->append("{searchTerms}", 13); 214 else 215 FormDataBuilder::encodeStringAsFormData(*encodedString, j->data()); 216 } 217 } 218 219 return textElement; 220 } 221 222 } // namespace 223 224 namespace WebKit { 225 226 WebSearchableFormData::WebSearchableFormData(const WebFormElement& form) 227 { 228 RefPtr<HTMLFormElement> formElement = form.operator PassRefPtr<HTMLFormElement>(); 229 const Frame* frame = formElement->document()->frame(); 230 if (!frame) 231 return; 232 233 // Only consider forms that GET data and the action targets an http page. 234 if (equalIgnoringCase(formElement->getAttribute(HTMLNames::methodAttr), "post") || !IsHTTPFormSubmit(formElement.get())) 235 return; 259 return; 260 } 261 262 // Look for a suitable search text field in the form when a 263 // selectedInputElement is not provided. 264 if (!inputElement) { 265 inputElement = findSuitableSearchInputElement(formElement.get()); 266 267 // Return if no suitable text element has been found. 268 if (!inputElement) 269 return; 270 } 236 271 237 272 HTMLFormControlElement* firstSubmitButton = GetButtonToActivate(formElement.get()); … … 242 277 firstSubmitButton->setActivatedSubmit(true); 243 278 } 244 Vector<char> encodedString; 245 String encoding;246 bool hasElement = HasSuitableTextElement(formElement.get(), &encodedString, &encoding); 279 280 bool isValidSearchString = buildSearchString(formElement.get(), &encodedString, &encoding, inputElement); 281 247 282 if (firstSubmitButton) 248 283 firstSubmitButton->setActivatedSubmit(false); 249 if (!hasElement) { 250 // Not a searchable form.251 return;252 }284 285 // Return if the search string is not valid. 286 if (!isValidSearchString) 287 return; 253 288 254 289 String action(formElement->action()); … … 257 292 url.setQuery(formData->flattenToString()); 258 293 m_url = url; 259 m_encoding = encoding;294 m_encoding = String(encoding.name()); 260 295 } 261 296
Note: See TracChangeset
for help on using the changeset viewer.