1/* 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 4 * Copyright (C) 2004, 2005, 2006, 2007, 2010 Apple Inc. 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#include "config.h" 23#include "HTMLMapElement.h" 24 25#include "Attribute.h" 26#include "Document.h" 27#include "HTMLAreaElement.h" 28#include "HTMLCollection.h" 29#include "HTMLImageElement.h" 30#include "HTMLNames.h" 31#include "HitTestResult.h" 32#include "IntSize.h" 33#include "RenderObject.h" 34 35using namespace std; 36 37namespace WebCore { 38 39using namespace HTMLNames; 40 41HTMLMapElement::HTMLMapElement(const QualifiedName& tagName, Document* document) 42 : HTMLElement(tagName, document) 43{ 44 ASSERT(hasTagName(mapTag)); 45} 46 47PassRefPtr<HTMLMapElement> HTMLMapElement::create(Document* document) 48{ 49 return adoptRef(new HTMLMapElement(mapTag, document)); 50} 51 52PassRefPtr<HTMLMapElement> HTMLMapElement::create(const QualifiedName& tagName, Document* document) 53{ 54 return adoptRef(new HTMLMapElement(tagName, document)); 55} 56 57HTMLMapElement::~HTMLMapElement() 58{ 59} 60 61bool HTMLMapElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestResult& result) 62{ 63 HTMLAreaElement* defaultArea = 0; 64 Node *node = this; 65 while ((node = node->traverseNextNode(this))) { 66 if (node->hasTagName(areaTag)) { 67 HTMLAreaElement* areaElt = static_cast<HTMLAreaElement*>(node); 68 if (areaElt->isDefault()) { 69 if (!defaultArea) 70 defaultArea = areaElt; 71 } else if (areaElt->mapMouseEvent(x, y, size, result)) 72 return true; 73 } 74 } 75 76 if (defaultArea) { 77 result.setInnerNode(defaultArea); 78 result.setURLElement(defaultArea); 79 } 80 return defaultArea; 81} 82 83HTMLImageElement* HTMLMapElement::imageElement() const 84{ 85 RefPtr<HTMLCollection> coll = document()->images(); 86 for (Node* curr = coll->firstItem(); curr; curr = coll->nextItem()) { 87 if (!curr->hasTagName(imgTag)) 88 continue; 89 90 // The HTMLImageElement's useMap() value includes the '#' symbol at the beginning, 91 // which has to be stripped off. 92 HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(curr); 93 String useMapName = imageElement->getAttribute(usemapAttr).string().substring(1); 94 if (equalIgnoringCase(useMapName, m_name)) 95 return imageElement; 96 } 97 98 return 0; 99} 100 101void HTMLMapElement::parseMappedAttribute(Attribute* attribute) 102{ 103 // FIXME: This logic seems wrong for XML documents. 104 // Either the id or name will be used depending on the order the attributes are parsed. 105 106 const QualifiedName& attrName = attribute->name(); 107 if (isIdAttributeName(attrName) || attrName == nameAttr) { 108 Document* document = this->document(); 109 if (isIdAttributeName(attrName)) { 110 // Call base class so that hasID bit gets set. 111 HTMLElement::parseMappedAttribute(attribute); 112 if (document->isHTMLDocument()) 113 return; 114 } 115 if (inDocument()) 116 document->removeImageMap(this); 117 String mapName = attribute->value(); 118 if (mapName[0] == '#') 119 mapName = mapName.substring(1); 120 m_name = document->isHTMLDocument() ? mapName.lower() : mapName; 121 if (inDocument()) 122 document->addImageMap(this); 123 return; 124 } 125 126 HTMLElement::parseMappedAttribute(attribute); 127} 128 129PassRefPtr<HTMLCollection> HTMLMapElement::areas() 130{ 131 return HTMLCollection::create(this, MapAreas); 132} 133 134void HTMLMapElement::insertedIntoDocument() 135{ 136 document()->addImageMap(this); 137 HTMLElement::insertedIntoDocument(); 138} 139 140void HTMLMapElement::removedFromDocument() 141{ 142 document()->removeImageMap(this); 143 HTMLElement::removedFromDocument(); 144} 145 146} 147