1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) 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 35 using namespace std; 36 37 namespace WebCore { 38 39 using namespace HTMLNames; 40 41 HTMLMapElement::HTMLMapElement(const QualifiedName& tagName, Document* document) 42 : HTMLElement(tagName, document) 43 { 44 ASSERT(hasTagName(mapTag)); 45 } 46 47 PassRefPtr<HTMLMapElement> HTMLMapElement::create(Document* document) 48 { 49 return adoptRef(new HTMLMapElement(mapTag, document)); 50 } 51 52 PassRefPtr<HTMLMapElement> HTMLMapElement::create(const QualifiedName& tagName, Document* document) 53 { 54 return adoptRef(new HTMLMapElement(tagName, document)); 55 } 56 57 HTMLMapElement::~HTMLMapElement() 58 { 59 } 60 61 bool 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 83 HTMLImageElement* 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 101 void 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 129 PassRefPtr<HTMLCollection> HTMLMapElement::areas() 130 { 131 return HTMLCollection::create(this, MapAreas); 132 } 133 134 void HTMLMapElement::insertedIntoDocument() 135 { 136 document()->addImageMap(this); 137 HTMLElement::insertedIntoDocument(); 138 } 139 140 void HTMLMapElement::removedFromDocument() 141 { 142 document()->removeImageMap(this); 143 HTMLElement::removedFromDocument(); 144 } 145 146 } 147