Use NeverDestroyed instead of DEPRECATED_DEFINE_STATIC_LOCAL
[WebKit-https.git] / Source / WebCore / dom / PseudoElement.cpp
1 /*
2  * Copyright (C) 2012 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  *     * Neither the name of Google Inc. nor the names of its
11  * contributors may be used to endorse or promote products derived from
12  * this software without specific prior written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "PseudoElement.h"
29
30 #include "ContentData.h"
31 #include "InspectorInstrumentation.h"
32 #include "RenderElement.h"
33 #include "RenderImage.h"
34 #include "RenderQuote.h"
35
36 namespace WebCore {
37
38 const QualifiedName& pseudoElementTagName()
39 {
40     static NeverDestroyed<QualifiedName> name(nullAtom, "<pseudo>", nullAtom);
41     return name;
42 }
43
44 String PseudoElement::pseudoElementNameForEvents(PseudoId pseudoId)
45 {
46     static NeverDestroyed<const String> after(ASCIILiteral("::after"));
47     static NeverDestroyed<const String> before(ASCIILiteral("::before"));
48     switch (pseudoId) {
49     case AFTER:
50         return after;
51     case BEFORE:
52         return before;
53     default:
54         return emptyString();
55     }
56 }
57
58 PseudoElement::PseudoElement(Element& host, PseudoId pseudoId)
59     : Element(pseudoElementTagName(), host.document(), CreatePseudoElement)
60     , m_hostElement(&host)
61     , m_pseudoId(pseudoId)
62 {
63     ASSERT(pseudoId == BEFORE || pseudoId == AFTER);
64     setHasCustomStyleResolveCallbacks();
65 }
66
67 PseudoElement::~PseudoElement()
68 {
69     ASSERT(!m_hostElement);
70 }
71
72 void PseudoElement::clearHostElement()
73 {
74     InspectorInstrumentation::pseudoElementDestroyed(document().page(), *this);
75
76     m_hostElement = nullptr;
77 }
78
79 RefPtr<RenderStyle> PseudoElement::customStyleForRenderer(RenderStyle& parentStyle)
80 {
81     return m_hostElement->renderer()->getCachedPseudoStyle(m_pseudoId, &parentStyle);
82 }
83
84 void PseudoElement::didAttachRenderers()
85 {
86     RenderElement* renderer = this->renderer();
87     if (!renderer || renderer->style().hasFlowFrom())
88         return;
89
90     const RenderStyle& style = renderer->style();
91     ASSERT(style.contentData());
92
93     for (const ContentData* content = style.contentData(); content; content = content->next()) {
94         auto child = content->createContentRenderer(document(), style);
95         if (renderer->isChildAllowed(*child, style)) {
96             auto* childPtr = child.get();
97             renderer->addChild(child.leakPtr());
98             if (is<RenderQuote>(*childPtr))
99                 downcast<RenderQuote>(*childPtr).attachQuote();
100         }
101     }
102 }
103
104 bool PseudoElement::rendererIsNeeded(const RenderStyle& style)
105 {
106     return pseudoElementRendererIsNeeded(&style);
107 }
108
109 void PseudoElement::didRecalcStyle(Style::Change)
110 {
111     if (!renderer())
112         return;
113
114     // The renderers inside pseudo elements are anonymous so they don't get notified of recalcStyle and must have
115     // the style propagated downward manually similar to RenderObject::propagateStyleToAnonymousChildren.
116     RenderElement& renderer = *this->renderer();
117     for (RenderObject* child = renderer.nextInPreOrder(&renderer); child; child = child->nextInPreOrder(&renderer)) {
118         // We only manage the style for the generated content which must be images or text.
119         if (!is<RenderImage>(*child) && !is<RenderQuote>(*child))
120             continue;
121         Ref<RenderStyle> createdStyle = RenderStyle::createStyleInheritingFromPseudoStyle(renderer.style());
122         downcast<RenderElement>(*child).setStyle(WTFMove(createdStyle));
123     }
124 }
125
126 } // namespace