Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(431)

Side by Side Diff: third_party/WebKit/Source/core/dom/ScriptLoader.cpp

Issue 2723793002: De-Element ScriptLoader (Closed)
Patch Set: ScriptLoaderClient->ScriptElementBase, pure virtual interface, add fixme Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights
6 * reserved. 6 * reserved.
7 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> 7 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 13 matching lines...) Expand all
24 24
25 #include "core/dom/ScriptLoader.h" 25 #include "core/dom/ScriptLoader.h"
26 26
27 #include "bindings/core/v8/ScriptController.h" 27 #include "bindings/core/v8/ScriptController.h"
28 #include "bindings/core/v8/ScriptSourceCode.h" 28 #include "bindings/core/v8/ScriptSourceCode.h"
29 #include "core/HTMLNames.h" 29 #include "core/HTMLNames.h"
30 #include "core/SVGNames.h" 30 #include "core/SVGNames.h"
31 #include "core/dom/Document.h" 31 #include "core/dom/Document.h"
32 #include "core/dom/DocumentParserTiming.h" 32 #include "core/dom/DocumentParserTiming.h"
33 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" 33 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
34 #include "core/dom/ScriptLoaderClient.h" 34 #include "core/dom/ScriptElementBase.h"
35 #include "core/dom/ScriptRunner.h" 35 #include "core/dom/ScriptRunner.h"
36 #include "core/dom/ScriptableDocumentParser.h" 36 #include "core/dom/ScriptableDocumentParser.h"
37 #include "core/dom/Text.h" 37 #include "core/dom/Text.h"
38 #include "core/events/Event.h" 38 #include "core/events/Event.h"
39 #include "core/frame/LocalFrame.h" 39 #include "core/frame/LocalFrame.h"
40 #include "core/frame/SubresourceIntegrity.h" 40 #include "core/frame/SubresourceIntegrity.h"
41 #include "core/frame/UseCounter.h" 41 #include "core/frame/UseCounter.h"
42 #include "core/frame/csp/ContentSecurityPolicy.h" 42 #include "core/frame/csp/ContentSecurityPolicy.h"
43 #include "core/html/CrossOriginAttribute.h" 43 #include "core/html/CrossOriginAttribute.h"
44 #include "core/html/HTMLScriptElement.h"
45 #include "core/html/imports/HTMLImport.h" 44 #include "core/html/imports/HTMLImport.h"
46 #include "core/html/parser/HTMLParserIdioms.h" 45 #include "core/html/parser/HTMLParserIdioms.h"
47 #include "core/inspector/ConsoleMessage.h" 46 #include "core/inspector/ConsoleMessage.h"
48 #include "core/svg/SVGScriptElement.h"
49 #include "platform/WebFrameScheduler.h" 47 #include "platform/WebFrameScheduler.h"
50 #include "platform/loader/fetch/AccessControlStatus.h" 48 #include "platform/loader/fetch/AccessControlStatus.h"
51 #include "platform/loader/fetch/FetchRequest.h" 49 #include "platform/loader/fetch/FetchRequest.h"
52 #include "platform/loader/fetch/MemoryCache.h" 50 #include "platform/loader/fetch/MemoryCache.h"
53 #include "platform/loader/fetch/ResourceFetcher.h" 51 #include "platform/loader/fetch/ResourceFetcher.h"
54 #include "platform/network/mime/MIMETypeRegistry.h" 52 #include "platform/network/mime/MIMETypeRegistry.h"
55 #include "platform/weborigin/SecurityOrigin.h" 53 #include "platform/weborigin/SecurityOrigin.h"
56 #include "public/platform/WebCachePolicy.h" 54 #include "public/platform/WebCachePolicy.h"
57 #include "wtf/StdLibExtras.h" 55 #include "wtf/StdLibExtras.h"
58 #include "wtf/text/StringBuilder.h" 56 #include "wtf/text/StringBuilder.h"
59 #include "wtf/text/StringHash.h" 57 #include "wtf/text/StringHash.h"
60 58
61 namespace blink { 59 namespace blink {
62 60
63 ScriptLoader::ScriptLoader(Element* element, 61 ScriptLoader::ScriptLoader(ScriptElementBase* element,
64 bool parserInserted, 62 bool parserInserted,
65 bool alreadyStarted, 63 bool alreadyStarted,
66 bool createdDuringDocumentWrite) 64 bool createdDuringDocumentWrite)
67 : m_element(element), 65 : m_element(element),
68 m_startLineNumber(WTF::OrdinalNumber::beforeFirst()), 66 m_startLineNumber(WTF::OrdinalNumber::beforeFirst()),
69 m_haveFiredLoad(false), 67 m_haveFiredLoad(false),
70 m_willBeParserExecuted(false), 68 m_willBeParserExecuted(false),
71 m_willExecuteWhenDocumentFinishedParsing(false), 69 m_willExecuteWhenDocumentFinishedParsing(false),
72 m_createdDuringDocumentWrite(createdDuringDocumentWrite), 70 m_createdDuringDocumentWrite(createdDuringDocumentWrite),
73 m_asyncExecType(ScriptRunner::None), 71 m_asyncExecType(ScriptRunner::None),
74 m_documentWriteIntervention( 72 m_documentWriteIntervention(
75 DocumentWriteIntervention::DocumentWriteInterventionNone) { 73 DocumentWriteIntervention::DocumentWriteInterventionNone) {
76 DCHECK(m_element);
77
78 // https://html.spec.whatwg.org/#already-started 74 // https://html.spec.whatwg.org/#already-started
79 // "The cloning steps for script elements must set the "already started" 75 // "The cloning steps for script elements must set the "already started"
80 // flag on the copy if it is set on the element being cloned." 76 // flag on the copy if it is set on the element being cloned."
81 // TODO(hiroshige): Cloning is implemented together with 77 // TODO(hiroshige): Cloning is implemented together with
82 // {HTML,SVG}ScriptElement::cloneElementWithoutAttributesAndChildren(). 78 // {HTML,SVG}ScriptElement::cloneElementWithoutAttributesAndChildren().
83 // Clean up these later. 79 // Clean up these later.
84 if (alreadyStarted) 80 if (alreadyStarted)
85 m_alreadyStarted = true; 81 m_alreadyStarted = true;
86 82
87 if (parserInserted) { 83 if (parserInserted) {
88 // https://html.spec.whatwg.org/#parser-inserted 84 // https://html.spec.whatwg.org/#parser-inserted
89 // "It is set by the HTML parser and the XML parser 85 // "It is set by the HTML parser and the XML parser
90 // on script elements they insert" 86 // on script elements they insert"
91 m_parserInserted = true; 87 m_parserInserted = true;
92 88
93 // https://html.spec.whatwg.org/#non-blocking 89 // https://html.spec.whatwg.org/#non-blocking
94 // "It is unset by the HTML parser and the XML parser 90 // "It is unset by the HTML parser and the XML parser
95 // on script elements they insert." 91 // on script elements they insert."
96 m_nonBlocking = false; 92 m_nonBlocking = false;
97 } 93 }
98 94
99 if (parserInserted && element->document().scriptableDocumentParser() && 95 if (parserInserted && m_element->document().scriptableDocumentParser() &&
100 !element->document().isInDocumentWrite()) 96 !m_element->document().isInDocumentWrite()) {
101 m_startLineNumber = 97 m_startLineNumber =
102 element->document().scriptableDocumentParser()->lineNumber(); 98 m_element->document().scriptableDocumentParser()->lineNumber();
99 }
103 } 100 }
104 101
105 ScriptLoader::~ScriptLoader() {} 102 ScriptLoader::~ScriptLoader() {}
106 103
107 DEFINE_TRACE(ScriptLoader) { 104 DEFINE_TRACE(ScriptLoader) {
108 visitor->trace(m_element); 105 visitor->trace(m_element);
109 visitor->trace(m_resource); 106 visitor->trace(m_resource);
110 visitor->trace(m_pendingScript); 107 visitor->trace(m_pendingScript);
111 PendingScriptClient::trace(visitor); 108 PendingScriptClient::trace(visitor);
112 } 109 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 equalIgnoringASCIICase(language, "javascript1.4") || 165 equalIgnoringASCIICase(language, "javascript1.4") ||
169 equalIgnoringASCIICase(language, "javascript1.5") || 166 equalIgnoringASCIICase(language, "javascript1.5") ||
170 equalIgnoringASCIICase(language, "javascript1.6") || 167 equalIgnoringASCIICase(language, "javascript1.6") ||
171 equalIgnoringASCIICase(language, "javascript1.7") || 168 equalIgnoringASCIICase(language, "javascript1.7") ||
172 equalIgnoringASCIICase(language, "livescript") || 169 equalIgnoringASCIICase(language, "livescript") ||
173 equalIgnoringASCIICase(language, "ecmascript") || 170 equalIgnoringASCIICase(language, "ecmascript") ||
174 equalIgnoringASCIICase(language, "jscript"); 171 equalIgnoringASCIICase(language, "jscript");
175 } 172 }
176 173
177 void ScriptLoader::dispatchErrorEvent() { 174 void ScriptLoader::dispatchErrorEvent() {
178 m_element->dispatchEvent(Event::create(EventTypeNames::error)); 175 m_element->dispatchErrorEvent();
179 } 176 }
180 177
181 void ScriptLoader::dispatchLoadEvent() { 178 void ScriptLoader::dispatchLoadEvent() {
182 if (ScriptLoaderClient* client = this->client()) 179 m_element->dispatchLoadEvent();
183 client->dispatchLoadEvent();
184 setHaveFiredLoadEvent(true); 180 setHaveFiredLoadEvent(true);
185 } 181 }
186 182
187 bool ScriptLoader::isValidScriptTypeAndLanguage( 183 bool ScriptLoader::isValidScriptTypeAndLanguage(
188 const String& type, 184 const String& type,
189 const String& language, 185 const String& language,
190 LegacyTypeSupport supportLegacyTypes) { 186 LegacyTypeSupport supportLegacyTypes) {
191 // FIXME: isLegacySupportedJavaScriptLanguage() is not valid HTML5. It is used 187 // FIXME: isLegacySupportedJavaScriptLanguage() is not valid HTML5. It is used
192 // here to maintain backwards compatibility with existing layout tests. The 188 // here to maintain backwards compatibility with existing layout tests. The
193 // specific violations are: 189 // specific violations are:
(...skipping 14 matching lines...) Expand all
208 (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && 204 (supportLegacyTypes == AllowLegacyTypeInTypeAttribute &&
209 isLegacySupportedJavaScriptLanguage(type))) { 205 isLegacySupportedJavaScriptLanguage(type))) {
210 return true; 206 return true;
211 } 207 }
212 208
213 return false; 209 return false;
214 } 210 }
215 211
216 bool ScriptLoader::isScriptTypeSupported( 212 bool ScriptLoader::isScriptTypeSupported(
217 LegacyTypeSupport supportLegacyTypes) const { 213 LegacyTypeSupport supportLegacyTypes) const {
218 return isValidScriptTypeAndLanguage(client()->typeAttributeValue(), 214 return isValidScriptTypeAndLanguage(m_element->typeAttributeValue(),
219 client()->languageAttributeValue(), 215 m_element->languageAttributeValue(),
220 supportLegacyTypes); 216 supportLegacyTypes);
221 } 217 }
222 218
223 // https://html.spec.whatwg.org/#prepare-a-script 219 // https://html.spec.whatwg.org/#prepare-a-script
224 bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, 220 bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition,
225 LegacyTypeSupport supportLegacyTypes) { 221 LegacyTypeSupport supportLegacyTypes) {
226 // 1. "If the script element is marked as having "already started", then 222 // 1. "If the script element is marked as having "already started", then
227 // abort these steps at this point. The script is not executed." 223 // abort these steps at this point. The script is not executed."
228 if (m_alreadyStarted) 224 if (m_alreadyStarted)
229 return false; 225 return false;
230 226
231 ScriptLoaderClient* client = this->client();
232
233 // 2. "If the element has its "parser-inserted" flag set, then 227 // 2. "If the element has its "parser-inserted" flag set, then
234 // set was-parser-inserted to true and unset the element's 228 // set was-parser-inserted to true and unset the element's
235 // "parser-inserted" flag. 229 // "parser-inserted" flag.
236 // Otherwise, set was-parser-inserted to false." 230 // Otherwise, set was-parser-inserted to false."
237 bool wasParserInserted; 231 bool wasParserInserted;
238 if (m_parserInserted) { 232 if (m_parserInserted) {
239 wasParserInserted = true; 233 wasParserInserted = true;
240 m_parserInserted = false; 234 m_parserInserted = false;
241 } else { 235 } else {
242 wasParserInserted = false; 236 wasParserInserted = false;
243 } 237 }
244 238
245 // 3. "If was-parser-inserted is true and the element does not have an 239 // 3. "If was-parser-inserted is true and the element does not have an
246 // async attribute, then set the element's "non-blocking" flag to true." 240 // async attribute, then set the element's "non-blocking" flag to true."
247 if (wasParserInserted && !client->asyncAttributeValue()) 241 if (wasParserInserted && !m_element->asyncAttributeValue())
248 m_nonBlocking = true; 242 m_nonBlocking = true;
249 243
250 // 4. "If the element has no src attribute, and its child nodes, if any, 244 // 4. "If the element has no src attribute, and its child nodes, if any,
251 // consist only of comment nodes and empty Text nodes, 245 // consist only of comment nodes and empty Text nodes,
252 // then abort these steps at this point. The script is not executed." 246 // then abort these steps at this point. The script is not executed."
253 // FIXME: HTML5 spec says we should check that all children are either 247 // FIXME: HTML5 spec says we should check that all children are either
254 // comments or empty text nodes. 248 // comments or empty text nodes.
255 if (!client->hasSourceAttribute() && !m_element->hasChildren()) 249 if (!m_element->hasSourceAttribute() && !m_element->hasChildren())
256 return false; 250 return false;
257 251
258 // 5. "If the element is not connected, then abort these steps. 252 // 5. "If the element is not connected, then abort these steps.
259 // The script is not executed." 253 // The script is not executed."
260 if (!m_element->isConnected()) 254 if (!m_element->isConnected())
261 return false; 255 return false;
262 256
263 // 6. 257 // 6.
264 // TODO(hiroshige): Annotate and/or cleanup this step. 258 // TODO(hiroshige): Annotate and/or cleanup this step.
265 if (!isScriptTypeSupported(supportLegacyTypes)) 259 if (!isScriptTypeSupported(supportLegacyTypes))
(...skipping 10 matching lines...) Expand all
276 // 8. "Set the element's "already started" flag." 270 // 8. "Set the element's "already started" flag."
277 m_alreadyStarted = true; 271 m_alreadyStarted = true;
278 272
279 // 9. "If the element is flagged as "parser-inserted", but the element's 273 // 9. "If the element is flagged as "parser-inserted", but the element's
280 // node document is not the Document of the parser that created the element, 274 // node document is not the Document of the parser that created the element,
281 // then abort these steps." 275 // then abort these steps."
282 // FIXME: If script is parser inserted, verify it's still in the original 276 // FIXME: If script is parser inserted, verify it's still in the original
283 // document. 277 // document.
284 Document& elementDocument = m_element->document(); 278 Document& elementDocument = m_element->document();
285 Document* contextDocument = elementDocument.contextDocument(); 279 Document* contextDocument = elementDocument.contextDocument();
286 if (!contextDocument) 280 if (!elementDocument.executingFrame())
281 return false;
282 if (!contextDocument || !contextDocument->executingFrame())
287 return false; 283 return false;
288 284
289 // 10. "If scripting is disabled for the script element, then abort these 285 // 10. "If scripting is disabled for the script element, then abort these
290 // steps at this point. The script is not executed." 286 // steps at this point. The script is not executed."
291 if (!contextDocument->allowExecutingScripts(m_element)) 287 if (!contextDocument->canExecuteScripts(AboutToExecuteScript))
292 return false; 288 return false;
293 289
294 // 13. 290 // 13.
295 if (!isScriptForEventSupported()) 291 if (!isScriptForEventSupported())
296 return false; 292 return false;
297 293
298 // 14. "If the script element has a charset attribute, 294 // 14. "If the script element has a charset attribute,
299 // then let encoding be the result of 295 // then let encoding be the result of
300 // getting an encoding from the value of the charset attribute." 296 // getting an encoding from the value of the charset attribute."
301 // "If the script element does not have a charset attribute, 297 // "If the script element does not have a charset attribute,
302 // or if getting an encoding failed, let encoding 298 // or if getting an encoding failed, let encoding
303 // be the same as the encoding of the script element's node document." 299 // be the same as the encoding of the script element's node document."
304 // TODO(hiroshige): Should we handle failure in getting an encoding? 300 // TODO(hiroshige): Should we handle failure in getting an encoding?
305 String encoding; 301 String encoding;
306 if (!client->charsetAttributeValue().isEmpty()) 302 if (!m_element->charsetAttributeValue().isEmpty())
307 encoding = client->charsetAttributeValue(); 303 encoding = m_element->charsetAttributeValue();
308 else 304 else
309 encoding = elementDocument.characterSet(); 305 encoding = elementDocument.characterSet();
310 306
311 // Steps 15--20 are handled in fetchScript(). 307 // Steps 15--20 are handled in fetchScript().
312 308
313 // 21. "If the element has a src content attribute, run these substeps:" 309 // 21. "If the element has a src content attribute, run these substeps:"
314 if (client->hasSourceAttribute()) { 310 if (m_element->hasSourceAttribute()) {
315 FetchRequest::DeferOption defer = FetchRequest::NoDefer; 311 FetchRequest::DeferOption defer = FetchRequest::NoDefer;
316 if (!m_parserInserted || client->asyncAttributeValue() || 312 if (!m_parserInserted || m_element->asyncAttributeValue() ||
317 client->deferAttributeValue()) 313 m_element->deferAttributeValue())
318 defer = FetchRequest::LazyLoad; 314 defer = FetchRequest::LazyLoad;
319 if (m_documentWriteIntervention == 315 if (m_documentWriteIntervention ==
320 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) 316 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle)
321 defer = FetchRequest::IdleLoad; 317 defer = FetchRequest::IdleLoad;
322 if (!fetchScript(client->sourceAttributeValue(), encoding, defer)) 318 if (!fetchScript(m_element->sourceAttributeValue(), encoding, defer))
323 return false; 319 return false;
324 } 320 }
325 321
326 // 22. "If the element does not have a src content attribute, 322 // 22. "If the element does not have a src content attribute,
327 // run these substeps:" 323 // run these substeps:"
328 324
329 // 22.1. "Let source text be the value of the text IDL attribute." 325 // 22.1. "Let source text be the value of the text IDL attribute."
330 // This step is done later: 326 // This step is done later:
331 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause), 327 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause),
332 // as Element::textFromChildren() in ScriptLoader::scriptContent(), 328 // as Element::textFromChildren() in ScriptLoader::scriptContent(),
(...skipping 11 matching lines...) Expand all
344 // 22.2. "Switch on the script's type:" 340 // 22.2. "Switch on the script's type:"
345 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic". 341 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic".
346 // TODO(hiroshige): Implement Step 22.2 for "module". 342 // TODO(hiroshige): Implement Step 22.2 for "module".
347 343
348 // [Intervention] 344 // [Intervention]
349 // Since the asynchronous, low priority fetch for doc.written blocked 345 // Since the asynchronous, low priority fetch for doc.written blocked
350 // script is not for execution, return early from here. Watch for its 346 // script is not for execution, return early from here. Watch for its
351 // completion to be able to remove it from the memory cache. 347 // completion to be able to remove it from the memory cache.
352 if (m_documentWriteIntervention == 348 if (m_documentWriteIntervention ==
353 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { 349 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) {
354 m_pendingScript = PendingScript::create(m_element, m_resource.get()); 350 m_pendingScript = PendingScript::create(m_element.get(), m_resource.get());
355 m_pendingScript->watchForLoad(this); 351 m_pendingScript->watchForLoad(this);
356 return true; 352 return true;
357 } 353 }
358 354
359 // 23. "Then, follow the first of the following options that describes the 355 // 23. "Then, follow the first of the following options that describes the
360 // situation:" 356 // situation:"
361 357
362 // Three flags are used to instruct the caller of prepareScript() to execute 358 // Three flags are used to instruct the caller of prepareScript() to execute
363 // a part of Step 23, when |m_willBeParserExecuted| is true: 359 // a part of Step 23, when |m_willBeParserExecuted| is true:
364 // - |m_willBeParserExecuted| 360 // - |m_willBeParserExecuted|
365 // - |m_willExecuteWhenDocumentFinishedParsing| 361 // - |m_willExecuteWhenDocumentFinishedParsing|
366 // - |m_readyToBeParserExecuted| 362 // - |m_readyToBeParserExecuted|
367 // TODO(hiroshige): Clean up the dependency. 363 // TODO(hiroshige): Clean up the dependency.
368 364
369 // 1st Clause: 365 // 1st Clause:
370 // - "If the script's type is "classic", and 366 // - "If the script's type is "classic", and
371 // the element has a src attribute, and the element has a defer attribute, 367 // the element has a src attribute, and the element has a defer attribute,
372 // and the element has been flagged as "parser-inserted", 368 // and the element has been flagged as "parser-inserted",
373 // and the element does not have an async attribute" 369 // and the element does not have an async attribute"
374 // TODO(hiroshige): Check the script's type and implement "module" case. 370 // TODO(hiroshige): Check the script's type and implement "module" case.
375 if (client->hasSourceAttribute() && client->deferAttributeValue() && 371 if (m_element->hasSourceAttribute() && m_element->deferAttributeValue() &&
376 m_parserInserted && !client->asyncAttributeValue()) { 372 m_parserInserted && !m_element->asyncAttributeValue()) {
377 // This clause is implemented by the caller-side of prepareScript(): 373 // This clause is implemented by the caller-side of prepareScript():
378 // - HTMLParserScriptRunner::requestDeferredScript(), and 374 // - HTMLParserScriptRunner::requestDeferredScript(), and
379 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 375 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
380 m_willExecuteWhenDocumentFinishedParsing = true; 376 m_willExecuteWhenDocumentFinishedParsing = true;
381 m_willBeParserExecuted = true; 377 m_willBeParserExecuted = true;
382 378
383 return true; 379 return true;
384 } 380 }
385 381
386 // 2nd Clause: 382 // 2nd Clause:
387 // - "If the script's type is "classic", 383 // - "If the script's type is "classic",
388 // and the element has a src attribute, 384 // and the element has a src attribute,
389 // and the element has been flagged as "parser-inserted", 385 // and the element has been flagged as "parser-inserted",
390 // and the element does not have an async attribute" 386 // and the element does not have an async attribute"
391 // TODO(hiroshige): Check the script's type. 387 // TODO(hiroshige): Check the script's type.
392 if (client->hasSourceAttribute() && m_parserInserted && 388 if (m_element->hasSourceAttribute() && m_parserInserted &&
393 !client->asyncAttributeValue()) { 389 !m_element->asyncAttributeValue()) {
394 // This clause is implemented by the caller-side of prepareScript(): 390 // This clause is implemented by the caller-side of prepareScript():
395 // - HTMLParserScriptRunner::requestParsingBlockingScript() 391 // - HTMLParserScriptRunner::requestParsingBlockingScript()
396 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 392 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
397 m_willBeParserExecuted = true; 393 m_willBeParserExecuted = true;
398 394
399 return true; 395 return true;
400 } 396 }
401 397
402 // 5th Clause: 398 // 5th Clause:
403 // TODO(hiroshige): Reorder the clauses to match the spec. 399 // TODO(hiroshige): Reorder the clauses to match the spec.
404 // - "If the element does not have a src attribute, 400 // - "If the element does not have a src attribute,
405 // and the element has been flagged as "parser-inserted", 401 // and the element has been flagged as "parser-inserted",
406 // and either the parser that created the script is an XML parser 402 // and either the parser that created the script is an XML parser
407 // or it's an HTML parser whose script nesting level is not greater than 403 // or it's an HTML parser whose script nesting level is not greater than
408 // one, 404 // one,
409 // and the Document of the HTML parser or XML parser that created 405 // and the Document of the HTML parser or XML parser that created
410 // the script element has a style sheet that is blocking scripts" 406 // the script element has a style sheet that is blocking scripts"
411 // The last part "... has a style sheet that is blocking scripts" 407 // The last part "... has a style sheet that is blocking scripts"
412 // is implemented in Document::isScriptExecutionReady(). 408 // is implemented in Document::isScriptExecutionReady().
413 // Part of the condition check is done in 409 // Part of the condition check is done in
414 // HTMLParserScriptRunner::processScriptElementInternal(). 410 // HTMLParserScriptRunner::processScriptElementInternal().
415 // TODO(hiroshige): Clean up the split condition check. 411 // TODO(hiroshige): Clean up the split condition check.
416 if (!client->hasSourceAttribute() && m_parserInserted && 412 if (!m_element->hasSourceAttribute() && m_parserInserted &&
417 !elementDocument.isScriptExecutionReady()) { 413 !elementDocument.isScriptExecutionReady()) {
418 // The former part of this clause is 414 // The former part of this clause is
419 // implemented by the caller-side of prepareScript(): 415 // implemented by the caller-side of prepareScript():
420 // - HTMLParserScriptRunner::requestParsingBlockingScript() 416 // - HTMLParserScriptRunner::requestParsingBlockingScript()
421 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 417 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
422 m_willBeParserExecuted = true; 418 m_willBeParserExecuted = true;
423 // "Set the element's "ready to be parser-executed" flag." 419 // "Set the element's "ready to be parser-executed" flag."
424 m_readyToBeParserExecuted = true; 420 m_readyToBeParserExecuted = true;
425 421
426 return true; 422 return true;
427 } 423 }
428 424
429 // 3rd Clause: 425 // 3rd Clause:
430 // - "If the script's type is "classic", 426 // - "If the script's type is "classic",
431 // and the element has a src attribute, 427 // and the element has a src attribute,
432 // and the element does not have an async attribute, 428 // and the element does not have an async attribute,
433 // and the element does not have the "non-blocking" flag set" 429 // and the element does not have the "non-blocking" flag set"
434 // TODO(hiroshige): Check the script's type and implement "module" case. 430 // TODO(hiroshige): Check the script's type and implement "module" case.
435 if (client->hasSourceAttribute() && !client->asyncAttributeValue() && 431 if (m_element->hasSourceAttribute() && !m_element->asyncAttributeValue() &&
436 !m_nonBlocking) { 432 !m_nonBlocking) {
437 // "Add the element to the end of the list of scripts that will execute 433 // "Add the element to the end of the list of scripts that will execute
438 // in order as soon as possible associated with the node document of the 434 // in order as soon as possible associated with the node document of the
439 // script element at the time the prepare a script algorithm started." 435 // script element at the time the prepare a script algorithm started."
440 m_pendingScript = PendingScript::create(m_element, m_resource.get()); 436 m_pendingScript = PendingScript::create(m_element.get(), m_resource.get());
441 m_asyncExecType = ScriptRunner::InOrder; 437 m_asyncExecType = ScriptRunner::InOrder;
442 // TODO(hiroshige): Here |contextDocument| is used as "node document" 438 // TODO(hiroshige): Here |contextDocument| is used as "node document"
443 // while Step 14 uses |elementDocument| as "node document". Fix this. 439 // while Step 14 uses |elementDocument| as "node document". Fix this.
444 contextDocument->scriptRunner()->queueScriptForExecution(this, 440 contextDocument->scriptRunner()->queueScriptForExecution(this,
445 m_asyncExecType); 441 m_asyncExecType);
446 // Note that watchForLoad can immediately call pendingScriptFinished. 442 // Note that watchForLoad can immediately call pendingScriptFinished.
447 m_pendingScript->watchForLoad(this); 443 m_pendingScript->watchForLoad(this);
448 // The part "When the script is ready..." is implemented in 444 // The part "When the script is ready..." is implemented in
449 // ScriptRunner::notifyScriptReady(). 445 // ScriptRunner::notifyScriptReady().
450 // TODO(hiroshige): Annotate it. 446 // TODO(hiroshige): Annotate it.
451 447
452 return true; 448 return true;
453 } 449 }
454 450
455 // 4th Clause: 451 // 4th Clause:
456 // - "If the script's type is "classic", and the element has a src attribute" 452 // - "If the script's type is "classic", and the element has a src attribute"
457 // TODO(hiroshige): Check the script's type and implement "module" case. 453 // TODO(hiroshige): Check the script's type and implement "module" case.
458 if (client->hasSourceAttribute()) { 454 if (m_element->hasSourceAttribute()) {
459 // "The element must be added to the set of scripts that will execute 455 // "The element must be added to the set of scripts that will execute
460 // as soon as possible of the node document of the script element at the 456 // as soon as possible of the node document of the script element at the
461 // time the prepare a script algorithm started." 457 // time the prepare a script algorithm started."
462 m_pendingScript = PendingScript::create(m_element, m_resource.get()); 458 m_pendingScript = PendingScript::create(m_element.get(), m_resource.get());
463 m_asyncExecType = ScriptRunner::Async; 459 m_asyncExecType = ScriptRunner::Async;
464 LocalFrame* frame = m_element->document().frame(); 460 LocalFrame* frame = m_element->document().frame();
465 if (frame) { 461 if (frame) {
466 ScriptState* scriptState = ScriptState::forMainWorld(frame); 462 ScriptState* scriptState = ScriptState::forMainWorld(frame);
467 if (scriptState) 463 if (scriptState)
468 ScriptStreamer::startStreaming( 464 ScriptStreamer::startStreaming(
469 m_pendingScript.get(), ScriptStreamer::Async, frame->settings(), 465 m_pendingScript.get(), ScriptStreamer::Async, frame->settings(),
470 scriptState, frame->frameScheduler()->loadingTaskRunner()); 466 scriptState, frame->frameScheduler()->loadingTaskRunner());
471 } 467 }
472 // TODO(hiroshige): Here |contextDocument| is used as "node document" 468 // TODO(hiroshige): Here |contextDocument| is used as "node document"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 return false; 502 return false;
507 } 503 }
508 504
509 return true; 505 return true;
510 } 506 }
511 507
512 // Steps 15--21 of https://html.spec.whatwg.org/#prepare-a-script 508 // Steps 15--21 of https://html.spec.whatwg.org/#prepare-a-script
513 bool ScriptLoader::fetchScript(const String& sourceUrl, 509 bool ScriptLoader::fetchScript(const String& sourceUrl,
514 const String& encoding, 510 const String& encoding,
515 FetchRequest::DeferOption defer) { 511 FetchRequest::DeferOption defer) {
516 DCHECK(m_element);
517
518 Document* elementDocument = &(m_element->document()); 512 Document* elementDocument = &(m_element->document());
519 if (!m_element->isConnected() || m_element->document() != elementDocument) 513 if (!m_element->isConnected() || m_element->document() != elementDocument)
520 return false; 514 return false;
521 515
522 DCHECK(!m_resource); 516 DCHECK(!m_resource);
523 // 21. "If the element has a src content attribute, run these substeps:" 517 // 21. "If the element has a src content attribute, run these substeps:"
524 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { 518 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
525 // 21.4. "Parse src relative to the element's node document." 519 // 21.4. "Parse src relative to the element's node document."
526 ResourceRequest resourceRequest(elementDocument->completeURL(sourceUrl)); 520 ResourceRequest resourceRequest(elementDocument->completeURL(sourceUrl));
527 521
528 // [Intervention] 522 // [Intervention]
529 if (m_documentWriteIntervention == 523 if (m_documentWriteIntervention ==
530 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { 524 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) {
531 resourceRequest.setHTTPHeaderField( 525 resourceRequest.setHTTPHeaderField(
532 "Intervention", 526 "Intervention",
533 "<https://www.chromestatus.com/feature/5718547946799104>"); 527 "<https://www.chromestatus.com/feature/5718547946799104>");
534 } 528 }
535 529
536 FetchRequest request(resourceRequest, m_element->localName()); 530 FetchRequest request(resourceRequest, m_element->initiatorName());
537 531
538 // 15. "Let CORS setting be the current state of the element's 532 // 15. "Let CORS setting be the current state of the element's
539 // crossorigin content attribute." 533 // crossorigin content attribute."
540 CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( 534 CrossOriginAttributeValue crossOrigin =
541 m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); 535 crossOriginAttributeValue(m_element->crossOriginAttributeValue());
542 536
543 // 16. "Let module script credentials mode be determined by switching 537 // 16. "Let module script credentials mode be determined by switching
544 // on CORS setting:" 538 // on CORS setting:"
545 // TODO(hiroshige): Implement this step for "module". 539 // TODO(hiroshige): Implement this step for "module".
546 540
547 // 21.6, "classic": "Fetch a classic script given ... CORS setting 541 // 21.6, "classic": "Fetch a classic script given ... CORS setting
548 // ... and encoding." 542 // ... and encoding."
549 if (crossOrigin != CrossOriginAttributeNotSet) 543 if (crossOrigin != CrossOriginAttributeNotSet)
550 request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), 544 request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(),
551 crossOrigin); 545 crossOrigin);
552 546
553 request.setCharset(encoding); 547 request.setCharset(encoding);
554 548
555 // 17. "If the script element has a nonce attribute, 549 // 17. "If the script element has a nonce attribute,
556 // then let cryptographic nonce be that attribute's value. 550 // then let cryptographic nonce be that attribute's value.
557 // Otherwise, let cryptographic nonce be the empty string." 551 // Otherwise, let cryptographic nonce be the empty string."
558 if (ContentSecurityPolicy::isNonceableElement(m_element.get())) 552 if (m_element->isNonceableElement())
559 request.setContentSecurityPolicyNonce(client()->nonce()); 553 request.setContentSecurityPolicyNonce(m_element->nonce());
560 554
561 // 19. "Let parser state be "parser-inserted" 555 // 19. "Let parser state be "parser-inserted"
562 // if the script element has been flagged as "parser-inserted", 556 // if the script element has been flagged as "parser-inserted",
563 // and "not parser-inserted" otherwise." 557 // and "not parser-inserted" otherwise."
564 request.setParserDisposition(isParserInserted() ? ParserInserted 558 request.setParserDisposition(isParserInserted() ? ParserInserted
565 : NotParserInserted); 559 : NotParserInserted);
566 560
567 request.setDefer(defer); 561 request.setDefer(defer);
568 562
569 // 18. "If the script element has an integrity attribute, 563 // 18. "If the script element has an integrity attribute,
570 // then let integrity metadata be that attribute's value. 564 // then let integrity metadata be that attribute's value.
571 // Otherwise, let integrity metadata be the empty string." 565 // Otherwise, let integrity metadata be the empty string."
572 String integrityAttr = 566 String integrityAttr = m_element->integrityAttributeValue();
573 m_element->fastGetAttribute(HTMLNames::integrityAttr);
574 if (!integrityAttr.isEmpty()) { 567 if (!integrityAttr.isEmpty()) {
575 IntegrityMetadataSet metadataSet; 568 IntegrityMetadataSet metadataSet;
576 SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet, 569 SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet,
577 elementDocument); 570 elementDocument);
578 request.setIntegrityMetadata(metadataSet); 571 request.setIntegrityMetadata(metadataSet);
579 } 572 }
580 573
581 // 21.6. "Switch on the script's type:" 574 // 21.6. "Switch on the script's type:"
582 575
583 // - "classic": 576 // - "classic":
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 if (m_createdDuringDocumentWrite && 611 if (m_createdDuringDocumentWrite &&
619 m_resource->resourceRequest().getCachePolicy() == 612 m_resource->resourceRequest().getCachePolicy() ==
620 WebCachePolicy::ReturnCacheDataDontLoad) { 613 WebCachePolicy::ReturnCacheDataDontLoad) {
621 m_documentWriteIntervention = 614 m_documentWriteIntervention =
622 DocumentWriteIntervention::DoNotFetchDocWrittenScript; 615 DocumentWriteIntervention::DoNotFetchDocWrittenScript;
623 } 616 }
624 617
625 return true; 618 return true;
626 } 619 }
627 620
628 bool isHTMLScriptLoader(Element* element) {
629 DCHECK(element);
630 return isHTMLScriptElement(*element);
631 }
632
633 bool isSVGScriptLoader(Element* element) {
634 DCHECK(element);
635 return isSVGScriptElement(*element);
636 }
637
638 void ScriptLoader::logScriptMIMEType(LocalFrame* frame, 621 void ScriptLoader::logScriptMIMEType(LocalFrame* frame,
639 ScriptResource* resource, 622 ScriptResource* resource,
640 const String& mimeType) { 623 const String& mimeType) {
641 if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType)) 624 if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType))
642 return; 625 return;
643 bool isText = mimeType.startsWith("text/", TextCaseASCIIInsensitive); 626 bool isText = mimeType.startsWith("text/", TextCaseASCIIInsensitive);
644 if (isText && isLegacySupportedJavaScriptLanguage(mimeType.substring(5))) 627 if (isText && isLegacySupportedJavaScriptLanguage(mimeType.substring(5)))
645 return; 628 return;
646 bool isSameOrigin = 629 bool isSameOrigin =
647 m_element->document().getSecurityOrigin()->canRequest(resource->url()); 630 m_element->document().getSecurityOrigin()->canRequest(resource->url());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 if (!frame) 680 if (!frame)
698 return true; 681 return true;
699 682
700 const ContentSecurityPolicy* csp = elementDocument->contentSecurityPolicy(); 683 const ContentSecurityPolicy* csp = elementDocument->contentSecurityPolicy();
701 bool shouldBypassMainWorldCSP = 684 bool shouldBypassMainWorldCSP =
702 (frame->script().shouldBypassMainWorldCSP()) || 685 (frame->script().shouldBypassMainWorldCSP()) ||
703 csp->allowScriptWithHash(sourceCode.source(), 686 csp->allowScriptWithHash(sourceCode.source(),
704 ContentSecurityPolicy::InlineType::Block); 687 ContentSecurityPolicy::InlineType::Block);
705 688
706 AtomicString nonce = 689 AtomicString nonce =
707 ContentSecurityPolicy::isNonceableElement(m_element.get()) 690 m_element->isNonceableElement() ? m_element->nonce() : nullAtom;
708 ? client()->nonce() 691 if (!m_isExternalScript && !shouldBypassMainWorldCSP &&
709 : nullAtom; 692 !m_element->allowInlineScriptForCSP(nonce, m_startLineNumber,
710 if (!m_isExternalScript && 693 sourceCode.source())) {
711 (!shouldBypassMainWorldCSP &&
712 !csp->allowInlineScript(m_element, elementDocument->url(), nonce,
713 m_startLineNumber, sourceCode.source()))) {
714 return false; 694 return false;
715 } 695 }
716 696
717 if (m_isExternalScript) { 697 if (m_isExternalScript) {
718 ScriptResource* resource = sourceCode.resource(); 698 ScriptResource* resource = sourceCode.resource();
719 CHECK_EQ(resource, m_resource); 699 CHECK_EQ(resource, m_resource);
720 CHECK(resource); 700 CHECK(resource);
721 if (!ScriptResource::mimeTypeAllowedByNosniff(resource->response())) { 701 if (!ScriptResource::mimeTypeAllowedByNosniff(resource->response())) {
722 contextDocument->addConsoleMessage(ConsoleMessage::create( 702 contextDocument->addConsoleMessage(ConsoleMessage::create(
723 SecurityMessageSource, ErrorMessageLevel, 703 SecurityMessageSource, ErrorMessageLevel,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 759
780 // 4. "Let old script element be the value to which the script element's 760 // 4. "Let old script element be the value to which the script element's
781 // node document's currentScript object was most recently set." 761 // node document's currentScript object was most recently set."
782 // This is implemented as push/popCurrentScript(). 762 // This is implemented as push/popCurrentScript().
783 763
784 // 5. "Switch on the script's type:" 764 // 5. "Switch on the script's type:"
785 // - "classic": 765 // - "classic":
786 // 1. "If the script element's root is not a shadow root, 766 // 1. "If the script element's root is not a shadow root,
787 // then set the script element's node document's currentScript 767 // then set the script element's node document's currentScript
788 // attribute to the script element. Otherwise, set it to null." 768 // attribute to the script element. Otherwise, set it to null."
789 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) 769 contextDocument->pushCurrentScript(m_element.get());
790 contextDocument->pushCurrentScript(m_element);
791 770
792 // 2. "Run the classic script given by the script's script." 771 // 2. "Run the classic script given by the script's script."
793 // Note: This is where the script is compiled and actually executed. 772 // Note: This is where the script is compiled and actually executed.
794 frame->script().executeScriptInMainWorld(sourceCode, accessControlStatus); 773 frame->script().executeScriptInMainWorld(sourceCode, accessControlStatus);
795 774
796 // - "module": 775 // - "module":
797 // TODO(hiroshige): Implement this. 776 // TODO(hiroshige): Implement this.
798 777
799 // 6. "Set the script element's node document's currentScript attribute 778 // 6. "Set the script element's node document's currentScript attribute
800 // to old script element." 779 // to old script element."
801 if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) { 780 contextDocument->popCurrentScript(m_element.get());
802 DCHECK(contextDocument->currentScript() == m_element);
803 contextDocument->popCurrentScript();
804 }
805 781
806 return true; 782 return true;
807 783
808 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc, 784 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc,
809 // if it was incremented in the earlier step." 785 // if it was incremented in the earlier step."
810 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer. 786 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer.
811 } 787 }
812 788
813 void ScriptLoader::execute() { 789 void ScriptLoader::execute() {
814 DCHECK(!m_willBeParserExecuted); 790 DCHECK(!m_willBeParserExecuted);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 detachPendingScript(); 834 detachPendingScript();
859 dispatchErrorEvent(); 835 dispatchErrorEvent();
860 return; 836 return;
861 } 837 }
862 contextDocument->scriptRunner()->notifyScriptReady(this, m_asyncExecType); 838 contextDocument->scriptRunner()->notifyScriptReady(this, m_asyncExecType);
863 m_pendingScript->stopWatchingForLoad(); 839 m_pendingScript->stopWatchingForLoad();
864 } 840 }
865 841
866 bool ScriptLoader::ignoresLoadRequest() const { 842 bool ScriptLoader::ignoresLoadRequest() const {
867 return m_alreadyStarted || m_isExternalScript || m_parserInserted || 843 return m_alreadyStarted || m_isExternalScript || m_parserInserted ||
868 !element() || !element()->isConnected(); 844 !m_element->isConnected();
869 } 845 }
870 846
871 // Step 13 of https://html.spec.whatwg.org/#prepare-a-script 847 // Step 13 of https://html.spec.whatwg.org/#prepare-a-script
872 bool ScriptLoader::isScriptForEventSupported() const { 848 bool ScriptLoader::isScriptForEventSupported() const {
873 // 1. "Let for be the value of the for attribute." 849 // 1. "Let for be the value of the for attribute."
874 String eventAttribute = client()->eventAttributeValue(); 850 String eventAttribute = m_element->eventAttributeValue();
875 // 2. "Let event be the value of the event attribute." 851 // 2. "Let event be the value of the event attribute."
876 String forAttribute = client()->forAttributeValue(); 852 String forAttribute = m_element->forAttributeValue();
877 853
878 // "If the script element has an event attribute and a for attribute, and 854 // "If the script element has an event attribute and a for attribute, and
879 // the script's type is "classic", then run these substeps:" 855 // the script's type is "classic", then run these substeps:"
880 // TODO(hiroshige): Check the script's type. 856 // TODO(hiroshige): Check the script's type.
881 if (eventAttribute.isNull() || forAttribute.isNull()) 857 if (eventAttribute.isNull() || forAttribute.isNull())
882 return true; 858 return true;
883 859
884 // 3. "Strip leading and trailing ASCII whitespace from event and for." 860 // 3. "Strip leading and trailing ASCII whitespace from event and for."
885 forAttribute = forAttribute.stripWhiteSpace(); 861 forAttribute = forAttribute.stripWhiteSpace();
886 // 4. "If for is not an ASCII case-insensitive match for the string 862 // 4. "If for is not an ASCII case-insensitive match for the string
887 // "window", 863 // "window",
888 // then abort these steps at this point. The script is not executed." 864 // then abort these steps at this point. The script is not executed."
889 if (!equalIgnoringCase(forAttribute, "window")) 865 if (!equalIgnoringCase(forAttribute, "window"))
890 return false; 866 return false;
891 eventAttribute = eventAttribute.stripWhiteSpace(); 867 eventAttribute = eventAttribute.stripWhiteSpace();
892 // 5. "If event is not an ASCII case-insensitive match for either the 868 // 5. "If event is not an ASCII case-insensitive match for either the
893 // string "onload" or the string "onload()", 869 // string "onload" or the string "onload()",
894 // then abort these steps at this point. The script is not executed. 870 // then abort these steps at this point. The script is not executed.
895 return equalIgnoringCase(eventAttribute, "onload") || 871 return equalIgnoringCase(eventAttribute, "onload") ||
896 equalIgnoringCase(eventAttribute, "onload()"); 872 equalIgnoringCase(eventAttribute, "onload()");
897 } 873 }
898 874
899 String ScriptLoader::scriptContent() const { 875 String ScriptLoader::scriptContent() const {
900 return m_element->textFromChildren(); 876 return m_element->textFromChildren();
901 } 877 }
902 878
903 ScriptLoaderClient* ScriptLoader::client() const {
904 if (isHTMLScriptLoader(m_element))
905 return toHTMLScriptElement(m_element);
906
907 if (isSVGScriptLoader(m_element))
908 return toSVGScriptElement(m_element);
909
910 NOTREACHED();
911 return 0;
912 }
913
914 ScriptLoader* toScriptLoaderIfPossible(Element* element) {
915 if (isHTMLScriptLoader(element))
916 return toHTMLScriptElement(element)->loader();
917
918 if (isSVGScriptLoader(element))
919 return toSVGScriptElement(element)->loader();
920
921 return 0;
922 }
923
924 } // namespace blink 879 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/dom/ScriptLoader.h ('k') | third_party/WebKit/Source/core/dom/ScriptLoaderClient.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698