1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * Copyright (C) 2003, 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
23#include "config.h"
24#include "core/html/HTMLMarqueeElement.h"
25
26#include "bindings/core/v8/ExceptionState.h"
27#include "core/CSSPropertyNames.h"
28#include "core/CSSValueKeywords.h"
29#include "core/HTMLNames.h"
30#include "core/dom/ExceptionCode.h"
31#include "core/rendering/RenderMarquee.h"
32
33namespace blink {
34
35using namespace HTMLNames;
36
37inline HTMLMarqueeElement::HTMLMarqueeElement(Document& document)
38    : HTMLElement(marqueeTag, document)
39    , ActiveDOMObject(&document)
40{
41}
42
43PassRefPtrWillBeRawPtr<HTMLMarqueeElement> HTMLMarqueeElement::create(Document& document)
44{
45    RefPtrWillBeRawPtr<HTMLMarqueeElement> marqueeElement(adoptRefWillBeNoop(new HTMLMarqueeElement(document)));
46    marqueeElement->suspendIfNeeded();
47    return marqueeElement.release();
48}
49
50int HTMLMarqueeElement::minimumDelay() const
51{
52    if (fastGetAttribute(truespeedAttr).isEmpty()) {
53        // WinIE uses 60ms as the minimum delay by default.
54        return 60;
55    }
56    return 0;
57}
58
59void HTMLMarqueeElement::didMoveToNewDocument(Document& oldDocument)
60{
61    ActiveDOMObject::didMoveToNewExecutionContext(&document());
62    HTMLElement::didMoveToNewDocument(oldDocument);
63}
64
65bool HTMLMarqueeElement::isPresentationAttribute(const QualifiedName& name) const
66{
67    if (name == widthAttr || name == heightAttr || name == bgcolorAttr || name == vspaceAttr || name == hspaceAttr || name == scrollamountAttr || name == scrolldelayAttr || name == loopAttr || name == behaviorAttr || name == directionAttr)
68        return true;
69    return HTMLElement::isPresentationAttribute(name);
70}
71
72void HTMLMarqueeElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
73{
74    if (name == widthAttr) {
75        if (!value.isEmpty())
76            addHTMLLengthToStyle(style, CSSPropertyWidth, value);
77    } else if (name == heightAttr) {
78        if (!value.isEmpty())
79            addHTMLLengthToStyle(style, CSSPropertyHeight, value);
80    } else if (name == bgcolorAttr) {
81        if (!value.isEmpty())
82            addHTMLColorToStyle(style, CSSPropertyBackgroundColor, value);
83    } else if (name == vspaceAttr) {
84        if (!value.isEmpty()) {
85            addHTMLLengthToStyle(style, CSSPropertyMarginTop, value);
86            addHTMLLengthToStyle(style, CSSPropertyMarginBottom, value);
87        }
88    } else if (name == hspaceAttr) {
89        if (!value.isEmpty()) {
90            addHTMLLengthToStyle(style, CSSPropertyMarginLeft, value);
91            addHTMLLengthToStyle(style, CSSPropertyMarginRight, value);
92        }
93    } else if (name == scrollamountAttr) {
94        if (!value.isEmpty())
95            addHTMLLengthToStyle(style, CSSPropertyInternalMarqueeIncrement, value);
96    } else if (name == scrolldelayAttr) {
97        if (!value.isEmpty())
98            addHTMLLengthToStyle(style, CSSPropertyInternalMarqueeSpeed, value);
99    } else if (name == loopAttr) {
100        if (!value.isEmpty()) {
101            if (value == "-1" || equalIgnoringCase(value, "infinite"))
102                addPropertyToPresentationAttributeStyle(style, CSSPropertyInternalMarqueeRepetition, CSSValueInfinite);
103            else
104                addHTMLLengthToStyle(style, CSSPropertyInternalMarqueeRepetition, value);
105        }
106    } else if (name == behaviorAttr) {
107        if (!value.isEmpty())
108            addPropertyToPresentationAttributeStyle(style, CSSPropertyInternalMarqueeStyle, value);
109    } else if (name == directionAttr) {
110        if (!value.isEmpty())
111            addPropertyToPresentationAttributeStyle(style, CSSPropertyInternalMarqueeDirection, value);
112    } else
113        HTMLElement::collectStyleForPresentationAttribute(name, value, style);
114}
115
116void HTMLMarqueeElement::start()
117{
118    if (RenderMarquee* marqueeRenderer = renderMarquee())
119        marqueeRenderer->start();
120}
121
122void HTMLMarqueeElement::stop()
123{
124    if (RenderMarquee* marqueeRenderer = renderMarquee())
125        marqueeRenderer->stop();
126}
127
128void HTMLMarqueeElement::suspend()
129{
130    if (RenderMarquee* marqueeRenderer = renderMarquee())
131        marqueeRenderer->suspend();
132}
133
134void HTMLMarqueeElement::resume()
135{
136    if (RenderMarquee* marqueeRenderer = renderMarquee())
137        marqueeRenderer->updateMarqueePosition();
138}
139
140RenderMarquee* HTMLMarqueeElement::renderMarquee() const
141{
142    if (renderer() && renderer()->isMarquee())
143        return toRenderMarquee(renderer());
144    return 0;
145}
146
147RenderObject* HTMLMarqueeElement::createRenderer(RenderStyle*)
148{
149    return new RenderMarquee(this);
150}
151
152void HTMLMarqueeElement::timerFired(Timer<HTMLMarqueeElement>*)
153{
154    if (!renderer())
155        return;
156
157    document().updateLayout();
158
159    // The updateLayout() could have destroyed renderer(), so this re-check is very important.
160    if (renderer())
161        toRenderMarquee(renderer())->timerFired();
162}
163
164} // namespace blink
165