/
803.txt
2167 lines (1780 loc) · 113 KB
/
803.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
[FIG(pull-quote)[
>
[512] [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[闇は深い]]。
[FIGCAPTION[
或る [[Web開発者]]曰く
]FIGCAPTION]
]FIG]
[1] [[HTML]] の [DFN[[CODE(HTMLe)@en[[[script]]]]]] [[要素]]は、動的な[[スクリプト]]や、
[[スクリプト]]が使うデータを[[文書]]に埋め込むものです。
* 仕様書
[REFS[
- [130] '''[CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2016-02-16 01:30:20 +09:00]] 版) <https://html.spec.whatwg.org/#the-script-element>'''
- [413] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2016-02-21 07:50:23 +09:00]] 版) <https://html.spec.whatwg.org/#scriptTag>
- [419] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2016-02-21 07:50:23 +09:00]] 版) <https://html.spec.whatwg.org/#parsing-main-incdata>
- [422] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2016-02-21 07:50:23 +09:00]] 版) <https://html.spec.whatwg.org/#scriptEndTag>
- [427] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2016-02-21 07:50:23 +09:00]] 版) <https://html.spec.whatwg.org/#scriptForeignEndTag>
- [424] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2016-02-21 07:50:23 +09:00]] 版) <https://html.spec.whatwg.org/#scriptTagXML>
- [482] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2016-02-21 07:50:23 +09:00]] 版) <https://html.spec.whatwg.org/#stop-parsing>
- [503] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2016-02-21 07:50:23 +09:00]] 版) <https://html.spec.whatwg.org/#HTMLScriptElement-partial>
]REFS]
* 意味
[131] [CODE(HTMLe)@en[[[script]]]] [[要素]]は、動的な[[スクリプト]]や、データブロックを[[文書]]に含めるために使うことができます。
[SRC[>>130]]
;; [134] どちらであるかは [CODE(HTMLa)@en[[[type]]]] [[属性]]や [CODE(HTMLa)@en[[[language]]]]
[[属性]]によって決まります。 [CODE(HTML)@en[[[<script type>]]]] を参照。
[132] [CODE(HTMLe)@en[[[script]]]] [[要素]]は[[利用者]]に対する[[内容]]を[[表現]]していません。 [SRC[>>130]]
[186] [CODE(HTMLe)@en[[[script]]]] [[要素]]は、次の通り分類されています。
[FIG(short list)[
- [[メタデータ内容]] [SRC[>>130]]
- [[フロー内容]] [SRC[>>130]]
- [[語句内容]] [SRC[>>130]]
- [[スクリプト支援要素]] [SRC[>>130]]
]FIG]
* 構文
[188] [[開始タグ]]も[[終了タグ]]も[[必須]]であり、省略できません [SRC[>>130]]。
* 文脈
[14] [CODE(HTMLe)@en[[[script]]]] [[要素]]は、
[[フロー内容]]、[[語句内容]]、[[スクリプト支援要素]]のいずれかが求められる場面で使うことができます
[SRC[>>130]]。つまり [[HTML文書]]のほとんどあらゆる場所で使うことができます。
[HISTORY[
[187] [[HTML4]] 時代も大部分で使うことが認められていました [SRC[HTML 4 18.2.1]]
が、 [[HTML5]] で更に制約が緩和され、[[構文解析器]]等の都合で困難な場面を除き、
ほとんどすべての場面で使えるようになりました。
]HISTORY]
* 属性
[9] 次の[[属性]]があります。
[FIG(short list)[
- [[大域属性]]
- [CODE(HTMLa)@en[[[async]]]]
- [CODE(HTMLa)@en[[[charset]]]]
- [CODE(HTMLa)@en[[[crossorigin]]]]
- [CODE(HTMLa)@en[[[defer]]]]
- [CODE(HTMLa)@en[[[nonce]]]]
- [CODE(HTMLa)@en[[[src]]]]
- [CODE(HTMLa)@en[[[type]]]]
]FIG]
;; [135] [CODE(HTML)@en[[[<script type>]]]] 依存の制約もあります (そちらの項を参照)。
[HISTORY[
[189] 他に次の歴史的な[[属性]]があります。
[FIG(list short)[
,[CODE(HTMLa)[[[archive]]]] , , ,[NC4]
,[CODE(HTMLa)[[[classname]]]] ,[[逆ドメイン名]] , ,級名 ,[ECMA-290]
- [CODE(HTMLa)[[[event]]]]
- [CODE(HTMLa)[[[for]]]]
- [CODE(HTMLa)[[[language]]]]
- [CODE(HTMLa)@en[x-mojo-version]]
- [CODE(HTMLa)[name]]
- [CODE(HTMLa)@en[pagespeed_no_defer]]
,[CODE(HTMLa)[[[purpose]]]] , , ,実行目的 ,[ECMA-290]
- [CODE(XMLa)[[[[VAR[ev:]]event]]]]
- [CODE(XMLa)[[[[VAR[ev:]]observer]]]]
- [CODE(XMLa)[[[[VAR[ev:]]phase]]]]
- [CODE(XMLa)[[[[VAR[ev:]]propagate]]]]
- [CODE(XMLa)[[[[VAR[ev:]]target]]]]
]FIG]
]HISTORY]
[249] [CODE(HTMLa)@en[[[async]]]] [[属性]]や [CODE(HTMLa)@en[[[src]]]]
[[属性]]については[[属性が追加]]された時の処理が規定されています。
[500] [[属性]]の有無と[[構文解析器]]によって作成されたか [[DOM]]
[[メソッド]]で作成されたかにより、[[スクリプト]]の実行のタイミングは次のように変化します。
[FIG(table)[
:e: [[要素]]
:timing: 実行時機
:order: 相対的順序保存
:pause parser: 構文解析器中断
:c: >>360
:e: [CODE(HTML)@en[<script>]]
:order: はい
:pause parser: はい
:timing: 挿入直後・妨害条件解消後の遅い方
:c: 己、戊
:e: [CODE(HTML)@en[<script src>]]
:order: はい
:pause parser: はい
:timing: [[fetch]] 直後・妨害条件解消後の遅い方
:c: 乙
:e: [CODE(HTML)@en[<script src defer>]]
:order: はい
:timing: 構文解析終了直後・[[fetch]] 直後・妨害条件解消後の遅い方
:c: 甲
:e: [CODE(HTML)@en[<script src async>]]
:timing: [[fetch]] 直後
:c: 丁
:e: [CODE(HTML)@en[<script type=module>]]
:order: はい
:timing: 構文解析終了直後・妨害条件解消後の遅い方
:c: 甲
:e: [CODE(HTML)@en[<script type=module async>]]
:timing: [[fetch]] 直後
:c: 丁
:e: [CODE(HTML)@en[<script type=module src>]]
:order: はい
:timing: 構文解析終了直後・[[fetch]] 直後・妨害条件解消後の遅い方
:c: 甲
:e: [CODE(HTML)@en[<script type=module src async>]]
:timing: [[fetch]] 直後
:c: 丁
:e: [CODE(JS)@en[s = document.createElement ('script')]]
:order: はい
:timing: 挿入直後・妨害条件解消後の遅い方
:c: 己
:e: [CODE(JS)@en[s = document.createElement ('script'); s.src = ...]]
:timing: [[fetch]] 直後
:c: 丁
:e: [CODE(JS)@en[s = document.createElement ('script'); s.async = false; s.src = ...]]
:timing: [[fetch]] 直後・妨害条件解消後の遅い方
:order: はい
:c: 丙
:e: [CODE(JS)@en[s = document.createElement ('script'); s.async = true; s.src = ...]]
:timing: [[fetch]] 直後
:c: 丁
:e: [CODE(JS)@en[s = document.createElement ('script'); s.type = 'module']]
:timing: 妨害条件解消後
:c: 丁
:e: [CODE(JS)@en[s = document.createElement ('script'); s.type = 'module'; s.src = ...]]
:timing: [[fetch]] 直後
:c: 丁
:e: [CODE(JS)@en[s = document.createElement ('script'); s.type = 'module'; s.async = false; s.src = ...]]
:order: はい
:timing: [[fetch]] 直後・妨害条件解消後の遅い方
:c: 丙
:e: [CODE(JS)@en[s = document.createElement ('script'); s.type = 'module'; s.async = true; s.src = ...]]
:timing: [[fetch]] 直後
:c: 丁
]FIG]
* 内容
[194] [CODE(HTMLe)@en[[[script]]]] [[要素]]の種別が[[古典スクリプト]]や[[モジュールスクリプト]]の場合は、
[CODE(HTMLa)@en[[[src]]]] [[属性]]を使って外部スクリプト資源を指定することもできますし、
[[内容]]として直接埋め込むこともできます [SRC[>>130]]。
;; [CODE(HTML)@en[[[<script src>]]]] も参照。
[137] [CODE(HTMLe)@en[[[script]]]] [[要素]]の種別が[[データブロック]]の時は、
[[内容]]として直接埋め込まなければ[['''なりません''']] [SRC[>>130]]。
;; [133] [CODE(HTMLe)@en[[[script]]]] [[要素]]の種別については [CODE(HTML)@en[[[<script type>]]]] を参照。
** 言語依存の制約
[193] [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[内容]]が[[古典スクリプト]]や[[モジュールスクリプト]]を表しているときは、
それぞれ [[JavaScript]] の [CODE[[[Script]]]] や [CODE[[[Module]]]]
の制約に従わなければ[['''なりません''']] [SRC[>>130]]。
[HISTORY[
[192] かつては次のような若干曖昧な規定でした。
[150] [[HTML Standard]] は共通の制約以外には [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[内容]]について制約を課しておらず、
[CODE(HTMLa)@en[[[type]]]] (と [CODE(HTMLa)@en[[[language]]]]) によって決定される[[言語]]の仕様による制限に適合しなければならないとしています。
[151] ただし実際にはそのような制約を明示している仕様はありません。
[152] [[HTML Standard]] によれば、 [CODE(HTMLe)@en[[[script]]]] [[要素]]で [CODE(HTMLa)@en[[[src]]]]
[[属性]]がない場合、 [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[内容]]は
- [153] [[XML]] ベースの[[言語]]であれば[[子供]]を
- [154] テキストベースの[[言語]]であれば[[子供]]の[[テキスト節点]]を
... 使うことになっています。ここから推測すると、
- [155] [[XML]] ベースの[[言語]]であれば、 [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[内容]]がその [[XML]]
[[言語]]の[[要素]]や[[テキスト]]
- [156] テキストベースの[[言語]]であればその[[言語]]によって記述された[[テキスト]]のみで、
[[要素]]は使用してはいけない
... という風に解釈するのが妥当でしょう。
[157] ただし [[HTML]] 構文では [CODE(HTMLe)@en[[[script]]]]
[[要素]]の構文解析直後の状態は常に[[テキスト節点]]を高々1つだけ含んだ状態になります。[[要素]]を[[子供]]にするためには
[[XML]] 構文を使うか[[スクリプト]]で挿入するしかありません。そのため、データブロックとして [[XML]]
ベースのデータが [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[内容]]に埋め込まれることがありますが、
[[XML]] のソースを[[テキスト節点]]として含んだ状態になってしまいます。
]HISTORY]
[139] [CODE(HTMLe)@en[[[script]]]] [[要素]]の種別が[[データブロック]]の時は、
[CODE(HTMLa)@en[[[type]]]] [[属性]]で指定された書式の要件に従わなければ[['''なりません''']] [SRC[>>130]]。
** 外部スクリプトについてのドキュメントの制約
[142] [CODE(HTMLa)@en[[[src]]]] [[属性]]が指定されている場合、 [CODE(HTMLe)@en[[[script]]]]
[[要素]]の[[内容]]は外部の[[スクリプト]]についての[[ドキュメント]]とみなされます。
[[スクリプト]]として実行はされません。この場合には、 ([[スクリプト言語]]に関わらず)
次のものだけを使わなければならないという制約が課されます (空でも構いません) [SRC[>>130]]。
[FIG[
- [145] [CODE(charname)@en[[[SPACE]]]]
- [146] [CODE(char)@en[[[U+0009]]]]
- [147] [CODE(charname)@en[[[LF]]]]
- [148] [[JavaScript]] の行内コメント [CODE[/* ... */]]
- [149] [[JavaScript]] の一行コメント [CODE[[[//]] ... [[LF]]]]
-- 末尾に[[改行]]が必要です。
]FIG]
** 共通の制約
[140] [CODE(HTMLe)@en[[[script]]]] [[要素]]の [CODE(DOMa)@en[[[textContent]]]] は次の要件を満たさなければ[['''なりません''']]
[SRC[>>130]]。
[FIG[
- [143] [CODE[[[<!--]]]] があると、それに対応する [CODE[[[-->]]]] が必要です。
- [144] [CODE[[[<!--]]]] と [CODE[[[-->]]]] の間には他の [CODE[[[-->]]]] や
[CODE[<script]] ([[大文字]]または[[小文字]]) の後に[[空白文字]]や [CODE[[[/]]]] や [CODE[[[>]]]]
が続く文字列が入ってはいけません。
]FIG]
[141] [[HTML]] の[[構文解析器]]は [CODE(HTMLe)@en[[[script]]]] [[要素]]内において [CODE[[[<!--]]]]
と [CODE[[[-->]]]] の対応関係や [CODE[<script>]] と [CODE[</script>]]
の対応関係を考慮して複雑な解釈を行います。それに反して [[HTML]] として[[直列化]]できない値や混乱を招くものを禁止するために
>>140 のような規定があります。
*** 擬似注釈宣言の使用
[18] [CODE(HTMLe)[script]] 要素に対応していない古い WWW ブラウザは、
[CODE(HTMLe)[script]] 要素内の[[文字データ]]も構わず解釈してしまいます。
そこで、 [CODE(HTMLe)[script]] 要素の内容としてスクリプトを記述するときには、
HTML の[[注釈宣言]]のように最初に [CODE(HTML)[<!--]] を、
最後に [CODE(HTML)[-->]] をつけることが慣習となっています。
HTML 4 によれば、これは HTML の機能ではなく、[[スクリプト機関]]の機能とされています。
この機能に対応している言語には [[JavaScript]], [[VBScript]], [[Tcl]]
があるようです。 [SRC[HTML 4 18.3.2]] より正確には、この3つの言語は
[CODE(HTMLe)[script]] 要素の内容の一番最初の非[[空白]]文字列が
[CODE[<!--]] であるとき、これを無視するらしいです。
最後の [CODE[-->]] は、3つの言語のいずれも、それだけで書くことはできず、
それぞれの言語の注釈の内容として (JavaScript の場合は [SAMP(JS)[// -->]]
のようにして) 書くことが必要らしいです。
[Q[らしい]]というのは、正確にこれを規定した仕様がないからです。
HTML 4 は[Q[スクリプト機関]]によるものだと言っていますから、
スクリプト言語の言語仕様かなにかに規定があってもよさそうなものですが、
そのようなものは見たことがありません。また、 HTML
に直接埋め込まれていない [[ECMAScript]] のスクリプトのソース・コードに
[CODE[<!--]] という文字列があってもよいという話も聞きません。
([CODE(HTMLe)[[[style]]]] 要素も同じような事情ですが、こちらは
[[CSS2]] で言語仕様の一部としてきちんと定義されています。)
[42] 少なくても [[JavaScript]] では、
最初の [SAMP[<!--]] が含まれる行の行末までを無視するのが
Web ブラウザの普通の実装のようです。
[27] このような注釈宣言 (のようなもの) の中では、 (SGML
的には [CODE(SGML)[CDATA]] なので注釈宣言ではないとはいえ、
古い UA の立場からしても SGML 的に正当であるために) [CODE(SGML)[[[COM]]]]
([CODE(HTML)[--]]) を含めるべきではないと考える人もいます。
[19] なお、 XHTML 1 の [CODE(HTMLe)[script]] 要素は、 [CODE(SGML)[CDATA]]
ではありませんので、注釈宣言 (のようなもの) を書くと、
本当に XML の注釈宣言と解釈されてしまいます。当然、
スクリプトとして解釈・実行されることはありません。
[40] [CODE(HTMLe)[script]] 要素が使われ始めたばかりの1996年ごろまでは、
注釈宣言 (のようなもの) の閉じの前に
[PRE(HTML)[
<script language="javascript">
<!-- hide script from old browsers
[VAR[...]]
// hide script from old browsers -->
</script>
]PRE]
のように自然言語の注釈を入れておくことがよく行われていました
(初期の使用例にそう載っていたからみんなで真似したのでしょう)。
(この例のように開き (のようなもの) の後に書くこともできましたが、
閉じの前に書くのが普通だったと記憶しております。)
後にこのような冗長なことはせず、
[PRE(HTML)[
<script language="javascript">
<!--
[VAR[...]]
//-->
</script>
]PRE]
のように簡単に書くようになりました。
[35] また、[Q[裏技]]的なものとして、
[PRE(HTML)[
<script language="javascript">
<!--
[VAR[...]]
// -->スクリプトに対応していません。<!--
[VAR[...]]
// -->
</script>
]PRE]
のような書き方が紹介されることもありました。
(この例のようになぜかスクリプトの途中に書いているものもあれば、
注釈宣言 (のようなもの) の前後に書いているものもありました。
どこに入れるにせよ、書く内容は一行にするか、
うまくして行頭にスクリプト言語の注釈導入子が来るように調整することが重要です。
また、 [CODE(SGML)[[[etago]]]] が使えないことにも注意が必要です。)
[38] スクリプト言語の演算子として [CODE[>]] を使うことが良くありますが、
古いブラウザの中には注釈宣言を [CODE[>]] で終えてしまうものがあることが知られています。
[SAMP(JS)[[VAR[x]] > [VAR[y]]]] のような式は [SAMP(JS)[[VAR[y]] < [VAR[x]]]]
と書くことで回避できます。 [SRC[HTML 4 18.3.2 Note]]
もっとも、そのようなブラウザは HTML 4 の時点でも骨董品ですし、
HTML 4 も特にそうするべきだなどとは言っていません。
参考文献:
- [16] [CITE[<SCRIPT>〜</SCRIPT> 内の要素はすべてコメントで囲んだ方が安全です。]]
<http://openlab.ring.gr.jp/k16/htmllint/explain.html#comment-element>
誤って「[CODE(JS)@en[//->]]」のようなもので終わることもあるみたいです。
* 適合性検査
[136] [CODE(HTMLe)@en[[[script]]]] [[要素]][VAR[要素]]の[[属性]]と[[内容]]の[[適合性]]の検査は、
次のように行えます。
[FIG(steps)[
= [292] [VAR[元の型]]を、[VAR[要素]]の [CODE(HTMLa)@en[[[type]]]] [[属性値]]に設定します。
= [138] [VAR[型]]を、[VAR[要素]]の[[スクリプトブロックの型文字列]]に設定します。
= [195] [VAR[型]]により、
[FIG(switch)[
:[223] [[JavaScript MIME型]]のいずれか ([[ASCII大文字・小文字不区別]]):
[FIG(steps)[
= [224] [VAR[検査]]を、「[CODE[[[Script]]]] としての検査」に設定します。
= [207] [VAR[元の型]]が[[空文字列]]なら、
== [220] 不適合であると報告します。
= [225] それ以外で、[VAR[元の型]]が null でなければ、
== [234] 原則として不適合であると報告します。
= [226] [VAR[要素]]に [CODE(HTMLa)@en[[[async]]]] [[属性]]と
[CODE(HTMLa)@en[[[defer]]]] [[属性]]の両方があれば、
警告します。
= [484] [VAR[要素]]に [CODE(HTMLa)@en[[[defer]]]] [[属性]]があって
[CODE(HTMLa)@en[[[src]]]] [[属性]]がなければ、警告します。
= [499] [VAR[要素]]に [CODE(HTMLa)@en[[[async]]]] [[属性]]があって
[CODE(HTMLa)@en[[[src]]]] [[属性]]がなければ、警告します。
= [219] [VAR[要素]]に [CODE(HTMLa)@en[[[crossorigin]]]] [[属性]]があって
[CODE(HTMLa)@en[[[src]]]] [[属性]]がなければ、警告します。
= [218] [VAR[要素]]に [CODE(HTMLa)@en[[[charset]]]] [[属性]]があって
[CODE(HTMLa)@en[[[src]]]] [[属性]]がなければ、不適合を報告します。
]FIG]
:[196] [CODE[[[module]]]] ([[ASCII大文字・小文字不区別]]):
[FIG(steps)[
= [293] [VAR[元の型]]が [CODE[[[module]]]] ([[ASCII大文字・小文字不区別]])
でなければ、不適合を報告します。
= [221] [VAR[検査]]を、「[CODE[[[Module]]]] としての検査」に設定します。
= [198] [VAR[要素]]に [F[[CODE(HTMLa)@en[[[charset]]]] [[属性]]]]があれば、不適合を報告します。
= [199] [VAR[要素]]に [F[[CODE(HTMLa)@en[[[defer]]]] [[属性]]]]があれば、不適合を報告します。
]FIG]
:[197] それ以外:
[FIG(steps)[
= [222] [VAR[検査]]を、[VAR[型]]によって決まる検査 (なければ null) に設定します。
= [202] [VAR[要素]]に [F[[CODE(HTMLa)@en[[[async]]]] [[属性]]]]があれば、不適合を報告します。
= [200] [VAR[要素]]に [F[[CODE(HTMLa)@en[[[charset]]]] [[属性]]]]があれば、不適合を報告します。
= [204] [VAR[要素]]に [F[[CODE(HTMLa)@en[[[crossorigin]]]] [[属性]]]]があれば、不適合を報告します。
= [201] [VAR[要素]]に [F[[CODE(HTMLa)@en[[[defer]]]] [[属性]]]]があれば、不適合を報告します。
= [205] [VAR[要素]]に [F[[CODE(HTMLa)@en[[[nonce]]]] [[属性]]]]があれば、不適合を報告します。
= [203] [VAR[要素]]に [F[[CODE(HTMLa)@en[[[src]]]] [[属性]]]]があれば、不適合を報告します。
= [206] [VAR[型]]が[[妥当なMIME型]]であるか検査します。
= [235] [VAR[型]]の[F[[[引数]]]]を無視すると [[JavaScript MIME型]]になるなら、警告します。
= [236] [VAR[型]]がかつて[[スクリプト言語]]に用いられた値なら、警告します。
]FIG]
]FIG]
= [211] [VAR[要素]]に [CODE(HTMLa)@en[[[async]]]] [[属性]]があれば、検査します。
= [215] [VAR[要素]]に [CODE(HTMLa)@en[[[charset]]]] [[属性]]があれば、検査します。
= [212] [VAR[要素]]に [CODE(HTMLa)@en[[[crossorigin]]]] [[属性]]があれば、検査します。
= [216] [VAR[要素]]に [CODE(HTMLa)@en[[[defer]]]] [[属性]]があれば、検査します。
= [213] [VAR[要素]]に [CODE(HTMLa)@en[[[nonce]]]] [[属性]]があれば、検査します。
= [210] [VAR[要素]]に [CODE(HTMLa)@en[[[src]]]] [[属性]]があれば、検査します。
= [504] [VAR[要素]]に [CODE(HTMLa)@en[[[language]]]] [[属性]]があれば、
== [506] [VAR[要素]]の [CODE(HTMLa)@en[[[language]]]] [[属性値]]が
[[ASCII大文字・小文字不区別]]で [CODE[[[javascript]]]] と一致するなら、
=== [505] [VAR[元の型]]が null か [CODE(MIME)@en[[[text/javascript]]]]
([[ASCII大文字・小文字不区別]]) なら、
==== [509] [[obsolete but conforming]] を報告します。
=== [510] それ以外なら、
==== [511] 不適合を報告します。
== [507] それ以外なら、
=== [508] 不適合を報告します。
= [209] [VAR[要素]]の[F[[[属性]]リスト]]のうち、以上で検査していない[[属性]]を検査します。
= [244] [VAR[要素]]の[[内容]]の共通の制約を検査します。
= [214] [VAR[要素]]に [F[[CODE(HTMLa)@en[[[src]]]] [[属性]]]]があれば、
== [245] [VAR[要素]]の[F[[[内容]]]]のドキュメント制約を検査します。
= [208] [VAR[検査]]の値により、
[FIG(switch)[
:[233] null:
[FIG(steps)[
= [228] 検査不能を報告します。
]FIG]
:[227] 「[CODE[[[Script]]]] として検査」か「[CODE[[[Module]]]] として検査」:
[FIG(steps)[
= [237] [VAR[要素]]に [F[[CODE(HTMLa)@en[[[src]]]] [[属性]]]]があれば、
== [239] [[古典スクリプトのfetch]]を実行します。
[VAR[URL]] を[VAR[要素]]の [CODE(DOMa)@en[[[src]]]] [[IDL属性]]の値、
[VAR[CORS設定群]]を[VAR[要素]]の [CODE(DOMa)@en[[[crossorigin]]]] [[属性値]]、
[VAR[文字符号化]]を[VAR[要素]]の [CODE(DOMa)@en[[[charset]]]] [[属性値]]とします。
[VAR[続きの処理]]は、[VAR[スクリプト]]についての次のような処理とします。
=== [240] [VAR[スクリプト]]の[F[[[ソーステキスト]]]]について、[VAR[検査]]を実行します。
=== [243] [VAR[charset]] を、 [VAR[スクリプト]]の生成に使われた[[応答]]の
[F[[[Content-Typeメタデータ]]]]の[F[[CODE(MIME)@en[[[charset]]]]]]に設定します。
=== [241] [VAR[charset]] があり、[VAR[要素]]の [CODE(DOMa)@en[[[charset]]]] [[属性]]もある場合、
==== [242] [VAR[charset]] と[VAR[要素]]の [CODE(DOMa)@en[[[charset]]]] [[属性]]とどちらも同じ[[符号化]]の[[ラベル]]であるか検査します。
= [238] それ以外なら、
== [229] [VAR[ソーステキスト]]を、[VAR[要素]]の [F[[CODE(DOMa)@en[[[text]]]] [[IDL属性]]の値]]に設定します。
== [230] [VAR[ソーステキスト]]について、[VAR[検査]]を実行します。
]FIG]
:[231] それ以外:
[FIG(steps)[
= [232] [VAR[要素]]について、[VAR[検査]]を実行します。
]FIG]
]FIG]
]FIG]
* 状態
[246] [[HTML要素]]の状態に加えて、次の状態を持ちます。
[FIG(list members)[
: [F[[DFN[[RUBYB[「開始済み」]@en["already started"]]]]フラグ]] :
[[スクリプト]]が実行開始されたかどうかを表します。
初期状態では未設定です [SRC[>>130]]。
実行された場合の他に、
[[内容]]の処理中に[[構文解析器]]が [[EOF]] に遭遇した時や、
[[素片構文解析アルゴリズム]]の実行中の時 ([CODE(DOMa)@en[[[innerHTML]]]] 等の時)
にも設定されます。
: [F[「構文解析器挿入」フラグ]] :
[[構文解析器]]が挿入した [CODE(HTMLe)@en[[[script]]]] [[要素]]に設定されます。
初期状態では未設定です [SRC[>>130]]。
: [F[[DFN[[RUBYB[「非ブロッキング」]@en["non-blocking"]]]]フラグ]] :
他の [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[スクリプト]]の実行との相対的な順序が保存されるべき
(ブロッキング) か否か (非ブロッキング) の判断に使われるフラグです。
初期状態では設定され [SRC[>>130]]、
[CODE(HTMLa)@en[[[async]]]] [[内容属性]]が操作されると消去されます。
: [F[[DFN[[RUBYB[「構文解析器実行準備完了」]@en["ready to be parser-executed"]]]]フラグ]] :
初期状態では未設定です [SRC[>>130]]。
: [F[[[スクリプトの型]]]] :
[[古典スクリプト]]と[[モジュールスクリプト]]の別を表します。
初期状態では未設定です [SRC[>>130]]。
: [F[[DFN[[RUBYB[外部ファイルから]@en[from an external file]]]]]] [SRC[>>130]] :
[[外部スクリプト]]かどうかを表します。
: [F[[DFN[[RUBYB[スクリプトのスクリプト]@en[the script's script]]]]]] [SRC[>>130]] :
[CODE(HTMLe)@en[[[script]]]] [[要素]]から得た[[スクリプト]]です。
: [F[[[スクリプトの準備完了]]]] :
[[スクリプトのfetch]]の完了を表します。
それまで[[loadイベントが遅延]]されます。
: [F[準備完了フラグ]] : >>371 で利用されます。
: 作成した構文解析器 :
本[[要素]]を作成した[[構文解析器]]。[[スクリプトの準備]]で参照されます。
[[構文解析器 (Web)]] も参照。
]FIG]
[HISTORY[
[183] かつては次の状態がありました。
[FIG(short list)[
- [F[[[スクリプトブロックの型]]]]
]FIG]
]HISTORY]
* 処理
[477] [CODE(HTMLe)@en[[[script]]]] [[要素]]の処理は、 [[HTML要素]]の中でもトップレベルに複雑です。
[[イベントループ]]はもちろん、
[[構文解析器]]とも密結合しています。
[412] [[要素]]の作成時点で、作成方法により、次のように各フラグが設定されます。
[FIG(table)[
:create: 作成方法
:parser-inserted: [[「構文解析器挿入」]]
:already started: [[「開始済み」]]
:non-blocking: [[「非ブロッキング」]]
:execute: スクリプト実行
:create: [CODE(DOMm)@en[[[createElement]]]], [CODE(DOMm)@en[[[createElementNS]]]]
:parser-inserted: いいえ
:already started: いいえ
:non-blocking: はい
:execute: はい
:create: [[構文解析器]]
:parser-inserted: はい
:non-blocking: いいえ
:execute: はい
:already started: いいえ
:create: [[構文解析器]] ([CODE(DOMa)@en[[[innerHTML]]]], [CODE(DOMa)@en[[[outerHTML]]]],
[CODE(DOMm)@en[[[insertAdjacentHTML]]]], [CODE(DOMm)@en[[[createContextualFragment]]]])
:parser-inserted: はい
:non-blocking: いいえ
:already started: はい
:execute: いいえ
:create: [CODE(XML)@en[[[xml-stylesheet]]]] で参照された
[[XSLTスタイルシート]] [SRC[>>130]]
:parser-inserted: はい
:already started: いいえ
:non-blocking: ?
:execute: はい
:create: [CODE(DOMm)@en[[[transformToDocument]]]] [SRC[>>130]]
:parser-inserted: はい
:already started: はい
:non-blocking: ?
:execute: いいえ
:create: [CODE(DOMm)@en[[[transformToFragment]]]] [SRC[>>130]]
:parser-inserted: いいえ
:already started: いいえ
:non-blocking: ?
:execute: はい
:create: [CODE(DOMm)@en[[[cloneNode]]]]
:already started: 複製元と同じ
:parser-inserted: いいえ
:non-blocking: はい
:create: 作成後 [CODE(DOMm)@en[[[setAttribute]]]] 等で [CODE(HTMLa)@en[[[async]]]] [[内容属性]]追加
:non-blocking: いいえ
:create: 作成後 [CODE(DOMa)@en[[[async]]]] [[IDL属性]]に値を設定
:non-blocking: いいえ
]FIG]
[479] 更に、[[要素]]が[[文書に挿入]]された時点で、[[スクリプトの準備]]が行われます。
ただし[[スクリプト]]ではなく[[構文解析器]]によって挿入された場合は、
([[開始タグ]]時点で発生する) [[挿入]]の時点ではなく、[[終了タグ]]時点で行われます。
[480] [[スクリプトの準備]]の後に、[[スクリプトブロックの実行]]で、
実際に[[スクリプト]]が実行されます。これは [[fetch]] など必要な条件が整った時に行われます。
([[スクリプトの準備]]から直接呼び出されることもあれば、
[[構文解析]]完了時などかなり遅延される場合もあります。)
[481] これだけでも相当複雑ですが、[[構文解析器]]が挿入した
[CODE(HTMLe)@en[[[script]]]] [[要素]]の[[スクリプト]]が [CODE(JS)@en[[[document.write]]]]
を呼び出し、そこで[[構文解析器]]が再帰的に実行されて [CODE(HTMLe)@en[[[script]]]]
[[要素]]が新たに挿入される場合も考慮する必要があるので、
[[スパゲッティ]]もびっくりなレベルで複雑に交錯しています。
** 構文解析器の処理
[414] [[構文解析器]]は、 [CODE(HTMLe)@en[[[script]]]] [[開始タグ]]の処理において
[CODE(HTMLe)@en[[[script]]]] [[要素]][VAR[要素]]を作成した直後、
[[挿入]]する直前に、次のようにしなければ[['''なりません''']] [SRC[>>413, >>424]]。
[FIG(steps)[
= [415] [VAR[要素]]の[F[[[「構文解析器挿入」]]フラグ]]を設定します。
= [416] [VAR[要素]]の[F[[[「非ブロッキング」]]フラグ]]を消去します。
= [417] 本[[構文解析器]]が[[素片構文解析アルゴリズム]]で作られたものなら、
== [418] [VAR[要素]]の[F[[[「開始済み」]]フラグ]]を設定します。
]FIG]
;; [425] [[HTML Standard]] は[[XML構文解析器]]の処理において >>414
を[[スクリプトが有効]]な場合に限定していますが、
[[HTML構文解析器]]にはそのような制約はありません。
処理の整合性を考慮すると[[HTML構文解析器]]の動作が正しいと思われます。
[420] [[HTML構文解析器]]は、 [["in text"]] [[挿入モード]]で
[CODE(HTMLe)@en[[[script]]]] [[要素]]が[[現在節点]]の時
[[EOF]] [[字句]]を処理する場合には、
[[開いている要素のスタック]]から[[現在節点]]を除去する直前に、
次のようにしなければ[['''なりません''']] [SRC[>>419]]。
[FIG(steps)[
= [421] [VAR[要素]]の[F[[[「開始済み」]]フラグ]]を設定します。
]FIG]
;; [426] [[HTML Standard]] には [[XML構文解析器]]の処理でこれに相当する規定がありませんが、
[[整形式]]でなくても場合によっては[[スクリプト]]からアクセスできるとすると、
同様の扱いが必要と思われます。
;; [428] [[HTML構文解析器]]で [[SVG]] [CODE(XMLe)@en[[[script]]]]
[[要素]]を処理する際にも、同様の措置が必要かもしれません。
[423] [[構文解析器]][VAR[構文解析器]]は、 [CODE(HTMLe)@en[[[script]]]]
[[要素]][VAR[要素]]が[[現在節点]]である時、[VAR[要素]]を[[開いている要素のスタック]]から
[[pop]] したり、[[挿入モード]]など[[構文解析器]]の状態を適宜変更した直後に、
次のようにしなければ[['''なりません''']] [SRC[>>422, >>424]]。
[FIG(steps)[
= [432] [VAR[構文解析器]]の[F[[[文書]]]]の[F[[[イベントループ]]]]の[F[[[JavaScript実行文脈スタック]]]]が空なら、
== [433] [VAR[構文解析器]]の[F[[[文書]]]]の[F[[[イベントループ]]]]について[[マイクロタスクチェックポイントを実行]]します。
= [434] [VAR[旧挿入点]]を、[VAR[構文解析器]]の[F[[[挿入点]]]]に設定します。
= [435] [VAR[構文解析器]]の[F[[[挿入点]]]]を、[VAR[構文解析器]]の[F[[[次入力文字]]]]の直前に設定します。
= [436] [VAR[構文解析器]]の[F[[[スクリプト入れ子水準]]]]を、[[インクリメント]]します。
= [437] [VAR[要素]]について[[スクリプトの準備]]を実行します。
=- [438] ここで[[スクリプト]]が実行されることがあります。
=- [439] つまり [CODE(JS)@en[[[document.write]]]] が呼び出されることがあります。
= [440] [VAR[構文解析器]]の[F[[[スクリプト入れ子水準]]]]を、[[デクリメント]]します。
= [441] [VAR[構文解析器]]の[F[[[スクリプト入れ子水準]]]]が0なら、
== [442] [VAR[構文解析器]]の[F[[[parser pause flag]]]] を、[[偽]]に設定します。
= [443] [VAR[構文解析器]]の[F[[[挿入点]]]]を、[VAR[旧挿入点]]に設定します。
= [465] [VAR[構文解析器]]の [[pending parsing-blocking script]] の処理 (>>466) を行います。
]FIG]
;; [431] これは [[HTML構文解析器]]では [["in text"]] [[挿入モード]]で
[CODE(HTMLe)@en[[[script]]]] [[終了タグ]]を処理する時に実行されます [SRC[>>422]]。
[[XML構文解析器]]では [CODE(HTMLe)@en[[[script]]]]
[[要素]]が[[開いている要素のスタック]]から [[pop]] した時に実行されます [SRC[>>424]]。
[[整形式]]でない [[XML文書]]を考慮する場合は、仕様書に明文化されている場合の他、
複数の[[要素]]をまとめて [[pop]] する場合もあるかもしれません。
;; [464] [[HTML Standard]] は[[XML構文解析器]]についてもう少し違った
(より簡単な) 手順を示していますが、[[HTML構文解析器]]特有の内部状態が
[[XML構文解析器]]にも存在すると考えれば、場合分けなく共通の処理にできます。
[430] [[Firefox]] と [[IE11]] は [[HTML Standard]] に従い[[スクリプト]]実行前に[[マイクロタスクチェックポイント]]を実行するように見えます。
[[Chrome]] は実行しないように見えます。 [TIME[2016-02-22T15:45:40.600Z]]
@@ [429] [[HTML構文解析器]]で [[SVG]] [CODE(XMLe)@en[[[script]]]] [[要素]] [SRC[>>427]]
** DOM 操作の副作用
[250] [[節点]][VAR[子節点]]の[[節点の接続]]の処理は、
次のようにしなければ[['''なりません''']] [SRC[>>130]]。
[FIG(steps)[
= [252] [VAR[子節点]]が [CODE(HTMLe)@en[[[script]]]] [[要素]]であり、
[F[[[「構文解析器挿入」]]フラグ]]が設定されてい''なければ''、
== [253] [VAR[子節点]]について[[スクリプトを準備]]します。
= [254] [VAR[子節点]]の[F[親][parentNode]]が [CODE(HTMLe)@en[script]] [[要素]]であり、
[VAR[子節点]]の[F[親][parentNode]]の[F[[[「構文解析器挿入」]]フラグ]]が設定されてい''なければ''、
== [255] [VAR[子節点]]の[F[親][parentNode]]について[[スクリプトを準備]]します。
]FIG]
;; [251] [[節点の接続]]、すなわち[[影を含む文書中]]となったときに実行されます。
つまり[[文書木]]本体のみならず、[[影木]]への[[挿入]]でも [CODE(HTMLe)@en[script]]
[[要素]]は実行されます。
[247] [[clone]] 時の処理は、 [[cloning steps]] 参照。
** スクリプトの準備
[257] [VAR[要素]]の[DFN[[RUBYB[スクリプトの準備]@en[prepare a script]]]]は、
次のようにしなければ[['''なりません''']] [SRC[>>130]]。
[FIG(steps)[
= [258] [VAR[要素]]の[F[[RUBYB[[[「開始済み」]]]@en["already executed"]]フラグ]]が設定されていれば、
ここで停止します。
= [259] [VAR[要素]]の[F[[[「構文解析器挿入」]]フラグ]]が設定されていれば、
== [260] [VAR[構文解析器挿入だった]]を、[[真]]に設定します。
== [263] [VAR[要素]]の[F[[[「構文解析器挿入」]]フラグ]]を消去します。
== [267] [VAR[要素]]に [CODE(HTMLa)@en[[[async]]]] [[内容属性]]がなければ、
=== [268] [VAR[要素]]の[F[[[「非ブロッキング」]]フラグ]]を設定します。
= [261] それ以外なら、
== [262] [VAR[構文解析器挿入だった]]を、[[偽]]に設定します。
= [269] [VAR[要素]]に [CODE(HTMLa)@en[[[src]]]] [[属性]]がなく、
[VAR[要素]]の[F[[[子供]]]]が0個[[以上]]の[[注釈節点]]と[F[[[データ]]]]が[[空文字列]]の
[CODE(DOMi)@en[[[Text]]]] [[節点]]で構成されているなら、
ここで停止します。
= [270] [VAR[要素]]が[[文書中]]でなければ、ここで停止します。
= [286] [VAR[要素]]の[[スクリプトブロックの型文字列]]により、
[FIG(switch)[
: [[JavaScript MIME型]]のいずれかと [[ASCII大文字・小文字不区別]]で一致 :
[VAR[要素]]の[F[[[スクリプトの型]]]]を、[CODE[[[classic]]]] に設定します。
: [CODE[[[module]]]] と [[ASCII大文字・小文字不区別]]で一致 :
[VAR[要素]]の[F[[[スクリプトの型]]]]を、[CODE[[[module]]]] に設定します。
: それ以外 :
ここで停止します。
]FIG]
= [274] [VAR[要素]]の[F[[[「開始済み」]]フラグ]]を設定します。
= [271] [VAR[構文解析器挿入だった]]が[[真]]なら、
== [272] [VAR[要素]]の[F[[[「構文解析器挿入」]]フラグ]]を設定します。
== [273] [VAR[要素]]の[F[[[「非ブロッキング」]]フラグ]]を消去します。
== [275] [VAR[要素]]の[F[[[節点文書]]]]が[VAR[要素]]を作成した[[構文解析器]]の[[文書]]と異なるなら、
=== [276] ここで停止します。
= [282] [VAR[要素]]について[F[[[スクリプトが無効]]]]なら、ここで停止します。
= [283] [VAR[要素]]が [CODE(HTMLa)@en[[[src]]]] [[属性]]を持たない場合、
== [284] [VAR[結果]]を、[VAR[要素]]と [CODE[[[script]]]] について
[[Should element's inline behavior be blocked by Content Security Policy?]] を実行した結果に設定します。
== [288] [VAR[結果]]が [CODE[[[Blocked]]]] なら、ここで停止します。
= [289] [VAR[要素]]が [CODE(HTMLa)@en[[[event]]]] [[属性]]と
[CODE(HTMLa)@en[[[for]]]] [[属性]]を持ち、
[VAR[要素]]の[F[[[スクリプトの型]]]]が [CODE[[[classic]]]] なら、
== [290] [VAR[要素]]の [CODE(HTMLa)[[[for]]]] [[属性値]]が先頭と末尾の0個[[以上]]の[[間隔文字]]を無視すると
[[ASCII大文字・小文字不区別]]で [CODE[[[window]]]] と一致するなら、ここで停止します。
== [291] [VAR[要素]]の [CODE(HTMLa)[[[event]]]] [[属性値]]が先頭と末尾の0個[[以上]]の[[間隔文字]]を無視すると
[[ASCII大文字・小文字不区別]]で [CODE[[[onload]]]] または
[CODE[[[onload()]]]] と一致するなら、ここで停止します。
= [298] それ以外なら、
== [299] [VAR[符号化]]を、[VAR[要素]]の[F[[[節点文書]]]]の[F[[[文書の符号化]]]]に設定します。
= [300] [VAR[CORS設定]]を、[VAR[要素]]の [CODE(HTMLa)@en[crossorigin]] [[属性]]の[F[状態]]に設定します。
= [516] [VAR[nonce]] を、 [CODE(HTMLa)@en[nonce]] [[属性値]]に設定します。
= [517] [VAR[nonce]] が [[null]] なら、 [VAR[nonce]] を、[[空文字列]]に設定します。
= [301] [VAR[設定群]]を、[VAR[要素]]の[F[[[節点文書]]]]の[F[[CODE(DOMi)@en[[[Window]]]]]]の[F[[[環境設定群オブジェクト]]]]に設定します。
= [338] [[[CODE(DOMe)@en[load]]イベントの遅延]] (>>248) を開始します。
= [302] [VAR[要素]]に [CODE(HTMLa)@en[[[src]]]] [[属性]]があれば、
== [303] [VAR[src]] を、[VAR[要素]]の [CODE(HTMLa)@en[[[src]]]] [[属性値]]に設定します。
== [304] [VAR[src]] が[[空文字列]]なら、
=== [385] [VAR[要素]]のエラーを通知するタスクを追加 (>>305) します。
=== [341] [[[CODE(DOMe)@en[load]]イベントの遅延]] (>>248) を終了します。
=== [386] ここで停止します。
== [308] [VAR[要素]]の[F[[[外部ファイルから]]]]フラグを設定します。
== [309] [VAR[URL]] を、 [VAR[src]] について[VAR[要素]]の[F[[[節点文書]]]]に対して[[URLの構文解析]]を実行した[[結果URL記録]]に設定します。
== [310] [VAR[URL]] が失敗なら、
=== [387] [VAR[要素]]のエラーを通知するタスクを追加 (>>305) します。
=== [388] [[[CODE(DOMe)@en[load]]イベントの遅延]] (>>248) を終了します。
=== [389] ここで停止します。
== [311] [VAR[要素]]の[F[スクリプトの型]]により、
[FIG(switch)[
: [CODE[classic]] :
[FIG(steps)[
= [294] [VAR[要素]]が [CODE(HTMLa)@en[[[charset]]]] [[属性]]を持つなら、
== [295] [VAR[符号化]]を、[VAR[要素]]の [CODE(HTMLa)@en[[[charset]]]] [[属性値]]について[[符号化を取得]]した結果に設定します。
== [296] [VAR[符号化]]が失敗なら、
=== [297] [VAR[符号化]]を、[VAR[要素]]の[F[節点文書]]の[F[符号化][文書の符号化]]に設定します。
= [522] それ以外なら、
== [523] [VAR[符号化]]を、[VAR[要素]]の[F[節点文書]]の[F[符号化][文書の符号化]]に設定します。
= [313] [[古典スクリプトのfetch]]を実行します。
[FIG(list members)[
: [VAR[URL]] : [VAR[URL]]
: [VAR[CORS設定]] : [VAR[CORS設定]]
: [VAR[nonce]] : [VAR[nonce]]
: [VAR[構文解析器状態]] :
[VAR[要素]]の[F[「構文解析器挿入」フラグ]]が[[真]]なら
[CODE[parser-inserted]]、それ以外なら [CODE[not-parser-inserted]]
: [VAR[設定群]] : [VAR[設定群]]
: [VAR[符号化]] : [VAR[符号化]]
: [VAR[続きの処理]] : >>316
]FIG]
]FIG]
: [CODE[module]] :
[[モジュールスクリプト木のfetch]]を実行します。
[FIG(list members)[
: [VAR[URL]] : [VAR[URL]]
: [VAR[nonce]] : [VAR[nonce]]
: [VAR[構文解析器状態]] :
[VAR[要素]]の[F[「構文解析器挿入」フラグ]]が[[真]]なら
[CODE[parser-inserted]]、それ以外なら [CODE[not-parser-inserted]]
: [VAR[設定群]] : [VAR[設定群]]
: [VAR[終点]] : [CODE[script]]
: [VAR[credentialsモード]] : [VAR[CORS設定]]から得た [[credentialsモード]]
: [VAR[続きの処理]] : >>316
]FIG]
]FIG]
= [327] それ以外なら、
== [328] [VAR[ソーステキスト]]を、 [VAR[要素]]の [CODE(DOMa)@en[[[text]]]]
[[IDL属性]]の値に設定します。
== [329] [VAR[要素]]の[F[スクリプトの型]]により、
[FIG(switch)[
: [CODE[classic]] :
[FIG(steps)[
= [331] [VAR[要素]]の[F[[[スクリプトのスクリプト]]]]を、
[VAR[ソーステキスト]]と[VAR[設定群]]について[[古典スクリプトを作成]]した結果に設定します。
= [332] [VAR[要素]]の[F[[[スクリプトの準備完了]]]]とします。
]FIG]
: [CODE[module]] :
[FIG(steps)[
= [333] [VAR[基底URL]]を、 [VAR[要素]]の[F[[[設定文書]]]]の[F[[[文書基底URL]]]]に設定します。
= [334] [VAR[スクリプト]]を、[VAR[ソーステキスト]]、[VAR[設定群]]、
[VAR[基底URL]]、[VAR[CORS設定]]について[[モジュールスクリプトを作成]]した結果に設定します。
= [335] [VAR[スクリプト]]が null なら、
== [336] [VAR[要素]]の[F[[[スクリプトのスクリプト]]]]を null に設定します。
== [337] [VAR[要素]]の[F[[[スクリプトの準備完了]]]]とします。
= [339] それ以外の場合、
== [340] [VAR[スクリプト]]について[[モジュールスクリプトの子孫のfetch]]を実行します。
[VAR[続きの処理]]は、 >>316 とします。
]FIG]
]FIG]
= [361] >>360 の実行タイミングにより、
[FIG(switch)[
:甲:
[VAR[要素]]を作成した[[構文解析器]]の[F[[[文書]]]]の
[F[[[list of scripts that will execute when the document has finished parsing]]]]
の末尾に[VAR[要素]]を追加します。
:乙:
[VAR[要素]]を作成した[[構文解析器]]の[F[[[文書]]]]の
[F[[[pending parsing-blocking script]]]] を、[VAR[要素]]に設定します。
:丙:
[VAR[要素]]の[F[[[節点文書]]]]の
[F[[[list of scripts that will execute in order as soon as possible]]]]
の末尾に[VAR[要素]]を追加します。
:丁:
[VAR[要素]]の[F[[[節点文書]]]]の
[F[[[set of scripts that will execute as soon as possible]]]]
に[VAR[要素]]を追加します。
:戊:
[VAR[要素]]を作成した[[構文解析器]]の[F[[[文書]]]]の
[F[[[pending parsing-blocking script]]]]
を、[VAR[要素]]に設定します。
]FIG]
]FIG]
[316] [[スクリプトのfetch]]の[VAR[続きの処理]]は、
[VAR[スクリプト]]について次のようにしなければ[['''なりません''']] [SRC[>>130]]。
[FIG(steps)[
= [317] [VAR[要素]]の[F[[[スクリプトのスクリプト]]]]を、[VAR[スクリプト]]に設定します。
= [318] [VAR[要素]]の[F[[[スクリプトの準備完了]]]]とします (>>365)。
]FIG]
[320] [[スクリプトの準備]]は、次の動作から呼び出されることがあります。
[FIG(list)[
- [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[挿入手順]] (>>250)
- [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[子供]]の[[挿入手順]] (>>250)
- [CODE(HTML)@en[[[<script src>]]]] の[[属性の追加]]
]FIG]
[319] [[利用者エージェント]]は、[[性能]]のため、
[CODE(HTMLe)@en[[[script]]]] [[要素]]に [CODE(HTMLa)@en[[[src]]]]
[[属性の設定]]が行われた時点で、[[スクリプトの準備]]による[[スクリプトのfetch]]を行って構いません
[SRC[>>130]]。 (実行はまだ行わず、後に[[文書に挿入]]された時に
([[属性]]などの状況が変わっていなければ) [[fetch]] 結果を利用します。)
;; [326] 実装によっては更に早い段階 ([[preload scanner]]) で [[fetch]]
が実行されています。
[264] [[スクリプトの準備]]の処理に関連して、
[CODE(HTMLe)@en[[[script]]]] [[要素]]には次のような性質があります。
[FIG(list)[
- [285] [CODE(HTMLa)@en[[[language]]]] [[属性]]は、 [CODE(HTMLa)@en[[[type]]]]
[[属性]]があれば無視されます。
- [287] [CODE(HTMLa)@en[[[type]]]] [[属性]]の [[MIME型]]に[[引数]]を指定すると、
[[JavaScript]] とはみなされず、[[スクリプト]]は実行されません。
- [265] [CODE(DOMa)@en[[[innerHTML]]]] などで挿入された [CODE(HTMLe)@en[[[script]]]]
[[要素]]は、実行されません。
- [266] [[構文解析器]]によって挿入されたものの実行されなかった [CODE(HTMLe)@en[[[script]]]]
[[要素]]は、(適当な[[属性]]の変更などを経て) 別の機会に実行される可能性があります。
その場合は [CODE(HTMLa)@en[[[async]]]] [[属性]]が設定されていたものとみなされることがあります。
- [321] [CODE(HTMLa)@en[[[event]]]] [[属性]]や [CODE(HTMLa)@en[[[for]]]]
[[属性]]は、[[古典スクリプト]]でのみ効力を持ちます。
- [322] [CODE(HTMLa)@en[[[charset]]]] [[属性]]は、[[古典スクリプト]]でのみ効力を持ちます。
- [363] [[構文解析器]]の実行途中で挿入された [CODE(HTMLe)@en[[[script]]]]
[[要素]]が [[fetch]] 待ちの間に他の[[文書]]に [[adopt]] されると、
その[[スクリプト]]は実行されなくなります。しかし [[fetch]]
完了まで[[構文解析器]]の停止や[[[CODE(DOMe)@en[load]]イベントの遅延]]は継続します。
- [501] [CODE(HTMLa)@en[[[defer]]]] [[属性]]と [CODE(HTMLa)@en[[[async]]]]
[[属性]]は、[[古典スクリプト]]では [CODE(HTMLa)@en[[[src]]]]
[[属性]]が無い時無視されます。
- [502] [[古典スクリプト]]では [CODE(HTMLa)@en[[[src]]]]
[[属性]]の有無で動作が大きく変わりますが、
[[モジュールスクリプト]]ではそこまで大きくは変わりません。
]FIG]
** スクリプトの準備完了
[364] [CODE(HTMLe)@en[[[script]]]] [[要素]]は、
[[スクリプトの準備]]の実行の過程で、
[DFN[[RUBYB[スクリプトの準備完了]@en[the script is ready]]]] [SRC[>>130]]
となります。
[248] [CODE(HTMLe)@en[[[script]]]] [[要素]]の[F[[[スクリプトが準備完了]]]]するまで、
[F[[[節点文書]]]]の[[loadイベントを遅延]]しなければ[['''なりません''']] [SRC[>>130]]。
つまり[[構文解析器]]の動作中に[[スクリプトのfetch]]が開始されると、
それが (成功であれ失敗であれ) 完了するまでは [CODE(DOMe)@en[[[load]]]]
は[[発火]]されません。
;; [367] [F[[[節点文書]]]]が変化した場合の扱いは不明です。
[365] [VAR[要素]]の[[スクリプトの準備完了]]により、
次のようにしなければ[['''なりません''']] [SRC[>>130]]。
[FIG(steps)[
= [366] >>360 の実行タイミングにより、
[FIG(switch)[
:甲、乙、戊:
[FIG(steps)[
= [368] [VAR[要素]]の[F[[[「構文解析器実行準備完了」]]フラグ]]を設定します。
= [475] >>453 や >>489 の[[スピン]]を終了できるかもしれません。
]FIG]
:丙:
[FIG(steps)[
= [369] [VAR[リスト]]を、 >>361 の
[F[[[list of scripts that will execute in order as soon as possible]]]] に設定します。
= [373] [VAR[リスト]]の最初の[[要素]]が[VAR[要素]]の場合、
== [371] [VAR[要素]]の[F[準備完了フラグ]]を設定します。
= [370] [VAR[リスト]]の最初の[[要素]]の[F[準備完了フラグ]]が設定されている限り繰り返し、
== [372] [VAR[リスト]]の最初の[[要素]]について[[スクリプトブロックを実行]]します。
== [374] [VAR[リスト]]から最初の[[要素]]を削除します。
= [497] [[stop parsing]] 内の[[スピン]]中なら、これを終了できるかもしれません。
]FIG]
:丁:
[FIG(steps)[
= [375] [VAR[要素]]について[[スクリプトブロックを実行]]します。
= [376] >>361 の
[F[[[set of scripts that will execute as soon as possible]]]]
から[VAR[要素]]を削除します。
= [498] [[stop parsing]] 内の[[スピン]]中なら、これを終了できるかもしれません。
]FIG]
:己:
[FIG(steps)[
= [378] [VAR[要素]]について[[スクリプトブロックを実行]]します。
]FIG]
]FIG]
]FIG]
;; [377] >>361 とは通常は[VAR[要素]]の[F[[[節点文書]]]]ですが、
処理がここに到着するまでの間に[VAR[要素]]が他の[[文書]]に [[adopt]]
される可能性もあります。
** 実行タイミング
[164] [CODE(HTMLe)@en[[[script]]]] [[要素]]から作成された[[スクリプト]]の実行のタイミングは、
[[構文解析器]]によって作られた [CODE(HTMLe)@en[[[script]]]]
[[要素]]か否かや、[[属性]]の有無により、何種類かあります。
[FIG(list)[
- [169] その場
-- その他の場合
-- その場 (挿入や[[終了タグ]]の時点) で実行されます。
[[スクリプト]]内から呼ばれている場合も、再帰的に[[スクリプト]]を実行します。
- [165] [[文書]]の[F[[[pending parsing-blocking script]]]]
-- ([CODE(HTMLa)@en[[[src]]]] & [["parser-inserted"]]) or [[has a style sheet that is blocking scripts]] の場合
-- [[構文解析器]]によって[[スクリプト]]を実行中ならすべて完了させてから、
必要な[[スクリプト]]や[[スタイルシート]]が読み込まれるまで[[構文解析]]を中断し、
読み込まれた時点で実行され、[[構文解析]]も再開されます。
- [166] [[文書]]の[F[[[list of scripts that will execute when the document has finished parsing]]]]
-- [CODE(HTMLa)@en[[[src]]]] & [CODE(HTMLa)@en[[[defer]]]] & [["parser-inserted"]] の場合
-- [[stop parsing]] が実行します。
- [167] [[文書]]の[F[[DFN[[[list of scripts that will execute in order as soon as possible]]]]]] [SRC[>>130]]
-- [CODE(HTMLa)@en[[[src]]]] の場合
-- [[fetch]] 完了時の[[タスク]]で実行します。
-- [[構文解析]]実行中に登録された場合、実行完了まで [CODE(DOMe)@en[[[load]]]] を遅延させます。
- [168] [[文書]]の[F[[DFN[[[set of scripts that will execute as soon as possible]]]]]] [SRC[>>130]]
-- [CODE(HTMLa)@en[[[src]]]] & [CODE(HTMLa)@en[[[async]]]] の場合
-- [[fetch]] 完了時の[[タスク]]で実行します。
-- [[構文解析]]実行中に登録された場合、実行完了まで [CODE(DOMe)@en[[[load]]]] を遅延させます。
]FIG]
[170] >>169、>>165、>>166 は、[[構文解析器]]を呼び出した[[タスク]]の中で直接[[スクリプト]]が同期的に実行されます。
いずれにせよ[[構文解析器]]内部で[[スクリプト]]が実行されるのは、 [[HTML]] または [[SVG]]
の [CODE(HTMLe)@en[[[script]]]] [[終了タグ]] (または
[[SVG]] [CODE(HTMLe)@en[[[script]]]] [[空要素タグ]]) の処理中に限られます。
[171] >>167 と >>168 は、[[構文解析器]]とは別の[[タスク]]で[[スクリプト]]が実行されます。
[172] [[タスク]]は[[イベントループ]]によって処理されるので、
>>171 の場合[[構文解析器]]と[[スクリプト]]が同時に実行されることはありません。
また [[UIイベント]]や [CODE(DOMm)@en[[[setTimeout]]]] の[[コールバック]]などが[[構文解析器]]の動作期間中に実行されることもありますが、
やはり別の[[タスク]]として処理されるので、[[構文解析器]]や他の[[スクリプト]]と同時に実行されることはありません。
[173] なお [CODE(HTMLe)@en[[[script]]]] [[要素]]の[[スクリプト]]は、
それ自体のコードの実行の他に、前後に各種[[イベント]]が[[dispatch]]されたり、
[[エラーの報告]]が行われたりすることがあり、[[同期的]]に複数の[[スクリプト]]が同[[タスク]]内で実行されることがあります
[WEAK[(が、やはり同時にではありません)]]。
[174] [CODE(HTMLe)@en[[[script]]]] [[タグ]]の処理前には[[マイクロタスクチェックポイント]]があり、
[[マイクロタスク]]があればそのタイミングで、つまり[[構文解析器]]と同じ[[タスク]]の内部で同期的に実行されます。
*** 実行タイミングの決定
[360] [VAR[要素]]の実行タイミングの種別は、次の通り決定しなければ[['''なりません''']] [SRC[>>140]]。
甲乙丙丁戊己のいずれかに定まります。
[FIG(steps)[
= [342] [VAR[要素]]の[F[[[スクリプトの型]]]]が [CODE[[[classic]]]] の場合、
== [356] [VAR[要素]]が [CODE(HTMLa)@en[[[src]]]] [[属性]]を持つ場合、
=== [352] [VAR[要素]]が [CODE(HTMLa)@en[[[async]]]] [[属性]]を持たない場合、
==== [347] [VAR[要素]]が[F[[[「構文解析器挿入」]]フラグ]]を持つ場合、
===== [345] [VAR[要素]]が [CODE(HTMLa)@en[[[defer]]]] [[属性]]を持つ場合、
====== 甲
===== [346] それ以外の場合、
====== 乙
==== [348] それ以外で、[VAR[要素]]が[F[[[「非ブロッキング」]]フラグ]]を持たない場合、