18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 1999 Antti Koivisto (koivisto@kde.org)
45af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke * Copyright (C) 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reserved.
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLMapElement.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
25e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "Attribute.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLAreaElement.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLCollection.h"
29d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "HTMLImageElement.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HitTestResult.h"
325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "IntSize.h"
33d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "RenderObject.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std;
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
415af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeHTMLMapElement::HTMLMapElement(const QualifiedName& tagName, Document* document)
425af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    : HTMLElement(tagName, document)
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
44635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(hasTagName(mapTag));
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
475af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkePassRefPtr<HTMLMapElement> HTMLMapElement::create(Document* document)
485af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
4906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return adoptRef(new HTMLMapElement(mapTag, document));
505af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
515af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
525af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkePassRefPtr<HTMLMapElement> HTMLMapElement::create(const QualifiedName& tagName, Document* document)
535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
5406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return adoptRef(new HTMLMapElement(tagName, document));
555af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
565af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLMapElement::~HTMLMapElement()
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLMapElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestResult& result)
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLAreaElement* defaultArea = 0;
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Node *node = this;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while ((node = node->traverseNextNode(this))) {
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (node->hasTagName(areaTag)) {
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            HTMLAreaElement* areaElt = static_cast<HTMLAreaElement*>(node);
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (areaElt->isDefault()) {
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (!defaultArea)
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    defaultArea = areaElt;
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else if (areaElt->mapMouseEvent(x, y, size, result))
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return true;
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (defaultArea) {
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result.setInnerNode(defaultArea);
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result.setURLElement(defaultArea);
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return defaultArea;
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
83d0825bca7fe65beaee391d30da42e937db621564Steve BlockHTMLImageElement* HTMLMapElement::imageElement() const
84d0825bca7fe65beaee391d30da42e937db621564Steve Block{
85dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    RefPtr<HTMLCollection> coll = document()->images();
86d0825bca7fe65beaee391d30da42e937db621564Steve Block    for (Node* curr = coll->firstItem(); curr; curr = coll->nextItem()) {
87d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!curr->hasTagName(imgTag))
88d0825bca7fe65beaee391d30da42e937db621564Steve Block            continue;
89d0825bca7fe65beaee391d30da42e937db621564Steve Block
90d0825bca7fe65beaee391d30da42e937db621564Steve Block        // The HTMLImageElement's useMap() value includes the '#' symbol at the beginning,
91d0825bca7fe65beaee391d30da42e937db621564Steve Block        // which has to be stripped off.
92d0825bca7fe65beaee391d30da42e937db621564Steve Block        HTMLImageElement* imageElement = static_cast<HTMLImageElement*>(curr);
93d0825bca7fe65beaee391d30da42e937db621564Steve Block        String useMapName = imageElement->getAttribute(usemapAttr).string().substring(1);
94d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (equalIgnoringCase(useMapName, m_name))
95d0825bca7fe65beaee391d30da42e937db621564Steve Block            return imageElement;
96d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
97d0825bca7fe65beaee391d30da42e937db621564Steve Block
98d0825bca7fe65beaee391d30da42e937db621564Steve Block    return 0;
99d0825bca7fe65beaee391d30da42e937db621564Steve Block}
100545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
101545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid HTMLMapElement::parseMappedAttribute(Attribute* attribute)
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
103545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // FIXME: This logic seems wrong for XML documents.
104545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    // Either the id or name will be used depending on the order the attributes are parsed.
105545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
106545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    const QualifiedName& attrName = attribute->name();
107545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    if (isIdAttributeName(attrName) || attrName == nameAttr) {
108545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        Document* document = this->document();
109545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (isIdAttributeName(attrName)) {
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Call base class so that hasID bit gets set.
111545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            HTMLElement::parseMappedAttribute(attribute);
112545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            if (document->isHTMLDocument())
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
115545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (inDocument())
116545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            document->removeImageMap(this);
117545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        String mapName = attribute->value();
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mapName[0] == '#')
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mapName = mapName.substring(1);
120545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        m_name = document->isHTMLDocument() ? mapName.lower() : mapName;
121545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (inDocument())
122545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            document->addImageMap(this);
123545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        return;
124545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    }
125545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
126545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    HTMLElement::parseMappedAttribute(attribute);
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<HTMLCollection> HTMLMapElement::areas()
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return HTMLCollection::create(this, MapAreas);
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
134545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid HTMLMapElement::insertedIntoDocument()
135545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
136545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    document()->addImageMap(this);
137545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    HTMLElement::insertedIntoDocument();
138545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
139545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
140545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid HTMLMapElement::removedFromDocument()
141545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
142545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    document()->removeImageMap(this);
143545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    HTMLElement::removedFromDocument();
144545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
145545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
147