1/*
2 * Copyright (c) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include "HTMLOutputElement.h"
33
34#include "ExceptionCodePlaceholder.h"
35#include "HTMLFormElement.h"
36#include "HTMLNames.h"
37
38namespace WebCore {
39
40inline HTMLOutputElement::HTMLOutputElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
41    : HTMLFormControlElement(tagName, document, form)
42    , m_isDefaultValueMode(true)
43    , m_isSetTextContentInProgress(false)
44    , m_defaultValue("")
45    , m_tokens(DOMSettableTokenList::create())
46{
47}
48
49PassRefPtr<HTMLOutputElement> HTMLOutputElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
50{
51    return adoptRef(new HTMLOutputElement(tagName, document, form));
52}
53
54const AtomicString& HTMLOutputElement::formControlType() const
55{
56    DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, output, ("output", AtomicString::ConstructFromLiteral));
57    return output;
58}
59
60bool HTMLOutputElement::supportsFocus() const
61{
62    return HTMLElement::supportsFocus();
63}
64
65void HTMLOutputElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
66{
67    if (name == HTMLNames::forAttr)
68        setFor(value);
69    else
70        HTMLFormControlElement::parseAttribute(name, value);
71}
72
73DOMSettableTokenList* HTMLOutputElement::htmlFor() const
74{
75    return m_tokens.get();
76}
77
78void HTMLOutputElement::setFor(const String& value)
79{
80    m_tokens->setValue(value);
81}
82
83void HTMLOutputElement::childrenChanged(const ChildChange& change)
84{
85    HTMLFormControlElement::childrenChanged(change);
86
87    if (change.source == ChildChangeSourceParser || m_isSetTextContentInProgress) {
88        m_isSetTextContentInProgress = false;
89        return;
90    }
91
92    if (m_isDefaultValueMode)
93        m_defaultValue = textContent();
94}
95
96void HTMLOutputElement::reset()
97{
98    // The reset algorithm for output elements is to set the element's
99    // value mode flag to "default" and then to set the element's textContent
100    // attribute to the default value.
101    m_isDefaultValueMode = true;
102    if (m_defaultValue == value())
103        return;
104    setTextContentInternal(m_defaultValue);
105}
106
107String HTMLOutputElement::value() const
108{
109    return textContent();
110}
111
112void HTMLOutputElement::setValue(const String& value)
113{
114    // The value mode flag set to "value" when the value attribute is set.
115    m_isDefaultValueMode = false;
116    if (value == this->value())
117        return;
118    setTextContentInternal(value);
119}
120
121String HTMLOutputElement::defaultValue() const
122{
123    return m_defaultValue;
124}
125
126void HTMLOutputElement::setDefaultValue(const String& value)
127{
128    if (m_defaultValue == value)
129        return;
130    m_defaultValue = value;
131    // The spec requires the value attribute set to the default value
132    // when the element's value mode flag to "default".
133    if (m_isDefaultValueMode)
134        setTextContentInternal(value);
135}
136
137void HTMLOutputElement::setTextContentInternal(const String& value)
138{
139    ASSERT(!m_isSetTextContentInProgress);
140    m_isSetTextContentInProgress = true;
141    setTextContent(value, IGNORE_EXCEPTION);
142}
143
144} // namespace
145