Node: removedFrom() and insertedInto() should use references.
[WebKit-https.git] / Source / WebCore / html / HTMLTitleElement.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2003, 2010 Apple Inc. All rights reserved.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include "config.h"
24 #include "HTMLTitleElement.h"
25
26 #include "Document.h"
27 #include "HTMLNames.h"
28 #include "RenderStyle.h"
29 #include "StyleInheritedData.h"
30 #include "Text.h"
31 #include "TextNodeTraversal.h"
32 #include <wtf/Ref.h>
33 #include <wtf/text/StringBuilder.h>
34
35 namespace WebCore {
36
37 using namespace HTMLNames;
38
39 inline HTMLTitleElement::HTMLTitleElement(const QualifiedName& tagName, Document& document)
40     : HTMLElement(tagName, document)
41 {
42     ASSERT(hasTagName(titleTag));
43 }
44
45 PassRefPtr<HTMLTitleElement> HTMLTitleElement::create(const QualifiedName& tagName, Document& document)
46 {
47     return adoptRef(new HTMLTitleElement(tagName, document));
48 }
49
50 Node::InsertionNotificationRequest HTMLTitleElement::insertedInto(ContainerNode& insertionPoint)
51 {
52     HTMLElement::insertedInto(insertionPoint);
53     if (inDocument() && !isInShadowTree())
54         document().setTitleElement(m_title, this);
55     return InsertionDone;
56 }
57
58 void HTMLTitleElement::removedFrom(ContainerNode& insertionPoint)
59 {
60     HTMLElement::removedFrom(insertionPoint);
61     if (insertionPoint.inDocument() && !insertionPoint.isInShadowTree())
62         document().removeTitle(this);
63 }
64
65 void HTMLTitleElement::childrenChanged(const ChildChange& change)
66 {
67     HTMLElement::childrenChanged(change);
68     m_title = textWithDirection();
69     if (inDocument()) {
70         if (!isInShadowTree())
71             document().setTitleElement(m_title, this);
72         else
73             document().removeTitle(this);
74     }
75 }
76
77 String HTMLTitleElement::text() const
78 {
79     return TextNodeTraversal::contentsAsString(this);
80 }
81
82 StringWithDirection HTMLTitleElement::textWithDirection()
83 {
84     TextDirection direction = LTR;
85     if (RenderStyle* style = computedStyle())
86         direction = style->direction();
87     else if (RefPtr<RenderStyle> style = styleForRenderer())
88         direction = style->direction();
89     return StringWithDirection(text(), direction);
90 }
91
92 void HTMLTitleElement::setText(const String &value)
93 {
94     Ref<HTMLTitleElement> protectFromMutationEvents(*this);
95
96     int numChildren = childNodeCount();
97     
98     if (numChildren == 1 && firstChild()->isTextNode())
99         toText(firstChild())->setData(value, IGNORE_EXCEPTION);
100     else {
101         // We make a copy here because entity of "value" argument can be Document::m_title,
102         // which goes empty during removeChildren() invocation below,
103         // which causes HTMLTitleElement::childrenChanged(), which ends up Document::setTitle().
104         String valueCopy(value);
105
106         if (numChildren > 0)
107             removeChildren();
108
109         appendChild(document().createTextNode(valueCopy.impl()), IGNORE_EXCEPTION);
110     }
111 }
112
113 }