1/**
2 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 *
19 */
20
21#include "config.h"
22
23#if ENABLE(WML)
24#include "WMLImageElement.h"
25
26#include "Attribute.h"
27#include "CSSPropertyNames.h"
28#include "CSSValueKeywords.h"
29#include "HTMLElement.h"
30#include "HTMLNames.h"
31#include "RenderImage.h"
32#include "WMLNames.h"
33#include "WMLVariables.h"
34
35namespace WebCore {
36
37using namespace WMLNames;
38
39WMLImageElement::WMLImageElement(const QualifiedName& tagName, Document* doc)
40    : WMLElement(tagName, doc)
41    , m_imageLoader(this)
42    , m_useFallbackAttribute(false)
43{
44}
45
46PassRefPtr<WMLImageElement> WMLImageElement::create(const QualifiedName& tagName, Document* document)
47{
48    return adoptRef(new WMLImageElement(tagName, document));
49}
50
51WMLImageElement::~WMLImageElement()
52{
53}
54
55bool WMLImageElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
56{
57    if (attrName == HTMLNames::widthAttr ||
58        attrName == HTMLNames::heightAttr ||
59        attrName == HTMLNames::vspaceAttr ||
60        attrName == HTMLNames::hspaceAttr) {
61        result = eUniversal;
62        return false;
63    }
64
65    if (attrName == HTMLNames::alignAttr) {
66        result = eReplaced;
67        return false;
68    }
69
70    return WMLElement::mapToEntry(attrName, result);
71}
72
73void WMLImageElement::parseMappedAttribute(Attribute* attr)
74{
75    const QualifiedName& attrName = attr->name();
76
77    if (attrName == HTMLNames::altAttr) {
78        if (renderer() && renderer()->isImage())
79            toRenderImage(renderer())->updateAltText();
80    } else if (attrName == HTMLNames::srcAttr || attrName == localsrcAttr)
81        m_imageLoader.updateFromElementIgnoringPreviousError();
82    else if (attrName == HTMLNames::widthAttr)
83        addCSSLength(attr, CSSPropertyWidth, attr->value());
84    else if (attrName == HTMLNames::heightAttr)
85        addCSSLength(attr, CSSPropertyHeight, attr->value());
86    else if (attrName == HTMLNames::vspaceAttr) {
87        addCSSLength(attr, CSSPropertyMarginTop, attr->value());
88        addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
89    } else if (attrName == HTMLNames::hspaceAttr) {
90        addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
91        addCSSLength(attr, CSSPropertyMarginRight, attr->value());
92    } else if (attrName == HTMLNames::alignAttr)
93        HTMLElement::addHTMLAlignmentToStyledElement(this, attr);
94    else
95        WMLElement::parseMappedAttribute(attr);
96}
97
98void WMLImageElement::attach()
99{
100    WMLElement::attach();
101
102    if (renderer() && renderer()->isImage() && m_imageLoader.haveFiredBeforeLoadEvent()) {
103        RenderImage* imageObj = toRenderImage(renderer());
104        RenderImageResource* renderImageResource = imageObj->imageResource();
105        if (renderImageResource->hasImage())
106            return;
107        renderImageResource->setCachedImage(m_imageLoader.image());
108
109        // If we have no image at all because we have no src attribute, set
110        // image height and width for the alt text instead.
111        if (!m_imageLoader.image() && !imageObj->cachedImage())
112            imageObj->setImageSizeForAltText();
113    }
114}
115
116RenderObject* WMLImageElement::createRenderer(RenderArena* arena, RenderStyle*)
117{
118    RenderImage* image = new (arena) RenderImage(this);
119    image->setImageResource(RenderImageResource::create());
120    return image;
121}
122
123void WMLImageElement::insertedIntoDocument()
124{
125    // If we have been inserted from a renderer-less document,
126    // our loader may have not fetched the image, so do it now.
127    if (!m_imageLoader.image())
128        m_imageLoader.updateFromElement();
129
130    WMLElement::insertedIntoDocument();
131}
132
133bool WMLImageElement::isURLAttribute(Attribute* attr) const
134{
135    return attr->name() == HTMLNames::srcAttr
136           || attr->name() == localsrcAttr;
137}
138
139const QualifiedName& WMLImageElement::imageSourceAttributeName() const
140{
141    // Spec: Any 'localsrc' parameter specified takes precedence over the
142    // image specified in the src parameter.
143    if (hasAttribute(localsrcAttr) && !m_useFallbackAttribute)
144        return localsrcAttr;
145
146    return HTMLNames::srcAttr;
147}
148
149String WMLImageElement::altText() const
150{
151    return substituteVariableReferences(getAttribute(HTMLNames::altAttr), document());
152}
153
154}
155
156#endif
157