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

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

Issue 2781713003: Enable module scripts in ScriptLoader (Closed)
Patch Set: Rebase Created 3 years, 8 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
11 * License as published by the Free Software Foundation; either 11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version. 12 * version 2 of the License, or (at your option) any later version.
13 * 13 *
14 * This library is distributed in the hope that it will be useful, 14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details. 17 * Library General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU Library General Public License 19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to 20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA. 22 * Boston, MA 02110-1301, USA.
23 */ 23 */
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 "bindings/core/v8/V8Binding.h"
29 #include "core/HTMLNames.h" 30 #include "core/HTMLNames.h"
30 #include "core/SVGNames.h" 31 #include "core/SVGNames.h"
31 #include "core/dom/ClassicPendingScript.h" 32 #include "core/dom/ClassicPendingScript.h"
32 #include "core/dom/ClassicScript.h" 33 #include "core/dom/ClassicScript.h"
33 #include "core/dom/Document.h" 34 #include "core/dom/Document.h"
34 #include "core/dom/DocumentParserTiming.h" 35 #include "core/dom/DocumentParserTiming.h"
35 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" 36 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
37 #include "core/dom/Modulator.h"
38 #include "core/dom/ModulePendingScript.h"
36 #include "core/dom/Script.h" 39 #include "core/dom/Script.h"
37 #include "core/dom/ScriptElementBase.h" 40 #include "core/dom/ScriptElementBase.h"
38 #include "core/dom/ScriptRunner.h" 41 #include "core/dom/ScriptRunner.h"
39 #include "core/dom/ScriptableDocumentParser.h" 42 #include "core/dom/ScriptableDocumentParser.h"
40 #include "core/dom/Text.h" 43 #include "core/dom/Text.h"
41 #include "core/events/Event.h" 44 #include "core/events/Event.h"
42 #include "core/frame/LocalFrame.h" 45 #include "core/frame/LocalFrame.h"
43 #include "core/frame/SubresourceIntegrity.h" 46 #include "core/frame/SubresourceIntegrity.h"
44 #include "core/frame/csp/ContentSecurityPolicy.h" 47 #include "core/frame/csp/ContentSecurityPolicy.h"
45 #include "core/html/CrossOriginAttribute.h" 48 #include "core/html/CrossOriginAttribute.h"
46 #include "core/html/imports/HTMLImport.h" 49 #include "core/html/imports/HTMLImport.h"
47 #include "core/html/parser/HTMLParserIdioms.h" 50 #include "core/html/parser/HTMLParserIdioms.h"
51 #include "core/loader/modulescript/ModuleScriptFetchRequest.h"
52 #include "core/loader/resource/ScriptResource.h"
48 #include "platform/WebFrameScheduler.h" 53 #include "platform/WebFrameScheduler.h"
49 #include "platform/loader/fetch/AccessControlStatus.h" 54 #include "platform/loader/fetch/AccessControlStatus.h"
50 #include "platform/loader/fetch/FetchParameters.h" 55 #include "platform/loader/fetch/FetchParameters.h"
51 #include "platform/loader/fetch/ResourceFetcher.h" 56 #include "platform/loader/fetch/ResourceFetcher.h"
52 #include "platform/network/mime/MIMETypeRegistry.h" 57 #include "platform/network/mime/MIMETypeRegistry.h"
53 #include "platform/weborigin/SecurityOrigin.h" 58 #include "platform/weborigin/SecurityOrigin.h"
54 #include "platform/wtf/StdLibExtras.h" 59 #include "platform/wtf/StdLibExtras.h"
55 #include "platform/wtf/text/StringBuilder.h" 60 #include "platform/wtf/text/StringBuilder.h"
56 #include "platform/wtf/text/StringHash.h" 61 #include "platform/wtf/text/StringHash.h"
57 #include "public/platform/WebCachePolicy.h" 62 #include "public/platform/WebCachePolicy.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 element_->GetDocument().GetScriptableDocumentParser()->LineNumber(); 104 element_->GetDocument().GetScriptableDocumentParser()->LineNumber();
100 } 105 }
101 } 106 }
102 107
103 ScriptLoader::~ScriptLoader() {} 108 ScriptLoader::~ScriptLoader() {}
104 109
105 DEFINE_TRACE(ScriptLoader) { 110 DEFINE_TRACE(ScriptLoader) {
106 visitor->Trace(element_); 111 visitor->Trace(element_);
107 visitor->Trace(resource_); 112 visitor->Trace(resource_);
108 visitor->Trace(pending_script_); 113 visitor->Trace(pending_script_);
114 visitor->Trace(module_tree_client_);
109 PendingScriptClient::Trace(visitor); 115 PendingScriptClient::Trace(visitor);
110 } 116 }
111 117
112 void ScriptLoader::SetFetchDocWrittenScriptDeferIdle() { 118 void ScriptLoader::SetFetchDocWrittenScriptDeferIdle() {
113 DCHECK(!created_during_document_write_); 119 DCHECK(!created_during_document_write_);
114 document_write_intervention_ = 120 document_write_intervention_ =
115 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle; 121 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle;
116 } 122 }
117 123
118 void ScriptLoader::DidNotifySubtreeInsertionsToDocument() { 124 void ScriptLoader::DidNotifySubtreeInsertionsToDocument() {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 // 5. "If the element is not connected, then abort these steps. 234 // 5. "If the element is not connected, then abort these steps.
229 // The script is not executed." 235 // The script is not executed."
230 if (!element_->IsConnected()) 236 if (!element_->IsConnected())
231 return false; 237 return false;
232 238
233 // 6. 239 // 6.
234 // TODO(hiroshige): Annotate and/or cleanup this step. 240 // TODO(hiroshige): Annotate and/or cleanup this step.
235 if (!IsScriptTypeSupported(support_legacy_types)) 241 if (!IsScriptTypeSupported(support_legacy_types))
236 return false; 242 return false;
237 243
244 // TODO(hiroshige): Make the determination of script type spec-comformant.
245 if (RuntimeEnabledFeatures::moduleScriptsEnabled() &&
246 element_->TypeAttributeValue() == "module") {
247 script_type_ = ScriptType::kModule;
248 } else {
249 script_type_ = ScriptType::kClassic;
250 }
251
238 // 7. "If was-parser-inserted is true, 252 // 7. "If was-parser-inserted is true,
239 // then flag the element as "parser-inserted" again, 253 // then flag the element as "parser-inserted" again,
240 // and set the element's "non-blocking" flag to false." 254 // and set the element's "non-blocking" flag to false."
241 if (was_parser_inserted) { 255 if (was_parser_inserted) {
242 parser_inserted_ = true; 256 parser_inserted_ = true;
243 non_blocking_ = false; 257 non_blocking_ = false;
244 } 258 }
245 259
246 // 8. "Set the element's "already started" flag." 260 // 8. "Set the element's "already started" flag."
247 already_started_ = true; 261 already_started_ = true;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 if (!parser_inserted_ || element_->AsyncAttributeValue() || 302 if (!parser_inserted_ || element_->AsyncAttributeValue() ||
289 element_->DeferAttributeValue()) 303 element_->DeferAttributeValue())
290 defer = FetchParameters::kLazyLoad; 304 defer = FetchParameters::kLazyLoad;
291 if (document_write_intervention_ == 305 if (document_write_intervention_ ==
292 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) 306 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle)
293 defer = FetchParameters::kIdleLoad; 307 defer = FetchParameters::kIdleLoad;
294 if (!FetchScript(element_->SourceAttributeValue(), encoding, defer)) 308 if (!FetchScript(element_->SourceAttributeValue(), encoding, defer))
295 return false; 309 return false;
296 } 310 }
297 311
312 // Inline module script is not yet supported.
313 if (GetScriptType() == ScriptType::kModule && !module_tree_client_) {
314 fprintf(stderr,
315 "Inline module script is not yet supported (Document URL: %s)\n",
316 element_document.Url().GetString().Utf8().Data());
317 CHECK(false);
318 }
319
298 // 22. "If the element does not have a src content attribute, 320 // 22. "If the element does not have a src content attribute,
299 // run these substeps:" 321 // run these substeps:"
300 322
301 // 22.1. "Let source text be the value of the text IDL attribute." 323 // 22.1. "Let source text be the value of the text IDL attribute."
302 // This step is done later: 324 // This step is done later:
303 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause), 325 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause),
304 // as Element::textFromChildren() in ScriptLoader::scriptContent(), 326 // as Element::textFromChildren() in ScriptLoader::scriptContent(),
305 // - in HTMLParserScriptRunner::processScriptElementInternal() 327 // - in HTMLParserScriptRunner::processScriptElementInternal()
306 // (Duplicated code of Step 23, 6th Clause), 328 // (Duplicated code of Step 23, 6th Clause),
307 // as Element::textContent(), 329 // as Element::textContent(),
308 // - in XMLDocumentParser::endElementNs() (Step 23, 5th Clause), 330 // - in XMLDocumentParser::endElementNs() (Step 23, 5th Clause),
309 // as Element::textFromChildren() in ScriptLoader::scriptContent(), 331 // as Element::textFromChildren() in ScriptLoader::scriptContent(),
310 // - PendingScript::getSource() (Indirectly used via 332 // - PendingScript::getSource() (Indirectly used via
311 // HTMLParserScriptRunner::processScriptElementInternal(), 333 // HTMLParserScriptRunner::processScriptElementInternal(),
312 // Step 23, 5th Clause), 334 // Step 23, 5th Clause),
313 // as Element::textContent(). 335 // as Element::textContent().
314 // TODO(hiroshige): Make them merged or consistent. 336 // TODO(hiroshige): Make them merged or consistent.
315 337
316 // 22.2. "Switch on the script's type:" 338 // 22.2. "Switch on the script's type:"
317 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic". 339 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic".
318 // TODO(hiroshige): Implement Step 22.2 for "module". 340 // TODO(hiroshige): Implement Step 22.2 for "module".
319 341
320 // [Intervention] 342 // [Intervention]
321 // Since the asynchronous, low priority fetch for doc.written blocked 343 // Since the asynchronous, low priority fetch for doc.written blocked
322 // script is not for execution, return early from here. Watch for its 344 // script is not for execution, return early from here. Watch for its
323 // completion to be able to remove it from the memory cache. 345 // completion to be able to remove it from the memory cache.
324 if (document_write_intervention_ == 346 if (GetScriptType() == ScriptType::kClassic &&
325 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { 347 document_write_intervention_ ==
348 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) {
326 pending_script_ = CreatePendingScript(); 349 pending_script_ = CreatePendingScript();
327 pending_script_->WatchForLoad(this); 350 pending_script_->WatchForLoad(this);
328 return true; 351 return true;
329 } 352 }
330 353
331 // 23. "Then, follow the first of the following options that describes the 354 // 23. "Then, follow the first of the following options that describes the
332 // situation:" 355 // situation:"
333 356
334 // Three flags are used to instruct the caller of prepareScript() to execute 357 // Three flags are used to instruct the caller of prepareScript() to execute
335 // a part of Step 23, when |m_willBeParserExecuted| is true: 358 // a part of Step 23, when |m_willBeParserExecuted| is true:
336 // - |m_willBeParserExecuted| 359 // - |m_willBeParserExecuted|
337 // - |m_willExecuteWhenDocumentFinishedParsing| 360 // - |m_willExecuteWhenDocumentFinishedParsing|
338 // - |m_readyToBeParserExecuted| 361 // - |m_readyToBeParserExecuted|
339 // TODO(hiroshige): Clean up the dependency. 362 // TODO(hiroshige): Clean up the dependency.
340 363
341 // 1st Clause: 364 // 1st Clause:
342 // - "If the script's type is "classic", and 365 // - "If the script's type is "classic", and
343 // the element has a src attribute, and the element has a defer attribute, 366 // the element has a src attribute, and the element has a defer attribute,
344 // and the element has been flagged as "parser-inserted", 367 // and the element has been flagged as "parser-inserted",
345 // and the element does not have an async attribute" 368 // and the element does not have an async attribute"
346 // TODO(hiroshige): Check the script's type and implement "module" case. 369 // - "If the script's type is "module",
347 if (element_->HasSourceAttribute() && element_->DeferAttributeValue() && 370 // and the element has been flagged as "parser-inserted",
348 parser_inserted_ && !element_->AsyncAttributeValue()) { 371 // and the element does not have an async attribute"
372 if ((GetScriptType() == ScriptType::kClassic &&
373 element_->HasSourceAttribute() && element_->DeferAttributeValue() &&
374 parser_inserted_ && !element_->AsyncAttributeValue()) ||
375 (GetScriptType() == ScriptType::kModule && parser_inserted_ &&
376 !element_->AsyncAttributeValue())) {
349 // This clause is implemented by the caller-side of prepareScript(): 377 // This clause is implemented by the caller-side of prepareScript():
350 // - HTMLParserScriptRunner::requestDeferredScript(), and 378 // - HTMLParserScriptRunner::requestDeferredScript(), and
351 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 379 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
352 will_execute_when_document_finished_parsing_ = true; 380 will_execute_when_document_finished_parsing_ = true;
353 will_be_parser_executed_ = true; 381 will_be_parser_executed_ = true;
354 382
355 return true; 383 return true;
356 } 384 }
357 385
358 // 2nd Clause: 386 // 2nd Clause:
359 // - "If the script's type is "classic", 387 // - "If the script's type is "classic",
360 // and the element has a src attribute, 388 // and the element has a src attribute,
361 // and the element has been flagged as "parser-inserted", 389 // and the element has been flagged as "parser-inserted",
362 // and the element does not have an async attribute" 390 // and the element does not have an async attribute"
363 // TODO(hiroshige): Check the script's type. 391 // TODO(hiroshige): Check the script's type.
364 if (element_->HasSourceAttribute() && parser_inserted_ && 392 if (GetScriptType() == ScriptType::kClassic &&
393 element_->HasSourceAttribute() && parser_inserted_ &&
365 !element_->AsyncAttributeValue()) { 394 !element_->AsyncAttributeValue()) {
366 // This clause is implemented by the caller-side of prepareScript(): 395 // This clause is implemented by the caller-side of prepareScript():
367 // - HTMLParserScriptRunner::requestParsingBlockingScript() 396 // - HTMLParserScriptRunner::requestParsingBlockingScript()
368 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 397 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
369 will_be_parser_executed_ = true; 398 will_be_parser_executed_ = true;
370 399
371 return true; 400 return true;
372 } 401 }
373 402
374 // 5th Clause: 403 // 5th Clause:
375 // TODO(hiroshige): Reorder the clauses to match the spec. 404 // TODO(hiroshige): Reorder the clauses to match the spec.
376 // - "If the element does not have a src attribute, 405 // - "If the element does not have a src attribute,
377 // and the element has been flagged as "parser-inserted", 406 // and the element has been flagged as "parser-inserted",
378 // and either the parser that created the script is an XML parser 407 // and either the parser that created the script is an XML parser
379 // or it's an HTML parser whose script nesting level is not greater than 408 // or it's an HTML parser whose script nesting level is not greater than
380 // one, 409 // one,
381 // and the Document of the HTML parser or XML parser that created 410 // and the Document of the HTML parser or XML parser that created
382 // the script element has a style sheet that is blocking scripts" 411 // the script element has a style sheet that is blocking scripts"
383 // The last part "... has a style sheet that is blocking scripts" 412 // The last part "... has a style sheet that is blocking scripts"
384 // is implemented in Document::isScriptExecutionReady(). 413 // is implemented in Document::isScriptExecutionReady().
385 // Part of the condition check is done in 414 // Part of the condition check is done in
386 // HTMLParserScriptRunner::processScriptElementInternal(). 415 // HTMLParserScriptRunner::processScriptElementInternal().
387 // TODO(hiroshige): Clean up the split condition check. 416 // TODO(hiroshige): Clean up the split condition check.
388 if (!element_->HasSourceAttribute() && parser_inserted_ && 417 // We check that the type is "classic" here, because according to the spec
418 // a "module" script doesn't reach the 5th Clause because the 4th Clause
419 // catches all "module" scripts.
420 if (GetScriptType() == ScriptType::kClassic &&
421 !element_->HasSourceAttribute() && parser_inserted_ &&
389 !element_document.IsScriptExecutionReady()) { 422 !element_document.IsScriptExecutionReady()) {
390 // The former part of this clause is 423 // The former part of this clause is
391 // implemented by the caller-side of prepareScript(): 424 // implemented by the caller-side of prepareScript():
392 // - HTMLParserScriptRunner::requestParsingBlockingScript() 425 // - HTMLParserScriptRunner::requestParsingBlockingScript()
393 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 426 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
394 will_be_parser_executed_ = true; 427 will_be_parser_executed_ = true;
395 // "Set the element's "ready to be parser-executed" flag." 428 // "Set the element's "ready to be parser-executed" flag."
396 ready_to_be_parser_executed_ = true; 429 ready_to_be_parser_executed_ = true;
397 430
398 return true; 431 return true;
399 } 432 }
400 433
401 // 3rd Clause: 434 // 3rd Clause:
402 // - "If the script's type is "classic", 435 // - "If the script's type is "classic",
403 // and the element has a src attribute, 436 // and the element has a src attribute,
404 // and the element does not have an async attribute, 437 // and the element does not have an async attribute,
405 // and the element does not have the "non-blocking" flag set" 438 // and the element does not have the "non-blocking" flag set"
439 // - "If the script's type is "module",
440 // and the element does not have an async attribute,
441 // and the element does not have the "non-blocking" flag set"
406 // TODO(hiroshige): Check the script's type and implement "module" case. 442 // TODO(hiroshige): Check the script's type and implement "module" case.
407 if (element_->HasSourceAttribute() && !element_->AsyncAttributeValue() && 443 if ((GetScriptType() == ScriptType::kClassic &&
408 !non_blocking_) { 444 element_->HasSourceAttribute() && !element_->AsyncAttributeValue() &&
445 !non_blocking_) ||
446 (GetScriptType() == ScriptType::kModule &&
447 !element_->AsyncAttributeValue() && !non_blocking_)) {
409 // "Add the element to the end of the list of scripts that will execute 448 // "Add the element to the end of the list of scripts that will execute
410 // in order as soon as possible associated with the node document of the 449 // in order as soon as possible associated with the node document of the
411 // script element at the time the prepare a script algorithm started." 450 // script element at the time the prepare a script algorithm started."
412 pending_script_ = CreatePendingScript(); 451 pending_script_ = CreatePendingScript();
413 async_exec_type_ = ScriptRunner::kInOrder; 452 async_exec_type_ = ScriptRunner::kInOrder;
414 // TODO(hiroshige): Here |contextDocument| is used as "node document" 453 // TODO(hiroshige): Here |contextDocument| is used as "node document"
415 // while Step 14 uses |elementDocument| as "node document". Fix this. 454 // while Step 14 uses |element_document| as "node document". Fix this.
416 context_document->GetScriptRunner()->QueueScriptForExecution( 455 context_document->GetScriptRunner()->QueueScriptForExecution(
417 this, async_exec_type_); 456 this, async_exec_type_);
418 // Note that watchForLoad can immediately call pendingScriptFinished. 457 // Note that watchForLoad can immediately call pendingScriptFinished.
419 pending_script_->WatchForLoad(this); 458 pending_script_->WatchForLoad(this);
420 // The part "When the script is ready..." is implemented in 459 // The part "When the script is ready..." is implemented in
421 // ScriptRunner::notifyScriptReady(). 460 // ScriptRunner::notifyScriptReady().
422 // TODO(hiroshige): Annotate it. 461 // TODO(hiroshige): Annotate it.
423 462
424 return true; 463 return true;
425 } 464 }
426 465
427 // 4th Clause: 466 // 4th Clause:
428 // - "If the script's type is "classic", and the element has a src attribute" 467 // - "If the script's type is "classic", and the element has a src attribute"
429 // TODO(hiroshige): Check the script's type and implement "module" case. 468 // - "If the script's type is "module""
430 if (element_->HasSourceAttribute()) { 469 if ((GetScriptType() == ScriptType::kClassic &&
470 element_->HasSourceAttribute()) ||
471 GetScriptType() == ScriptType::kModule) {
431 // "The element must be added to the set of scripts that will execute 472 // "The element must be added to the set of scripts that will execute
432 // as soon as possible of the node document of the script element at the 473 // as soon as possible of the node document of the script element at the
433 // time the prepare a script algorithm started." 474 // time the prepare a script algorithm started."
434 pending_script_ = CreatePendingScript(); 475 pending_script_ = CreatePendingScript();
435 async_exec_type_ = ScriptRunner::kAsync; 476 async_exec_type_ = ScriptRunner::kAsync;
436 pending_script_->StartStreamingIfPossible(&element_->GetDocument(), 477 pending_script_->StartStreamingIfPossible(&element_->GetDocument(),
437 ScriptStreamer::kAsync); 478 ScriptStreamer::kAsync);
479
438 // TODO(hiroshige): Here |contextDocument| is used as "node document" 480 // TODO(hiroshige): Here |contextDocument| is used as "node document"
439 // while Step 14 uses |elementDocument| as "node document". Fix this. 481 // while Step 14 uses |element_document| as "node document". Fix this.
440 context_document->GetScriptRunner()->QueueScriptForExecution( 482 context_document->GetScriptRunner()->QueueScriptForExecution(
441 this, async_exec_type_); 483 this, async_exec_type_);
442 // Note that watchForLoad can immediately call pendingScriptFinished. 484 // Note that watchForLoad can immediately call pendingScriptFinished.
443 pending_script_->WatchForLoad(this); 485 pending_script_->WatchForLoad(this);
444 // The part "When the script is ready..." is implemented in 486 // The part "When the script is ready..." is implemented in
445 // ScriptRunner::notifyScriptReady(). 487 // ScriptRunner::notifyScriptReady().
446 // TODO(hiroshige): Annotate it. 488 // TODO(hiroshige): Annotate it.
447 489
448 return true; 490 return true;
449 } 491 }
450 492
451 // 6th Clause: 493 // 6th Clause:
452 // - "Otherwise" 494 // - "Otherwise"
453 // "Immediately execute the script block, 495 // "Immediately execute the script block,
454 // even if other scripts are already executing." 496 // even if other scripts are already executing."
455 // Note: this block is also duplicated in 497 // Note: this block is also duplicated in
456 // HTMLParserScriptRunner::processScriptElementInternal(). 498 // HTMLParserScriptRunner::processScriptElementInternal().
457 // TODO(hiroshige): Merge the duplicated code. 499 // TODO(hiroshige): Merge the duplicated code.
458 500
459 // This clause is executed only if the script's type is "classic" 501 // This clause is executed only if the script's type is "classic"
460 // and the element doesn't have a src attribute. 502 // and the element doesn't have a src attribute.
503 DCHECK_EQ(GetScriptType(), ScriptType::kClassic);
504 DCHECK(!is_external_script_);
461 505
462 // Reset line numbering for nested writes. 506 // Reset line numbering for nested writes.
463 TextPosition position = element_document.IsInDocumentWrite() 507 TextPosition position = element_document.IsInDocumentWrite()
464 ? TextPosition() 508 ? TextPosition()
465 : script_start_position; 509 : script_start_position;
466 KURL script_url = (!element_document.IsInDocumentWrite() && parser_inserted_) 510 KURL script_url = (!element_document.IsInDocumentWrite() && parser_inserted_)
467 ? element_document.Url() 511 ? element_document.Url()
468 : KURL(); 512 : KURL();
469 513
470 if (!ExecuteScript(ClassicScript::Create( 514 if (!ExecuteScript(ClassicScript::Create(
471 ScriptSourceCode(ScriptContent(), script_url, position)))) { 515 ScriptSourceCode(ScriptContent(), script_url, position)))) {
472 DispatchErrorEvent(); 516 DispatchErrorEvent();
473 return false; 517 return false;
474 } 518 }
475 519
476 return true; 520 return true;
477 } 521 }
478 522
479 // Steps 15--21 of https://html.spec.whatwg.org/#prepare-a-script 523 // Steps 15--21 of https://html.spec.whatwg.org/#prepare-a-script
480 bool ScriptLoader::FetchScript(const String& source_url, 524 bool ScriptLoader::FetchScript(const String& source_url,
481 const String& encoding, 525 const String& encoding,
482 FetchParameters::DeferOption defer) { 526 FetchParameters::DeferOption defer) {
483 Document* element_document = &(element_->GetDocument()); 527 Document* element_document = &(element_->GetDocument());
484 if (!element_->IsConnected() || element_->GetDocument() != element_document) 528 if (!element_->IsConnected() || element_->GetDocument() != element_document)
485 return false; 529 return false;
486 530
487 DCHECK(!resource_); 531 DCHECK(!resource_);
532 DCHECK(!module_tree_client_);
533
488 // 21. "If the element has a src content attribute, run these substeps:" 534 // 21. "If the element has a src content attribute, run these substeps:"
489 if (!StripLeadingAndTrailingHTMLSpaces(source_url).IsEmpty()) { 535 if (!StripLeadingAndTrailingHTMLSpaces(source_url).IsEmpty()) {
490 // 21.4. "Parse src relative to the element's node document." 536 // 21.4. "Parse src relative to the element's node document."
491 ResourceRequest resource_request(element_document->CompleteURL(source_url)); 537 KURL url = element_document->CompleteURL(source_url);
492
493 // [Intervention]
494 if (document_write_intervention_ ==
495 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) {
496 resource_request.SetHTTPHeaderField(
497 "Intervention",
498 "<https://www.chromestatus.com/feature/5718547946799104>");
499 }
500
501 FetchParameters params(resource_request, element_->InitiatorName());
502 538
503 // 15. "Let CORS setting be the current state of the element's 539 // 15. "Let CORS setting be the current state of the element's
504 // crossorigin content attribute." 540 // crossorigin content attribute."
505 CrossOriginAttributeValue cross_origin = 541 CrossOriginAttributeValue cross_origin =
506 GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue()); 542 GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue());
507 543
508 // 16. "Let module script credentials mode be determined by switching
509 // on CORS setting:"
510 // TODO(hiroshige): Implement this step for "module".
511
512 // 21.6, "classic": "Fetch a classic script given ... CORS setting
513 // ... and encoding."
514 if (cross_origin != kCrossOriginAttributeNotSet) {
515 params.SetCrossOriginAccessControl(element_document->GetSecurityOrigin(),
516 cross_origin);
517 }
518
519 params.SetCharset(encoding);
520
521 // 17. "If the script element has a nonce attribute, 544 // 17. "If the script element has a nonce attribute,
522 // then let cryptographic nonce be that attribute's value. 545 // then let cryptographic nonce be that attribute's value.
523 // Otherwise, let cryptographic nonce be the empty string." 546 // Otherwise, let cryptographic nonce be the empty string."
547 String nonce;
524 if (element_->IsNonceableElement()) 548 if (element_->IsNonceableElement())
525 params.SetContentSecurityPolicyNonce(element_->nonce()); 549 nonce = element_->nonce();
526 550
527 // 19. "Let parser state be "parser-inserted" 551 // 19. "Let parser state be "parser-inserted"
528 // if the script element has been flagged as "parser-inserted", 552 // if the script element has been flagged as "parser-inserted",
529 // and "not parser-inserted" otherwise." 553 // and "not parser-inserted" otherwise."
530 params.SetParserDisposition(IsParserInserted() ? kParserInserted 554 ParserDisposition parser_state =
531 : kNotParserInserted); 555 IsParserInserted() ? kParserInserted : kNotParserInserted;
532
533 params.SetDefer(defer);
534
535 // 18. "If the script element has an integrity attribute,
536 // then let integrity metadata be that attribute's value.
537 // Otherwise, let integrity metadata be the empty string."
538 String integrity_attr = element_->IntegrityAttributeValue();
539 if (!integrity_attr.IsEmpty()) {
540 IntegrityMetadataSet metadata_set;
541 SubresourceIntegrity::ParseIntegrityAttribute(
542 integrity_attr, metadata_set, element_document);
543 params.SetIntegrityMetadata(metadata_set);
544 }
545 556
546 // 21.6. "Switch on the script's type:" 557 // 21.6. "Switch on the script's type:"
558 if (RuntimeEnabledFeatures::moduleScriptsEnabled() &&
559 GetScriptType() == ScriptType::kModule) {
560 // - "module":
547 561
548 // - "classic": 562 // 16. "Let module script credentials mode be determined by switching
549 // "Fetch a classic script given url, settings, cryptographic nonce, 563 // on CORS setting:"
550 // integrity metadata, parser state, CORS setting, and encoding." 564 // FOXME
551 resource_ = ScriptResource::Fetch(params, element_document->Fetcher()); 565 WebURLRequest::FetchCredentialsMode credentials_mode =
566 WebURLRequest::kFetchCredentialsModeOmit;
567 switch (cross_origin) {
568 case kCrossOriginAttributeNotSet:
569 credentials_mode = WebURLRequest::kFetchCredentialsModeOmit;
570 break;
571 case kCrossOriginAttributeAnonymous:
572 credentials_mode = WebURLRequest::kFetchCredentialsModeSameOrigin;
573 break;
574 case kCrossOriginAttributeUseCredentials:
575 credentials_mode = WebURLRequest::kFetchCredentialsModeInclude;
576 break;
577 }
552 578
553 // - "module": 579 // Step 18 is skipped because "integrity metadata" is not used
554 // "Fetch a module script graph given url, settings, "script", 580 // for module scripts.
555 // cryptographic nonce, parser state, and 581
556 // module script credentials mode." 582 // TODO(hiroshige): (How) should we reflect |defer|?
557 // TODO(kouhei, hiroshige): Implement this. 583
584 // "Fetch a module script graph given url, settings, "script",
585 // cryptographic nonce, parser state, and
586 // module script credentials mode."
587 ModuleScriptFetchRequest module_request(url, nonce, parser_state,
588 credentials_mode);
589 module_tree_client_ = ModulePendingScriptTreeClient::Create();
590 Modulator::From(ToScriptStateForMainWorld(element_document->GetFrame()))
591 ->FetchTree(module_request, module_tree_client_);
592 } else {
593 // - "classic":
594
595 // Step 16 is skipped because "module script credentials" is not used
596 // for classic scripts.
597
598 // 18. "If the script element has an integrity attribute,
599 // then let integrity metadata be that attribute's value.
600 // Otherwise, let integrity metadata be the empty string."
601 String integrity_attr = element_->IntegrityAttributeValue();
602
603 // "Fetch a classic script given url, settings, ..."
604 ResourceRequest resource_request(url);
605
606 // [Intervention]
607 if (document_write_intervention_ ==
608 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) {
609 resource_request.SetHTTPHeaderField(
610 "Intervention",
611 "<https://www.chromestatus.com/feature/5718547946799104>");
612 }
613
614 FetchParameters params(resource_request, element_->InitiatorName());
615
616 // "... cryptographic nonce, ..."
617 params.SetContentSecurityPolicyNonce(nonce);
618
619 // "... integrity metadata, ..."
620 if (!integrity_attr.IsEmpty()) {
621 IntegrityMetadataSet metadata_set;
622 SubresourceIntegrity::ParseIntegrityAttribute(
623 integrity_attr, metadata_set, element_document);
624 params.SetIntegrityMetadata(metadata_set);
625 }
626
627 // "... parser state, ..."
628 params.SetParserDisposition(parser_state);
629
630 // "... CORS setting, ..."
631 if (cross_origin != kCrossOriginAttributeNotSet) {
632 params.SetCrossOriginAccessControl(
633 element_document->GetSecurityOrigin(), cross_origin);
634 }
635
636 // "... and encoding."
637 params.SetCharset(encoding);
638
639 params.SetDefer(defer);
640
641 resource_ = ScriptResource::Fetch(params, element_document->Fetcher());
642 }
558 643
559 // "When the chosen algorithm asynchronously completes, set 644 // "When the chosen algorithm asynchronously completes, set
560 // the script's script to the result. At that time, the script is ready." 645 // the script's script to the result. At that time, the script is ready."
561 // When the script is ready, PendingScriptClient::pendingScriptFinished() 646 // When the script is ready, PendingScriptClient::pendingScriptFinished()
562 // is used as the notification, and the action to take when 647 // is used as the notification, and the action to take when
563 // the script is ready is specified later, in 648 // the script is ready is specified later, in
564 // - ScriptLoader::prepareScript(), or 649 // - ScriptLoader::prepareScript(), or
565 // - HTMLParserScriptRunner, 650 // - HTMLParserScriptRunner,
566 // depending on the conditions in Step 23 of "prepare a script". 651 // depending on the conditions in Step 23 of "prepare a script".
567 652
568 // 21.3. "Set the element's from an external file flag." 653 // 21.3. "Set the element's from an external file flag."
569 is_external_script_ = true; 654 is_external_script_ = true;
570 } 655 }
571 656
572 if (!resource_) { 657 if (GetScriptType() == ScriptType::kClassic && !resource_) {
573 // 21.2. "If src is the empty string, queue a task to 658 // 21.2. "If src is the empty string, queue a task to
574 // fire an event named error at the element, and abort these steps." 659 // fire an event named error at the element, and abort these steps."
575 // 21.5. "If the previous step failed, queue a task to 660 // 21.5. "If the previous step failed, queue a task to
576 // fire an event named error at the element, and abort these steps." 661 // fire an event named error at the element, and abort these steps."
577 // TODO(hiroshige): Make this asynchronous. 662 // TODO(hiroshige): Make this asynchronous.
578 DispatchErrorEvent(); 663 DispatchErrorEvent();
579 return false; 664 return false;
580 } 665 }
581 666
582 // [Intervention] 667 // [Intervention]
583 if (created_during_document_write_ && 668 if (GetScriptType() == ScriptType::kClassic &&
669 created_during_document_write_ &&
584 resource_->GetResourceRequest().GetCachePolicy() == 670 resource_->GetResourceRequest().GetCachePolicy() ==
585 WebCachePolicy::kReturnCacheDataDontLoad) { 671 WebCachePolicy::kReturnCacheDataDontLoad) {
586 document_write_intervention_ = 672 document_write_intervention_ =
587 DocumentWriteIntervention::kDoNotFetchDocWrittenScript; 673 DocumentWriteIntervention::kDoNotFetchDocWrittenScript;
588 } 674 }
589 675
590 return true; 676 return true;
591 } 677 }
592 678
593 PendingScript* ScriptLoader::CreatePendingScript() { 679 PendingScript* ScriptLoader::CreatePendingScript() {
594 CHECK(resource_); 680 switch (GetScriptType()) {
595 return ClassicPendingScript::Create(element_, resource_); 681 case ScriptType::kClassic:
682 CHECK(resource_);
683 return ClassicPendingScript::Create(element_, resource_);
684 case ScriptType::kModule:
685 CHECK(module_tree_client_);
686 return ModulePendingScript::Create(element_, module_tree_client_);
687 }
688 NOTREACHED();
689 return nullptr;
596 } 690 }
597 691
598 bool ScriptLoader::ExecuteScript(const Script* script) { 692 bool ScriptLoader::ExecuteScript(const Script* script) {
599 double script_exec_start_time = MonotonicallyIncreasingTime(); 693 double script_exec_start_time = MonotonicallyIncreasingTime();
600 bool result = DoExecuteScript(script); 694 bool result = DoExecuteScript(script);
601 695
602 // NOTE: we do not check m_willBeParserExecuted here, since 696 // NOTE: we do not check m_willBeParserExecuted here, since
603 // m_willBeParserExecuted is false for inline scripts, and we want to 697 // m_willBeParserExecuted is false for inline scripts, and we want to
604 // include inline script execution time as part of parser blocked script 698 // include inline script execution time as part of parser blocked script
605 // execution time. 699 // execution time.
606 if (async_exec_type_ == ScriptRunner::kNone) 700 if (async_exec_type_ == ScriptRunner::kNone)
607 DocumentParserTiming::From(element_->GetDocument()) 701 DocumentParserTiming::From(element_->GetDocument())
608 .RecordParserBlockedOnScriptExecutionDuration( 702 .RecordParserBlockedOnScriptExecutionDuration(
609 MonotonicallyIncreasingTime() - script_exec_start_time, 703 MonotonicallyIncreasingTime() - script_exec_start_time,
610 WasCreatedDuringDocumentWrite()); 704 WasCreatedDuringDocumentWrite());
611 return result; 705 return result;
612 } 706 }
613 707
614 // https://html.spec.whatwg.org/#execute-the-script-block 708 // https://html.spec.whatwg.org/#execute-the-script-block
615 // with additional support for HTML imports. 709 // with additional support for HTML imports.
616 // Note that Steps 2 and 8 must be handled by the caller of doExecuteScript(), 710 // Note that Steps 2 and 8 must be handled by the caller of doExecuteScript(),
617 // i.e. load/error events are dispatched by the caller. 711 // i.e. load/error events are dispatched by the caller.
618 // Steps 3--7 are implemented here in doExecuteScript(). 712 // Steps 3--7 are implemented here in doExecuteScript().
619 // TODO(hiroshige): Move event dispatching code to doExecuteScript(). 713 // TODO(hiroshige): Move event dispatching code to doExecuteScript().
620 bool ScriptLoader::DoExecuteScript(const Script* script) { 714 bool ScriptLoader::DoExecuteScript(const Script* script) {
621 DCHECK(already_started_); 715 DCHECK(already_started_);
716 CHECK_EQ(script->GetScriptType(), GetScriptType());
622 717
623 if (script->IsEmpty()) 718 if (script->IsEmpty())
624 return true; 719 return true;
625 720
626 Document* element_document = &(element_->GetDocument()); 721 Document* element_document = &(element_->GetDocument());
627 Document* context_document = element_document->ContextDocument(); 722 Document* context_document = element_document->ContextDocument();
628 if (!context_document) 723 if (!context_document)
629 return true; 724 return true;
630 725
631 LocalFrame* frame = context_document->GetFrame(); 726 LocalFrame* frame = context_document->GetFrame();
(...skipping 15 matching lines...) Expand all
647 script->InlineSourceTextForCSP())) { 742 script->InlineSourceTextForCSP())) {
648 return false; 743 return false;
649 } 744 }
650 } 745 }
651 746
652 if (is_external_script_) { 747 if (is_external_script_) {
653 if (!script->CheckMIMETypeBeforeRunScript( 748 if (!script->CheckMIMETypeBeforeRunScript(
654 context_document, element_->GetDocument().GetSecurityOrigin())) 749 context_document, element_->GetDocument().GetSecurityOrigin()))
655 return false; 750 return false;
656 } 751 }
752 // FOXME: In module cases, AccessControlStatus is not set or used here.
753 // Instead, it is used when module script is fetched (and compiled).
657 754
658 const bool is_imported_script = context_document != element_document; 755 const bool is_imported_script = context_document != element_document;
659 756
660 // 3. "If the script is from an external file, 757 // 3. "If the script is from an external file,
661 // or the script's type is module", 758 // or the script's type is module",
662 // then increment the ignore-destructive-writes counter of the 759 // then increment the ignore-destructive-writes counter of the
663 // script element's node document. Let neutralized doc be that Document." 760 // script element's node document. Let neutralized doc be that Document."
664 // TODO(hiroshige): Implement "module" case. 761 // TODO(hiroshige): Implement "module" case.
665 IgnoreDestructiveWriteCountIncrementer 762 IgnoreDestructiveWriteCountIncrementer
666 ignore_destructive_write_count_incrementer( 763 ignore_destructive_write_count_incrementer(
667 is_external_script_ || is_imported_script ? context_document : 0); 764 is_external_script_ ||
765 script->GetScriptType() == ScriptType::kModule ||
766 is_imported_script
767 ? context_document
768 : 0);
668 769
669 // 4. "Let old script element be the value to which the script element's 770 // 4. "Let old script element be the value to which the script element's
670 // node document's currentScript object was most recently set." 771 // node document's currentScript object was most recently set."
671 // This is implemented as push/popCurrentScript(). 772 // This is implemented as push/popCurrentScript().
672 773
673 // 5. "Switch on the script's type:" 774 // 5. "Switch on the script's type:"
674 // - "classic": 775 // - "classic":
675 // 1. "If the script element's root is not a shadow root, 776 // 1. "If the script element's root is not a shadow root,
676 // then set the script element's node document's currentScript 777 // then set the script element's node document's currentScript
677 // attribute to the script element. Otherwise, set it to null." 778 // attribute to the script element. Otherwise, set it to null."
678 context_document->PushCurrentScript(element_.Get()); 779 // - "module":
780 // 1. "Set the script element's node document's currentScript attribute
781 // to null."
782 ScriptElementBase* current_script = nullptr;
783 if (script->GetScriptType() == ScriptType::kClassic)
784 current_script = element_;
785 context_document->PushCurrentScript(current_script);
679 786
787 // - "classic":
680 // 2. "Run the classic script given by the script's script." 788 // 2. "Run the classic script given by the script's script."
681 // Note: This is where the script is compiled and actually executed. 789 // Note: This is where the script is compiled and actually executed.
790 // - "module":
791 // 2. "Run the module script given by the script's script."
682 script->RunScript(frame, element_->GetDocument().GetSecurityOrigin()); 792 script->RunScript(frame, element_->GetDocument().GetSecurityOrigin());
683 793
684 // - "module":
685 // TODO(hiroshige): Implement this.
686
687 // 6. "Set the script element's node document's currentScript attribute 794 // 6. "Set the script element's node document's currentScript attribute
688 // to old script element." 795 // to old script element."
689 context_document->PopCurrentScript(element_.Get()); 796 context_document->PopCurrentScript(current_script);
690 797
691 return true; 798 return true;
692 799
693 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc, 800 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc,
694 // if it was incremented in the earlier step." 801 // if it was incremented in the earlier step."
695 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer. 802 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer.
696 } 803 }
697 804
698 void ScriptLoader::Execute() { 805 void ScriptLoader::Execute() {
699 DCHECK(!will_be_parser_executed_); 806 DCHECK(!will_be_parser_executed_);
700 DCHECK(async_exec_type_ != ScriptRunner::kNone); 807 DCHECK(async_exec_type_ != ScriptRunner::kNone);
701 DCHECK(pending_script_->IsExternal()); 808 DCHECK(pending_script_->IsExternal());
702 bool error_occurred = false; 809 bool error_occurred = false;
703 Script* script = pending_script_->GetSource(KURL(), error_occurred); 810 Script* script = pending_script_->GetSource(KURL(), error_occurred);
704 const bool wasCanceled = pending_script_->WasCanceled(); 811 const bool was_canceled = pending_script_->WasCanceled();
705 DetachPendingScript(); 812 DetachPendingScript();
706 if (error_occurred) { 813 if (error_occurred) {
707 DispatchErrorEvent(); 814 DispatchErrorEvent();
708 } else if (!wasCanceled) { 815 } else if (!was_canceled) {
709 if (ExecuteScript(script)) 816 if (ExecuteScript(script))
710 DispatchLoadEvent(); 817 DispatchLoadEvent();
711 else 818 else
712 DispatchErrorEvent(); 819 DispatchErrorEvent();
713 } 820 }
714 resource_ = nullptr; 821 resource_ = nullptr;
822 module_tree_client_ = nullptr;
715 } 823 }
716 824
717 void ScriptLoader::PendingScriptFinished(PendingScript* pending_script) { 825 void ScriptLoader::PendingScriptFinished(PendingScript* pending_script) {
718 DCHECK(!will_be_parser_executed_); 826 DCHECK(!will_be_parser_executed_);
719 DCHECK_EQ(pending_script_, pending_script); 827 DCHECK_EQ(pending_script_, pending_script);
828 DCHECK_EQ(pending_script_->GetScriptType(), GetScriptType());
720 829
721 // We do not need this script in the memory cache. The primary goals of 830 // We do not need this script in the memory cache. The primary goals of
722 // sending this fetch request are to let the third party server know 831 // sending this fetch request are to let the third party server know
723 // about the document.write scripts intervention and populate the http 832 // about the document.write scripts intervention and populate the http
724 // cache for subsequent uses. 833 // cache for subsequent uses.
725 if (document_write_intervention_ == 834 if (document_write_intervention_ ==
726 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { 835 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) {
727 DCHECK_EQ(pending_script_->GetScriptType(), ScriptType::kClassic); 836 DCHECK_EQ(pending_script_->GetScriptType(), ScriptType::kClassic);
728 pending_script_->RemoveFromMemoryCache(); 837 pending_script_->RemoveFromMemoryCache();
729 pending_script_->StopWatchingForLoad(); 838 pending_script_->StopWatchingForLoad();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 // then abort these steps at this point. The script is not executed. 890 // then abort these steps at this point. The script is not executed.
782 return DeprecatedEqualIgnoringCase(event_attribute, "onload") || 891 return DeprecatedEqualIgnoringCase(event_attribute, "onload") ||
783 DeprecatedEqualIgnoringCase(event_attribute, "onload()"); 892 DeprecatedEqualIgnoringCase(event_attribute, "onload()");
784 } 893 }
785 894
786 String ScriptLoader::ScriptContent() const { 895 String ScriptLoader::ScriptContent() const {
787 return element_->TextFromChildren(); 896 return element_->TextFromChildren();
788 } 897 }
789 898
790 } // namespace blink 899 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698