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-2017 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 "HTMLScriptElement.h"
25
26#include "Document.h"
27#include "Event.h"
28#include "EventNames.h"
29#include "HTMLNames.h"
30#include "HTMLParserIdioms.h"
31#include "Text.h"
32#include <wtf/IsoMallocInlines.h>
33#include <wtf/Ref.h>
34
35namespace WebCore {
36
37WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLScriptElement);
38
39using namespace HTMLNames;
40
41inline HTMLScriptElement::HTMLScriptElement(const QualifiedName& tagName, Document& document, bool wasInsertedByParser, bool alreadyStarted)
42 : HTMLElement(tagName, document)
43 , ScriptElement(*this, wasInsertedByParser, alreadyStarted)
44{
45 ASSERT(hasTagName(scriptTag));
46}
47
48Ref<HTMLScriptElement> HTMLScriptElement::create(const QualifiedName& tagName, Document& document, bool wasInsertedByParser, bool alreadyStarted)
49{
50 return adoptRef(*new HTMLScriptElement(tagName, document, wasInsertedByParser, alreadyStarted));
51}
52
53bool HTMLScriptElement::isURLAttribute(const Attribute& attribute) const
54{
55 return attribute.name() == srcAttr || HTMLElement::isURLAttribute(attribute);
56}
57
58void HTMLScriptElement::childrenChanged(const ChildChange& change)
59{
60 HTMLElement::childrenChanged(change);
61 ScriptElement::childrenChanged(change);
62}
63
64void HTMLScriptElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
65{
66 if (name == srcAttr)
67 handleSourceAttribute(value);
68 else if (name == asyncAttr)
69 handleAsyncAttribute();
70 else
71 HTMLElement::parseAttribute(name, value);
72}
73
74Node::InsertedIntoAncestorResult HTMLScriptElement::insertedIntoAncestor(InsertionType insertionType, ContainerNode& parentOfInsertedTree)
75{
76 HTMLElement::insertedIntoAncestor(insertionType, parentOfInsertedTree);
77 return ScriptElement::insertedIntoAncestor(insertionType, parentOfInsertedTree);
78}
79
80void HTMLScriptElement::didFinishInsertingNode()
81{
82 ScriptElement::didFinishInsertingNode();
83}
84
85// https://html.spec.whatwg.org/multipage/scripting.html#dom-script-text
86void HTMLScriptElement::setText(const String& value)
87{
88 setTextContent(value);
89}
90
91void HTMLScriptElement::setAsync(bool async)
92{
93 setBooleanAttribute(asyncAttr, async);
94 handleAsyncAttribute();
95}
96
97bool HTMLScriptElement::async() const
98{
99 return hasAttributeWithoutSynchronization(asyncAttr) || forceAsync();
100}
101
102void HTMLScriptElement::setCrossOrigin(const AtomicString& value)
103{
104 setAttributeWithoutSynchronization(crossoriginAttr, value);
105}
106
107String HTMLScriptElement::crossOrigin() const
108{
109 return parseCORSSettingsAttribute(attributeWithoutSynchronization(crossoriginAttr));
110}
111
112URL HTMLScriptElement::src() const
113{
114 return document().completeURL(sourceAttributeValue());
115}
116
117void HTMLScriptElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
118{
119 HTMLElement::addSubresourceAttributeURLs(urls);
120
121 addSubresourceURL(urls, src());
122}
123
124String HTMLScriptElement::sourceAttributeValue() const
125{
126 return attributeWithoutSynchronization(srcAttr).string();
127}
128
129String HTMLScriptElement::charsetAttributeValue() const
130{
131 return attributeWithoutSynchronization(charsetAttr).string();
132}
133
134String HTMLScriptElement::typeAttributeValue() const
135{
136 return attributeWithoutSynchronization(typeAttr).string();
137}
138
139String HTMLScriptElement::languageAttributeValue() const
140{
141 return attributeWithoutSynchronization(languageAttr).string();
142}
143
144String HTMLScriptElement::forAttributeValue() const
145{
146 return attributeWithoutSynchronization(forAttr).string();
147}
148
149String HTMLScriptElement::eventAttributeValue() const
150{
151 return attributeWithoutSynchronization(eventAttr).string();
152}
153
154bool HTMLScriptElement::hasAsyncAttribute() const
155{
156 return hasAttributeWithoutSynchronization(asyncAttr);
157}
158
159bool HTMLScriptElement::hasDeferAttribute() const
160{
161 return hasAttributeWithoutSynchronization(deferAttr);
162}
163
164bool HTMLScriptElement::hasNoModuleAttribute() const
165{
166 return hasAttributeWithoutSynchronization(nomoduleAttr);
167}
168
169bool HTMLScriptElement::hasSourceAttribute() const
170{
171 return hasAttributeWithoutSynchronization(srcAttr);
172}
173
174void HTMLScriptElement::dispatchLoadEvent()
175{
176 ASSERT(!haveFiredLoadEvent());
177 setHaveFiredLoadEvent(true);
178
179 dispatchEvent(Event::create(eventNames().loadEvent, Event::CanBubble::No, Event::IsCancelable::No));
180}
181
182Ref<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren(Document& targetDocument)
183{
184 return adoptRef(*new HTMLScriptElement(tagQName(), targetDocument, false, alreadyStarted()));
185}
186
187}
188