[WPE][GTK] Build failure with ENABLE_ACCESSIBILITY=OFF
[WebKit-https.git] / Source / WebCore / html / HTMLBodyElement.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Simon Hausmann (hausmann@kde.org)
5  *           (C) 2001 Dirk Mueller (mueller@kde.org)
6  * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 #include "config.h"
25 #include "HTMLBodyElement.h"
26
27 #include "CSSImageValue.h"
28 #include "CSSParser.h"
29 #include "CSSValueKeywords.h"
30 #include "DOMWindow.h"
31 #include "DOMWrapperWorld.h"
32 #include "EventNames.h"
33 #include "HTMLFrameElement.h"
34 #include "HTMLIFrameElement.h"
35 #include "HTMLNames.h"
36 #include "HTMLParserIdioms.h"
37 #include "StyleProperties.h"
38 #include <wtf/IsoMallocInlines.h>
39 #include <wtf/NeverDestroyed.h>
40
41 namespace WebCore {
42
43 WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLBodyElement);
44
45 using namespace HTMLNames;
46
47 HTMLBodyElement::HTMLBodyElement(const QualifiedName& tagName, Document& document)
48     : HTMLElement(tagName, document)
49 {
50     ASSERT(hasTagName(bodyTag));
51 }
52
53 Ref<HTMLBodyElement> HTMLBodyElement::create(Document& document)
54 {
55     return adoptRef(*new HTMLBodyElement(bodyTag, document));
56 }
57
58 Ref<HTMLBodyElement> HTMLBodyElement::create(const QualifiedName& tagName, Document& document)
59 {
60     return adoptRef(*new HTMLBodyElement(tagName, document));
61 }
62
63 HTMLBodyElement::~HTMLBodyElement() = default;
64
65 bool HTMLBodyElement::isPresentationAttribute(const QualifiedName& name) const
66 {
67     if (name == backgroundAttr || name == marginwidthAttr || name == leftmarginAttr || name == marginheightAttr || name == topmarginAttr || name == bgcolorAttr || name == textAttr || name == bgpropertiesAttr)
68         return true;
69     return HTMLElement::isPresentationAttribute(name);
70 }
71
72 void HTMLBodyElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomString& value, MutableStyleProperties& style)
73 {
74     if (name == backgroundAttr) {
75         String url = stripLeadingAndTrailingHTMLSpaces(value);
76         if (!url.isEmpty()) {
77             auto imageValue = CSSImageValue::create(document().completeURL(url), LoadedFromOpaqueSource::No);
78             imageValue.get().setInitiator(localName());
79             style.setProperty(CSSProperty(CSSPropertyBackgroundImage, WTFMove(imageValue)));
80         }
81     } else if (name == marginwidthAttr || name == leftmarginAttr) {
82         addHTMLLengthToStyle(style, CSSPropertyMarginRight, value);
83         addHTMLLengthToStyle(style, CSSPropertyMarginLeft, value);
84     } else if (name == marginheightAttr || name == topmarginAttr) {
85         addHTMLLengthToStyle(style, CSSPropertyMarginBottom, value);
86         addHTMLLengthToStyle(style, CSSPropertyMarginTop, value);
87     } else if (name == bgcolorAttr) {
88         addHTMLColorToStyle(style, CSSPropertyBackgroundColor, value);
89     } else if (name == textAttr) {
90         addHTMLColorToStyle(style, CSSPropertyColor, value);
91     } else if (name == bgpropertiesAttr) {
92         if (equalLettersIgnoringASCIICase(value, "fixed"))
93            addPropertyToPresentationAttributeStyle(style, CSSPropertyBackgroundAttachment, CSSValueFixed);
94     } else
95         HTMLElement::collectStyleForPresentationAttribute(name, value, style);
96 }
97
98 HTMLElement::EventHandlerNameMap HTMLBodyElement::createWindowEventHandlerNameMap()
99 {
100     static const QualifiedName* const table[] = {
101         &onafterprintAttr.get(),
102         &onbeforeprintAttr.get(),
103         &onbeforeunloadAttr.get(),
104         &onblurAttr.get(),
105         &onerrorAttr.get(),
106         &onfocusAttr.get(),
107         &onfocusinAttr.get(),
108         &onfocusoutAttr.get(),
109         &onhashchangeAttr.get(),
110         &onlanguagechangeAttr.get(),
111         &onloadAttr.get(),
112         &onmessageAttr.get(),
113         &onofflineAttr.get(),
114         &ononlineAttr.get(),
115         &onorientationchangeAttr.get(),
116         &onpagehideAttr.get(),
117         &onpageshowAttr.get(),
118         &onpopstateAttr.get(),
119         &onresizeAttr.get(),
120         &onscrollAttr.get(),
121         &onstorageAttr.get(),
122         &onunloadAttr.get(),
123         &onwebkitmouseforcechangedAttr.get(),
124         &onwebkitmouseforcedownAttr.get(),
125         &onwebkitmouseforceupAttr.get(),
126         &onwebkitmouseforcewillbeginAttr.get(),
127         &onwebkitwillrevealbottomAttr.get(),
128         &onwebkitwillrevealleftAttr.get(),
129         &onwebkitwillrevealrightAttr.get(),
130         &onwebkitwillrevealtopAttr.get(),
131     };
132
133     EventHandlerNameMap map;
134     populateEventHandlerNameMap(map, table);
135     return map;
136 }
137
138 const AtomString& HTMLBodyElement::eventNameForWindowEventHandlerAttribute(const QualifiedName& attributeName)
139 {
140     static NeverDestroyed<EventHandlerNameMap> map = createWindowEventHandlerNameMap();
141     return eventNameForEventHandlerAttribute(attributeName, map.get());
142 }
143
144 void HTMLBodyElement::parseAttribute(const QualifiedName& name, const AtomString& value)
145 {
146     if (name == vlinkAttr || name == alinkAttr || name == linkAttr) {
147         if (value.isNull()) {
148             if (name == linkAttr)
149                 document().resetLinkColor();
150             else if (name == vlinkAttr)
151                 document().resetVisitedLinkColor();
152             else
153                 document().resetActiveLinkColor();
154         } else {
155             Color color = CSSParser::parseColor(value, !document().inQuirksMode());
156             if (color.isValid()) {
157                 if (name == linkAttr)
158                     document().setLinkColor(color);
159                 else if (name == vlinkAttr)
160                     document().setVisitedLinkColor(color);
161                 else
162                     document().setActiveLinkColor(color);
163             }
164         }
165
166         invalidateStyleForSubtree();
167         return;
168     }
169
170     if (name == onselectionchangeAttr) {
171         document().setAttributeEventListener(eventNames().selectionchangeEvent, name, value, mainThreadNormalWorld());
172         return;
173     }
174
175     auto& eventName = eventNameForWindowEventHandlerAttribute(name);
176     if (!eventName.isNull()) {
177         document().setWindowAttributeEventListener(eventName, name, value, mainThreadNormalWorld());
178         return;
179     }
180
181     HTMLElement::parseAttribute(name, value);
182 }
183
184 Node::InsertedIntoAncestorResult HTMLBodyElement::insertedIntoAncestor(InsertionType insertionType, ContainerNode& parentOfInsertedTree)
185 {
186     HTMLElement::insertedIntoAncestor(insertionType, parentOfInsertedTree);
187     if (!insertionType.connectedToDocument)
188         return InsertedIntoAncestorResult::Done;
189
190     // FIXME: It's surprising this is web compatible since it means a marginwidth and marginheight attribute can
191     // magically appear on the <body> of all documents embedded through <iframe> or <frame>.
192     // FIXME: Perhaps this code should be in attach() instead of here.
193     auto ownerElement = makeRefPtr(document().ownerElement());
194     if (!is<HTMLFrameElementBase>(ownerElement))
195         return InsertedIntoAncestorResult::Done;
196
197     return InsertedIntoAncestorResult::NeedsPostInsertionCallback;
198 }
199
200 void HTMLBodyElement::didFinishInsertingNode()
201 {
202     auto ownerElement = makeRefPtr(document().ownerElement());
203     RELEASE_ASSERT(is<HTMLFrameElementBase>(ownerElement));
204     auto& ownerFrameElement = downcast<HTMLFrameElementBase>(*ownerElement);
205
206     // Read values from the owner before setting any attributes, since setting an attribute can run arbitrary
207     // JavaScript, which might delete the owner element.
208     int marginWidth = ownerFrameElement.marginWidth();
209     int marginHeight = ownerFrameElement.marginHeight();
210
211     if (marginWidth != -1)
212         setIntegralAttribute(marginwidthAttr, marginWidth);
213     if (marginHeight != -1)
214         setIntegralAttribute(marginheightAttr, marginHeight);
215 }
216
217 bool HTMLBodyElement::isURLAttribute(const Attribute& attribute) const
218 {
219     return attribute.name() == backgroundAttr || HTMLElement::isURLAttribute(attribute);
220 }
221
222 bool HTMLBodyElement::supportsFocus() const
223 {
224     return hasEditableStyle() || HTMLElement::supportsFocus();
225 }
226
227 void HTMLBodyElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
228 {
229     HTMLElement::addSubresourceAttributeURLs(urls);
230
231     addSubresourceURL(urls, document().completeURL(attributeWithoutSynchronization(backgroundAttr)));
232 }
233
234 } // namespace WebCore