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#include <wtf/PassOwnPtr.h> 37 38namespace WebCore { 39 40using namespace HTMLNames; 41 42inline ImageInputType::ImageInputType(HTMLInputElement* element) 43 : BaseButtonInputType(element) 44{ 45} 46 47PassOwnPtr<InputType> ImageInputType::create(HTMLInputElement* element) 48{ 49 return adoptPtr(new ImageInputType(element)); 50} 51 52const AtomicString& ImageInputType::formControlType() const 53{ 54 return InputTypeNames::image(); 55} 56 57bool ImageInputType::isFormDataAppendable() const 58{ 59 return true; 60} 61 62bool ImageInputType::appendFormData(FormDataList& encoding, bool) const 63{ 64 if (!element()->isActivatedSubmit()) 65 return false; 66 const AtomicString& name = element()->name(); 67 if (name.isEmpty()) { 68 encoding.appendData("x", m_clickLocation.x()); 69 encoding.appendData("y", m_clickLocation.y()); 70 return true; 71 } 72 73 DEFINE_STATIC_LOCAL(String, dotXString, (ASCIILiteral(".x"))); 74 DEFINE_STATIC_LOCAL(String, dotYString, (ASCIILiteral(".y"))); 75 encoding.appendData(name + dotXString, m_clickLocation.x()); 76 encoding.appendData(name + dotYString, m_clickLocation.y()); 77 78 if (!element()->value().isEmpty()) 79 encoding.appendData(name, element()->value()); 80 return true; 81} 82 83bool ImageInputType::supportsValidation() const 84{ 85 return false; 86} 87 88void ImageInputType::handleDOMActivateEvent(Event* event) 89{ 90 RefPtr<HTMLInputElement> element = this->element(); 91 if (element->isDisabledFormControl() || !element->form()) 92 return; 93 element->setActivatedSubmit(true); 94 if (event->underlyingEvent() && event->underlyingEvent()->isMouseEvent()) { 95 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event->underlyingEvent()); 96 m_clickLocation = IntPoint(mouseEvent->offsetX(), mouseEvent->offsetY()); 97 } else 98 m_clickLocation = IntPoint(); 99 element->form()->prepareForSubmission(event); // Event handlers can run. 100 element->setActivatedSubmit(false); 101 event->setDefaultHandled(); 102} 103 104RenderObject* ImageInputType::createRenderer(RenderArena* arena, RenderStyle*) const 105{ 106 RenderImage* image = new (arena) RenderImage(element()); 107 image->setImageResource(RenderImageResource::create()); 108 return image; 109} 110 111void ImageInputType::altAttributeChanged() 112{ 113 RenderImage* image = toRenderImage(element()->renderer()); 114 if (!image) 115 return; 116 image->updateAltText(); 117} 118 119void ImageInputType::srcAttributeChanged() 120{ 121 if (!element()->renderer()) 122 return; 123 element()->imageLoader()->updateFromElementIgnoringPreviousError(); 124} 125 126void ImageInputType::attach() 127{ 128 BaseButtonInputType::attach(); 129 130 HTMLImageLoader* imageLoader = element()->imageLoader(); 131 imageLoader->updateFromElement(); 132 133 RenderImage* renderer = toRenderImage(element()->renderer()); 134 if (!renderer) 135 return; 136 137 if (imageLoader->hasPendingBeforeLoadEvent()) 138 return; 139 140 RenderImageResource* imageResource = renderer->imageResource(); 141 imageResource->setCachedImage(imageLoader->image()); 142 143 // If we have no image at all because we have no src attribute, set 144 // image height and width for the alt text instead. 145 if (!imageLoader->image() && !imageResource->cachedImage()) 146 renderer->setImageSizeForAltText(); 147} 148 149bool ImageInputType::shouldRespectAlignAttribute() 150{ 151 return true; 152} 153 154bool ImageInputType::canBeSuccessfulSubmitButton() 155{ 156 return true; 157} 158 159bool ImageInputType::isImageButton() const 160{ 161 return true; 162} 163 164bool ImageInputType::isEnumeratable() 165{ 166 return false; 167} 168 169bool ImageInputType::shouldRespectHeightAndWidthAttributes() 170{ 171 return true; 172} 173 174unsigned ImageInputType::height() const 175{ 176 RefPtr<HTMLInputElement> element = this->element(); 177 178 if (!element->renderer()) { 179 // Check the attribute first for an explicit pixel value. 180 unsigned height; 181 if (parseHTMLNonNegativeInteger(element->fastGetAttribute(heightAttr), height)) 182 return height; 183 184 // If the image is available, use its height. 185 if (element->hasImageLoader()) { 186 HTMLImageLoader* imageLoader = element->imageLoader(); 187 if (imageLoader->image()) 188 return imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).height(); 189 } 190 } 191 192 element->document()->updateLayout(); 193 194 RenderBox* box = element->renderBox(); 195 return box ? adjustForAbsoluteZoom(box->contentHeight(), box) : 0; 196} 197 198unsigned ImageInputType::width() const 199{ 200 RefPtr<HTMLInputElement> element = this->element(); 201 202 if (!element->renderer()) { 203 // Check the attribute first for an explicit pixel value. 204 unsigned width; 205 if (parseHTMLNonNegativeInteger(element->fastGetAttribute(widthAttr), width)) 206 return width; 207 208 // If the image is available, use its width. 209 if (element->hasImageLoader()) { 210 HTMLImageLoader* imageLoader = element->imageLoader(); 211 if (imageLoader->image()) 212 return imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).width(); 213 } 214 } 215 216 element->document()->updateLayout(); 217 218 RenderBox* box = element->renderBox(); 219 return box ? adjustForAbsoluteZoom(box->contentWidth(), box) : 0; 220} 221 222} // namespace WebCore 223