1/* 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. 3 * Copyright (C) 2010 Google Inc. All rights reserved. 4 * Copyright (C) 2012 Samsung Electronics. All rights reserved. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 * 21 */ 22 23#include "config.h" 24#include "ImageInputType.h" 25 26#include "CachedImage.h" 27#include "FormDataList.h" 28#include "HTMLFormElement.h" 29#include "HTMLImageLoader.h" 30#include "HTMLInputElement.h" 31#include "HTMLNames.h" 32#include "HTMLParserIdioms.h" 33#include "InputTypeNames.h" 34#include "MouseEvent.h" 35#include "RenderImage.h" 36 37namespace WebCore { 38 39using namespace HTMLNames; 40 41ImageInputType::ImageInputType(HTMLInputElement& element) 42 : BaseButtonInputType(element) 43{ 44} 45 46const AtomicString& ImageInputType::formControlType() const 47{ 48 return InputTypeNames::image(); 49} 50 51bool ImageInputType::isFormDataAppendable() const 52{ 53 return true; 54} 55 56bool ImageInputType::appendFormData(FormDataList& encoding, bool) const 57{ 58 if (!element().isActivatedSubmit()) 59 return false; 60 const AtomicString& name = element().name(); 61 if (name.isEmpty()) { 62 encoding.appendData("x", m_clickLocation.x()); 63 encoding.appendData("y", m_clickLocation.y()); 64 return true; 65 } 66 67 DEPRECATED_DEFINE_STATIC_LOCAL(String, dotXString, (ASCIILiteral(".x"))); 68 DEPRECATED_DEFINE_STATIC_LOCAL(String, dotYString, (ASCIILiteral(".y"))); 69 encoding.appendData(name + dotXString, m_clickLocation.x()); 70 encoding.appendData(name + dotYString, m_clickLocation.y()); 71 72 if (!element().value().isEmpty()) 73 encoding.appendData(name, element().value()); 74 return true; 75} 76 77bool ImageInputType::supportsValidation() const 78{ 79 return false; 80} 81 82void ImageInputType::handleDOMActivateEvent(Event* event) 83{ 84 Ref<HTMLInputElement> element(this->element()); 85 if (element->isDisabledFormControl() || !element->form()) 86 return; 87 element->setActivatedSubmit(true); 88 89 m_clickLocation = IntPoint(); 90 if (event->underlyingEvent()) { 91 Event& underlyingEvent = *event->underlyingEvent(); 92 if (underlyingEvent.isMouseEvent()) { 93 MouseEvent& mouseEvent = toMouseEvent(underlyingEvent); 94 if (!mouseEvent.isSimulated()) 95 m_clickLocation = IntPoint(mouseEvent.offsetX(), mouseEvent.offsetY()); 96 } 97 } 98 99 element->form()->prepareForSubmission(event); // Event handlers can run. 100 element->setActivatedSubmit(false); 101 event->setDefaultHandled(); 102} 103 104RenderPtr<RenderElement> ImageInputType::createInputRenderer(PassRef<RenderStyle> style) 105{ 106 return createRenderer<RenderImage>(element(), WTF::move(style)); 107} 108 109void ImageInputType::altAttributeChanged() 110{ 111 RenderImage* image = toRenderImage(element().renderer()); 112 if (!image) 113 return; 114 image->updateAltText(); 115} 116 117void ImageInputType::srcAttributeChanged() 118{ 119 if (!element().renderer()) 120 return; 121 element().imageLoader()->updateFromElementIgnoringPreviousError(); 122} 123 124void ImageInputType::attach() 125{ 126 BaseButtonInputType::attach(); 127 128 HTMLImageLoader* imageLoader = element().imageLoader(); 129 imageLoader->updateFromElement(); 130 131 RenderImage* renderer = toRenderImage(element().renderer()); 132 if (!renderer) 133 return; 134 135 if (imageLoader->hasPendingBeforeLoadEvent()) 136 return; 137 138 auto& imageResource = renderer->imageResource(); 139 imageResource.setCachedImage(imageLoader->image()); 140 141 // If we have no image at all because we have no src attribute, set 142 // image height and width for the alt text instead. 143 if (!imageLoader->image() && !imageResource.cachedImage()) 144 renderer->setImageSizeForAltText(); 145} 146 147bool ImageInputType::shouldRespectAlignAttribute() 148{ 149 return true; 150} 151 152bool ImageInputType::canBeSuccessfulSubmitButton() 153{ 154 return true; 155} 156 157bool ImageInputType::isImageButton() const 158{ 159 return true; 160} 161 162bool ImageInputType::isEnumeratable() 163{ 164 return false; 165} 166 167bool ImageInputType::shouldRespectHeightAndWidthAttributes() 168{ 169 return true; 170} 171 172unsigned ImageInputType::height() const 173{ 174 Ref<HTMLInputElement> element(this->element()); 175 176 if (!element->renderer()) { 177 // Check the attribute first for an explicit pixel value. 178 unsigned height; 179 if (parseHTMLNonNegativeInteger(element->fastGetAttribute(heightAttr), height)) 180 return height; 181 182 // If the image is available, use its height. 183 if (element->hasImageLoader()) { 184 HTMLImageLoader* imageLoader = element->imageLoader(); 185 if (imageLoader->image()) 186 return imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).height(); 187 } 188 } 189 190 element->document().updateLayout(); 191 192 RenderBox* box = element->renderBox(); 193 return box ? adjustForAbsoluteZoom(box->contentHeight(), *box) : 0; 194} 195 196unsigned ImageInputType::width() const 197{ 198 Ref<HTMLInputElement> element(this->element()); 199 200 if (!element->renderer()) { 201 // Check the attribute first for an explicit pixel value. 202 unsigned width; 203 if (parseHTMLNonNegativeInteger(element->fastGetAttribute(widthAttr), width)) 204 return width; 205 206 // If the image is available, use its width. 207 if (element->hasImageLoader()) { 208 HTMLImageLoader* imageLoader = element->imageLoader(); 209 if (imageLoader->image()) 210 return imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).width(); 211 } 212 } 213 214 element->document().updateLayout(); 215 216 RenderBox* box = element->renderBox(); 217 return box ? adjustForAbsoluteZoom(box->contentWidth(), *box) : 0; 218} 219 220} // namespace WebCore 221